diff options
author | Antonio Vazquez <blendergit@gmail.com> | 2022-04-25 11:11:55 +0300 |
---|---|---|
committer | Antonio Vazquez <blendergit@gmail.com> | 2022-04-25 11:11:55 +0300 |
commit | d3b5ab37772aafd6892466a61eb75741f70189de (patch) | |
tree | fd5a4c1b0a76313ddee5b2a1fa93a7b6f618cd85 | |
parent | 99dfc769f32a53c118692451d38d534bed697e88 (diff) | |
parent | 416ef3b6b2d21a2eb7a24183ab67c8a540f79d57 (diff) |
Merge branch 'master' into temp-gp-overlay-refactortemp-gp-overlay-refactor
457 files changed, 11559 insertions, 7710 deletions
diff --git a/.editorconfig b/.editorconfig index 41ec3a1dc3d..0d2ec3d0766 100644 --- a/.editorconfig +++ b/.editorconfig @@ -34,6 +34,15 @@ indent_style = space indent_size = 2 max_line_length = 99 +# Tom's Obvious Minimal Language +[*.toml] +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 +max_line_length = 120 + # reStructuredText [*.rst] charset = utf-8 diff --git a/CMakeLists.txt b/CMakeLists.txt index cc39429742e..3a80fefac8c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,7 +284,7 @@ option(WITH_IMAGE_TIFF "Enable LibTIFF Support" ON) option(WITH_IMAGE_DDS "Enable DDS Image Support" ON) option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON) option(WITH_IMAGE_HDR "Enable HDR Image Support" ON) -option(WITH_IMAGE_WEBP "Enable WebP Image Support" OFF) +option(WITH_IMAGE_WEBP "Enable WebP Image Support" ON) # Audio/Video format support option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON) @@ -302,7 +302,7 @@ option(WITH_USD "Enable Universal Scene Description (USD) Suppor option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON) # Sound output -option(WITH_SDL "Enable SDL for sound and joystick support" ON) +option(WITH_SDL "Enable SDL for sound" ON) option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON) if(APPLE) option(WITH_COREAUDIO "Enable CoreAudio for audio support on macOS" ON) @@ -439,12 +439,7 @@ endif() # AMD HIP if(NOT APPLE) - if(WIN32) - option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON) - else() - option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" OFF) - endif() - + option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON) option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF) set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 CACHE STRING "AMD HIP architectures to build binaries for") mark_as_advanced(WITH_CYCLES_DEVICE_HIP) diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 40e5c35f990..8f4738d1f1c 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -29,8 +29,9 @@ cmake_minimum_required(VERSION 3.5) include(ExternalProject) include(cmake/check_software.cmake) -include(cmake/options.cmake) include(cmake/versions.cmake) +include(cmake/options.cmake) +include(cmake/boost_build_options.cmake) include(cmake/download.cmake) if(ENABLE_MINGW64) @@ -46,6 +47,7 @@ include(cmake/png.cmake) include(cmake/jpeg.cmake) include(cmake/blosc.cmake) include(cmake/pthreads.cmake) +include(cmake/imath.cmake) include(cmake/openexr.cmake) include(cmake/brotli.cmake) include(cmake/freetype.cmake) @@ -75,7 +77,6 @@ endif() include(cmake/osl.cmake) include(cmake/tbb.cmake) include(cmake/openvdb.cmake) -include(cmake/nanovdb.cmake) include(cmake/python.cmake) option(USE_PIP_NUMPY "Install NumPy using pip wheel instead of building from source" OFF) if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64")) @@ -94,12 +95,15 @@ include(cmake/pugixml.cmake) include(cmake/ispc.cmake) include(cmake/openimagedenoise.cmake) include(cmake/embree.cmake) +include(cmake/fmt.cmake) +include(cmake/robinmap.cmake) if(NOT APPLE) include(cmake/xr_openxr.cmake) endif() # OpenColorIO and dependencies. include(cmake/expat.cmake) +include(cmake/pystring.cmake) include(cmake/yamlcpp.cmake) include(cmake/opencolorio.cmake) @@ -107,8 +111,9 @@ if(BLENDER_PLATFORM_ARM) include(cmake/sse2neon.cmake) endif() -if(WITH_WEBP) - include(cmake/webp.cmake) +include(cmake/webp.cmake) +if(NOT APPLE) + include(cmake/level-zero.cmake) endif() if(NOT WIN32 OR ENABLE_MINGW64) diff --git a/build_files/build_environment/cmake/alembic.cmake b/build_files/build_environment/cmake/alembic.cmake index 29251afe58f..484a7849ace 100644 --- a/build_files/build_environment/cmake/alembic.cmake +++ b/build_files/build_environment/cmake/alembic.cmake @@ -1,30 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later set(ALEMBIC_EXTRA_ARGS - -DBUILDSTATIC=ON - -DLINKSTATIC=ON - -DILMBASE_ROOT=${LIBDIR}/openexr - -DALEMBIC_ILMBASE_INCLUDE_DIRECTORY=${LIBDIR}/openexr/include/OpenEXR - -DALEMBIC_ILMBASE_HALF_LIB=${LIBDIR}/openexr/lib/${LIBPREFIX}Half${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DALEMBIC_ILMBASE_IMATH_LIB=${LIBDIR}/openexr/lib/${LIBPREFIX}Imath${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DALEMBIC_ILMBASE_ILMTHREAD_LIB=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmThread${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DALEMBIC_ILMBASE_IEX_LIB=${LIBDIR}/openexr/lib/${LIBPREFIX}Iex${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DALEMBIC_ILMBASE_IEXMATH_LIB=${LIBDIR}/openexr/lib/${LIBPREFIX}IexMath${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DUSE_PYILMBASE=0 - -DUSE_PYALEMBIC=0 - -DUSE_ARNOLD=0 - -DUSE_MAYA=0 - -DUSE_PRMAN=0 - -DUSE_HDF5=Off - -DUSE_STATIC_HDF5=Off - -DUSE_TESTS=Off - -DALEMBIC_NO_OPENGL=1 + -DImath_ROOT=${LIBDIR}/imath + -DUSE_PYALEMBIC=OFF + -DUSE_ARNOLD=OFF + -DUSE_MAYA=OFF + -DUSE_PRMAN=OFF + -DUSE_HDF5=OFF + -DUSE_TESTS=OFF -DUSE_BINARIES=ON - -DALEMBIC_ILMBASE_LINK_STATIC=On + -DALEMBIC_ILMBASE_LINK_STATIC=OFF -DALEMBIC_SHARED_LIBS=OFF - -DGLUT_INCLUDE_DIR="" - -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY} - -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/ ) ExternalProject_Add(external_alembic @@ -55,6 +41,5 @@ endif() add_dependencies( external_alembic - external_zlib external_openexr ) diff --git a/build_files/build_environment/cmake/blosc.cmake b/build_files/build_environment/cmake/blosc.cmake index 57817a075c7..7dfa8853a8a 100644 --- a/build_files/build_environment/cmake/blosc.cmake +++ b/build_files/build_environment/cmake/blosc.cmake @@ -24,7 +24,6 @@ ExternalProject_Add(external_blosc DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${BLOSC_HASH_TYPE}=${BLOSC_HASH} PREFIX ${BUILD_DIR}/blosc - PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/blosc/src/external_blosc < ${PATCH_DIR}/blosc.diff CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/blosc ${DEFAULT_CMAKE_FLAGS} ${BLOSC_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/blosc ) diff --git a/build_files/build_environment/cmake/boost.cmake b/build_files/build_environment/cmake/boost.cmake index ca60bf832f5..57088e59cee 100644 --- a/build_files/build_environment/cmake/boost.cmake +++ b/build_files/build_environment/cmake/boost.cmake @@ -1,22 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later -set(BOOST_ADDRESS_MODEL 64) - -if(BLENDER_PLATFORM_ARM) - set(BOOST_ARCHITECTURE arm) -else() - set(BOOST_ARCHITECTURE x86) -endif() - if(WIN32) - if(MSVC_VERSION GREATER_EQUAL 1920) # 2019 - set(BOOST_TOOLSET toolset=msvc-14.2) - set(BOOST_COMPILER_STRING -vc142) - else() # 2017 - set(BOOST_TOOLSET toolset=msvc-14.1) - set(BOOST_COMPILER_STRING -vc141) - endif() - set(BOOST_CONFIGURE_COMMAND bootstrap.bat) set(BOOST_BUILD_COMMAND b2) set(BOOST_BUILD_OPTIONS runtime-link=shared ) @@ -36,11 +20,6 @@ else() set(BOOST_BUILD_COMMAND ./b2) set(BOOST_BUILD_OPTIONS cxxflags=${PLATFORM_CXXFLAGS} --disable-icu boost.locale.icu=off) set(BOOST_PATCH_COMMAND echo .) - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(BOOST_ADDRESS_MODEL 64) - else() - set(BOOST_ADDRESS_MODEL 32) - endif() endif() if(WITH_BOOST_PYTHON) diff --git a/build_files/build_environment/cmake/boost_build_options.cmake b/build_files/build_environment/cmake/boost_build_options.cmake new file mode 100644 index 00000000000..cc471078fcd --- /dev/null +++ b/build_files/build_environment/cmake/boost_build_options.cmake @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(BOOST_ADDRESS_MODEL 64) +if(BLENDER_PLATFORM_ARM) + set(BOOST_ARCHITECTURE arm) +else() + set(BOOST_ARCHITECTURE x86) +endif() + +if(WIN32) + if(MSVC_VERSION GREATER_EQUAL 1920) # 2019 + set(BOOST_TOOLSET toolset=msvc-14.2) + set(BOOST_COMPILER_STRING -vc142) + else() # 2017 + set(BOOST_TOOLSET toolset=msvc-14.1) + set(BOOST_COMPILER_STRING -vc141) + endif() +endif() + +set(DEFAULT_BOOST_FLAGS + -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING} + -DBoost_USE_MULTITHREADED=ON + -DBoost_USE_STATIC_LIBS=ON + -DBoost_USE_STATIC_RUNTIME=OFF + -DBOOST_ROOT=${LIBDIR}/boost + -DBoost_NO_SYSTEM_PATHS=ON + -DBoost_NO_BOOST_CMAKE=ON + -DBoost_ADDITIONAL_VERSIONS=${BOOST_VERSION_SHORT} + -DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/ +) diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index 5ca46c15d8d..80c53d05c28 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -71,9 +71,7 @@ download_source(FFMPEG) download_source(FFTW) download_source(ICONV) download_source(SNDFILE) -if(WITH_WEBP) - download_source(WEBP) -endif() +download_source(WEBP) download_source(SPNAV) download_source(JEMALLOC) download_source(XML2) @@ -102,3 +100,8 @@ download_source(HARU) download_source(ZSTD) download_source(FLEX) download_source(BROTLI) +download_source(FMT) +download_source(ROBINMAP) +download_source(IMATH) +download_source(PYSTRING) +download_source(LEVEL_ZERO) diff --git a/build_files/build_environment/cmake/embree.cmake b/build_files/build_environment/cmake/embree.cmake index 229c1800e16..2eafc729111 100644 --- a/build_files/build_environment/cmake/embree.cmake +++ b/build_files/build_environment/cmake/embree.cmake @@ -17,6 +17,16 @@ set(EMBREE_EXTRA_ARGS -DTBB_STATIC_LIB=${TBB_STATIC_LIBRARY} ) +if(BLENDER_PLATFORM_ARM) + set(EMBREE_EXTRA_ARGS + ${EMBREE_EXTRA_ARGS} + -DEMBREE_MAX_ISA=NEON) +else() + set(EMBREE_EXTRA_ARGS + ${EMBREE_EXTRA_ARGS} + -DEMBREE_MAX_ISA=AVX2) +endif() + if(TBB_STATIC_LIBRARY) set(EMBREE_EXTRA_ARGS ${EMBREE_EXTRA_ARGS} @@ -37,26 +47,15 @@ else() set(EMBREE_BUILD_DIR) endif() -if(BLENDER_PLATFORM_ARM) - ExternalProject_Add(external_embree - GIT_REPOSITORY ${EMBREE_ARM_GIT} - GIT_TAG "blender-arm" - DOWNLOAD_DIR ${DOWNLOAD_DIR} - PREFIX ${BUILD_DIR}/embree - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/embree ${DEFAULT_CMAKE_FLAGS} ${EMBREE_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/embree - ) -else() - ExternalProject_Add(external_embree - URL file://${PACKAGE_DIR}/${EMBREE_FILE} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH ${EMBREE_HASH_TYPE}=${EMBREE_HASH} - PREFIX ${BUILD_DIR}/embree - PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/embree/src/external_embree < ${PATCH_DIR}/embree.diff - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/embree ${DEFAULT_CMAKE_FLAGS} ${EMBREE_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/embree - ) -endif() +ExternalProject_Add(external_embree + URL file://${PACKAGE_DIR}/${EMBREE_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${EMBREE_HASH_TYPE}=${EMBREE_HASH} + PREFIX ${BUILD_DIR}/embree + PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/embree/src/external_embree < ${PATCH_DIR}/embree.diff + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/embree ${DEFAULT_CMAKE_FLAGS} ${EMBREE_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/embree +) add_dependencies( external_embree diff --git a/build_files/build_environment/cmake/fmt.cmake b/build_files/build_environment/cmake/fmt.cmake new file mode 100644 index 00000000000..74cb9e0c8ad --- /dev/null +++ b/build_files/build_environment/cmake/fmt.cmake @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(FMT_EXTRA_ARGS + -DFMT_TEST=Off +) + +ExternalProject_Add(external_fmt + URL file://${PACKAGE_DIR}/${FMT_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${FMT_HASH_TYPE}=${FMT_HASH} + PREFIX ${BUILD_DIR}/fmt + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/fmt ${DEFAULT_CMAKE_FLAGS} ${FMT_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/fmt +) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 28f921b30d8..2e23c23998a 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -14,8 +14,8 @@ if(WIN32) if(BUILD_MODE STREQUAL Release) add_custom_target(Harvest_Release_Results COMMAND # jpeg rename libfile + copy include - ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpg/include/ ${HARVEST_TARGET}/jpeg/include/ && + ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ && # png ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ && @@ -67,6 +67,8 @@ harvest(brotli/include brotli/include "*.h") harvest(brotli/lib brotli/lib "*.a") harvest(boost/include boost/include "*") harvest(boost/lib boost/lib "*.a") +harvest(imath/include imath/include "*.h") +harvest(imath/lib imath/lib "*.a") harvest(ffmpeg/include ffmpeg/include "*.h") harvest(ffmpeg/lib ffmpeg/lib "*.a") harvest(fftw3/include fftw3/include "*.h") @@ -80,9 +82,13 @@ harvest(gmp/include gmp/include "*.h") harvest(gmp/lib gmp/lib "*.a") harvest(jemalloc/include jemalloc/include "*.h") harvest(jemalloc/lib jemalloc/lib "*.a") -harvest(jpg/include jpeg/include "*.h") -harvest(jpg/lib jpeg/lib "libjpeg.a") +harvest(jpeg/include jpeg/include "*.h") +harvest(jpeg/lib jpeg/lib "libjpeg.a") harvest(lame/lib ffmpeg/lib "*.a") +if(NOT APPLE) + harvest(level-zero/include/level_zero level-zero/include/level_zero "*.h") + harvest(level-zero/lib level-zero/lib "*.a") +endif() harvest(llvm/bin llvm/bin "clang-format") if(BUILD_CLANG_TOOLS) harvest(llvm/bin llvm/bin "clang-tidy") @@ -135,7 +141,7 @@ harvest(openimagedenoise/include openimagedenoise/include "*") harvest(openimagedenoise/lib openimagedenoise/lib "*.a") harvest(embree/include embree/include "*.h") harvest(embree/lib embree/lib "*.a") -harvest(openjpeg/include/openjpeg-2.3 openjpeg/include "*.h") +harvest(openjpeg/include/openjpeg-${OPENJPEG_SHORT_VERSION} openjpeg/include "*.h") harvest(openjpeg/lib openjpeg/lib "*.a") harvest(opensubdiv/include opensubdiv/include "*.h") harvest(opensubdiv/lib opensubdiv/lib "*.a") @@ -169,9 +175,10 @@ harvest(tiff/lib tiff/lib "*.a") harvest(vorbis/lib ffmpeg/lib "*.a") harvest(opus/lib ffmpeg/lib "*.a") harvest(vpx/lib ffmpeg/lib "*.a") -harvest(webp/lib ffmpeg/lib "*.a") harvest(x264/lib ffmpeg/lib "*.a") harvest(xvidcore/lib ffmpeg/lib "*.a") +harvest(webp/lib webp/lib "*.a") +harvest(webp/include webp/include "*.h") harvest(usd/include usd/include "*.h") harvest(usd/lib/usd usd/lib/usd "*") harvest(usd/plugin usd/plugin "*") diff --git a/build_files/build_environment/cmake/imath.cmake b/build_files/build_environment/cmake/imath.cmake new file mode 100644 index 00000000000..eb5465e6d37 --- /dev/null +++ b/build_files/build_environment/cmake/imath.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(IMATH_EXTRA_ARGS + -DBUILD_SHARED_LIBS=OFF + -DBUILD_TESTING=OFF + -DIMATH_LIB_SUFFIX=${OPENEXR_VERSION_BUILD_POSTFIX} +) + +ExternalProject_Add(external_imath + URL file://${PACKAGE_DIR}/${IMATH_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${IMATH_HASH_TYPE}=${IMATH_HASH} + PREFIX ${BUILD_DIR}/imath + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/imath ${DEFAULT_CMAKE_FLAGS} ${IMATH_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/imath +) + +if(WIN32) + ExternalProject_Add_Step(external_imath after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/imath/lib ${HARVEST_TARGET}/imath/lib + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/imath/include ${HARVEST_TARGET}/imath/include + DEPENDEES install + ) +endif() diff --git a/build_files/build_environment/cmake/jpeg.cmake b/build_files/build_environment/cmake/jpeg.cmake index 7c37f2cd25e..39388ad466b 100644 --- a/build_files/build_environment/cmake/jpeg.cmake +++ b/build_files/build_environment/cmake/jpeg.cmake @@ -2,44 +2,52 @@ if(WIN32) # cmake for windows - set(JPEG_EXTRA_ARGS -DNASM=${NASM_PATH} -DWITH_JPEG8=ON -DCMAKE_DEBUG_POSTFIX=d -DWITH_CRT_DLL=On) + set(JPEG_EXTRA_ARGS + -DNASM=${NASM_PATH} + -DWITH_JPEG8=ON + -DCMAKE_DEBUG_POSTFIX=d + -DWITH_CRT_DLL=On + -DENABLE_SHARED=OFF + -DENABLE_STATIC=ON + ) ExternalProject_Add(external_jpeg URL file://${PACKAGE_DIR}/${JPEG_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${JPEG_HASH_TYPE}=${JPEG_HASH} - PREFIX ${BUILD_DIR}/jpg - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/jpg + PREFIX ${BUILD_DIR}/jpeg + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpeg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/jpeg ) - if(BUILD_MODE STREQUAL Debug) - ExternalProject_Add_Step(external_jpeg after_install - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpegd${LIBEXT} ${LIBDIR}/jpg/lib/jpeg${LIBEXT} - DEPENDEES install - ) - endif() - if(BUILD_MODE STREQUAL Release) set(JPEG_LIBRARY jpeg-static${LIBEXT}) else() set(JPEG_LIBRARY jpeg-staticd${LIBEXT}) endif() + + if(BUILD_MODE STREQUAL Release) + ExternalProject_Add_Step(external_jpeg after_install + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/${JPEG_LIBRARY} ${LIBDIR}/jpeg/lib/jpeg${LIBEXT} + DEPENDEES install + ) + endif() + else(WIN32) # cmake for unix set(JPEG_EXTRA_ARGS -DWITH_JPEG8=ON -DENABLE_STATIC=ON -DENABLE_SHARED=OFF - -DCMAKE_INSTALL_LIBDIR=${LIBDIR}/jpg/lib) + -DCMAKE_INSTALL_LIBDIR=${LIBDIR}/jpeg/lib) ExternalProject_Add(external_jpeg URL file://${PACKAGE_DIR}/${JPEG_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${JPEG_HASH_TYPE}=${JPEG_HASH} - PREFIX ${BUILD_DIR}/jpg - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/jpg + PREFIX ${BUILD_DIR}/jpeg + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpeg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/jpeg ) set(JPEG_LIBRARY libjpeg${LIBEXT}) diff --git a/build_files/build_environment/cmake/level-zero.cmake b/build_files/build_environment/cmake/level-zero.cmake new file mode 100644 index 00000000000..4b1ef034abc --- /dev/null +++ b/build_files/build_environment/cmake/level-zero.cmake @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(LEVEL_ZERO_EXTRA_ARGS +) + +ExternalProject_Add(external_level-zero + URL file://${PACKAGE_DIR}/${LEVEL_ZERO_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${LEVEL_ZERO_HASH_TYPE}=${LEVEL_ZERO_HASH} + PREFIX ${BUILD_DIR}/level-zero + PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/level-zero/src/external_level-zero < ${PATCH_DIR}/level-zero.diff + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/level-zero ${DEFAULT_CMAKE_FLAGS} ${LEVEL_ZERO_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/level-zero +) + +if(BUILD_MODE STREQUAL Release AND WIN32) + ExternalProject_Add_Step(external_level-zero after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/level-zero ${HARVEST_TARGET}/level-zero + DEPENDEES install + ) +endif() diff --git a/build_files/build_environment/cmake/nanovdb.cmake b/build_files/build_environment/cmake/nanovdb.cmake deleted file mode 100644 index eb6bd618c00..00000000000 --- a/build_files/build_environment/cmake/nanovdb.cmake +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-or-later - -set(NANOVDB_EXTRA_ARGS - # NanoVDB is header-only, so only need the install target - -DNANOVDB_BUILD_UNITTESTS=OFF - -DNANOVDB_BUILD_EXAMPLES=OFF - -DNANOVDB_BUILD_BENCHMARK=OFF - -DNANOVDB_BUILD_DOCS=OFF - -DNANOVDB_BUILD_TOOLS=OFF - -DNANOVDB_CUDA_KEEP_PTX=OFF - # Do not need to include any of the dependencies because of this - -DNANOVDB_USE_OPENVDB=OFF - -DNANOVDB_USE_OPENGL=OFF - -DNANOVDB_USE_OPENCL=OFF - -DNANOVDB_USE_CUDA=OFF - -DNANOVDB_USE_TBB=OFF - -DNANOVDB_USE_BLOSC=OFF - -DNANOVDB_USE_ZLIB=OFF - -DNANOVDB_USE_OPTIX=OFF - -DNANOVDB_ALLOW_FETCHCONTENT=OFF -) - -ExternalProject_Add(nanovdb - URL file://${PACKAGE_DIR}/${NANOVDB_FILE} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH ${NANOVDB_HASH_TYPE}=${NANOVDB_HASH} - PREFIX ${BUILD_DIR}/nanovdb - SOURCE_SUBDIR nanovdb - PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/nanovdb/src/nanovdb < ${PATCH_DIR}/nanovdb.diff - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/nanovdb ${DEFAULT_CMAKE_FLAGS} ${NANOVDB_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/nanovdb -) - -if(WIN32) - ExternalProject_Add_Step(nanovdb after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/nanovdb/nanovdb ${HARVEST_TARGET}/nanovdb/include/nanovdb - DEPENDEES install - ) -endif() diff --git a/build_files/build_environment/cmake/opencolorio.cmake b/build_files/build_environment/cmake/opencolorio.cmake index e4ac1ff8890..2246031be83 100644 --- a/build_files/build_environment/cmake/opencolorio.cmake +++ b/build_files/build_environment/cmake/opencolorio.cmake @@ -11,13 +11,12 @@ set(OPENCOLORIO_EXTRA_ARGS -DOCIO_BUILD_GPU_TESTS=OFF -DOCIO_USE_SSE=ON - # Manually build ext packages except for pystring, which does not have - # a CMake or autotools build system that we can easily use. - -DOCIO_INSTALL_EXT_PACKAGES=MISSING - -DHalf_ROOT=${LIBDIR}/openexr - -DHalf_STATIC_LIBRARY=ON + -DOCIO_INSTALL_EXT_PACKAGES=NONE + -Dexpat_ROOT=${LIBDIR}/expat -Dyaml-cpp_ROOT=${LIBDIR}/yamlcpp + -Dpystring_ROOT=${LIBDIR}/pystring + -DImath_ROOT=${LIBDIR}/imath ) if(BLENDER_PLATFORM_ARM) @@ -30,7 +29,9 @@ endif() if(WIN32) set(OPENCOLORIO_EXTRA_ARGS ${OPENCOLORIO_EXTRA_ARGS} - -DOCIO_INLINES_HIDDEN=OFF + -Dexpat_LIBRARY=${LIBDIR}/expat/lib/libexpatMD + -Dyaml-cpp_LIBRARY=${LIBDIR}/expat/lib/libyaml-cppmd.lib + -DImath_LIBRARY=${LIBDIR}/imath/lib/imath${OPENEXR_VERSION_POSTFIX} ) else() set(OPENCOLORIO_EXTRA_ARGS @@ -62,7 +63,7 @@ if(WIN32) COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/lib ${HARVEST_TARGET}/opencolorio/lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatMD.lib - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/pystring/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring.lib DEPENDEES install ) endif() @@ -71,7 +72,7 @@ if(WIN32) COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencolorio/lib/Opencolorio.lib ${HARVEST_TARGET}/opencolorio/lib/OpencolorIO_d.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmdd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp_d.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatdMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatdMD.lib - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/pystring/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring_d.lib DEPENDEES install ) endif() @@ -79,7 +80,7 @@ else() ExternalProject_Add_Step(external_opencolorio after_install COMMAND cp ${LIBDIR}/yamlcpp/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/ COMMAND cp ${LIBDIR}/expat/lib/libexpat.a ${LIBDIR}/opencolorio/lib/ - COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libpystring.a ${LIBDIR}/opencolorio/lib/ + COMMAND cp ${LIBDIR}/pystring/lib/libpystring.a ${LIBDIR}/opencolorio/lib/ DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/openexr.cmake b/build_files/build_environment/cmake/openexr.cmake index 9bebada7a66..d283f638a17 100644 --- a/build_files/build_environment/cmake/openexr.cmake +++ b/build_files/build_environment/cmake/openexr.cmake @@ -16,12 +16,10 @@ set(OPENEXR_EXTRA_ARGS -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/ -DBUILD_TESTING=OFF -DOPENEXR_BUILD_BOTH_STATIC_SHARED=OFF - -DILMBASE_BUILD_BOTH_STATIC_SHARED=OFF -DBUILD_SHARED_LIBS=OFF - -DOPENEXR_BUILD_UTILS=OFF - -DPYILMBASE_ENABLE=OFF - -DOPENEXR_VIEWERS_ENABLE=OFF - -DILMBASE_LIB_SUFFIX=${OPENEXR_VERSION_BUILD_POSTFIX} + -DOPENEXR_INSTALL_TOOLS=OFF + -DOPENEXR_INSTALL_EXAMPLES=OFF + -DImath_DIR=${LIBDIR}/imath/lib/cmake/Imath -DOPENEXR_LIB_SUFFIX=${OPENEXR_VERSION_BUILD_POSTFIX} ) diff --git a/build_files/build_environment/cmake/openimagedenoise.cmake b/build_files/build_environment/cmake/openimagedenoise.cmake index 8b528de7ee4..3612e91a690 100644 --- a/build_files/build_environment/cmake/openimagedenoise.cmake +++ b/build_files/build_environment/cmake/openimagedenoise.cmake @@ -8,6 +8,7 @@ set(OIDN_EXTRA_ARGS -DOIDN_STATIC_LIB=ON -DOIDN_STATIC_RUNTIME=OFF -DISPC_EXECUTABLE=${LIBDIR}/ispc/bin/ispc + -DOIDN_FILTER_RTLIGHTMAP=OFF ) if(WIN32) diff --git a/build_files/build_environment/cmake/openimageio.cmake b/build_files/build_environment/cmake/openimageio.cmake index 755cd6fbba9..b7d7ce689a4 100644 --- a/build_files/build_environment/cmake/openimageio.cmake +++ b/build_files/build_environment/cmake/openimageio.cmake @@ -23,35 +23,20 @@ else() set(OIIO_SIMD_FLAGS) endif() -if(WITH_WEBP) - set(WEBP_ARGS - -DWEBP_INCLUDE_DIR=${LIBDIR}/webp/include - -DWEBP_LIBRARY=${LIBDIR}/webp/lib/${LIBPREFIX}webp${LIBEXT} - ) - set(WEBP_DEP external_webp) -endif() - if(MSVC) set(OPENJPEG_FLAGS - -DOpenJpeg_ROOT=${LIBDIR}/openjpeg_msvc + -DOpenJPEG_ROOT=${LIBDIR}/openjpeg_msvc ) else() set(OPENJPEG_FLAGS - -DOpenJpeg_ROOT=${LIBDIR}/openjpeg + -DOpenJPEG_ROOT=${LIBDIR}/openjpeg ) endif() set(OPENIMAGEIO_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF ${OPENIMAGEIO_LINKSTATIC} - -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING} - -DBoost_USE_MULTITHREADED=ON - -DBoost_USE_STATIC_LIBS=ON - -DBoost_USE_STATIC_RUNTIME=OFF - -DBOOST_ROOT=${LIBDIR}/boost - -DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/ - -DBoost_NO_SYSTEM_PATHS=ON - -DBoost_NO_BOOST_CMAKE=ON + ${DEFAULT_BOOST_FLAGS} -DUSE_LIBSQUISH=OFF -DUSE_QT5=OFF -DUSE_NUKE=OFF @@ -62,7 +47,6 @@ set(OPENIMAGEIO_EXTRA_ARGS -DUSE_LIBHEIF=OFF -DUSE_OPENGL=OFF -DUSE_TBB=OFF - -DUSE_FIELD3D=OFF -DUSE_QT=OFF -DUSE_PYTHON=OFF -DUSE_GIF=OFF @@ -73,7 +57,7 @@ set(OPENIMAGEIO_EXTRA_ARGS -DUSE_FREETYPE=OFF -DUSE_LIBRAW=OFF -DUSE_OPENCOLORIO=OFF - -DUSE_WEBP=${WITH_WEBP} + -DUSE_WEBP=ON -DOIIO_BUILD_TOOLS=${OIIO_TOOLS} -DOIIO_BUILD_TESTS=OFF -DBUILD_TESTING=OFF @@ -83,14 +67,9 @@ set(OPENIMAGEIO_EXTRA_ARGS -DPNG_PNG_INCLUDE_DIR=${LIBDIR}/png/include -DTIFF_LIBRARY=${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT} -DTIFF_INCLUDE_DIR=${LIBDIR}/tiff/include - -DJPEG_LIBRARY=${LIBDIR}/jpg/lib/${JPEG_LIBRARY} - -DJPEG_INCLUDE_DIR=${LIBDIR}/jpg/include + -DJPEG_LIBRARY=${LIBDIR}/jpeg/lib/${JPEG_LIBRARY} + -DJPEG_INCLUDE_DIR=${LIBDIR}/jpeg/include ${OPENJPEG_FLAGS} - -DOpenEXR_USE_STATIC_LIBS=On - -DILMBASE_INCLUDE_DIR=${LIBDIR}/openexr/include/ - -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/ - -DOPENEXR_HALF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Half${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DOPENEXR_IMATH_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Imath${OPENEXR_VERSION_POSTFIX}${LIBEXT} -DOPENEXR_ILMTHREAD_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmThread${OPENEXR_VERSION_POSTFIX}${LIBEXT} -DOPENEXR_IEX_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Iex${OPENEXR_VERSION_POSTFIX}${LIBEXT} -DOPENEXR_ILMIMF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf${OPENEXR_VERSION_POSTFIX}${LIBEXT} @@ -98,8 +77,14 @@ set(OPENIMAGEIO_EXTRA_ARGS -DUSE_EXTERNAL_PUGIXML=ON -DPUGIXML_LIBRARY=${LIBDIR}/pugixml/lib/${LIBPREFIX}pugixml${LIBEXT} -DPUGIXML_INCLUDE_DIR=${LIBDIR}/pugixml/include/ - ${WEBP_FLAGS} + -DBUILD_MISSING_ROBINMAP=OFF + -DBUILD_MISSING_FMT=OFF + -DFMT_INCLUDE_DIR=${LIBDIR}/fmt/include/ + -DRobinmap_ROOT=${LIBDIR}/robinmap + -DWebP_ROOT=${LIBDIR}/webp ${OIIO_SIMD_FLAGS} + -DOpenEXR_ROOT=${LIBDIR}/openexr + -DImath_ROOT=${LIBDIR}/imath ) ExternalProject_Add(external_openimageio @@ -117,12 +102,15 @@ add_dependencies( external_png external_zlib external_openexr + external_imath external_jpeg external_boost external_tiff external_pugixml + external_fmt + external_robinmap external_openjpeg${OPENJPEG_POSTFIX} - ${WEBP_DEP} + external_webp ) if(WIN32) @@ -137,8 +125,8 @@ if(WIN32) endif() if(BUILD_MODE STREQUAL Debug) ExternalProject_Add_Step(external_openimageio after_install - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO_Util.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_Util_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO_d.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO_Util_d.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_Util_d.lib DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/openjpeg.cmake b/build_files/build_environment/cmake/openjpeg.cmake index cdb808d60b4..ac35b5a6cc3 100644 --- a/build_files/build_environment/cmake/openjpeg.cmake +++ b/build_files/build_environment/cmake/openjpeg.cmake @@ -3,20 +3,24 @@ # Note the encoder/decoder may use png/tiff/lcms system libraries, but the # library itself does not depend on them, so should give no problems. -set(OPENJPEG_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF) - if(WIN32) set(OPENJPEG_EXTRA_ARGS -G "MSYS Makefiles" -DBUILD_PKGCONFIG_FILES=On) else() set(OPENJPEG_EXTRA_ARGS ${DEFAULT_CMAKE_FLAGS}) endif() +set(OPENJPEG_EXTRA_ARGS + ${OPENJPEG_EXTRA_ARGS} + -DBUILD_SHARED_LIBS=OFF + -DBUILD_CODEC=OFF +) + ExternalProject_Add(external_openjpeg URL file://${PACKAGE_DIR}/${OPENJPEG_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${OPENJPEG_HASH_TYPE}=${OPENJPEG_HASH} PREFIX ${BUILD_DIR}/openjpeg - CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build && ${CMAKE_COMMAND} ${OPENJPEG_EXTRA_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openjpeg -DBUILD_SHARED_LIBS=Off -DBUILD_THIRDPARTY=OFF ${BUILD_DIR}/openjpeg/src/external_openjpeg + CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build && ${CMAKE_COMMAND} ${OPENJPEG_EXTRA_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openjpeg ${BUILD_DIR}/openjpeg/src/external_openjpeg BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build/ && make -j${MAKE_THREADS} INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build/ && make install INSTALL_DIR ${LIBDIR}/openjpeg diff --git a/build_files/build_environment/cmake/opensubdiv.cmake b/build_files/build_environment/cmake/opensubdiv.cmake index 847ff3f6daf..6d6e3568406 100644 --- a/build_files/build_environment/cmake/opensubdiv.cmake +++ b/build_files/build_environment/cmake/opensubdiv.cmake @@ -1,15 +1,25 @@ # SPDX-License-Identifier: GPL-2.0-or-later set(OPENSUBDIV_EXTRA_ARGS + -DNO_LIB=OFF -DNO_EXAMPLES=ON + -DNO_TUTORIALS=ON -DNO_REGRESSION=ON - -DNO_PYTHON=ON - -DNO_MAYA=ON -DNO_PTEX=ON -DNO_DOC=ON - -DNO_CLEW=OFF + -DNO_OMP=ON + -DNO_TBB=OFF + -DNO_CUDA=ON -DNO_OPENCL=OFF - -DNO_TUTORIALS=ON + -DNO_CLEW=OFF + -DNO_OPENGL=OFF + -DNO_METAL=OFF + -DNO_DX=ON + -DNO_TESTS=ON + -DNO_GLTESTS=ON + -DNO_GLEW=OFF + -DNO_GLFW=OFF + -DNO_GLFW_X11=ON -DGLEW_INCLUDE_DIR=${LIBDIR}/glew/include -DGLEW_LIBRARY=${LIBDIR}/glew/lib/libGLEW${LIBEXT} -DGLFW_INCLUDE_DIR=${LIBDIR}/glfw/include @@ -26,22 +36,11 @@ if(WIN32) -DCUEW_INCLUDE_DIR=${LIBDIR}/cuew/include -DCUEW_LIBRARY=${LIBDIR}/cuew/lib/cuew${LIBEXT} ) - if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") - set(OPENSUBDIV_EXTRA_ARGS - ${OPENSUBDIV_EXTRA_ARGS} - -DNO_CUDA=OFF - ) - else() - set(OPENSUBDIV_EXTRA_ARGS - ${OPENSUBDIV_EXTRA_ARGS} - -DNO_CUDA=ON - ) - endif() - else() set(OPENSUBDIV_EXTRA_ARGS ${OPENSUBDIV_EXTRA_ARGS} - -DNO_CUDA=ON + -DTBB_INCLUDE_DIR=${LIBDIR}/tbb/include + -DTBB_tbb_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}tbb_static${LIBEXT} -DCUEW_INCLUDE_DIR=${LIBDIR}/cuew/include -DCLEW_INCLUDE_DIR=${LIBDIR}/clew/include/CL -DCLEW_LIBRARY=${LIBDIR}/clew/lib/static/${LIBPREFIX}clew${LIBEXT} diff --git a/build_files/build_environment/cmake/openvdb.cmake b/build_files/build_environment/cmake/openvdb.cmake index f1b7c3d1b7d..2d0f62cc1a0 100644 --- a/build_files/build_environment/cmake/openvdb.cmake +++ b/build_files/build_environment/cmake/openvdb.cmake @@ -13,6 +13,7 @@ else() endif() set(OPENVDB_EXTRA_ARGS + ${DEFAULT_BOOST_FLAGS} -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING} -DBoost_USE_MULTITHREADED=ON -DBoost_USE_STATIC_LIBS=ON @@ -24,22 +25,20 @@ set(OPENVDB_EXTRA_ARGS -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/ -DBlosc_INCLUDE_DIR=${LIBDIR}/blosc/include/ -DBlosc_LIBRARY=${LIBDIR}/blosc/lib/libblosc${BLOSC_POST}${LIBEXT} - -DOPENVDB_ENABLE_3_ABI_COMPATIBLE=OFF - -DOPENVDB_BUILD_UNITTESTS=Off - -DOPENVDB_BUILD_PYTHON_MODULE=Off + -DBlosc_LIBRARY_RELEASE=${LIBDIR}/blosc/lib/libblosc${BLOSC_POST}${LIBEXT} + -DBlosc_LIBRARY_DEBUG=${LIBDIR}/blosc/lib/libblosc${BLOSC_POST}${LIBEXT} + -DOPENVDB_BUILD_UNITTESTS=OFF + -DOPENVDB_BUILD_PYTHON_MODULE=OFF + -DOPENVDB_BUILD_NANOVDB=ON + -DNANOVDB_BUILD_TOOLS=OFF -DBlosc_ROOT=${LIBDIR}/blosc/ -DTBB_ROOT=${LIBDIR}/tbb/ - -DOpenEXR_ROOT=${LIBDIR}/openexr - -DIlmBase_ROOT=${LIBDIR}/openexr - -DOPENEXR_LIBRARYDIR=${LIBDIR}/openexr/lib - # All libs live in openexr, even the ilmbase ones - -DILMBASE_LIBRARYDIR=${LIBDIR}/openexr/lib -DOPENVDB_CORE_SHARED=${OPENVDB_SHARED} -DOPENVDB_CORE_STATIC=${OPENVDB_STATIC} - -DOPENVDB_BUILD_BINARIES=Off + -DOPENVDB_BUILD_BINARIES=OFF -DCMAKE_DEBUG_POSTFIX=_d - -DILMBASE_USE_STATIC_LIBS=On - -DOPENEXR_USE_STATIC_LIBS=On + -DBLOSC_USE_STATIC_LIBS=ON + -DUSE_NANOVDB=ON ) if(WIN32) @@ -48,15 +47,6 @@ if(WIN32) # needs to link pthreads due to it being a blosc dependency set(OPENVDB_EXTRA_ARGS ${OPENVDB_EXTRA_ARGS} -DCMAKE_CXX_STANDARD_LIBRARIES="${LIBDIR}/pthreads/lib/pthreadVC3.lib" - -DUSE_EXR=On - ) -else() - # OpenVDB can't find the _static libraries automatically. - set(OPENVDB_EXTRA_ARGS ${OPENVDB_EXTRA_ARGS} - -DTbb_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}tbb_static${LIBEXT} - -DTbb_tbb_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}tbb_static${LIBEXT} - -DTbb_tbbmalloc_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}tbbmalloc_static${LIBEXT} - -DTbb_tbbmalloc_proxy_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}tbbmalloc_proxy_static${LIBEXT} ) endif() @@ -74,7 +64,6 @@ add_dependencies( openvdb external_tbb external_boost - external_openexr external_zlib external_blosc ) @@ -82,7 +71,7 @@ add_dependencies( if(WIN32) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(openvdb after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/include/openvdb ${HARVEST_TARGET}/openvdb/include/openvdb + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/include ${HARVEST_TARGET}/openvdb/include COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/lib/openvdb.lib ${HARVEST_TARGET}/openvdb/lib/openvdb.lib COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/bin/openvdb.dll ${HARVEST_TARGET}/openvdb/bin/openvdb.dll DEPENDEES install diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 5cf197b59b7..7b9529068f4 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -3,7 +3,6 @@ if(WIN32) option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/fftw3 by installing mingw64" ON) endif() -option(WITH_WEBP "Enable building of oiio with webp support" OFF) option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF) cmake_host_system_information(RESULT NUM_CORES QUERY NUMBER_OF_LOGICAL_CORES) set(MAKE_THREADS ${NUM_CORES} CACHE STRING "Number of threads to run make with") @@ -42,29 +41,29 @@ if(WIN32) set(LIBPREFIX "") # For OIIO and OSL - set(COMMON_DEFINES /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS) + set(COMMON_DEFINES /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS) if(MSVC_VERSION GREATER 1909) set(COMMON_MSVC_FLAGS "/Wv:18") #some deps with warnings as error aren't quite ready for dealing with the new 2017 warnings. endif() string(APPEND COMMON_MSVC_FLAGS " /bigobj") if(WITH_OPTIMIZED_DEBUG) - set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") else() - set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /D_DEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /D_DEBUG /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") endif() - set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "/MD ${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") - set(BLENDER_CMAKE_C_FLAGS_RELEASE "/MD ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") - set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MD ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "/MD ${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_C_FLAGS_RELEASE "/MD ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MD ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") if(WITH_OPTIMIZED_DEBUG) - set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") else() - set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd ${COMMON_MSVC_FLAGS} /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") endif() - set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MD /${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") - set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MD ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") - set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MD /${COMMON_MSVC_FLAGS} /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MD ${COMMON_MSVC_FLAGS} /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") + set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MD ${COMMON_MSVC_FLAGS} /Zi /O2 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=2 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") set(PLATFORM_FLAGS) set(PLATFORM_CXX_FLAGS) diff --git a/build_files/build_environment/cmake/osl.cmake b/build_files/build_environment/cmake/osl.cmake index a14ca46334a..9719de94d47 100644 --- a/build_files/build_environment/cmake/osl.cmake +++ b/build_files/build_environment/cmake/osl.cmake @@ -3,33 +3,15 @@ if(WIN32) set(OSL_CMAKE_CXX_STANDARD_LIBRARIES "kernel32${LIBEXT} user32${LIBEXT} gdi32${LIBEXT} winspool${LIBEXT} shell32${LIBEXT} ole32${LIBEXT} oleaut32${LIBEXT} uuid${LIBEXT} comdlg32${LIBEXT} advapi32${LIBEXT} psapi${LIBEXT}") set(OSL_FLEX_BISON -DFLEX_EXECUTABLE=${LIBDIR}/flexbison/win_flex.exe -DBISON_EXECUTABLE=${LIBDIR}/flexbison/win_bison.exe) - set(OSL_SIMD_FLAGS -DOIIO_NOSIMD=1 -DOIIO_SIMD=sse2) else() set(OSL_CMAKE_CXX_STANDARD_LIBRARIES) set(OSL_FLEX_BISON) - set(OSL_OPENIMAGEIO_LIBRARY "${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO${LIBEXT};${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO_Util${LIBEXT};${LIBDIR}/png/lib/${LIBPREFIX}png16${LIBEXT};${LIBDIR}/jpg/lib/${LIBPREFIX}jpeg${LIBEXT};${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT};${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf${OPENEXR_VERSION_POSTFIX}${LIBEXT}") + set(OSL_OPENIMAGEIO_LIBRARY "${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO${LIBEXT};${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO_Util${LIBEXT};${LIBDIR}/png/lib/${LIBPREFIX}png16${LIBEXT};${LIBDIR}/jpeg/lib/${LIBPREFIX}jpeg${LIBEXT};${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT};${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf${OPENEXR_VERSION_POSTFIX}${LIBEXT}") endif() -set(OSL_ILMBASE_CUSTOM_LIBRARIES "${LIBDIR}/openexr/lib/Imath${OPENEXR_VERSION_POSTFIX}.lib^^${LIBDIR}/openexr/lib/Half{OPENEXR_VERSION_POSTFIX}.lib^^${LIBDIR}/openexr/lib/IlmThread${OPENEXR_VERSION_POSTFIX}.lib^^${LIBDIR}/openexr/lib/Iex${OPENEXR_VERSION_POSTFIX}.lib") - set(OSL_EXTRA_ARGS - -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING} - -DBoost_USE_MULTITHREADED=ON - -DBoost_USE_STATIC_LIBS=ON - -DBoost_USE_STATIC_RUNTIME=OFF - -DBOOST_ROOT=${LIBDIR}/boost - -DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/ - -DBoost_NO_SYSTEM_PATHS=ON - -DBoost_NO_BOOST_CMAKE=ON + ${DEFAULT_BOOST_FLAGS} -DOpenEXR_ROOT=${LIBDIR}/openexr/ - -DIlmBase_ROOT=${LIBDIR}/openexr/ - -DILMBASE_INCLUDE_DIR=${LIBDIR}/openexr/include/ - -DOPENEXR_HALF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Half${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DOPENEXR_IMATH_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Imath${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DOPENEXR_ILMTHREAD_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmThread${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DOPENEXR_IEX_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}Iex${OPENEXR_VERSION_POSTFIX}${LIBEXT} - -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/ - -DOPENEXR_ILMIMF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf${OPENEXR_VERSION_POSTFIX}${LIBEXT} -DOpenImageIO_ROOT=${LIBDIR}/openimageio/ -DOSL_BUILD_TESTS=OFF -DOSL_BUILD_MATERIALX=OFF @@ -49,10 +31,10 @@ set(OSL_EXTRA_ARGS -DUSE_QT=OFF -DUSE_Qt5=OFF -DINSTALL_DOCS=OFF - ${OSL_SIMD_FLAGS} -Dpugixml_ROOT=${LIBDIR}/pugixml -DUSE_PYTHON=OFF -DCMAKE_CXX_STANDARD=14 + -DImath_ROOT=${LIBDIR}/imath ) ExternalProject_Add(external_osl diff --git a/build_files/build_environment/cmake/pystring.cmake b/build_files/build_environment/cmake/pystring.cmake new file mode 100644 index 00000000000..dd4ea984f92 --- /dev/null +++ b/build_files/build_environment/cmake/pystring.cmake @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(PYSTRING_EXTRA_ARGS +) + +ExternalProject_Add(external_pystring + URL file://${PACKAGE_DIR}/${PYSTRING_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${PYSTRING_HASH_TYPE}=${PYSTRING_HASH} + PREFIX ${BUILD_DIR}/pystring + PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_pystring.txt ${BUILD_DIR}/pystring/src/external_pystring/CMakeLists.txt + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/pystring ${DEFAULT_CMAKE_FLAGS} ${PYSTRING_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/pystring +) + +if(WIN32) + ExternalProject_Add_Step(external_pystring after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pystring/lib ${HARVEST_TARGET}/pystring/lib + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pystring/include ${HARVEST_TARGET}/pystring/include + DEPENDEES install + ) +endif() diff --git a/build_files/build_environment/cmake/robinmap.cmake b/build_files/build_environment/cmake/robinmap.cmake new file mode 100644 index 00000000000..c2292ae8bb3 --- /dev/null +++ b/build_files/build_environment/cmake/robinmap.cmake @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +set(ROBINMAP_EXTRA_ARGS +) + +ExternalProject_Add(external_robinmap + URL file://${PACKAGE_DIR}/${ROBINMAP_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${ROBINMAP_HASH_TYPE}=${ROBINMAP_HASH} + PREFIX ${BUILD_DIR}/robinmap + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/robinmap ${DEFAULT_CMAKE_FLAGS} ${ROBINMAP_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/robinmap +) + +if(WIN32) + if(BUILD_MODE STREQUAL Release) + ExternalProject_Add_Step(external_robinmap after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/zstd/include/ ${HARVEST_TARGET}/zstd/include/ + DEPENDEES install + ) + endif() +endif() diff --git a/build_files/build_environment/cmake/tiff.cmake b/build_files/build_environment/cmake/tiff.cmake index fe64c56d670..bd495df2a4c 100644 --- a/build_files/build_environment/cmake/tiff.cmake +++ b/build_files/build_environment/cmake/tiff.cmake @@ -1,11 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-or-later -if(WITH_WEBP) - set(WITH_TIFF_WEBP ON) -else() - set(WITH_TIFF_WEBP OFF) -endif() - set(TIFF_EXTRA_ARGS -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY} -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include @@ -14,7 +8,7 @@ set(TIFF_EXTRA_ARGS -Dlzma=OFF -Djbig=OFF -Dzstd=OFF - -Dwebp=${WITH_TIFF_WEBP} + -Dwebp=OFF ) ExternalProject_Add(external_tiff diff --git a/build_files/build_environment/cmake/usd.cmake b/build_files/build_environment/cmake/usd.cmake index afa9f788b07..3b5f9d21d95 100644 --- a/build_files/build_environment/cmake/usd.cmake +++ b/build_files/build_environment/cmake/usd.cmake @@ -1,39 +1,59 @@ # SPDX-License-Identifier: GPL-2.0-or-later -set(USD_EXTRA_ARGS - -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING} - -DBoost_USE_MULTITHREADED=ON - -DBoost_USE_STATIC_LIBS=ON - -DBoost_USE_STATIC_RUNTIME=OFF - -DBOOST_ROOT=${LIBDIR}/boost - -DBoost_NO_SYSTEM_PATHS=ON - -DBoost_NO_BOOST_CMAKE=ON - -DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include - -DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} - -DTbb_TBB_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} - # USD wants the tbb debug lib set even when you are doing a release build - # Otherwise it will error out during the cmake configure phase. - -DTBB_LIBRARIES_DEBUG=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} +if(WIN32) + # OIIO and OSL are statically linked for us, but USD doesn't know + set(USD_CXX_FLAGS "${CMAKE_CXX_FLAGS} /DOIIO_STATIC_DEFINE /DOSL_STATIC_DEFINE") + if(BUILD_MODE STREQUAL Debug) + # USD does not look for debug libs, nor does it link them + # when building static, so this is just to keep find_package happy + # if we ever link dynamically on windows util will need to be linked as well. + set(USD_OIIO_CMAKE_DEFINES "-DOIIO_LIBRARIES=${LIBDIR}/openimageio/lib/OpenImageIO_d${LIBEXT}") + endif() + set(USD_PLATFORM_FLAGS + ${USD_OIIO_CMAKE_DEFINES} + -DCMAKE_CXX_FLAGS=${USD_CXX_FLAGS} + ) +endif() +set(USD_EXTRA_ARGS + ${DEFAULT_BOOST_FLAGS} + ${USD_PLATFORM_FLAGS} # This is a preventative measure that avoids possible conflicts when add-ons # try to load another USD library into the same process space. -DPXR_SET_INTERNAL_NAMESPACE=usdBlender - + -DOPENSUBDIV_ROOT_DIR=${LIBDIR}/opensubdiv + -DOpenImageIO_ROOT=${LIBDIR}/openimageio + -DOPENEXR_LIBRARIES=${LIBDIR}/imath/lib/imath${OPENEXR_VERSION_POSTFIX}${LIBEXT} + -DOPENEXR_INCLUDE_DIR=${LIBDIR}/imath/include + -DOSL_ROOT=${LIBDIR}/osl -DPXR_ENABLE_PYTHON_SUPPORT=OFF - -DPXR_BUILD_IMAGING=OFF + -DPXR_BUILD_IMAGING=ON -DPXR_BUILD_TESTS=OFF - -DBUILD_SHARED_LIBS=OFF + -DPXR_BUILD_EXAMPLES=OFF + -DPXR_BUILD_TUTORIALS=OFF + -DPXR_ENABLE_HDF5_SUPPORT=OFF + -DPXR_ENABLE_MATERIALX_SUPPORT=OFF + -DPXR_ENABLE_OPENVDB_SUPPORT=OFF -DPYTHON_EXECUTABLE=${PYTHON_BINARY} -DPXR_BUILD_MONOLITHIC=ON - - # The PXR_BUILD_USD_TOOLS argument is patched-in by usd.diff. An upstream pull request - # can be found at https://github.com/PixarAnimationStudios/USD/pull/1048. + -DPXR_ENABLE_OSL_SUPPORT=ON + -DPXR_BUILD_OPENIMAGEIO_PLUGIN=ON + # USD 22.03 does not support OCIO 2.x + # Tracking ticket https://github.com/PixarAnimationStudios/USD/issues/1386 + -DPXR_BUILD_OPENCOLORIO_PLUGIN=OFF + -DPXR_ENABLE_PTEX_SUPPORT=OFF -DPXR_BUILD_USD_TOOLS=OFF - -DCMAKE_DEBUG_POSTFIX=_d + -DBUILD_SHARED_LIBS=Off # USD is hellbound on making a shared lib, unless you point this variable to a valid cmake file # doesn't have to make sense, but as long as it points somewhere valid it will skip the shared lib. -DPXR_MONOLITHIC_IMPORT=${BUILD_DIR}/usd/src/external_usd/cmake/defaults/Version.cmake + -DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include + -DTBB_LIBRARIES=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} + -DTbb_TBB_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} + # USD wants the tbb debug lib set even when you are doing a release build + # Otherwise it will error out during the cmake configure phase. + -DTBB_LIBRARIES_DEBUG=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${LIBEXT} ) ExternalProject_Add(external_usd @@ -50,37 +70,33 @@ add_dependencies( external_usd external_tbb external_boost + external_openimageio + external_opensubdiv + external_osl ) # Since USD 21.11 the libraries are prefixed with "usd_", i.e. "libusd_m.a" became "libusd_usd_m.a". # See https://github.com/PixarAnimationStudios/USD/blob/release/CHANGELOG.md#2111---2021-11-01 -if (USD_VERSION VERSION_LESS 21.11) - set(PXR_LIB_PREFIX "") -else() - set(PXR_LIB_PREFIX "usd_") +if(NOT WIN32) + if (USD_VERSION VERSION_LESS 21.11) + set(PXR_LIB_PREFIX "") + else() + set(PXR_LIB_PREFIX "usd_") + endif() endif() if(WIN32) - # USD currently demands python be available at build time - # and then proceeds not to use it, but still checks that the - # version of the interpreter it is not going to use is atleast 2.7 - # so we need this dep currently since there is no system python - # on windows. - add_dependencies( - external_usd - external_python - ) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(external_usd after_install COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/ ${HARVEST_TARGET}/usd - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/${PXR_LIB_PREFIX}usd_m.lib ${HARVEST_TARGET}/usd/lib/lib${PXR_LIB_PREFIX}usd_m.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Release/usd_usd_m.lib ${HARVEST_TARGET}/usd/lib/usd_usd_m.lib DEPENDEES install ) endif() if(BUILD_MODE STREQUAL Debug) ExternalProject_Add_Step(external_usd after_install COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/usd/lib ${HARVEST_TARGET}/usd/lib - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/${PXR_LIB_PREFIX}usd_m_d.lib ${HARVEST_TARGET}/usd/lib/lib${PXR_LIB_PREFIX}usd_m_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/usd/src/external_usd-build/pxr/Debug/usd_usd_m_d.lib ${HARVEST_TARGET}/usd/lib/usd_usd_m_d.lib DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index d4cccb05ce4..de7aed23834 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -1,14 +1,14 @@ # SPDX-License-Identifier: GPL-2.0-or-later -set(ZLIB_VERSION 1.2.11) +set(ZLIB_VERSION 1.2.12) set(ZLIB_URI https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz) -set(ZLIB_HASH 1c9f62f0778697a09d36121ead88e08e) +set(ZLIB_HASH 5fc414a9726be31427b440b434d05f78) set(ZLIB_HASH_TYPE MD5) set(ZLIB_FILE zlib-${ZLIB_VERSION}.tar.gz) -set(OPENAL_VERSION 1.20.1) +set(OPENAL_VERSION 1.21.1) set(OPENAL_URI http://openal-soft.org/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2) -set(OPENAL_HASH 556695068ce8375b89986083d810fd35) +set(OPENAL_HASH a936806ebd8de417b0ffd8cf3f48f456) set(OPENAL_HASH_TYPE MD5) set(OPENAL_FILE openal-soft-${OPENAL_VERSION}.tar.bz2) @@ -18,24 +18,24 @@ set(PNG_HASH 505e70834d35383537b6491e7ae8641f1a4bed1876dbfe361201fc80868d88ca) set(PNG_HASH_TYPE SHA256) set(PNG_FILE libpng-${PNG_VERSION}.tar.xz) -set(JPEG_VERSION 2.0.4) +set(JPEG_VERSION 2.1.3) set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz) -set(JPEG_HASH 44c43e4a9fb352f47090804529317c88) +set(JPEG_HASH 627b980fad0573e08e4c3b80b290fc91) set(JPEG_HASH_TYPE MD5) set(JPEG_FILE libjpeg-turbo-${JPEG_VERSION}.tar.gz) -set(BOOST_VERSION 1.73.0) -set(BOOST_VERSION_NODOTS 1_73_0) -set(BOOST_VERSION_NODOTS_SHORT 1_73) +set(BOOST_VERSION 1.78.0) +set(BOOST_VERSION_SHORT 1.78) +set(BOOST_VERSION_NODOTS 1_78_0) +set(BOOST_VERSION_NODOTS_SHORT 1_78) set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz) -set(BOOST_HASH 4036cd27ef7548b8d29c30ea10956196) +set(BOOST_HASH c2f6428ac52b0e5a3c9b2e1d8cc832b5) set(BOOST_HASH_TYPE MD5) set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz) -# Using old version as recommended by OpenVDB build documentation. -set(BLOSC_VERSION 1.5.0) +set(BLOSC_VERSION 1.21.1) set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.tar.gz) -set(BLOSC_HASH 6e4a49c8c06f05aa543f3312cfce3d55) +set(BLOSC_HASH 134b55813b1dca57019d2a2dc1f7a923) set(BLOSC_HASH_TYPE MD5) set(BLOSC_FILE blosc-${BLOSC_VERSION}.tar.gz) @@ -45,12 +45,19 @@ set(PTHREADS_HASH f3bf81bb395840b3446197bcf4ecd653) set(PTHREADS_HASH_TYPE MD5) set(PTHREADS_FILE pthreads4w-code-${PTHREADS_VERSION}.zip) -set(OPENEXR_VERSION 2.5.5) +set(OPENEXR_VERSION 3.1.4) set(OPENEXR_URI https://github.com/AcademySoftwareFoundation/openexr/archive/v${OPENEXR_VERSION}.tar.gz) -set(OPENEXR_HASH 85e8a979092c9055d10ed103062d31a0) +set(OPENEXR_HASH e990be1ff765797bc2d93a8060e1c1f2) set(OPENEXR_HASH_TYPE MD5) set(OPENEXR_FILE openexr-${OPENEXR_VERSION}.tar.gz) +set(IMATH_VERSION 3.1.4) +set(IMATH_URI https://github.com/AcademySoftwareFoundation/Imath/archive/v${OPENEXR_VERSION}.tar.gz) +set(IMATH_HASH fddf14ec73e12c34e74c3c175e311a3f) +set(IMATH_HASH_TYPE MD5) +set(IMATH_FILE imath-${IMATH_VERSION}.tar.gz) + + if(WIN32) # Openexr started appending _d on its own so now # we need to tell the build the postfix is _s while @@ -85,9 +92,9 @@ set(FREEGLUT_HASH 90c3ca4dd9d51cf32276bc5344ec9754) set(FREEGLUT_HASH_TYPE MD5) set(FREEGLUT_FILE freeglut-${FREEGLUT_VERSION}.tar.gz) -set(ALEMBIC_VERSION 1.7.16) +set(ALEMBIC_VERSION 1.8.3) set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.tar.gz) -set(ALEMBIC_HASH effcc86e42fe6605588e3de57bde6677) +set(ALEMBIC_HASH 2cd8d6e5a3ac4a014e24a4b04f4fadf9) set(ALEMBIC_HASH_TYPE MD5) set(ALEMBIC_FILE alembic-${ALEMBIC_VERSION}.tar.gz) @@ -112,15 +119,15 @@ set(CUEW_HASH 86760d62978ebfd96cd93f5aa1abaf4a) set(CUEW_HASH_TYPE MD5) set(CUEW_FILE cuew-${CUEW_GIT_UID}.zip) -set(OPENSUBDIV_VERSION v3_4_3) +set(OPENSUBDIV_VERSION v3_4_4) set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.tar.gz) -set(OPENSUBDIV_HASH 7bbfa275d021fb829e521df749160edb) +set(OPENSUBDIV_HASH 39ecc5caf0abebc943d1ce131855e76e) set(OPENSUBDIV_HASH_TYPE MD5) set(OPENSUBDIV_FILE opensubdiv-${OPENSUBDIV_VERSION}.tar.gz) -set(SDL_VERSION 2.0.12) +set(SDL_VERSION 2.0.20) set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz) -set(SDL_HASH 783b6f2df8ff02b19bb5ce492b99c8ff) +set(SDL_HASH a53acc02e1cca98c4123229069b67c9e) set(SDL_HASH_TYPE MD5) set(SDL_FILE SDL2-${SDL_VERSION}.tar.gz) @@ -130,9 +137,9 @@ set(OPENCOLLADA_HASH ee7dae874019fea7be11613d07567493) set(OPENCOLLADA_HASH_TYPE MD5) set(OPENCOLLADA_FILE opencollada-${OPENCOLLADA_VERSION}.tar.gz) -set(OPENCOLORIO_VERSION 2.0.0) +set(OPENCOLORIO_VERSION 2.1.1) set(OPENCOLORIO_URI https://github.com/AcademySoftwareFoundation/OpenColorIO/archive/v${OPENCOLORIO_VERSION}.tar.gz) -set(OPENCOLORIO_HASH 1a2e3478b6cd9a1549f24e1b2205e3f0) +set(OPENCOLORIO_HASH 604f562e073f23d88ce89ed4f7f709ba) set(OPENCOLORIO_HASH_TYPE MD5) set(OPENCOLORIO_FILE OpenColorIO-${OPENCOLORIO_VERSION}.tar.gz) @@ -155,21 +162,37 @@ set(OPENMP_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${ set(OPENMP_HASH_TYPE MD5) set(OPENMP_FILE openmp-${OPENMP_VERSION}.src.tar.xz) -set(OPENIMAGEIO_VERSION 2.2.15.1) -set(OPENIMAGEIO_URI https://github.com/OpenImageIO/oiio/archive/Release-${OPENIMAGEIO_VERSION}.tar.gz) -set(OPENIMAGEIO_HASH 3db5c5f0b3dc91597c75e5df09eb9072) +set(OPENIMAGEIO_VERSION v2.3.13.0) +set(OPENIMAGEIO_URI https://github.com/OpenImageIO/oiio/archive/refs/tags/${OPENIMAGEIO_VERSION}.tar.gz) +set(OPENIMAGEIO_HASH de45fb38501c4581062b522b53b6141c) set(OPENIMAGEIO_HASH_TYPE MD5) set(OPENIMAGEIO_FILE OpenImageIO-${OPENIMAGEIO_VERSION}.tar.gz) -set(TIFF_VERSION 4.1.0) +# 8.0.0 is currently oiio's preferred vesion although never versions may be available. +# the preferred version can be found in oiio's externalpackages.cmake +set(FMT_VERSION 8.0.0) +set(FMT_URI https://github.com/fmtlib/fmt/archive/refs/tags/${FMT_VERSION}.tar.gz) +set(FMT_HASH 7bce0e9e022e586b178b150002e7c2339994e3c2bbe44027e9abb0d60f9cce83) +set(FMT_HASH_TYPE SHA256) +set(FMT_FILE fmt-${FMT_VERSION}.tar.gz) + +# 0.6.2 is currently oiio's preferred vesion although never versions may be available. +# the preferred version can be found in oiio's externalpackages.cmake +set(ROBINMAP_VERSION v0.6.2) +set(ROBINMAP_URI https://github.com/Tessil/robin-map/archive/refs/tags/${ROBINMAP_VERSION}.tar.gz) +set(ROBINMAP_HASH c08ec4b1bf1c85eb0d6432244a6a89862229da1cb834f3f90fba8dc35d8c8ef1) +set(ROBINMAP_HASH_TYPE SHA256) +set(ROBINMAP_FILE robinmap-${ROBINMAP_VERSION}.tar.gz) + +set(TIFF_VERSION 4.3.0) set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz) -set(TIFF_HASH 2165e7aba557463acc0664e71a3ed424) +set(TIFF_HASH 0a2e4744d1426a8fc8211c0cdbc3a1b3) set(TIFF_HASH_TYPE MD5) set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz) -set(OSL_VERSION 1.11.14.1) +set(OSL_VERSION 1.11.17.0) set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.tar.gz) -set(OSL_HASH 1abd7ce40481771a9fa937f19595d2f2) +set(OSL_HASH 63265472ce14548839ace2e21e401544) set(OSL_HASH_TYPE MD5) set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz) @@ -181,24 +204,18 @@ set(PYTHON_HASH 14e8c22458ed7779a1957b26cde01db9) set(PYTHON_HASH_TYPE MD5) set(PYTHON_FILE Python-${PYTHON_VERSION}.tar.xz) -set(TBB_VERSION 2020_U2) +set(TBB_VERSION 2020_U3) set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz) -set(TBB_HASH 1b711ae956524855088df3bbf5ec65dc) +set(TBB_HASH 55ec8df6eae5ed6364a47f0e671e460c) set(TBB_HASH_TYPE MD5) set(TBB_FILE oneTBB-${TBB_VERSION}.tar.gz) -set(OPENVDB_VERSION 8.0.1) +set(OPENVDB_VERSION 9.0.0) set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz) -set(OPENVDB_HASH 01b490be16cc0e15c690f9a153c21461) +set(OPENVDB_HASH 684ce40c2f74f3a0c9cac530e1c7b07e) set(OPENVDB_HASH_TYPE MD5) set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz) -set(NANOVDB_GIT_UID dc37d8a631922e7bef46712947dc19b755f3e841) -set(NANOVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/${NANOVDB_GIT_UID}.tar.gz) -set(NANOVDB_HASH e7b9e863ec2f3b04ead171dec2322807) -set(NANOVDB_HASH_TYPE MD5) -set(NANOVDB_FILE nano-vdb-${NANOVDB_GIT_UID}.tar.gz) - set(IDNA_VERSION 3.3) set(CHARSET_NORMALIZER_VERSION 2.0.10) set(URLLIB3_VERSION 1.26.8) @@ -222,15 +239,15 @@ set(LAME_HASH 83e260acbe4389b54fe08e0bdbf7cddb) set(LAME_HASH_TYPE MD5) set(LAME_FILE lame-${LAME_VERSION}.tar.gz) -set(OGG_VERSION 1.3.4) +set(OGG_VERSION 1.3.5) set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz) -set(OGG_HASH fe5670640bd49e828d64d2879c31cb4dde9758681bb664f9bdbf159a01b0c76e) +set(OGG_HASH 0eb4b4b9420a0f51db142ba3f9c64b333f826532dc0f48c6410ae51f4799b664) set(OGG_HASH_TYPE SHA256) set(OGG_FILE libogg-${OGG_VERSION}.tar.gz) -set(VORBIS_VERSION 1.3.6) +set(VORBIS_VERSION 1.3.7) set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz) -set(VORBIS_HASH 6ed40e0241089a42c48604dc00e362beee00036af2d8b3f46338031c9e0351cb) +set(VORBIS_HASH 0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab) set(VORBIS_HASH_TYPE SHA256) set(VORBIS_FILE libvorbis-${VORBIS_VERSION}.tar.gz) @@ -240,15 +257,15 @@ set(THEORA_HASH b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc set(THEORA_HASH_TYPE SHA256) set(THEORA_FILE libtheora-${THEORA_VERSION}.tar.bz2) -set(FLAC_VERSION 1.3.3) +set(FLAC_VERSION 1.3.4) set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz) -set(FLAC_HASH 213e82bd716c9de6db2f98bcadbc4c24c7e2efe8c75939a1a84e28539c4e1748) +set(FLAC_HASH 8ff0607e75a322dd7cd6ec48f4f225471404ae2730d0ea945127b1355155e737 ) set(FLAC_HASH_TYPE SHA256) set(FLAC_FILE flac-${FLAC_VERSION}.tar.xz) -set(VPX_VERSION 1.8.2) +set(VPX_VERSION 1.11.0) set(VPX_URI https://github.com/webmproject/libvpx/archive/v${VPX_VERSION}/libvpx-v${VPX_VERSION}.tar.gz) -set(VPX_HASH 8735d9fcd1a781ae6917f28f239a8aa358ce4864ba113ea18af4bb2dc8b474ac) +set(VPX_HASH 965e51c91ad9851e2337aebcc0f517440c637c506f3a03948062e3d5ea129a83) set(VPX_HASH_TYPE SHA256) set(VPX_FILE libvpx-v${VPX_VERSION}.tar.gz) @@ -258,9 +275,9 @@ set(OPUS_HASH 65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d) set(OPUS_HASH_TYPE SHA256) set(OPUS_FILE opus-${OPUS_VERSION}.tar.gz) -set(X264_VERSION 33f9e1474613f59392be5ab6a7e7abf60fa63622) +set(X264_VERSION 35fe20d1ba49918ec739a5b068c208ca82f977f7) set(X264_URI https://code.videolan.org/videolan/x264/-/archive/${X264_VERSION}/x264-${X264_VERSION}.tar.gz) -set(X264_HASH 5456450ee1ae02cd2328be3157367a232a0ab73315e8c8f80dab80469524f525) +set(X264_HASH bb4f7da03936b5a030ed5827133b58eb3f701d7e5dce32cca4ba6df93797d42e) set(X264_HASH_TYPE SHA256) set(X264_FILE x264-${X264_VERSION}.tar.gz) @@ -270,22 +287,22 @@ set(XVIDCORE_HASH abbdcbd39555691dd1c9b4d08f0a031376a3b211652c0d8b3b8aa9be1303ce set(XVIDCORE_HASH_TYPE SHA256) set(XVIDCORE_FILE xvidcore-${XVIDCORE_VERSION}.tar.gz) -set(OPENJPEG_VERSION 2.3.1) -set(OPENJPEG_SHORT_VERSION 2.3) +set(OPENJPEG_VERSION 2.4.0) +set(OPENJPEG_SHORT_VERSION 2.4) set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/v${OPENJPEG_VERSION}.tar.gz) -set(OPENJPEG_HASH 63f5a4713ecafc86de51bfad89cc07bb788e9bba24ebbf0c4ca637621aadb6a9) +set(OPENJPEG_HASH 8702ba68b442657f11aaeb2b338443ca8d5fb95b0d845757968a7be31ef7f16d) set(OPENJPEG_HASH_TYPE SHA256) set(OPENJPEG_FILE openjpeg-v${OPENJPEG_VERSION}.tar.gz) -set(FFMPEG_VERSION 4.4) +set(FFMPEG_VERSION 5.0) set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2) -set(FFMPEG_HASH 42093549751b582cf0f338a21a3664f52e0a9fbe0d238d3c992005e493607d0e) +set(FFMPEG_HASH c0130b8db2c763430fd1c6905288d61bc44ee0548ad5fcd2dfd650b88432bed9) set(FFMPEG_HASH_TYPE SHA256) set(FFMPEG_FILE ffmpeg-${FFMPEG_VERSION}.tar.bz2) -set(FFTW_VERSION 3.3.8) +set(FFTW_VERSION 3.3.10) set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz) -set(FFTW_HASH 8aac833c943d8e90d51b697b27d4384d) +set(FFTW_HASH 8ccbf6a5ea78a16dbc3e1306e234cc5c) set(FFTW_HASH_TYPE MD5) set(FFTW_FILE fftw-${FFTW_VERSION}.tar.gz) @@ -301,9 +318,9 @@ set(SNDFILE_HASH 646b5f98ce89ac60cdb060fcd398247c) set(SNDFILE_HASH_TYPE MD5) set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.gz) -set(WEBP_VERSION 0.6.1) +set(WEBP_VERSION 1.2.2) set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz) -set(WEBP_HASH b49ce9c3e3e9acae4d91bca44bb85a72) +set(WEBP_HASH b5e2e414a8adee4c25fe56b18dd9c549) set(WEBP_HASH_TYPE MD5) set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz) @@ -338,9 +355,15 @@ set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2) set(YAMLCPP_HASH_TYPE MD5) set(YAMLCPP_FILE yaml-cpp-${YAMLCPP_VERSION}.tar.gz) -set(EXPAT_VERSION 2_2_10) +set(PYSTRING_VERSION v1.1.3) +set(PYSTRING_URI https://codeload.github.com/imageworks/pystring/tar.gz/refs/tags/${PYSTRING_VERSION}) +set(PYSTRING_HASH f2c68786b359f5e4e62bed53bc4fb86d) +set(PYSTRING_HASH_TYPE MD5) +set(PYSTRING_FILE pystring-${PYSTRING_VERSION}.tar.gz) + +set(EXPAT_VERSION 2_4_4) set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz) -set(EXPAT_HASH 7ca5f09959fcb9a57618368deb627b9f) +set(EXPAT_HASH 2d3e81dee94b452369dc6394ff0f8f98) set(EXPAT_HASH_TYPE MD5) set(EXPAT_FILE libexpat-${EXPAT_VERSION}.tar.gz) @@ -405,22 +428,21 @@ set(SQLITE_HASH fb558c49ee21a837713c4f1e7e413309aabdd9c7) set(SQLITE_HASH_TYPE SHA1) set(SQLITE_FILE sqlite-src-3240000.zip) -set(EMBREE_VERSION 3.10.0) +set(EMBREE_VERSION 3.13.3) set(EMBREE_URI https://github.com/embree/embree/archive/v${EMBREE_VERSION}.zip) -set(EMBREE_HASH 4bbe29e7eaa46417efc75fc5f1e8eb87) +set(EMBREE_HASH f62766ba54e48a2f327c3a22596e7133) set(EMBREE_HASH_TYPE MD5) set(EMBREE_FILE embree-v${EMBREE_VERSION}.zip) -set(EMBREE_ARM_GIT https://github.com/brechtvl/embree.git) -set(USD_VERSION 21.02) +set(USD_VERSION 22.03) set(USD_URI https://github.com/PixarAnimationStudios/USD/archive/v${USD_VERSION}.tar.gz) -set(USD_HASH 1dd1e2092d085ed393c1f7c450a4155a) +set(USD_HASH e0e441a05057692a83124a1195b09eed) set(USD_HASH_TYPE MD5) set(USD_FILE usd-v${USD_VERSION}.tar.gz) -set(OIDN_VERSION 1.4.1) +set(OIDN_VERSION 1.4.3) set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz) -set(OIDN_HASH df4007b0ab93b1c41cdf223b075d01c0) +set(OIDN_HASH 027093eaf5e8b4e45835b991137b38e6) set(OIDN_HASH_TYPE MD5) set(OIDN_FILE oidn-${OIDN_VERSION}.src.tar.gz) @@ -454,9 +476,9 @@ set(WL_PROTOCOLS_URI https://gitlab.freedesktop.org/wayland/wayland-protocols/-/ set(WL_PROTOCOLS_HASH af5ca07e13517cdbab33504492cef54a) set(WL_PROTOCOLS_HASH_TYPE MD5) -set(ISPC_VERSION v1.16.0) +set(ISPC_VERSION v1.17.0) set(ISPC_URI https://github.com/ispc/ispc/archive/${ISPC_VERSION}.tar.gz) -set(ISPC_HASH 2e3abedbc0ea9aaec17d6562c632454d) +set(ISPC_HASH 4f476a3109332a77fe839a9014c60ca9) set(ISPC_HASH_TYPE MD5) set(ISPC_FILE ispc-${ISPC_VERSION}.tar.gz) @@ -492,3 +514,9 @@ set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSI set(BROTLI_HASH f9e8d81d0405ba66d181529af42a3354f838c939095ff99930da6aa9cdf6fe46) set(BROTLI_HASH_TYPE SHA256) set(BROTLI_FILE brotli-${BROTLI_VERSION}.tar.gz) + +set(LEVEL_ZERO_VERSION v1.7.15) +set(LEVEL_ZERO_URI https://github.com/oneapi-src/level-zero/archive/refs/tags/${LEVEL_ZERO_VERSION}.tar.gz) +set(LEVEL_ZERO_HASH c39bb05a8e5898aa6c444e1704105b93d3f1888b9c333f8e7e73825ffbfb2617) +set(LEVEL_ZERO_HASH_TYPE SHA256) +set(LEVEL_ZERO_FILE level-zero-${LEVEL_ZERO_VERSION}.tar.gz) diff --git a/build_files/build_environment/cmake/webp.cmake b/build_files/build_environment/cmake/webp.cmake index 472d93cd15d..285c0748fab 100644 --- a/build_files/build_environment/cmake/webp.cmake +++ b/build_files/build_environment/cmake/webp.cmake @@ -4,9 +4,15 @@ # library itself does not depend on them, so should give no problems. set(WEBP_EXTRA_ARGS - -DWEBP_HAVE_SSE2=ON - -DWEBP_HAVE_SSE41=OFF - -DWEBP_HAVE_AVX2=OFF + -DWEBP_BUILD_ANIM_UTILS=OFF + -DWEBP_BUILD_CWEBP=OFF + -DWEBP_BUILD_DWEBP=OFF + -DWEBP_BUILD_GIF2WEBP=OFF + -DWEBP_BUILD_IMG2WEBP=OFF + -DWEBP_BUILD_VWEBP=OFF + -DWEBP_BUILD_WEBPINFO=OFF + -DWEBP_BUILD_WEBPMUX=OFF + -DWEBP_BUILD_EXTRAS=OFF ) if(WIN32) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index ecf5d215333..58702f69609 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -539,10 +539,10 @@ ALEMBIC_FORCE_BUILD=false ALEMBIC_FORCE_REBUILD=false ALEMBIC_SKIP=false -USD_VERSION="21.02" -USD_VERSION_SHORT="21.02" +USD_VERSION="22.03" +USD_VERSION_SHORT="22.03" USD_VERSION_MIN="20.05" -USD_VERSION_MEX="22.00" +USD_VERSION_MEX="23.00" USD_FORCE_BUILD=false USD_FORCE_REBUILD=false USD_SKIP=false diff --git a/build_files/build_environment/patches/cmakelists_pystring.txt b/build_files/build_environment/patches/cmakelists_pystring.txt new file mode 100644 index 00000000000..0a6dee7939d --- /dev/null +++ b/build_files/build_environment/patches/cmakelists_pystring.txt @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright Contributors to the OpenColorIO Project. + +project(pystring) + +cmake_minimum_required(VERSION 3.10) + +set(HEADERS + pystring.h +) + +set(SOURCES + pystring.cpp +) + +add_library(${PROJECT_NAME} STATIC ${HEADERS} ${SOURCES}) + +if(UNIX) + set(pystring_CXX_FLAGS "${pystring_CXX_FLAGS} -fPIC") +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES + COMPILE_FLAGS "${PLATFORM_COMPILE_FLAGS} ${pystring_CXX_FLAGS}" + PUBLIC_HEADER "${HEADERS}" +) + +install(TARGETS ${PROJECT_NAME} + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + PUBLIC_HEADER DESTINATION include/pystring +) diff --git a/build_files/build_environment/patches/embree.diff b/build_files/build_environment/patches/embree.diff index 9b2c66feaf7..e83d754a465 100644 --- a/build_files/build_environment/patches/embree.diff +++ b/build_files/build_environment/patches/embree.diff @@ -12,3 +12,19 @@ diff -Naur orig/common/sys/platform.h external_embree/common/sys/platform.h #else #define dll_export __attribute__ ((visibility ("default"))) #define dll_import +diff --git orig/common/tasking/CMakeLists.txt external_embree/common/tasking/CMakeLists.txt +--- orig/common/tasking/CMakeLists.txt ++++ external_embree/common/tasking/CMakeLists.txt +@@ -27,7 +27,11 @@ + else() + # If not found try getting older TBB via module (FindTBB.cmake) + unset(TBB_DIR CACHE) +- find_package(TBB 4.1 REQUIRED tbb) ++ if (TBB_STATIC_LIB) ++ find_package(TBB 4.1 REQUIRED tbb_static) ++ else() ++ find_package(TBB 4.1 REQUIRED tbb) ++ endif() + if (TBB_FOUND) + TARGET_LINK_LIBRARIES(tasking PUBLIC TBB) + TARGET_INCLUDE_DIRECTORIES(tasking PUBLIC "${TBB_INCLUDE_DIRS}") diff --git a/build_files/build_environment/patches/ispc.diff b/build_files/build_environment/patches/ispc.diff index 3ab67356e19..d0c09405603 100644 --- a/build_files/build_environment/patches/ispc.diff +++ b/build_files/build_environment/patches/ispc.diff @@ -1,43 +1,6 @@ -diff -Naur external_ispc/CMakeLists.txt external_ispc_fixed/CMakeLists.txt ---- external_ispc/CMakeLists.txt 2020-04-23 17:29:06 -0600 -+++ external_ispc_fixed/CMakeLists.txt 2020-05-05 09:01:09 -0600 -@@ -389,7 +389,7 @@ - - # Link against Clang libraries - foreach(clangLib ${CLANG_LIBRARY_LIST}) -- find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS}) -+ find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS} ${CLANG_LIBRARY_DIR}) - list(APPEND CLANG_LIBRARY_FULL_PATH_LIST ${${clangLib}Path}) - endforeach() - target_link_libraries(${PROJECT_NAME} ${CLANG_LIBRARY_FULL_PATH_LIST}) -diff -Naur orig/CMakeLists.txt external_ispc/CMakeLists.txt ---- orig/CMakeLists.txt 2020-05-05 09:19:11 -0600 -+++ external_ispc/CMakeLists.txt 2020-05-05 09:26:44 -0600 -@@ -333,7 +333,7 @@ - - # Include directories - target_include_directories(${PROJECT_NAME} PRIVATE -- ${LLVM_INCLUDE_DIRS} -+ ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS} - ${GENX_DEPS_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/src - ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}) -diff -Naur orig/cmake/GenerateBuiltins.cmake.txt external_ispc/cmake/GenerateBuiltins.cmake.txt -+++ orig/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200 -+++ external_ispc/cmake/GenerateBuiltins.cmake 2020-05-25 13:32:40.830803821 +0200 -@@ -97,6 +97,8 @@ - - if ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "x86") - set(target_arch "i686") -+ # Blender: disable 32bit due to build issues on Linux and being unnecessary. -+ set(SKIP ON) - elseif ("${bit}" STREQUAL "64" AND ${arch} STREQUAL "x86") - set(target_arch "x86_64") - elseif ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "arm") -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 46a8db8..f53beef 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt +diff -Naur ispc-1.17.0.org/CMakeLists.txt ispc-1.17.0/CMakeLists.txt +--- ispc-1.17.0.org/CMakeLists.txt 2022-01-15 01:35:15 -0700 ++++ ispc-1.17.0/CMakeLists.txt 2022-02-12 12:44:24 -0700 @@ -36,8 +36,12 @@ cmake_minimum_required(VERSION 3.13) @@ -53,7 +16,25 @@ index 46a8db8..f53beef 100644 endif() set(PROJECT_NAME ispc) -@@ -412,6 +416,29 @@ else() +@@ -443,7 +447,7 @@ + + # Include directories + target_include_directories(${PROJECT_NAME} PRIVATE +- ${LLVM_INCLUDE_DIRS} ++ ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS} + ${XE_DEPS_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}) +@@ -507,7 +511,7 @@ + + # Link against Clang libraries + foreach(clangLib ${CLANG_LIBRARY_LIST}) +- find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS}) ++ find_library(${clangLib}Path NAMES ${clangLib} HINTS ${LLVM_LIBRARY_DIRS} ${CLANG_LIBRARY_DIR}) + list(APPEND CLANG_LIBRARY_FULL_PATH_LIST ${${clangLib}Path}) + endforeach() + target_link_libraries(${PROJECT_NAME} ${CLANG_LIBRARY_FULL_PATH_LIST}) +@@ -546,6 +550,29 @@ endif() endif() @@ -83,3 +64,15 @@ index 46a8db8..f53beef 100644 # Build target for utility checking host ISA if (ISPC_INCLUDE_UTILS) add_executable(check_isa "") +diff -Naur ispc-1.17.0.org/cmake/GenerateBuiltins.cmake ispc-1.17.0/cmake/GenerateBuiltins.cmake +--- ispc-1.17.0.org/cmake/GenerateBuiltins.cmake 2022-01-15 01:35:15 -0700 ++++ ispc-1.17.0/cmake/GenerateBuiltins.cmake 2022-02-12 12:44:24 -0700 +@@ -124,6 +124,8 @@ + + if ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "x86") + set(target_arch "i686") ++ # Blender: disable 32bit due to build issues on Linux and being unnecessary. ++ set(SKIP ON) + elseif ("${bit}" STREQUAL "64" AND ${arch} STREQUAL "x86") + set(target_arch "x86_64") + elseif ("${bit}" STREQUAL "32" AND ${arch} STREQUAL "arm") diff --git a/build_files/build_environment/patches/level-zero.diff b/build_files/build_environment/patches/level-zero.diff new file mode 100644 index 00000000000..22680166723 --- /dev/null +++ b/build_files/build_environment/patches/level-zero.diff @@ -0,0 +1,13 @@ +diff -Naur external_levelzero_org/CMakeLists.txt external_levelzero/CMakeLists.txt +--- external_levelzero_org/CMakeLists.txt 2022-03-07 13:22:11 -0700 ++++ external_levelzero/CMakeLists.txt 2022-03-29 13:22:15 -0600 +@@ -77,9 +77,6 @@ + #enabling Control Flow Guard + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /guard:cf") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /guard:cf") +- # enable Spectre Mitigation +- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qspectre") +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Qspectre") + endif() + + #CXX compiler support
\ No newline at end of file diff --git a/build_files/build_environment/patches/openvdb.diff b/build_files/build_environment/patches/openvdb.diff index 2f6f735946b..b48efb81df1 100644 --- a/build_files/build_environment/patches/openvdb.diff +++ b/build_files/build_environment/patches/openvdb.diff @@ -1,35 +1,16 @@ -diff -Naur openvdb-8.0.0/cmake/FindIlmBase.cmake openvdb/cmake/FindIlmBase.cmake ---- openvdb-8.0.0/cmake/FindIlmBase.cmake 2020-12-24 10:13:14 -0700 -+++ openvdb/cmake/FindIlmBase.cmake 2021-02-05 12:07:49 -0700 -@@ -217,6 +217,12 @@ - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") - endif() - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_IlmBase_Version_Suffix}.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES -+ "_s.lib" -+ ) -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES -+ "_s_d.lib" -+ ) - else() - if(ILMBASE_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") -diff -Naur openvdb-8.0.0/cmake/FindOpenEXR.cmake openvdb/cmake/FindOpenEXR.cmake ---- openvdb-8.0.0/cmake/FindOpenEXR.cmake 2020-12-24 10:13:14 -0700 -+++ openvdb/cmake/FindOpenEXR.cmake 2021-02-05 12:23:39 -0700 -@@ -210,6 +210,12 @@ - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") - endif() - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES -+ "_s.lib" -+ ) -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES -+ "_s_d.lib" -+ ) - else() - if(OPENEXR_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") +diff -ur openvdb-9.0.0/cmake/FindTBB.cmake openvdb/cmake/FindTBB.cmake +--- openvdb-9.0.0/cmake/FindTBB.cmake 2021-10-30 03:55:40.000000000 +0100 ++++ openvdb/cmake/FindTBB.cmake 2022-03-31 11:33:15.592329750 +0100 +@@ -252,7 +252,8 @@ + set(_TBB_LIB_NAME "${_TBB_LIB_NAME}${TBB_DEBUG_SUFFIX}") + endif() + +- find_library(Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} ${_TBB_LIB_NAME} ++ find_library(Tbb_${COMPONENT}_LIBRARY_${BUILD_TYPE} ++ NAMES ${_TBB_LIB_NAME} ${_TBB_LIB_NAME}_static + ${_FIND_TBB_ADDITIONAL_OPTIONS} + PATHS ${_TBB_LIBRARYDIR_SEARCH_DIRS} + PATH_SUFFIXES ${CMAKE_INSTALL_LIBDIR} lib64 lib diff -Naur openvdb-8.0.0/openvdb/openvdb/CMakeLists.txt openvdb/openvdb/openvdb/CMakeLists.txt --- openvdb-8.0.0/openvdb/openvdb/CMakeLists.txt 2020-12-24 10:13:14 -0700 +++ openvdb/openvdb/openvdb/CMakeLists.txt 2021-02-05 11:18:33 -0700 diff --git a/build_files/build_environment/patches/osl.diff b/build_files/build_environment/patches/osl.diff index 54885323571..28e1d6e101d 100644 --- a/build_files/build_environment/patches/osl.diff +++ b/build_files/build_environment/patches/osl.diff @@ -48,25 +48,6 @@ diff -Naur org/CMakeLists.txt external_osl/CMakeLists.txt set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem") if (OSL_NO_DEFAULT_TEXTURESYSTEM) -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 990f50d69..46ef7351d 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -252,11 +252,9 @@ install (EXPORT OSL_EXPORTED_TARGETS - FILE ${OSL_TARGETS_EXPORT_NAME} - NAMESPACE ${PROJECT_NAME}::) - -- -- -- --osl_add_all_tests() -- -+if (${PROJECT_NAME}_BUILD_TESTS AND NOT ${PROJECT_NAME}_IS_SUBPROJECT) -+ osl_add_all_tests() -+endif () - - if (NOT ${PROJECT_NAME}_IS_SUBPROJECT) - include (packaging) diff -Naur external_osl_orig/src/cmake/externalpackages.cmake external_osl/src/cmake/externalpackages.cmake --- external_osl_orig/src/cmake/externalpackages.cmake 2021-06-01 13:44:18 -0600 +++ external_osl/src/cmake/externalpackages.cmake 2021-06-28 07:44:32 -0600 diff --git a/build_files/build_environment/patches/usd.diff b/build_files/build_environment/patches/usd.diff index 8ea1e2054c1..eb5905109a7 100644 --- a/build_files/build_environment/patches/usd.diff +++ b/build_files/build_environment/patches/usd.diff @@ -10,217 +10,22 @@ diff -x .git -ur usd.orig/cmake/defaults/Packages.cmake external_usd/cmake/defau add_definitions(${TBB_DEFINITIONS}) # --math -diff -Naur external_usd_base/cmake/macros/Public.cmake external_usd/cmake/macros/Public.cmake ---- external_usd_base/cmake/macros/Public.cmake 2019-10-24 14:39:53 -0600 -+++ external_usd/cmake/macros/Public.cmake 2020-01-11 13:33:29 -0700 -@@ -996,6 +996,12 @@ - foreach(lib ${PXR_OBJECT_LIBS}) - string(TOUPPER ${lib} uppercaseName) - list(APPEND exports "${uppercaseName}_EXPORTS=1") -+ # When building for blender, we do NOT want to export all symbols on windows. -+ # This is a dirty hack, but USD makes it impossible to do the right thing -+ # with the default options exposed. -+ if (WIN32) -+ list(APPEND exports "PXR_STATIC=1") -+ endif() - endforeach() - foreach(lib ${PXR_OBJECT_LIBS}) - set(objects "${objects};\$<TARGET_OBJECTS:${lib}>") -diff -ru USD-20.11/pxr/base/tf/pxrLZ4/lz4.cpp external_usd/pxr/base/tf/pxrLZ4/lz4.cpp ---- USD-20.11/pxr/base/tf/pxrLZ4/lz4.cpp 2020-10-14 19:25:19.000000000 +0100 -+++ external_usd/pxr/base/tf/pxrLZ4/lz4.cpp 2021-02-09 09:28:51.496190085 +0000 -@@ -614,6 +614,15 @@ - /*-************************************ - * Internal Definitions used in Tests - **************************************/ -+ -+/******************************************************************* -+ * Disabled in Blender. The BLOSC library also exposes these -+ * functions, and this causes 'duplicate symbol' linker errors. -+ * -+ * This problem has been reported upstream at -+ * https://github.com/PixarAnimationStudios/USD/issues/1447 -+ * -+ ******************************************************************* - #if defined (__cplusplus) - extern "C" { - #endif -@@ -627,6 +636,7 @@ - #if defined (__cplusplus) - } - #endif -+********************************************************************/ - - /*-****************************** - * Compression functions - -From 442d087962f762deeb8b6e49a0955753fcf9aeb9 Mon Sep 17 00:00:00 2001 -From: Tsahi Zidenberg <tsahee@amazon.com> -Date: Sun, 15 Nov 2020 15:18:24 +0000 -Subject: [PATCH 1/2] stackTrace: support aarch64/linux - -stacktrace calls syscall directly via assembler. Create compatible -aarch64 code. ---- - pxr/base/arch/stackTrace.cpp | 30 ++++++++++++++++++++++++------ - 1 file changed, 24 insertions(+), 6 deletions(-) -diff --git a/pxr/base/arch/stackTrace.cpp b/pxr/base/arch/stackTrace.cpp -index dcc1dfd46..c11aabeb1 100644 ---- a/pxr/base/arch/stackTrace.cpp -+++ b/pxr/base/arch/stackTrace.cpp -@@ -583,7 +583,6 @@ nonLockingLinux__execve (const char *file, - char *const argv[], - char *const envp[]) - { --#if defined(ARCH_BITS_64) - /* - * We make a direct system call here, because we can't find an - * execve which corresponds with the non-locking fork we call -@@ -594,7 +593,27 @@ nonLockingLinux__execve (const char *file, - * hangs in a threaded app. (We use the non-locking fork to get - * around problems with forking when we have had memory - * corruption.) whew. -- * -+ */ -+ -+ unsigned long result; -+ -+#if defined (__aarch64__) -+ { -+ register long __file_result asm ("x0") = (long)file; -+ register char* const* __argv asm ("x1") = argv; -+ register char* const* __envp asm ("x2") = envp; -+ register long __num_execve asm ("x8") = 221; -+ __asm__ __volatile__ ( -+ "svc 0" -+ : "=r" (__file_result) -+ : "r"(__num_execve), "r" (__file_result), "r" (__argv), "r" (__envp) -+ : "memory" -+ ); -+ result = __file_result; -+ } -+#elif defined(ARCH_CPU_INTEL) && defined(ARCH_BITS_64) -+ -+ /* - * %rdi, %rsi, %rdx, %rcx, %r8, %r9 are args 0-5 - * syscall clobbers %rcx and %r11 - * -@@ -603,7 +622,6 @@ nonLockingLinux__execve (const char *file, - * constraints to gcc. - */ +diff -Naur usd_orig/cmake/defaults/msvcdefaults.cmake external_usd/cmake/defaults/msvcdefaults.cmake +--- usd_orig/cmake/defaults/msvcdefaults.cmake 2022-02-18 14:49:09 -0700 ++++ external_usd/cmake/defaults/msvcdefaults.cmake 2022-03-14 11:41:50 -0600 +@@ -120,9 +120,6 @@ + # for all translation units. + set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /bigobj") -- unsigned long result; - __asm__ __volatile__ ( - "mov %0, %%rdi \n\t" - "mov %%rcx, %%rsi \n\t" -@@ -614,6 +632,9 @@ nonLockingLinux__execve (const char *file, - : "0" (file), "c" (argv), "d" (envp) - : "memory", "cc", "r11" - ); -+#else -+#error Unknown architecture -+#endif - - if (result >= 0xfffffffffffff000) { - errno = -result; -@@ -621,9 +642,6 @@ nonLockingLinux__execve (const char *file, - } - - return result; --#else --#error Unknown architecture --#endif - } - - #endif - -From a1dffe02519bb3c6ccbbe8c6c58304da5db98995 Mon Sep 17 00:00:00 2001 -From: Tsahi Zidenberg <tsahee@amazon.com> -Date: Sun, 15 Nov 2020 15:22:52 +0000 -Subject: [PATCH 2/2] timing: support aarch64/linux - -The aarch64 arch-timer is directly accessible to userspace via two -registers: -CNTVCT_EL0 - holds the current counter value -CNTFRQ_EL0 - holds the counter frequency (in Hz) ---- - pxr/base/arch/timing.cpp | 6 ++++++ - pxr/base/arch/timing.h | 6 +++++- - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/pxr/base/arch/timing.cpp b/pxr/base/arch/timing.cpp -index 27ad58fed..9022950c1 100644 ---- a/pxr/base/arch/timing.cpp -+++ b/pxr/base/arch/timing.cpp -@@ -59,6 +59,11 @@ ARCH_HIDDEN - void - Arch_InitTickTimer() - { -+#ifdef __aarch64__ -+ uint64_t counter_hz; -+ __asm __volatile("mrs %0, CNTFRQ_EL0" : "=&r" (counter_hz)); -+ Arch_NanosecondsPerTick = double(1e9) / double(counter_hz); -+#else - // NOTE: Normally ifstream would be cleaner, but it causes crashes when - // used in conjunction with DSOs and the Intel Compiler. - FILE *in; -@@ -135,6 +140,7 @@ Arch_InitTickTimer() - } - - Arch_NanosecondsPerTick = double(1e9) / double(cpuHz); -+#endif - } - #elif defined(ARCH_OS_WINDOWS) - -diff --git a/pxr/base/arch/timing.h b/pxr/base/arch/timing.h -index 67ec0d15f..6dc3e85a0 100644 ---- a/pxr/base/arch/timing.h -+++ b/pxr/base/arch/timing.h -@@ -36,7 +36,7 @@ - /// \addtogroup group_arch_SystemFunctions - ///@{ - --#if defined(ARCH_OS_LINUX) -+#if defined(ARCH_OS_LINUX) && defined(ARCH_CPU_INTEL) - #include <x86intrin.h> - #elif defined(ARCH_OS_DARWIN) - #include <mach/mach_time.h> -@@ -69,6 +69,10 @@ ArchGetTickTime() - #elif defined(ARCH_CPU_INTEL) - // On Intel we'll use the rdtsc instruction. - return __rdtsc(); -+#elif defined (__aarch64__) -+ uint64_t result; -+ __asm __volatile("mrs %0, CNTVCT_EL0" : "=&r" (result)); -+ return result; - #else - #error Unknown architecture. - #endif - -diff --git a/pxr/base/arch/demangle.cpp b/pxr/base/arch/demangle.cpp -index 67ec0d15f..6dc3e85a0 100644 ---- a/pxr/base/arch/demangle.cpp -+++ b/pxr/base/arch/demangle.cpp -@@ -36,6 +36,7 @@ - #if (ARCH_COMPILER_GCC_MAJOR == 3 && ARCH_COMPILER_GCC_MINOR >= 1) || \ - ARCH_COMPILER_GCC_MAJOR > 3 || defined(ARCH_COMPILER_CLANG) - #define _AT_LEAST_GCC_THREE_ONE_OR_CLANG -+#include <cxxabi.h> - #endif - - PXR_NAMESPACE_OPEN_SCOPE -@@ -138,7 +139,6 @@ - #endif - - #if defined(_AT_LEAST_GCC_THREE_ONE_OR_CLANG) --#include <cxxabi.h> - - /* - * This routine doesn't work when you get to gcc3.4. +-# Enable PDB generation. +-set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /Zi") +- + # Enable multiprocessor builds. + set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /MP") + set(_PXR_CXX_FLAGS "${_PXR_CXX_FLAGS} /Gm-") diff --git a/pxr/base/work/singularTask.h b/pxr/base/work/singularTask.h -index 67ec0d15f..6dc3e85a0 100644 --- a/pxr/base/work/singularTask.h +++ b/pxr/base/work/singularTask.h @@ -120,7 +120,7 @@ @@ -232,3 +37,17 @@ index 67ec0d15f..6dc3e85a0 100644 do { _fn(); } while ( !count.compare_exchange_strong(old, 0)); }); + +diff --git a/pxr/usd/sdr/shaderMetadataHelpers.h b/pxr/usd/sdr/shaderMetadataHelpers.h +--- a/pxr/usd/sdr/shaderMetadataHelpers.h ++++ b/pxr/usd/sdr/shaderMetadataHelpers.h +@@ -32,6 +32,8 @@ + #include "pxr/base/tf/token.h" + #include "pxr/usd/sdr/declare.h" + ++#include <limits> ++ + PXR_NAMESPACE_OPEN_SCOPE + + /// \namespace ShaderMetadataHelpers + diff --git a/build_files/build_environment/windows/build_deps.cmd b/build_files/build_environment/windows/build_deps.cmd index c0e13ac3a55..e13d59ef804 100644 --- a/build_files/build_environment/windows/build_deps.cmd +++ b/build_files/build_environment/windows/build_deps.cmd @@ -46,6 +46,15 @@ if "%3" == "debug" set CMAKE_DEBUG_OPTIONS=-DWITH_OPTIMIZED_DEBUG=Off set dobuild=1 if "%4" == "nobuild" set dobuild=0 +REM If Python is be available certain deps may try to +REM to use this over the version we build, to prevent that +REM make sure python is NOT in the path +for %%X in (python.exe) do (set PYTHON=%%~$PATH:X) +if EXIST "%PYTHON%" ( + echo PYTHON found at %PYTHON% dependencies cannot be build with python available in the path + goto exit +) + set SOURCE_DIR=%~dp0\.. set BUILD_DIR=%cd%\build set HARVEST_DIR=%BUILD_DIR%\output @@ -99,7 +108,7 @@ cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE echo %DATE% %TIME% : Release Configuration done >> %StatusFile% if "%dobuild%" == "1" ( msbuild /m "ll.vcxproj" /p:Configuration=Release /fl /flp:logfile=BlenderDeps_llvm.log;Verbosity=normal - msbuild /m "BlenderDependencies.sln" /p:Configuration=Release /fl /flp:logfile=BlenderDeps.log;Verbosity=minimal /verbosity:minimal + msbuild /maxcpucount:1 /m "BlenderDependencies.sln" /p:Configuration=Release /fl /flp:logfile=BlenderDeps.log;Verbosity=minimal /verbosity:minimal echo %DATE% %TIME% : Release Build done >> %StatusFile% cmake --build . --target Harvest_Release_Results > Harvest_Release.txt ) @@ -112,7 +121,7 @@ cmake -G "%CMAKE_BUILDER%" %CMAKE_BUILD_ARCH% -Thost=x64 %SOURCE_DIR% -DPACKAGE_ echo %DATE% %TIME% : Debug Configuration done >> %StatusFile% if "%dobuild%" == "1" ( msbuild /m "ll.vcxproj" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps_llvm.log;;Verbosity=normal - msbuild /m "BlenderDependencies.sln" /p:Configuration=Debug /verbosity:n /fl /flp:logfile=BlenderDeps.log;;Verbosity=normal + msbuild /maxcpucount:1 /m "BlenderDependencies.sln" /p:Configuration=Debug /verbosity:n /fl /flp:logfile=BlenderDeps.log;;Verbosity=normal echo %DATE% %TIME% : Debug Build done >> %StatusFile% cmake --build . --target Harvest_Debug_Results> Harvest_Debug.txt ) diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake index f772ef4e1ff..9107b562711 100644 --- a/build_files/cmake/Modules/FindOpenEXR.cmake +++ b/build_files/cmake/Modules/FindOpenEXR.cmake @@ -85,9 +85,9 @@ STRING(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _openexr_libs_ver ${OPENE IF(OPENEXR_VERSION VERSION_GREATER_EQUAL "3.0.0") SET(_openexr_FIND_COMPONENTS Iex - IlmThread OpenEXR OpenEXRCore + IlmThread ) ELSE() SET(_openexr_FIND_COMPONENTS diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py index b015c5c6e7c..db9fd2d57a4 100644 --- a/build_files/cmake/clang_array_check.py +++ b/build_files/cmake/clang_array_check.py @@ -202,9 +202,9 @@ def parm_size(node_child): # NOT PERFECT CODE, EXTRACT SIZE FROM TOKENS if len(tokens) >= 3: # foo [ 1 ] - if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and - (tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and - (tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")): + if ((tokens[-3].kind == TokenKind.PUNCTUATION and tokens[-3].spelling == "[") and + (tokens[-2].kind == TokenKind.LITERAL and tokens[-2].spelling.isdigit()) and + (tokens[-1].kind == TokenKind.PUNCTUATION and tokens[-1].spelling == "]")): # --- return int(tokens[-2].spelling) return -1 diff --git a/build_files/cmake/config/blender_full.cmake b/build_files/cmake/config/blender_full.cmake index 9faa0118ae2..e09577ac802 100644 --- a/build_files/cmake/config/blender_full.cmake +++ b/build_files/cmake/config/blender_full.cmake @@ -30,6 +30,7 @@ set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE) +set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE) set(WITH_INPUT_IME ON CACHE BOOL "" FORCE) set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_lite.cmake b/build_files/cmake/config/blender_lite.cmake index 2d895f55c31..2f6057ee9c0 100644 --- a/build_files/cmake/config/blender_lite.cmake +++ b/build_files/cmake/config/blender_lite.cmake @@ -34,6 +34,7 @@ set(WITH_IMAGE_HDR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE) set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE) +set(WITH_IMAGE_WEBP OFF CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE) set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE) set(WITH_JACK OFF CACHE BOOL "" FORCE) diff --git a/build_files/cmake/config/blender_release.cmake b/build_files/cmake/config/blender_release.cmake index 4e96975bd90..8ece5eec39e 100644 --- a/build_files/cmake/config/blender_release.cmake +++ b/build_files/cmake/config/blender_release.cmake @@ -31,6 +31,7 @@ set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENEXR ON CACHE BOOL "" FORCE) set(WITH_IMAGE_OPENJPEG ON CACHE BOOL "" FORCE) set(WITH_IMAGE_TIFF ON CACHE BOOL "" FORCE) +set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE) set(WITH_INPUT_NDOF ON CACHE BOOL "" FORCE) set(WITH_INPUT_IME ON CACHE BOOL "" FORCE) set(WITH_INTERNATIONAL ON CACHE BOOL "" FORCE) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index cdc9aa91a53..91d0b54e426 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -71,6 +71,7 @@ set(CMAKE_PREFIX_PATH ${LIB_SUBDIRS}) # Find precompiled libraries, and avoid system or user-installed ones. if(EXISTS ${LIBDIR}) + include(platform_old_libs_update) without_system_libs_begin() endif() diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake new file mode 100644 index 00000000000..014aa198caf --- /dev/null +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2022 Blender Foundation. All rights reserved. + +# Auto update existing CMake caches for new libraries + +function(unset_cache_variables pattern) + get_cmake_property(_cache_variables CACHE_VARIABLES) + foreach (_cache_variable ${_cache_variables}) + if("${_cache_variable}" MATCHES "${pattern}") + unset(${_cache_variable} CACHE) + endif() + endforeach() +endfunction() + +# Detect update from 3.1 to 3.2 libs. +if(UNIX AND + DEFINED OPENEXR_VERSION AND + OPENEXR_VERSION VERSION_LESS "3.0.0" AND + EXISTS ${LIBDIR}/imath) + message(STATUS "Auto updating CMake configuration for Blender 3.2 libraries") + + unset_cache_variables("^OPENIMAGEIO") + unset_cache_variables("^OPENEXR") + unset_cache_variables("^IMATH") + unset_cache_variables("^PNG") + unset_cache_variables("^USD") + unset_cache_variables("^WEBP") +endif() + +# Automatically set WebP on/off depending if libraries are available. +if(EXISTS ${LIBDIR}/webp) + if(WITH_OPENIMAGEIO) + set(WITH_IMAGE_WEBP ON CACHE BOOL "" FORCE) + endif() +else() + set(WITH_IMAGE_WEBP OFF) +endif() diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index cc168476d5d..6750c23d548 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -45,6 +45,9 @@ if(EXISTS ${LIBDIR}) # which is a part of OpenCollada. They have different ABI, and we # do need to use the official one. set(CMAKE_PREFIX_PATH ${LIBDIR}/zlib ${LIB_SUBDIRS}) + + include(platform_old_libs_update) + set(WITH_STATIC_LIBS ON) # OpenMP usually can't be statically linked into shared libraries, # due to not being compiled with position independent code. @@ -373,6 +376,7 @@ if(WITH_IMAGE_WEBP) find_package_wrapper(WebP) if(NOT WEBP_FOUND) set(WITH_IMAGE_WEBP OFF) + message(WARNING "WebP not found, disabling WITH_IMAGE_WEBP") endif() endif() @@ -394,6 +398,9 @@ if(WITH_OPENIMAGEIO) if(WITH_IMAGE_OPENEXR) list(APPEND OPENIMAGEIO_LIBRARIES "${OPENEXR_LIBRARIES}") endif() + if(WITH_IMAGE_WEBP) + list(APPEND OPENIMAGEIO_LIBRARIES "${WEBP_LIBRARIES}") + endif() if(NOT OPENIMAGEIO_FOUND) set(WITH_OPENIMAGEIO OFF) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index b0dbc0d3264..c5d2049b292 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -262,6 +262,8 @@ if(NOT EXISTS "${LIBDIR}/") message(FATAL_ERROR "\n\nWindows requires pre-compiled libs at: '${LIBDIR}'. Please run `make update` in the blender source folder to obtain them.") endif() +include(platform_old_libs_update) + if(CMAKE_GENERATOR MATCHES "^Visual Studio.+" AND # Only supported in the VS IDE MSVC_VERSION GREATER_EQUAL 1924 AND # Supported for 16.4+ WITH_CLANG_TIDY # And Clang Tidy needs to be on @@ -343,13 +345,18 @@ if(WITH_FFTW3) set(FFTW3_LIBPATH ${FFTW3}/lib) endif() -windows_find_package(WebP) -if(NOT WEBP_FOUND) - if(EXISTS ${LIBDIR}/webp) - set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include) - set(WEBP_ROOT_DIR ${LIBDIR}/webp) - set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib) - set(WEBP_FOUND ON) +if(WITH_IMAGE_WEBP) + windows_find_package(WebP) + if(NOT WEBP_FOUND) + if(EXISTS ${LIBDIR}/webp) + set(WEBP_INCLUDE_DIRS ${LIBDIR}/webp/include) + set(WEBP_ROOT_DIR ${LIBDIR}/webp) + set(WEBP_LIBRARIES ${LIBDIR}/webp/lib/webp.lib ${LIBDIR}/webp/lib/webpdemux.lib ${LIBDIR}/webp/lib/webpmux.lib) + set(WEBP_FOUND ON) + else() + message(STATUS "WITH_IMAGE_WEBP is ON but WEBP libraries are not found, setting WITH_IMAGE_WEBP=OFF") + set(WITH_IMAGE_WEBP OFF) + endif() endif() endif() @@ -414,27 +421,60 @@ if(WITH_CODEC_FFMPEG) endif() if(WITH_IMAGE_OPENEXR) - windows_find_package(OpenEXR REQUIRED) + # Imath and OpenEXR have a single combined build option and include and library variables + # used by the rest of the build system. + set(IMATH_ROOT_DIR ${LIBDIR}/imath) + set(IMATH_VERSION "3.14") + windows_find_package(IMATH REQUIRED) + if(NOT IMATH_FOUND) + set(IMATH ${LIBDIR}/imath) + set(IMATH_INCLUDE_DIR ${IMATH}/include) + set(IMATH_INCLUDE_DIRS ${IMATH_INCLUDE_DIR} ${IMATH}/include/Imath) + set(IMATH_LIBPATH ${IMATH}/lib) + set(IMATH_LIBRARIES + optimized ${IMATH_LIBPATH}/Imath_s.lib + debug ${IMATH_LIBPATH}/Imath_s_d.lib + ) + endif() + set(OPENEXR_ROOT_DIR ${LIBDIR}/openexr) + set(OPENEXR_VERSION "3.14") + windows_find_package(OPENEXR REQUIRED) if(NOT OpenEXR_FOUND) - set(OPENEXR_ROOT_DIR ${LIBDIR}/openexr) - set(OPENEXR_VERSION "2.1") warn_hardcoded_paths(OpenEXR) set(OPENEXR ${LIBDIR}/openexr) set(OPENEXR_INCLUDE_DIR ${OPENEXR}/include) - set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR}/include/OpenEXR) + set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${IMATH_INCLUDE_DIRS} ${OPENEXR}/include/OpenEXR) set(OPENEXR_LIBPATH ${OPENEXR}/lib) - set(OPENEXR_LIBRARIES - optimized ${OPENEXR_LIBPATH}/Iex_s.lib - optimized ${OPENEXR_LIBPATH}/Half_s.lib - optimized ${OPENEXR_LIBPATH}/IlmImf_s.lib - optimized ${OPENEXR_LIBPATH}/Imath_s.lib - optimized ${OPENEXR_LIBPATH}/IlmThread_s.lib - debug ${OPENEXR_LIBPATH}/Iex_s_d.lib - debug ${OPENEXR_LIBPATH}/Half_s_d.lib - debug ${OPENEXR_LIBPATH}/IlmImf_s_d.lib - debug ${OPENEXR_LIBPATH}/Imath_s_d.lib - debug ${OPENEXR_LIBPATH}/IlmThread_s_d.lib - ) + # Check if the 3.x library name exists + # if not assume this is a 2.x library folder + if(EXISTS "${OPENEXR_LIBPATH}/OpenEXR_s.lib") + set(OPENEXR_LIBRARIES + optimized ${OPENEXR_LIBPATH}/Iex_s.lib + optimized ${OPENEXR_LIBPATH}/IlmThread_s.lib + optimized ${OPENEXR_LIBPATH}/OpenEXR_s.lib + optimized ${OPENEXR_LIBPATH}/OpenEXRCore_s.lib + optimized ${OPENEXR_LIBPATH}/OpenEXRUtil_s.lib + debug ${OPENEXR_LIBPATH}/Iex_s_d.lib + debug ${OPENEXR_LIBPATH}/IlmThread_s_d.lib + debug ${OPENEXR_LIBPATH}/OpenEXR_s_d.lib + debug ${OPENEXR_LIBPATH}/OpenEXRCore_s_d.lib + debug ${OPENEXR_LIBPATH}/OpenEXRUtil_s_d.lib + ${IMATH_LIBRARIES} + ) + else() + set(OPENEXR_LIBRARIES + optimized ${OPENEXR_LIBPATH}/Iex_s.lib + optimized ${OPENEXR_LIBPATH}/Half_s.lib + optimized ${OPENEXR_LIBPATH}/IlmImf_s.lib + optimized ${OPENEXR_LIBPATH}/Imath_s.lib + optimized ${OPENEXR_LIBPATH}/IlmThread_s.lib + debug ${OPENEXR_LIBPATH}/Iex_s_d.lib + debug ${OPENEXR_LIBPATH}/Half_s_d.lib + debug ${OPENEXR_LIBPATH}/IlmImf_s_d.lib + debug ${OPENEXR_LIBPATH}/Imath_s_d.lib + debug ${OPENEXR_LIBPATH}/IlmThread_s_d.lib + ) + endif() endif() endif() @@ -500,8 +540,14 @@ if(WITH_BOOST) if(NOT BOOST_VERSION) message(FATAL_ERROR "Unable to determine Boost version") endif() - set(BOOST_POSTFIX "vc141-mt-x64-${BOOST_VERSION}.lib") - set(BOOST_DEBUG_POSTFIX "vc141-mt-gd-x64-${BOOST_VERSION}.lib") + set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}.lib") + set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}.lib") + if(NOT EXISTS ${BOOST_LIBPATH}/libboost_date_time-${BOOST_POSTFIX}) + # If the new library names do not exist fall back to the old ones + # to ease the transition period between the libs. + set(BOOST_POSTFIX "vc141-mt-x64-${BOOST_VERSION}.lib") + set(BOOST_DEBUG_POSTFIX "vc141-mt-gd-x64-${BOOST_VERSION}.lib") + endif() set(BOOST_LIBRARIES optimized ${BOOST_LIBPATH}/libboost_date_time-${BOOST_POSTFIX} optimized ${BOOST_LIBPATH}/libboost_filesystem-${BOOST_POSTFIX} @@ -545,7 +591,6 @@ if(WITH_OPENIMAGEIO) set(OIIO_DEBUG debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_d.lib debug ${OPENIMAGEIO_LIBPATH}/OpenImageIO_Util_d.lib) set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG}) endif() - set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0") set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe") add_definitions(-DOIIO_STATIC_DEFINE) @@ -575,6 +620,7 @@ if(WITH_LLVM) message(WARNING "LLVM debug libs not present on this system. Using release libs for debug builds.") set(LLVM_LIBRARY ${LLVM_LIBRARY_OPTIMIZED}) endif() + endif() if(WITH_OPENCOLORIO) @@ -594,7 +640,6 @@ if(WITH_OPENCOLORIO) debug ${OPENCOLORIO_LIBPATH}/pystring_d.lib ) endif() - set(OPENCOLORIO_DEFINITIONS "-DOpenColorIO_SKIP_IMPORTS") endif() @@ -604,17 +649,24 @@ if(WITH_OPENVDB) set(OPENVDB ${LIBDIR}/openVDB) set(OPENVDB_LIBPATH ${OPENVDB}/lib) set(OPENVDB_INCLUDE_DIRS ${OPENVDB}/include) - set(OPENVDB_LIBRARIES optimized ${OPENVDB_LIBPATH}/openvdb.lib debug ${OPENVDB_LIBPATH}/openvdb_d.lib) + set(OPENVDB_LIBRARIES optimized ${OPENVDB_LIBPATH}/openvdb.lib debug ${OPENVDB_LIBPATH}/openvdb_d.lib ) endif() - set(OPENVDB_DEFINITIONS -DNOMINMAX -D_USE_MATH_DEFINES) endif() if(WITH_NANOVDB) - set(NANOVDB ${LIBDIR}/nanoVDB) + set(NANOVDB ${LIBDIR}/openvdb) set(NANOVDB_INCLUDE_DIR ${NANOVDB}/include) + if(NOT EXISTS "${NANOVDB_INCLUDE_DIR}/nanovdb") + # When not found, could be an older lib folder with where nanovdb + # had its own lib folder, to ease the transition period, fall back + # to that copy if the copy in openvdb is not found. + set(NANOVDB ${LIBDIR}/nanoVDB) + set(NANOVDB_INCLUDE_DIR ${NANOVDB}/include) + endif() endif() + if(WITH_OPENIMAGEDENOISE) set(OPENIMAGEDENOISE ${LIBDIR}/OpenImageDenoise) set(OPENIMAGEDENOISE_LIBPATH ${LIBDIR}/OpenImageDenoise/lib) @@ -640,7 +692,12 @@ endif() if(WITH_IMAGE_OPENJPEG) set(OPENJPEG ${LIBDIR}/openjpeg) - set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.3) + set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.4) + if(NOT EXISTS "${OPENJPEG_INCLUDE_DIRS}") + # when not found, could be an older lib folder with openjpeg 2.3 + # to ease the transition period, fall back if 2.4 is not found. + set(OPENJPEG_INCLUDE_DIRS ${OPENJPEG}/include/openjpeg-2.3) + endif() set(OPENJPEG_LIBRARIES ${OPENJPEG}/lib/openjp2.lib) endif() @@ -783,9 +840,16 @@ if(WITH_USD) windows_find_package(USD) if(NOT USD_FOUND) set(USD_INCLUDE_DIRS ${LIBDIR}/usd/include) - set(USD_RELEASE_LIB ${LIBDIR}/usd/lib/libusd_m.lib) - set(USD_DEBUG_LIB ${LIBDIR}/usd/lib/libusd_m_d.lib) + set(USD_RELEASE_LIB ${LIBDIR}/usd/lib/usd_usd_m.lib) + set(USD_DEBUG_LIB ${LIBDIR}/usd/lib/usd_usd_m_d.lib) set(USD_LIBRARY_DIR ${LIBDIR}/usd/lib) + # Older USD had different filenames, if the new ones are + # not found see if the older ones exist, to ease the + # transition period while landing libs. + if(NOT EXISTS "${USD_RELEASE_LIB}") + set(USD_RELEASE_LIB ${LIBDIR}/usd/lib/libusd_m.lib) + set(USD_DEBUG_LIB ${LIBDIR}/usd/lib/libusd_m_d.lib) + endif() set(USD_LIBRARIES debug ${USD_DEBUG_LIB} optimized ${USD_RELEASE_LIB} diff --git a/build_files/cmake/project_source_info.py b/build_files/cmake/project_source_info.py index 1479d62e6c5..7a00f756e03 100644 --- a/build_files/cmake/project_source_info.py +++ b/build_files/cmake/project_source_info.py @@ -114,12 +114,11 @@ def makefile_log() -> List[str]: print("Can't execute process") sys.exit(1) - while process.poll(): time.sleep(1) # We know this is always true based on the input arguments to `Popen`. - stdout: IO[bytes] = process.stdout # type: ignore + stdout: IO[bytes] = process.stdout # type: ignore out = stdout.read() stdout.close() @@ -210,7 +209,7 @@ def build_defines_as_source() -> str: ) # We know this is always true based on the input arguments to `Popen`. - stdout: IO[bytes] = process.stdout # type: ignore + stdout: IO[bytes] = process.stdout # type: ignore return cast(str, stdout.read().strip().decode('ascii')) @@ -228,7 +227,7 @@ def build_defines_as_args() -> List[str]: def queue_processes( process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]], *, - job_total: int =-1, + job_total: int = -1, sleep: float = 0.1, ) -> None: """ Takes a list of function arg pairs, each function must return a process diff --git a/build_files/utils/make_source_archive.py b/build_files/utils/make_source_archive.py index e06be9d5ba7..befd6d84534 100755 --- a/build_files/utils/make_source_archive.py +++ b/build_files/utils/make_source_archive.py @@ -143,8 +143,8 @@ def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]: return Path(relpath) - -### Manifest creation +# ----------------------------------------------------------------------------- +# Manifest creation def create_manifest( @@ -195,7 +195,8 @@ def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None: print(path, file=outfile) -### Higher-level functions +# ----------------------------------------------------------------------------- +# Higher-level functions def create_tarball( @@ -249,7 +250,8 @@ def cleanup(manifest: Path) -> None: print("OK") -## Low-level commands +# ----------------------------------------------------------------------------- +# Low-level commands def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]: @@ -265,7 +267,7 @@ def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]: yield path -def git_command(*cli_args: Union[bytes, str, Path] ) -> Iterable[str]: +def git_command(*cli_args: Union[bytes, str, Path]) -> Iterable[str]: """Generator, yields lines of output from a Git command.""" command = ("git", *cli_args) diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index 3701913bd5d..bf140812ebb 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -129,6 +129,7 @@ def svn_update(args, release_version): call(svn_non_interactive + ["switch", svn_url + dirname, dirpath], exit_on_error=False) call(svn_non_interactive + ["update", dirpath]) + # Test if git repo can be updated. def git_update_skip(args, check_remote_exists=True): if make_utils.command_missing(args.git_command): diff --git a/build_files/utils/make_utils.py b/build_files/utils/make_utils.py index b1aab93d698..e4c676474b5 100755 --- a/build_files/utils/make_utils.py +++ b/build_files/utils/make_utils.py @@ -47,8 +47,10 @@ def check_output(cmd, exit_on_error=True): def git_branch_exists(git_command, branch): - return call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or \ - call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0 + return ( + call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or + call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0 + ) def git_branch(git_command): diff --git a/doc/blender_file_format/BlendFileDnaExporter_25.py b/doc/blender_file_format/BlendFileDnaExporter_25.py index f85d496b9b5..91a313b789f 100755 --- a/doc/blender_file_format/BlendFileDnaExporter_25.py +++ b/doc/blender_file_format/BlendFileDnaExporter_25.py @@ -378,7 +378,8 @@ def usage(): def main(): - import os, os.path + import os + import os.path try: bpy = __import__('bpy') diff --git a/doc/manpage/blender.1.py b/doc/manpage/blender.1.py index 640b00b0c00..6cf2f54b26f 100755 --- a/doc/manpage/blender.1.py +++ b/doc/manpage/blender.1.py @@ -103,10 +103,10 @@ blender \- a full-featured 3D application''') .PP .B blender is a full-featured 3D application. It supports the entirety of the 3D pipeline - ''' -'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing. + '''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing. Use Blender to create 3D images and animations, films and commercials, content for games, ''' -r'''architectural and industrial visualizations, and scientific visualizations. + r'''architectural and industrial visualizations, and scientific visualizations. https://www.blender.org''') diff --git a/doc/python_api/examples/bpy.app.timers.5.py b/doc/python_api/examples/bpy.app.timers.5.py index ddda0576f05..9770c84d4be 100644 --- a/doc/python_api/examples/bpy.app.timers.5.py +++ b/doc/python_api/examples/bpy.app.timers.5.py @@ -11,6 +11,7 @@ import queue execution_queue = queue.Queue() + # This function can safely be called in another thread. # The function will be executed when the timer runs the next time. def run_in_main_thread(function): diff --git a/doc/python_api/examples/bpy.ops.1.py b/doc/python_api/examples/bpy.ops.1.py index efc9f00b0ae..9b690823a18 100644 --- a/doc/python_api/examples/bpy.ops.1.py +++ b/doc/python_api/examples/bpy.ops.1.py @@ -9,7 +9,7 @@ operator in the different part of the user interface. The context overrides are passed as a dictionary, with keys matching the context member names in bpy.context. For example to override ``bpy.context.active_object``, -you would pass ``{'active_object': object}``. +you would pass ``{'active_object': object}`` to :class:`bpy.types.Context.temp_override`. .. note:: @@ -17,8 +17,10 @@ you would pass ``{'active_object': object}``. (otherwise, you'll have to find and gather all needed data yourself). """ -# remove all objects in scene rather than the selected ones +# Remove all objects in scene rather than the selected ones. import bpy -override = bpy.context.copy() -override['selected_objects'] = list(bpy.context.scene.objects) -bpy.ops.object.delete(override) +from bpy import context +override = context.copy() +override["selected_objects"] = list(context.scene.objects) +with context.temp_override(**override): + bpy.ops.object.delete() diff --git a/doc/python_api/examples/bpy.ops.3.py b/doc/python_api/examples/bpy.ops.3.py index 7dec69cf566..e068ab0c0cf 100644 --- a/doc/python_api/examples/bpy.ops.3.py +++ b/doc/python_api/examples/bpy.ops.3.py @@ -1,17 +1,16 @@ """ It is also possible to run an operator in a particular part of the user -interface. For this we need to pass the window, screen, area and sometimes -a region. +interface. For this we need to pass the window, area and sometimes a region. """ -# maximize 3d view in all windows +# Maximize 3d view in all windows. import bpy +from bpy import context -for window in bpy.context.window_manager.windows: +for window in context.window_manager.windows: screen = window.screen - for area in screen.areas: if area.type == 'VIEW_3D': - override = {'window': window, 'screen': screen, 'area': area} - bpy.ops.screen.screen_full_area(override) + with context.temp_override(window=window, area=area): + bpy.ops.screen.screen_full_area() break diff --git a/doc/python_api/examples/bpy.ops.py b/doc/python_api/examples/bpy.ops.py index 76c494ad4f5..e8d545fc855 100644 --- a/doc/python_api/examples/bpy.ops.py +++ b/doc/python_api/examples/bpy.ops.py @@ -33,6 +33,11 @@ There are 3 optional positional arguments (documented in detail below). bpy.ops.test.operator(override_context, execution_context, undo) - override_context - ``dict`` type. + + .. deprecated:: 3.2 + + :class:`bpy.types.Context.temp_override` should be used instead of this argument. + - execution_context - ``str`` (enum). - undo - ``bool`` type. diff --git a/doc/python_api/examples/bpy.types.Bone.convert_local_to_pose.py b/doc/python_api/examples/bpy.types.Bone.convert_local_to_pose.py index 4a88096cf6f..36b161640c2 100644 --- a/doc/python_api/examples/bpy.types.Bone.convert_local_to_pose.py +++ b/doc/python_api/examples/bpy.types.Bone.convert_local_to_pose.py @@ -4,6 +4,7 @@ the middle of updating the armature without having to update dependencies after each change, by manually carrying updated matrices in a recursive walk. """ + def set_pose_matrices(obj, matrix_map): "Assign pose space matrices of all bones at once, ignoring constraints." @@ -11,7 +12,7 @@ def set_pose_matrices(obj, matrix_map): if pbone.name in matrix_map: matrix = matrix_map[pbone.name] - ## Instead of: + # # Instead of: # pbone.matrix = matrix # bpy.context.view_layer.update() diff --git a/doc/python_api/examples/bpy.types.Context.temp_override.1.py b/doc/python_api/examples/bpy.types.Context.temp_override.1.py new file mode 100644 index 00000000000..68f0eef93c3 --- /dev/null +++ b/doc/python_api/examples/bpy.types.Context.temp_override.1.py @@ -0,0 +1,19 @@ +""" +Overriding the context can be used to temporarily activate another ``window`` / ``area`` & ``region``, +as well as other members such as the ``active_object`` or ``bone``. + +Notes: + +- When overriding window, area and regions: the arguments must be consistent, + so any region argument that's passed in must be contained by the current area or the area passed in. + The same goes for the area needing to be contained in the current window. + +- Temporary context overrides may be nested, when this is done, members will be added to the existing overrides. + +- Context members are restored outside the scope of the context. + The only exception to this is when the data is no longer available. + + In the event windowing data was removed (for example), the state of the context is left as-is. + While this isn't likely to happen, explicit window operation such as closing windows or loading a new file + remove the windowing data that was set before the temporary context was created. +""" diff --git a/doc/python_api/examples/bpy.types.Context.temp_override.2.py b/doc/python_api/examples/bpy.types.Context.temp_override.2.py new file mode 100644 index 00000000000..ce3e1594baa --- /dev/null +++ b/doc/python_api/examples/bpy.types.Context.temp_override.2.py @@ -0,0 +1,15 @@ +""" +Overriding the context can be useful to set the context after loading files +(which would otherwise by None). For example: +""" + +import bpy +from bpy import context + +# Reload the current file and select all. +bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath) +window = context.window_manager.windows[0] +with context.temp_override(window=window): + bpy.ops.mesh.primitive_uv_sphere_add() + # The context override is needed so it's possible to set edit-mode. + bpy.ops.object.mode_set(mode='EDIT') diff --git a/doc/python_api/examples/bpy.types.Context.temp_override.3.py b/doc/python_api/examples/bpy.types.Context.temp_override.3.py new file mode 100644 index 00000000000..e670bb7bafa --- /dev/null +++ b/doc/python_api/examples/bpy.types.Context.temp_override.3.py @@ -0,0 +1,16 @@ +""" +This example shows how it's possible to add an object to the scene in another window. +""" +import bpy +from bpy import context + +win_active = context.window +win_other = None +for win_iter in context.window_manager.windows: + if win_iter != win_active: + win_other = win_iter + break + +# Add cube in the other window. +with context.temp_override(window=win_other): + bpy.ops.mesh.primitive_cube_add() diff --git a/doc/python_api/examples/bpy.types.Operator.1.py b/doc/python_api/examples/bpy.types.Operator.1.py index 84397574856..a28db7e84bb 100644 --- a/doc/python_api/examples/bpy.types.Operator.1.py +++ b/doc/python_api/examples/bpy.types.Operator.1.py @@ -42,10 +42,12 @@ class SimpleMouseOperator(bpy.types.Operator): self.y = event.mouse_y return self.execute(context) -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(SimpleMouseOperator.bl_idname, text="Simple Mouse Operator") + # Register and add to the view menu (required to also use F3 search "Simple Mouse Operator" for quick access) bpy.utils.register_class(SimpleMouseOperator) bpy.types.VIEW3D_MT_view.append(menu_func) diff --git a/doc/python_api/examples/bpy.types.Operator.2.py b/doc/python_api/examples/bpy.types.Operator.2.py index 7ab0143b925..2a14d6b00f5 100644 --- a/doc/python_api/examples/bpy.types.Operator.2.py +++ b/doc/python_api/examples/bpy.types.Operator.2.py @@ -37,7 +37,7 @@ class ExportSomeData(bpy.types.Operator): return {'RUNNING_MODAL'} -# Only needed if you want to add into a dynamic menu +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator_context = 'INVOKE_DEFAULT' self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator") diff --git a/doc/python_api/examples/bpy.types.Operator.3.py b/doc/python_api/examples/bpy.types.Operator.3.py index 9a12a7e3615..fb40616d15d 100644 --- a/doc/python_api/examples/bpy.types.Operator.3.py +++ b/doc/python_api/examples/bpy.types.Operator.3.py @@ -27,7 +27,8 @@ class DialogOperator(bpy.types.Operator): wm = context.window_manager return wm.invoke_props_dialog(self) -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(DialogOperator.bl_idname, text="Dialog Operator") diff --git a/doc/python_api/examples/bpy.types.Operator.4.py b/doc/python_api/examples/bpy.types.Operator.4.py index 00c9cd250b1..d33f6a6113d 100644 --- a/doc/python_api/examples/bpy.types.Operator.4.py +++ b/doc/python_api/examples/bpy.types.Operator.4.py @@ -41,11 +41,13 @@ class CustomDrawOperator(bpy.types.Operator): col.prop(self, "my_string") -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(CustomDrawOperator.bl_idname, text="Custom Draw Operator") -# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access) + +# Register and add to the object menu (required to also use F3 search "Custom Draw Operator" for quick access). bpy.utils.register_class(CustomDrawOperator) bpy.types.VIEW3D_MT_object.append(menu_func) diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index a0b4a6d6841..90c899f222e 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -55,11 +55,13 @@ class ModalOperator(bpy.types.Operator): context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'} -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(ModalOperator.bl_idname, text="Modal Operator") -# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access) + +# Register and add to the object menu (required to also use F3 search "Modal Operator" for quick access). bpy.utils.register_class(ModalOperator) bpy.types.VIEW3D_MT_object.append(menu_func) diff --git a/doc/python_api/examples/bpy.types.Operator.6.py b/doc/python_api/examples/bpy.types.Operator.6.py index 20ee4c21446..cf556c63ab8 100644 --- a/doc/python_api/examples/bpy.types.Operator.6.py +++ b/doc/python_api/examples/bpy.types.Operator.6.py @@ -31,10 +31,12 @@ class SearchEnumOperator(bpy.types.Operator): context.window_manager.invoke_search_popup(self) return {'RUNNING_MODAL'} -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(SearchEnumOperator.bl_idname, text="Search Enum Operator") + # Register and add to the object menu (required to also use F3 search "Search Enum Operator" for quick access) bpy.utils.register_class(SearchEnumOperator) bpy.types.VIEW3D_MT_object.append(menu_func) diff --git a/doc/python_api/examples/bpy.types.Operator.py b/doc/python_api/examples/bpy.types.Operator.py index 5299b198774..41b96ac402f 100644 --- a/doc/python_api/examples/bpy.types.Operator.py +++ b/doc/python_api/examples/bpy.types.Operator.py @@ -22,13 +22,15 @@ class HelloWorldOperator(bpy.types.Operator): print("Hello World") return {'FINISHED'} -# Only needed if you want to add into a dynamic menu + +# Only needed if you want to add into a dynamic menu. def menu_func(self, context): self.layout.operator(HelloWorldOperator.bl_idname, text="Hello World Operator") -# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access) + +# Register and add to the view menu (required to also use F3 search "Hello World Operator" for quick access). bpy.utils.register_class(HelloWorldOperator) bpy.types.VIEW3D_MT_view.append(menu_func) -# test call to the newly defined operator +# Test call to the newly defined operator. bpy.ops.wm.hello_world() diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 477d2196666..eba12b75b63 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -409,7 +409,9 @@ BLENDER_VERSION_DOTS = "%d.%d" % (bpy.app.version[0], bpy.app.version[1]) if BLENDER_REVISION != "Unknown": # SHA1 Git hash BLENDER_VERSION_HASH = BLENDER_REVISION - BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % (BLENDER_VERSION_HASH, BLENDER_VERSION_HASH) + BLENDER_VERSION_HASH_HTML_LINK = "<a href=https://developer.blender.org/rB%s>%s</a>" % ( + BLENDER_VERSION_HASH, BLENDER_VERSION_HASH, + ) BLENDER_VERSION_DATE = time.strftime("%d/%m/%Y", time.localtime(BLENDER_REVISION_TIMESTAMP)) else: # Fallback: Should not be used @@ -1241,7 +1243,9 @@ def pycontext2sphinx(basepath): try: member_type, is_seq = context_type_map[member] except KeyError: - raise SystemExit("Error: context key %r not found in context_type_map; update %s" % (member, __file__)) from None + raise SystemExit( + "Error: context key %r not found in context_type_map; update %s" % + (member, __file__)) from None fw(" :type: %s :class:`bpy.types.%s`\n\n" % ("sequence of " if is_seq else "", member_type)) i += 1 diff --git a/extern/audaspace/include/util/Buffer.h b/extern/audaspace/include/util/Buffer.h index 9934e53625e..2b6a16cc154 100644 --- a/extern/audaspace/include/util/Buffer.h +++ b/extern/audaspace/include/util/Buffer.h @@ -34,7 +34,7 @@ class AUD_API Buffer { private: /// The size of the buffer in bytes. - int m_size; + long long m_size; /// The pointer to the buffer memory. data_t* m_buffer; @@ -48,7 +48,7 @@ public: * Creates a new buffer. * \param size The size of the buffer in bytes. */ - Buffer(int size = 0); + Buffer(long long size = 0); /** * Destroys the buffer. @@ -63,7 +63,7 @@ public: /** * Returns the size of the buffer in bytes. */ - int getSize() const; + long long getSize() const; /** * Resizes the buffer. @@ -71,7 +71,7 @@ public: * \param keep Whether to keep the old data. If the new buffer is smaller, * the data at the end will be lost. */ - void resize(int size, bool keep = false); + void resize(long long size, bool keep = false); /** * Makes sure the buffer has a minimum size. @@ -81,7 +81,7 @@ public: * \param keep Whether to keep the old data. If the new buffer is smaller, * the data at the end will be lost. */ - void assureSize(int size, bool keep = false); + void assureSize(long long size, bool keep = false); }; AUD_NAMESPACE_END diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp index 69bb45119a6..ad33c267c74 100644 --- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp @@ -361,7 +361,7 @@ int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size) { FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque); - int size = std::min(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos); + long long size = std::min(static_cast<long long>(buf_size), reader->m_membuffer->getSize() - reader->m_membufferpos); if(size < 0) return -1; diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h index 70f13911eca..ca0e8b024aa 100644 --- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h @@ -114,7 +114,7 @@ private: /** * Reading position of the buffer. */ - int m_membufferpos; + long long m_membufferpos; /** * Whether the audio data has to be interleaved after reading. diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp index 32eb2330594..ae6558ccfa5 100644 --- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp +++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp @@ -23,7 +23,9 @@ extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avio.h> +#if LIBAVCODEC_VERSION_MAJOR >= 59 #include <libavutil/channel_layout.h> +#endif } AUD_NAMESPACE_BEGIN @@ -398,7 +400,7 @@ FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container fo m_specs.rate = m_codecCtx->sample_rate; #ifdef FFMPEG_OLD_CODE - m_codecCtx->codec_id = outputFmt->audio_codec; + m_codecCtx->codec_id = audio_codec; #endif m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO; diff --git a/extern/audaspace/src/util/Buffer.cpp b/extern/audaspace/src/util/Buffer.cpp index d212278cacc..9c0314b4bea 100644 --- a/extern/audaspace/src/util/Buffer.cpp +++ b/extern/audaspace/src/util/Buffer.cpp @@ -25,7 +25,7 @@ AUD_NAMESPACE_BEGIN -Buffer::Buffer(int size) +Buffer::Buffer(long long size) { m_size = size; m_buffer = (data_t*) std::malloc(size + ALIGNMENT); @@ -41,12 +41,12 @@ sample_t* Buffer::getBuffer() const return (sample_t*) ALIGN(m_buffer); } -int Buffer::getSize() const +long long Buffer::getSize() const { return m_size; } -void Buffer::resize(int size, bool keep) +void Buffer::resize(long long size, bool keep) { if(keep) { @@ -63,7 +63,7 @@ void Buffer::resize(int size, bool keep) m_size = size; } -void Buffer::assureSize(int size, bool keep) +void Buffer::assureSize(long long size, bool keep) { if(m_size < size) resize(size, keep); diff --git a/extern/audaspace/src/util/StreamBuffer.cpp b/extern/audaspace/src/util/StreamBuffer.cpp index b87b363377d..68d199d23a2 100644 --- a/extern/audaspace/src/util/StreamBuffer.cpp +++ b/extern/audaspace/src/util/StreamBuffer.cpp @@ -18,8 +18,12 @@ #include "util/BufferReader.h" #include "util/Buffer.h" +#include <algorithm> + // 5 sec * 48000 samples/sec * 4 bytes/sample * 6 channels #define BUFFER_RESIZE_BYTES 5760000 +// 90 min * 60 sec/min * 48000 samples/sec * 4 bytes/sample * 2 channels +#define MAXIMUM_INITIAL_BUFFER_SIZE_BYTES 2073600000 AUD_NAMESPACE_BEGIN @@ -32,14 +36,15 @@ StreamBuffer::StreamBuffer(std::shared_ptr<ISound> sound) : int sample_size = AUD_SAMPLE_SIZE(m_specs); int length; - int index = 0; + long long index = 0; bool eos = false; // get an approximated size if possible - int size = reader->getLength(); + long long size = std::min(reader->getLength(), MAXIMUM_INITIAL_BUFFER_SIZE_BYTES / sample_size); + long long size_increase = BUFFER_RESIZE_BYTES / sample_size; if(size <= 0) - size = BUFFER_RESIZE_BYTES / sample_size; + size = size_increase; else size += m_specs.rate; @@ -47,13 +52,16 @@ StreamBuffer::StreamBuffer(std::shared_ptr<ISound> sound) : while(!eos) { // increase - m_buffer->resize(size*sample_size, true); + m_buffer->resize(static_cast<long long>(size) * sample_size, true); // read more length = size-index; reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels); if(index == m_buffer->getSize() / sample_size) - size += BUFFER_RESIZE_BYTES / sample_size; + { + size += size_increase; + size_increase <<= 1; + } index += length; } diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt index c9e2b54ef18..908c5d2ffd9 100644 --- a/extern/mantaflow/CMakeLists.txt +++ b/extern/mantaflow/CMakeLists.txt @@ -259,3 +259,10 @@ set(LIB ) blender_add_lib(extern_mantaflow "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") + +# The VDB libs above are only added to as INTERFACE libs by blender_add_lib, +# meaning extern_mantaflow itself actually does not have a dependency on the +# openvdb libraries, and CMAKE is free to link the vdb libs before +# extern_mantaflow causing linker errors on linux. By explicitly declaring +# a dependency here, cmake will do the right thing. +target_link_libraries(extern_mantaflow PRIVATE ${OPENVDB_LIBRARIES}) diff --git a/intern/cycles/app/io_export_cycles_xml.py b/intern/cycles/app/io_export_cycles_xml.py index 0009995653e..ceb30f8fb56 100644 --- a/intern/cycles/app/io_export_cycles_xml.py +++ b/intern/cycles/app/io_export_cycles_xml.py @@ -10,6 +10,7 @@ import bpy from bpy_extras.io_utils import ExportHelper from bpy.props import PointerProperty, StringProperty + def strip(root): root.text = None root.tail = None @@ -17,6 +18,7 @@ def strip(root): for elem in root: strip(elem) + def write(node, fname): strip(node) @@ -26,25 +28,31 @@ def write(node, fname): f = open(fname, "w") f.write(s) + class CyclesXMLSettings(bpy.types.PropertyGroup): @classmethod def register(cls): bpy.types.Scene.cycles_xml = PointerProperty( - type=cls, - name="Cycles XML export Settings", - description="Cycles XML export settings") + type=cls, + name="Cycles XML export Settings", + description="Cycles XML export settings", + ) cls.filepath = StringProperty( - name='Filepath', - description='Filepath for the .xml file', - maxlen=256, - default='', - subtype='FILE_PATH') + name='Filepath', + description='Filepath for the .xml file', + maxlen=256, + default='', + subtype='FILE_PATH', + ) @classmethod def unregister(cls): del bpy.types.Scene.cycles_xml -# User Interface Drawing Code + +# User Interface Drawing Code. + + class RenderButtonsPanel(): bl_space_type = 'PROPERTIES' bl_region_type = 'WINDOW' @@ -114,22 +122,31 @@ class ExportCyclesXML(bpy.types.Operator, ExportHelper): uvs += str(uvf.uv1[0]) + " " + str(uvf.uv1[1]) + " " uvs += str(uvf.uv2[0]) + " " + str(uvf.uv2[1]) + " " uvs += str(uvf.uv3[0]) + " " + str(uvf.uv3[1]) + " " - if vcount==4: + if vcount == 4: uvs += " " + str(uvf.uv4[0]) + " " + str(uvf.uv4[1]) + " " - - node = etree.Element('mesh', attrib={'nverts': nverts.strip(), 'verts': verts.strip(), 'P': P, 'UV' : uvs.strip()}) + node = etree.Element( + 'mesh', + attrib={ + 'nverts': nverts.strip(), + 'verts': verts.strip(), + 'P': P, + 'UV': uvs.strip(), + }) # write to file write(node, filepath) return {'FINISHED'} + def register(): bpy.utils.register_module(__name__) + def unregister(): bpy.utils.unregister_module(__name__) + if __name__ == "__main__": register() diff --git a/intern/cycles/blender/addon/camera.py b/intern/cycles/blender/addon/camera.py index 9841e031201..0e78112699e 100644 --- a/intern/cycles/blender/addon/camera.py +++ b/intern/cycles/blender/addon/camera.py @@ -4,11 +4,14 @@ # <pep8 compliant> # Fit to match default projective camera with focal_length 50 and sensor_width 36. -default_fisheye_polynomial = [-1.1735143712967577e-05, - -0.019988736953434998, - -3.3525322965709175e-06, - 3.099275275886036e-06, - -2.6064646454854524e-08] +default_fisheye_polynomial = [ + -1.1735143712967577e-05, + -0.019988736953434998, + -3.3525322965709175e-06, + 3.099275275886036e-06, + -2.6064646454854524e-08, +] + # Utilities to generate lens polynomials to match built-in camera types, only here # for reference at the moment, not used by the code. @@ -51,7 +54,9 @@ def fisheye_lens_polynomial_from_equidistant(fov=180, sensor_width=36, sensor_he return [0, -np.radians(fov) / sensor_width, 0, 0, 0] -def fisheye_lens_polynomial_from_distorted_projective_polynomial(k1, k2, k3, focal_length=50, sensor_width=36, sensor_height=None): +def fisheye_lens_polynomial_from_distorted_projective_polynomial( + k1, k2, k3, focal_length=50, sensor_width=36, sensor_height=None, +): import numpy as np rr = create_grid(sensor_height, sensor_width) r2 = (rr / focal_length) ** 2 @@ -61,7 +66,10 @@ def fisheye_lens_polynomial_from_distorted_projective_polynomial(k1, k2, k3, foc polynomial = np.polyfit(rr.flat, (-np.arctan(rr / focal_length * r_coeff)).flat, 4) return list(reversed(polynomial)) -def fisheye_lens_polynomial_from_distorted_projective_divisions(k1, k2, focal_length=50, sensor_width=36, sensor_height=None): + +def fisheye_lens_polynomial_from_distorted_projective_divisions( + k1, k2, focal_length=50, sensor_width=36, sensor_height=None, +): import numpy as np rr = create_grid(sensor_height, sensor_width) r2 = (rr / focal_length) ** 2 diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py index 1b03581ae03..724e1b8f727 100644 --- a/intern/cycles/blender/addon/engine.py +++ b/intern/cycles/blender/addon/engine.py @@ -98,6 +98,7 @@ def render_frame_finish(engine): import _cycles _cycles.render_frame_finish(engine.session) + def draw(engine, depsgraph, space_image): if not engine.session: return @@ -168,6 +169,9 @@ def list_render_passes(scene, srl): # Combined pass. yield ("Combined", "RGBA", 'COLOR') + # Keep alignment for readability. + # autopep8: off + # Data passes. if srl.use_pass_z: yield ("Depth", "Z", 'VALUE') if srl.use_pass_mist: yield ("Mist", "Z", 'VALUE') @@ -195,9 +199,11 @@ def list_render_passes(scene, srl): if srl.use_pass_shadow: yield ("Shadow", "RGB", 'COLOR') if srl.use_pass_ambient_occlusion: yield ("AO", "RGB", 'COLOR') if crl.use_pass_shadow_catcher: yield ("Shadow Catcher", "RGB", 'COLOR') + # autopep8: on # Debug passes. - if crl.pass_debug_sample_count: yield ("Debug Sample Count", "X", 'VALUE') + if crl.pass_debug_sample_count: + yield ("Debug Sample Count", "X", 'VALUE') # Cryptomatte passes. crypto_depth = (srl.pass_cryptomatte_depth + 1) // 2 @@ -217,9 +223,9 @@ def list_render_passes(scene, srl): if crl.use_pass_shadow_catcher: yield ("Noisy Shadow Catcher", "RGBA", 'COLOR') if crl.denoising_store_passes: - yield ("Denoising Normal", "XYZ", 'VECTOR') - yield ("Denoising Albedo", "RGB", 'COLOR') - yield ("Denoising Depth", "Z", 'VALUE') + yield ("Denoising Normal", "XYZ", 'VECTOR') + yield ("Denoising Albedo", "RGB", 'COLOR') + yield ("Denoising Depth", "Z", 'VALUE') # Custom AOV passes. for aov in srl.aovs: diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py index 973088ac3e7..e5d7f00a381 100644 --- a/intern/cycles/blender/addon/operators.py +++ b/intern/cycles/blender/addon/operators.py @@ -34,8 +34,8 @@ class CYCLES_OT_use_shading_nodes(Operator): class CYCLES_OT_denoise_animation(Operator): "Denoise rendered animation sequence using current scene and view " \ - "layer settings. Requires denoising data passes and output to " \ - "OpenEXR multilayer files" + "layer settings. Requires denoising data passes and output to " \ + "OpenEXR multilayer files" bl_idname = "cycles.denoise_animation" bl_label = "Denoise Animation" @@ -117,7 +117,7 @@ class CYCLES_OT_denoise_animation(Operator): class CYCLES_OT_merge_images(Operator): "Combine OpenEXR multilayer images rendered with different sample " \ - "ranges into one image with reduced noise" + "ranges into one image with reduced noise" bl_idname = "cycles.merge_images" bl_label = "Merge Images" diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py index a84c9f07c55..5eaa592a9de 100644 --- a/intern/cycles/blender/addon/presets.py +++ b/intern/cycles/blender/addon/presets.py @@ -85,6 +85,7 @@ class AddPresetViewportSampling(AddPresetBase, Operator): preset_subdir = "cycles/viewport_sampling" + classes = ( AddPresetIntegrator, AddPresetSampling, diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index ed054b041d8..a0ceb9c3c29 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -83,7 +83,8 @@ enum_sampling_pattern = ( enum_volume_sampling = ( ('DISTANCE', "Distance", "Use distance sampling, best for dense volumes with lights far away"), ('EQUIANGULAR', "Equiangular", "Use equiangular sampling, best for volumes with low density with light inside or near the volume"), - ('MULTIPLE_IMPORTANCE', "Multiple Importance", "Combine distance and equi-angular sampling for volumes where neither method is ideal"), + ('MULTIPLE_IMPORTANCE', "Multiple Importance", + "Combine distance and equi-angular sampling for volumes where neither method is ideal"), ) enum_volume_interpolation = ( @@ -181,7 +182,12 @@ def enum_preview_denoiser(self, context): oidn_items = enum_openimagedenoise_denoiser(self, context) if len(optix_items) or len(oidn_items): - items = [('AUTO', "Automatic", "Use the fastest available denoiser for viewport rendering (OptiX if available, OpenImageDenoise otherwise)", 0)] + items = [ + ('AUTO', + "Automatic", + ("Use the fastest available denoiser for viewport rendering " + "(OptiX if available, OpenImageDenoise otherwise)"), + 0)] else: items = [('AUTO', "None", "Blender was compiled without a viewport denoiser", 0)] @@ -210,11 +216,14 @@ enum_denoising_prefilter = ( ) enum_direct_light_sampling_type = ( - ('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling", "Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0), + ('MULTIPLE_IMPORTANCE_SAMPLING', "Multiple Importance Sampling", + "Multiple importance sampling is used to combine direct light contributions from next-event estimation and forward path tracing", 0), ('FORWARD_PATH_TRACING', "Forward Path Tracing", "Direct light contributions are only sampled using forward path tracing", 1), - ('NEXT_EVENT_ESTIMATION', "Next-Event Estimation", "Direct light contributions are only sampled using next-event estimation", 2), + ('NEXT_EVENT_ESTIMATION', "Next-Event Estimation", + "Direct light contributions are only sampled using next-event estimation", 2), ) + def update_render_passes(self, context): view_layer = context.view_layer view_layer.update_render_passes() @@ -262,7 +271,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): description="Denoise the image with the selected denoiser. " "For denoising the image after rendering", items=enum_denoiser, - default=4, # Use integer to avoid error in builds without OpenImageDenoise. + default=4, # Use integer to avoid error in builds without OpenImageDenoise. update=update_render_passes, ) denoising_prefilter: EnumProperty( @@ -1507,9 +1516,12 @@ class CyclesPreferences(bpy.types.AddonPreferences): col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1') elif device_type == 'HIP': import sys - col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1') if sys.platform[:3] == "win": + col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1') col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1') + elif sys.platform.startswith("linux"): + col.label(text="Requires discrete AMD GPU with RDNA architecture", icon='BLANK1') + col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1') elif device_type == 'METAL': col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1') col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1') @@ -1547,7 +1559,6 @@ class CyclesPreferences(bpy.types.AddonPreferences): row.use_property_split = True row.prop(self, "use_metalrt") - def draw(self, context): self.draw_impl(self.layout, context) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 739a555f037..131b849a094 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -14,6 +14,7 @@ from bl_ui.properties_grease_pencil_common import GreasePencilSimplifyPanel from bl_ui.properties_render import draw_curves_settings from bl_ui.properties_view_layer import ViewLayerCryptomattePanel, ViewLayerAOVPanel, ViewLayerLightgroupsPanel + class CyclesPresetPanel(PresetPanel, Panel): COMPAT_ENGINES = {'CYCLES'} preset_operator = "script.execute_preset" @@ -25,16 +26,19 @@ class CyclesPresetPanel(PresetPanel, Panel): render = context.scene.render render.filter_size = render.filter_size + class CYCLES_PT_sampling_presets(CyclesPresetPanel): bl_label = "Sampling Presets" preset_subdir = "cycles/sampling" preset_add_operator = "render.cycles_sampling_preset_add" + class CYCLES_PT_viewport_sampling_presets(CyclesPresetPanel): bl_label = "Viewport Sampling Presets" preset_subdir = "cycles/viewport_sampling" preset_add_operator = "render.cycles_viewport_sampling_preset_add" + class CYCLES_PT_integrator_presets(CyclesPresetPanel): bl_label = "Integrator Presets" preset_subdir = "cycles/integrator" @@ -90,6 +94,7 @@ def use_metal(context): return (get_device_type(context) == 'METAL' and cscene.device == 'GPU') + def use_cuda(context): cscene = context.scene.cycles @@ -101,11 +106,13 @@ def use_hip(context): return (get_device_type(context) == 'HIP' and cscene.device == 'GPU') + def use_optix(context): cscene = context.scene.cycles return (get_device_type(context) == 'OPTIX' and cscene.device == 'GPU') + def use_multi_device(context): cscene = context.scene.cycles if cscene.device != 'GPU': @@ -133,7 +140,6 @@ def get_effective_preview_denoiser(context): return 'OIDN' - class CYCLES_RENDER_PT_sampling(CyclesButtonsPanel, Panel): bl_label = "Sampling" @@ -353,6 +359,7 @@ class CYCLES_RENDER_PT_curves(CyclesButtonsPanel, Panel): if ccscene.shape == 'RIBBONS': col.prop(ccscene, "subdivisions", text="Curve Subdivisions") + class CYCLES_RENDER_PT_curves_viewport_display(CyclesButtonsPanel, Panel): bl_label = "Viewport Display" bl_parent_id = "CYCLES_RENDER_PT_curves" @@ -361,6 +368,7 @@ class CYCLES_RENDER_PT_curves_viewport_display(CyclesButtonsPanel, Panel): def draw(self, context): draw_curves_settings(self, context) + class CYCLES_RENDER_PT_volumes(CyclesButtonsPanel, Panel): bl_label = "Volumes" bl_options = {'DEFAULT_CLOSED'} @@ -478,10 +486,10 @@ class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel): col.prop(cscene, "fast_gi_method", text="Method") if world: - light = world.light_settings - col = layout.column(align=True) - col.prop(light, "ao_factor", text="AO Factor") - col.prop(light, "distance", text="AO Distance") + light = world.light_settings + col = layout.column(align=True) + col.prop(light, "ao_factor", text="AO Factor") + col.prop(light, "distance", text="AO Distance") if cscene.fast_gi_method == 'REPLACE': col = layout.column(align=True) @@ -1034,7 +1042,8 @@ class CYCLES_OBJECT_PT_motion_blur(CyclesButtonsPanel, Panel): def poll(cls, context): ob = context.object if CyclesButtonsPanel.poll(context) and ob: - if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', 'META', 'CAMERA', 'CURVES', 'POINTCLOUD'}: + if ob.type in {'MESH', 'CURVE', 'CURVE', 'SURFACE', 'FONT', + 'META', 'CAMERA', 'CURVES', 'POINTCLOUD', 'VOLUME'}: return True if ob.instance_type == 'COLLECTION' and ob.instance_collection: return True @@ -1446,7 +1455,14 @@ class CYCLES_WORLD_PT_surface(CyclesButtonsPanel, Panel): row.use_property_decorate = False sub = row.column(align=True) - sub.prop_search(world, "lightgroup", view_layer, "lightgroups", text="Light Group", results_are_suggestions=True) + sub.prop_search( + world, + "lightgroup", + view_layer, + "lightgroups", + text="Light Group", + results_are_suggestions=True, + ) sub = row.column(align=True) sub.active = bool(world.lightgroup) and not any(lg.name == world.lightgroup for lg in view_layer.lightgroups) @@ -1572,7 +1588,6 @@ class CYCLES_WORLD_PT_settings_surface(CyclesButtonsPanel, Panel): sub.prop(cworld, "is_caustics_light", text="Shadow Caustics") - class CYCLES_WORLD_PT_settings_volume(CyclesButtonsPanel, Panel): bl_label = "Volume" bl_parent_id = "CYCLES_WORLD_PT_settings" @@ -1894,6 +1909,7 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel): if cbk.target == 'IMAGE_TEXTURES': layout.prop(cbk, "use_clear", text="Clear Image") + class CYCLES_RENDER_PT_bake_output_margin(CyclesButtonsPanel, Panel): bl_label = "Margin" bl_context = "render" @@ -1932,7 +1948,6 @@ class CYCLES_RENDER_PT_bake_output_margin(CyclesButtonsPanel, Panel): layout.prop(cbk, "margin", text="Size") - class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel): bl_label = "Debug" bl_context = "render" diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index aade864e4c7..651613b0407 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -72,7 +72,7 @@ def do_versions(self): # Device might not currently be available so this can fail try: if system.legacy_compute_device_type == 1: - prop.compute_device_type = 'NONE' # Was OpenCL + prop.compute_device_type = 'NONE' # Was OpenCL elif system.legacy_compute_device_type == 2: prop.compute_device_type = 'CUDA' else: @@ -181,24 +181,24 @@ def do_versions(self): if version <= (2, 92, 4): if scene.render.engine == 'CYCLES': - for view_layer in scene.view_layers: - cview_layer = view_layer.cycles - view_layer.use_pass_cryptomatte_object = cview_layer.get("use_pass_crypto_object", False) - view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False) - view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False) - view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6) + for view_layer in scene.view_layers: + cview_layer = view_layer.cycles + view_layer.use_pass_cryptomatte_object = cview_layer.get("use_pass_crypto_object", False) + view_layer.use_pass_cryptomatte_material = cview_layer.get("use_pass_crypto_material", False) + view_layer.use_pass_cryptomatte_asset = cview_layer.get("use_pass_crypto_asset", False) + view_layer.pass_cryptomatte_depth = cview_layer.get("pass_crypto_depth", 6) if version <= (2, 93, 7): if scene.render.engine == 'CYCLES': - for view_layer in scene.view_layers: - cview_layer = view_layer.cycles - for caov in cview_layer.get("aovs", []): - aov_name = caov.get("name", "AOV") - if aov_name in view_layer.aovs: - continue - baov = view_layer.aovs.add() - baov.name = caov.get("name", "AOV") - baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE" + for view_layer in scene.view_layers: + cview_layer = view_layer.cycles + for caov in cview_layer.get("aovs", []): + aov_name = caov.get("name", "AOV") + if aov_name in view_layer.aovs: + continue + baov = view_layer.aovs.add() + baov.name = caov.get("name", "AOV") + baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE" if version <= (2, 93, 16): cscene = scene.cycles diff --git a/intern/cycles/blender/camera.cpp b/intern/cycles/blender/camera.cpp index cdd19341534..402fd7c4ec6 100644 --- a/intern/cycles/blender/camera.cpp +++ b/intern/cycles/blender/camera.cpp @@ -23,7 +23,7 @@ struct BlenderCamera { float lens; float shuttertime; - Camera::MotionPosition motion_position; + MotionPosition motion_position; array<float> shutter_curve; Camera::RollingShutterType rolling_shutter_type; @@ -114,7 +114,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings &b_rende bcam->sensor_width = 36.0f; bcam->sensor_height = 24.0f; bcam->sensor_fit = BlenderCamera::AUTO; - bcam->motion_position = Camera::MOTION_POSITION_CENTER; + bcam->motion_position = MOTION_POSITION_CENTER; bcam->border.right = 1.0f; bcam->border.top = 1.0f; bcam->viewport_camera_border.right = 1.0f; @@ -555,10 +555,8 @@ void BlenderSync::sync_camera(BL::RenderSettings &b_render, curvemapping_to_array(b_shutter_curve, bcam.shutter_curve, RAMP_TABLE_SIZE); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - bcam.motion_position = (Camera::MotionPosition)get_enum(cscene, - "motion_blur_position", - Camera::MOTION_NUM_POSITIONS, - Camera::MOTION_POSITION_CENTER); + bcam.motion_position = (MotionPosition)get_enum( + cscene, "motion_blur_position", MOTION_NUM_POSITIONS, MOTION_POSITION_CENTER); bcam.rolling_shutter_type = (Camera::RollingShutterType)get_enum( cscene, "rolling_shutter_type", diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index f77cbdf847d..9b08b564b25 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -16,6 +16,7 @@ #include "scene/shader.h" #include "scene/shader_graph.h" #include "scene/shader_nodes.h" +#include "scene/volume.h" #include "util/foreach.h" #include "util/hash.h" @@ -715,13 +716,13 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, float frame_center_delta = 0.0f; if (scene->need_motion() != Scene::MOTION_PASS && - scene->camera->get_motion_position() != Camera::MOTION_POSITION_CENTER) { + scene->camera->get_motion_position() != MOTION_POSITION_CENTER) { float shuttertime = scene->camera->get_shuttertime(); - if (scene->camera->get_motion_position() == Camera::MOTION_POSITION_END) { + if (scene->camera->get_motion_position() == MOTION_POSITION_END) { frame_center_delta = -shuttertime * 0.5f; } else { - assert(scene->camera->get_motion_position() == Camera::MOTION_POSITION_START); + assert(scene->camera->get_motion_position() == MOTION_POSITION_START); frame_center_delta = shuttertime * 0.5f; } diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index bd6bfafedeb..1028c940772 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -272,7 +272,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, geometry_synced.clear(); /* use for objects and motion sync */ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE || - scene->camera->get_motion_position() == Camera::MOTION_POSITION_CENTER) { + scene->camera->get_motion_position() == MOTION_POSITION_CENTER) { sync_objects(b_depsgraph, b_v3d); } sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state); diff --git a/intern/cycles/blender/volume.cpp b/intern/cycles/blender/volume.cpp index 381b3385a5a..8dd2d45c0b6 100644 --- a/intern/cycles/blender/volume.cpp +++ b/intern/cycles/blender/volume.cpp @@ -168,7 +168,8 @@ class BlenderSmokeLoader : public ImageLoader { AttributeStandard attribute; }; -static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame) +static void sync_smoke_volume( + BL::Scene &b_scene, Scene *scene, BObjectInfo &b_ob_info, Volume *volume, float frame) { if (!b_ob_info.is_real_object_data()) { return; @@ -178,6 +179,18 @@ static void sync_smoke_volume(Scene *scene, BObjectInfo &b_ob_info, Volume *volu return; } + float velocity_scale = b_domain.velocity_scale(); + /* Motion blur attribute is relative to seconds, we need it relative to frames. */ + const bool need_motion = object_need_motion_attribute(b_ob_info, scene); + const float motion_scale = (need_motion) ? + scene->motion_shutter_time() / + (b_scene.render().fps() / b_scene.render().fps_base()) : + 0.0f; + + velocity_scale *= motion_scale; + + volume->set_velocity_scale(velocity_scale); + AttributeStandard attributes[] = {ATTR_STD_VOLUME_DENSITY, ATTR_STD_VOLUME_COLOR, ATTR_STD_VOLUME_FLAME, @@ -234,6 +247,7 @@ class BlenderVolumeLoader : public VDBImageLoader { }; static void sync_volume_object(BL::BlendData &b_data, + BL::Scene &b_scene, BObjectInfo &b_ob_info, Scene *scene, Volume *volume) @@ -247,6 +261,20 @@ static void sync_volume_object(BL::BlendData &b_data, volume->set_step_size(b_render.step_size()); volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT)); + float velocity_scale = b_volume.velocity_scale(); + if (b_volume.velocity_unit() == BL::Volume::velocity_unit_SECOND) { + /* Motion blur attribute is relative to seconds, we need it relative to frames. */ + const bool need_motion = object_need_motion_attribute(b_ob_info, scene); + const float motion_scale = (need_motion) ? + scene->motion_shutter_time() / + (b_scene.render().fps() / b_scene.render().fps_base()) : + 0.0f; + + velocity_scale *= motion_scale; + } + + volume->set_velocity_scale(velocity_scale); + /* Find grid with matching name. */ for (BL::VolumeGrid &b_grid : b_volume.grids) { ustring name = ustring(b_grid.name()); @@ -267,9 +295,22 @@ static void sync_volume_object(BL::BlendData &b_data, else if (name == Attribute::standard_name(ATTR_STD_VOLUME_TEMPERATURE)) { std = ATTR_STD_VOLUME_TEMPERATURE; } - else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY)) { + else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY) || + name == b_volume.velocity_grid()) { std = ATTR_STD_VOLUME_VELOCITY; } + else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_X) || + name == b_volume.velocity_x_grid()) { + std = ATTR_STD_VOLUME_VELOCITY_X; + } + else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Y) || + name == b_volume.velocity_y_grid()) { + std = ATTR_STD_VOLUME_VELOCITY_Y; + } + else if (name == Attribute::standard_name(ATTR_STD_VOLUME_VELOCITY_Z) || + name == b_volume.velocity_z_grid()) { + std = ATTR_STD_VOLUME_VELOCITY_Z; + } if ((std != ATTR_STD_NONE && volume->need_attribute(scene, std)) || volume->need_attribute(scene, name)) { @@ -294,11 +335,11 @@ void BlenderSync::sync_volume(BObjectInfo &b_ob_info, Volume *volume) if (b_ob_info.object_data.is_a(&RNA_Volume)) { /* Volume object. Create only attributes, bounding mesh will then * be automatically generated later. */ - sync_volume_object(b_data, b_ob_info, scene, volume); + sync_volume_object(b_data, b_scene, b_ob_info, scene, volume); } else { /* Smoke domain. */ - sync_smoke_volume(scene, b_ob_info, volume, b_scene.frame_current()); + sync_smoke_volume(b_scene, scene, b_ob_info, volume, b_scene.frame_current()); } } diff --git a/intern/cycles/device/cuda/queue.cpp b/intern/cycles/device/cuda/queue.cpp index a2ca70611bf..38c71866ad0 100644 --- a/intern/cycles/device/cuda/queue.cpp +++ b/intern/cycles/device/cuda/queue.cpp @@ -71,11 +71,6 @@ void CUDADeviceQueue::init_execution() debug_init_execution(); } -bool CUDADeviceQueue::kernel_available(DeviceKernel kernel) const -{ - return cuda_device_->kernels.available(kernel); -} - bool CUDADeviceQueue::enqueue(DeviceKernel kernel, const int work_size, DeviceKernelArguments const &args) diff --git a/intern/cycles/device/cuda/queue.h b/intern/cycles/device/cuda/queue.h index 4612e517de7..b450f5b3592 100644 --- a/intern/cycles/device/cuda/queue.h +++ b/intern/cycles/device/cuda/queue.h @@ -27,8 +27,6 @@ class CUDADeviceQueue : public DeviceQueue { virtual void init_execution() override; - virtual bool kernel_available(DeviceKernel kernel) const override; - virtual bool enqueue(DeviceKernel kernel, const int work_size, DeviceKernelArguments const &args) override; diff --git a/intern/cycles/device/hip/queue.cpp b/intern/cycles/device/hip/queue.cpp index 42778bc31cf..6c2c2c29624 100644 --- a/intern/cycles/device/hip/queue.cpp +++ b/intern/cycles/device/hip/queue.cpp @@ -71,11 +71,6 @@ void HIPDeviceQueue::init_execution() debug_init_execution(); } -bool HIPDeviceQueue::kernel_available(DeviceKernel kernel) const -{ - return hip_device_->kernels.available(kernel); -} - bool HIPDeviceQueue::enqueue(DeviceKernel kernel, const int work_size, DeviceKernelArguments const &args) diff --git a/intern/cycles/device/hip/queue.h b/intern/cycles/device/hip/queue.h index 11f60d04ad4..729d8a19acb 100644 --- a/intern/cycles/device/hip/queue.h +++ b/intern/cycles/device/hip/queue.h @@ -27,8 +27,6 @@ class HIPDeviceQueue : public DeviceQueue { virtual void init_execution() override; - virtual bool kernel_available(DeviceKernel kernel) const override; - virtual bool enqueue(DeviceKernel kernel, const int work_size, DeviceKernelArguments const &args) override; diff --git a/intern/cycles/device/metal/queue.h b/intern/cycles/device/metal/queue.h index 1e1c6d5fcc1..6cc84a20787 100644 --- a/intern/cycles/device/metal/queue.h +++ b/intern/cycles/device/metal/queue.h @@ -39,8 +39,6 @@ class MetalDeviceQueue : public DeviceQueue { virtual void copy_to_device(device_memory &mem) override; virtual void copy_from_device(device_memory &mem) override; - virtual bool kernel_available(DeviceKernel kernel) const override; - protected: void prepare_resources(DeviceKernel kernel); diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm index c0f53386dff..1686ab95ffa 100644 --- a/intern/cycles/device/metal/queue.mm +++ b/intern/cycles/device/metal/queue.mm @@ -492,11 +492,6 @@ void MetalDeviceQueue::copy_from_device(device_memory &mem) } } -bool MetalDeviceQueue::kernel_available(DeviceKernel kernel) const -{ - return metal_device->kernels.available(kernel); -} - void MetalDeviceQueue::prepare_resources(DeviceKernel kernel) { std::lock_guard<std::recursive_mutex> lock(metal_device->metal_mem_map_mutex); diff --git a/intern/cycles/device/queue.h b/intern/cycles/device/queue.h index 2bd6e7ae460..14a5db3a204 100644 --- a/intern/cycles/device/queue.h +++ b/intern/cycles/device/queue.h @@ -112,9 +112,6 @@ class DeviceQueue { * Use this method after device synchronization has finished before enqueueing any kernels. */ virtual void init_execution() = 0; - /* Test if an optional device kernel is available. */ - virtual bool kernel_available(DeviceKernel kernel) const = 0; - /* Enqueue kernel execution. * * Execute the kernel work_size times on the device. diff --git a/intern/cycles/kernel/device/hip/compat.h b/intern/cycles/kernel/device/hip/compat.h index 9c93d87fd87..667352ed12e 100644 --- a/intern/cycles/kernel/device/hip/compat.h +++ b/intern/cycles/kernel/device/hip/compat.h @@ -62,7 +62,7 @@ typedef unsigned long long uint64_t; #define ccl_gpu_block_idx_x (blockIdx.x) #define ccl_gpu_grid_dim_x (gridDim.x) #define ccl_gpu_warp_size (warpSize) -#define ccl_gpu_thread_mask(thread_warp) uint64_t(0xFFFFFFFFFFFFFFFF >> (64 - thread_warp)) +#define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp)) #define ccl_gpu_global_id_x() (ccl_gpu_block_idx_x * ccl_gpu_block_dim_x + ccl_gpu_thread_idx_x) #define ccl_gpu_global_size_x() (ccl_gpu_grid_dim_x * ccl_gpu_block_dim_x) diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 7218165c67c..c523da8d3be 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -36,11 +36,13 @@ * https://cg.ivd.kit.edu/english/HSLT.php */ -# define MNEE_MAX_ITERATIONS 50 +# define MNEE_MAX_ITERATIONS 32 # define MNEE_MAX_INTERSECTION_COUNT 10 # define MNEE_SOLVER_THRESHOLD 0.001f +# define MNEE_MINIMUM_STEP_SIZE 0.0001f # define MNEE_MAX_CAUSTIC_CASTERS 6 # define MNEE_MIN_DISTANCE 0.001f +# define MNEE_MIN_PROGRESS_DISTANCE 0.0001f # define MNEE_MIN_DETERMINANT 0.0001f # define MNEE_PROJECTION_DISTANCE_MULTIPLIER 2.f @@ -168,7 +170,8 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, const float2 n_offset, ccl_private const Ray *ray, ccl_private const Intersection *isect, - ccl_private ShaderData *sd_vtx) + ccl_private ShaderData *sd_vtx, + bool seed) { sd_vtx->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) : isect->object; @@ -177,7 +180,7 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, sd_vtx->flag = 0; sd_vtx->object_flag = kernel_tex_fetch(__object_flag, sd_vtx->object); - /* matrices and time */ + /* Matrices and time. */ shader_setup_object_transforms(kg, sd_vtx, ray->time); sd_vtx->time = ray->time; @@ -191,83 +194,29 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, float3 verts[3]; float3 normals[3]; - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd_vtx->prim); - if (sd_vtx->type & PRIMITIVE_TRIANGLE) { - /* Static triangle. */ - - /* Load triangle vertices. */ - verts[0] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 0); - verts[1] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 1); - verts[2] = kernel_tex_fetch(__tri_verts, tri_vindex.w + 2); - - /* Vectors. */ - sd_vtx->P = triangle_point_from_uv(kg, sd_vtx, isect->object, isect->prim, isect->u, isect->v); - - /* Smooth normal. */ - if (sd_vtx->shader & SHADER_SMOOTH_NORMAL) { - /* Load triangle vertices. */ - normals[0] = kernel_tex_fetch(__tri_vnormal, tri_vindex.x); - normals[1] = kernel_tex_fetch(__tri_vnormal, tri_vindex.y); - normals[2] = kernel_tex_fetch(__tri_vnormal, tri_vindex.z); + /* Load triangle vertices and normals. */ + triangle_vertices_and_normals(kg, sd_vtx->prim, verts, normals); + + /* Compute refined position (same code as in triangle_point_from_uv). */ + sd_vtx->P = isect->u * verts[0] + isect->v * verts[1] + (1.f - isect->u - isect->v) * verts[2]; + if (!(sd_vtx->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { + const Transform tfm = object_get_transform(kg, sd_vtx); + sd_vtx->P = transform_point(&tfm, sd_vtx->P); } } else { /* if (sd_vtx->type & PRIMITIVE_MOTION_TRIANGLE) */ - /* Motion triangle. */ - - /* Get motion info. */ - int numsteps, numverts; - object_motion_info(kg, sd_vtx->object, &numsteps, &numverts, NULL); - - /* Figure out which steps we need to fetch and their interpolation factor. */ - int maxstep = numsteps * 2; - int step = min((int)(sd_vtx->time * maxstep), maxstep - 1); - float t = sd_vtx->time * maxstep - step; - - /* Find attribute. */ - int offset = intersection_find_attribute(kg, sd_vtx->object, ATTR_STD_MOTION_VERTEX_POSITION); - kernel_assert(offset != ATTR_STD_NOT_FOUND); - - /* Fetch vertex coordinates. */ - float3 next_verts[3]; - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd_vtx->prim); - motion_triangle_verts_for_step(kg, tri_vindex, offset, numverts, numsteps, step, verts); - motion_triangle_verts_for_step( - kg, tri_vindex, offset, numverts, numsteps, step + 1, next_verts); - - /* Interpolate between steps. */ - verts[0] = (1.0f - t) * verts[0] + t * next_verts[0]; - verts[1] = (1.0f - t) * verts[1] + t * next_verts[1]; - verts[2] = (1.0f - t) * verts[2] + t * next_verts[2]; + /* Load triangle vertices and normals. */ + motion_triangle_vertices_and_normals( + kg, sd_vtx->object, sd_vtx->prim, sd_vtx->time, verts, normals); /* Compute refined position. */ sd_vtx->P = motion_triangle_point_from_uv( kg, sd_vtx, isect->object, isect->prim, isect->u, isect->v, verts); - - /* Compute smooth normal. */ - if (sd_vtx->shader & SHADER_SMOOTH_NORMAL) { - /* Find attribute. */ - int offset = intersection_find_attribute(kg, sd_vtx->object, ATTR_STD_MOTION_VERTEX_NORMAL); - kernel_assert(offset != ATTR_STD_NOT_FOUND); - - /* Fetch vertex coordinates. */ - float3 next_normals[3]; - motion_triangle_normals_for_step(kg, tri_vindex, offset, numverts, numsteps, step, normals); - motion_triangle_normals_for_step( - kg, tri_vindex, offset, numverts, numsteps, step + 1, next_normals); - - /* Interpolate between steps. */ - normals[0] = (1.0f - t) * normals[0] + t * next_normals[0]; - normals[1] = (1.0f - t) * normals[1] + t * next_normals[1]; - normals[2] = (1.0f - t) * normals[2] + t * next_normals[2]; - } } - /* manifold vertex position */ - vtx->p = sd_vtx->P; - + /* Instance transform. */ if (!(sd_vtx->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - /* Instance transform. */ object_position_transform_auto(kg, sd_vtx, &verts[0]); object_position_transform_auto(kg, sd_vtx, &verts[1]); object_position_transform_auto(kg, sd_vtx, &verts[2]); @@ -277,94 +226,70 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, } /* Tangent space (position derivatives) WRT barycentric (u, v). */ - vtx->dp_du = verts[0] - verts[2]; - vtx->dp_dv = verts[1] - verts[2]; + float3 dp_du = verts[0] - verts[2]; + float3 dp_dv = verts[1] - verts[2]; /* Geometric normal. */ - vtx->ng = normalize(cross(vtx->dp_du, vtx->dp_dv)); + vtx->ng = normalize(cross(dp_du, dp_dv)); if (sd_vtx->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) vtx->ng = -vtx->ng; - /* Shading normal. */ - if (!(sd_vtx->shader & SHADER_SMOOTH_NORMAL)) { - vtx->n = vtx->ng; - vtx->dn_du = vtx->dn_dv = zero_float3(); - } - else { - /* Interpolate normals between vertices. */ - float n_len; - vtx->n = normalize_len(normals[0] * sd_vtx->u + normals[1] * sd_vtx->v + - normals[2] * (1.0f - sd_vtx->u - sd_vtx->v), - &n_len); - - /* Shading normal derivatives WRT barycentric (u, v) - * we calculate the derivative of n = |u*n0 + v*n1 + (1-u-v)*n2| using: - * d/du [f(u)/|f(u)|] = [d/du f(u)]/|f(u)| - f(u)/|f(u)|^3 <f(u), d/du f(u)>. */ - const float inv_n_len = 1.f / n_len; - vtx->dn_du = inv_n_len * (normals[0] - normals[2]); - vtx->dn_dv = inv_n_len * (normals[1] - normals[2]); - vtx->dn_du -= vtx->n * dot(vtx->n, vtx->dn_du); - vtx->dn_dv -= vtx->n * dot(vtx->n, vtx->dn_dv); - } + /* Shading normals: Interpolate normals between vertices. */ + float n_len; + vtx->n = normalize_len(normals[0] * sd_vtx->u + normals[1] * sd_vtx->v + + normals[2] * (1.0f - sd_vtx->u - sd_vtx->v), + &n_len); + + /* Shading normal derivatives WRT barycentric (u, v) + * we calculate the derivative of n = |u*n0 + v*n1 + (1-u-v)*n2| using: + * d/du [f(u)/|f(u)|] = [d/du f(u)]/|f(u)| - f(u)/|f(u)|^3 <f(u), d/du f(u)>. */ + const float inv_n_len = 1.f / n_len; + float3 dn_du = inv_n_len * (normals[0] - normals[2]); + float3 dn_dv = inv_n_len * (normals[1] - normals[2]); + dn_du -= vtx->n * dot(vtx->n, dn_du); + dn_dv -= vtx->n * dot(vtx->n, dn_dv); - /* dp_du and dp_dv need to be continuous across triangles for the h normal - * offset to yield a consistent halfvector while walking on the manifold. - * It's usually best to rely on the mesh uv layout, which is assumed to be - * continuous across the mesh. */ - float2 duv0, duv1; - bool found_uv = false; - AttributeDescriptor uv_desc = find_attribute(kg, sd_vtx, ATTR_STD_GENERATED); - if (uv_desc.offset != ATTR_STD_NOT_FOUND) { - float3 uvs[3]; - uvs[0] = kernel_tex_fetch(__attributes_float3, uv_desc.offset + tri_vindex.x); - uvs[1] = kernel_tex_fetch(__attributes_float3, uv_desc.offset + tri_vindex.y); - uvs[2] = kernel_tex_fetch(__attributes_float3, uv_desc.offset + tri_vindex.z); - duv0 = make_float2(uvs[0].x - uvs[2].x, uvs[0].y - uvs[2].y); - duv1 = make_float2(uvs[1].x - uvs[2].x, uvs[1].y - uvs[2].y); - found_uv = true; + /* Orthonormalize (dp_du,dp_dv) using a linear transformation, which + * we use on (dn_du,dn_dv) as well so the new (u,v) are consistent. */ + const float inv_len_dp_du = 1.f / len(dp_du); + dp_du *= inv_len_dp_du; + dn_du *= inv_len_dp_du; + + const float dpdu_dot_dpdv = dot(dp_du, dp_dv); + dp_dv -= dpdu_dot_dpdv * dp_du; + dn_dv -= dpdu_dot_dpdv * dn_du; + + const float inv_len_dp_dv = 1.f / len(dp_dv); + dp_dv *= inv_len_dp_dv; + dn_dv *= inv_len_dp_dv; + + /* Final local differential geometry. */ + if (seed) { + vtx->dp_du = dp_du; + vtx->dp_dv = dp_dv; + vtx->dn_du = dn_du; + vtx->dn_dv = dn_dv; } else { - uv_desc = find_attribute(kg, sd_vtx, ATTR_STD_UV); - if (uv_desc.offset != ATTR_STD_NOT_FOUND) { - float2 uvs[3]; - uvs[0] = kernel_tex_fetch(__attributes_float2, uv_desc.offset + tri_vindex.x); - uvs[1] = kernel_tex_fetch(__attributes_float2, uv_desc.offset + tri_vindex.y); - uvs[2] = kernel_tex_fetch(__attributes_float2, uv_desc.offset + tri_vindex.z); - duv0 = make_float2(uvs[0].x - uvs[2].x, uvs[0].y - uvs[2].y); - duv1 = make_float2(uvs[1].x - uvs[2].x, uvs[1].y - uvs[2].y); - found_uv = true; - } - } - if (found_uv) { - const float det = duv0.x * duv1.y - duv0.y * duv1.x; - if (det != 0.f) { - const float inv_det = 1.f / det; - - /* Tangent space (position derivatives) WRT texture (u, v). */ - const float3 dp_du = vtx->dp_du; - const float3 dp_dv = vtx->dp_dv; - vtx->dp_du = (duv1.y * dp_du - duv0.y * dp_dv) * inv_det; - vtx->dp_dv = (-duv1.x * dp_du + duv0.x * dp_dv) * inv_det; - - /* Shading normal derivatives WRT texture (u, v). */ - const float3 dn_du = vtx->dn_du; - const float3 dn_dv = vtx->dn_dv; - vtx->dn_du = (duv1.y * dn_du - duv0.y * dn_dv) * inv_det; - vtx->dn_dv = (-duv1.x * dn_du + duv0.x * dn_dv) * inv_det; - } + /* Find angle subtended by reference direction (travel direction). */ + const float3 reference_direction = normalize(sd_vtx->P - vtx->p); + const float reference_theta = atan2(dot(reference_direction, vtx->dp_dv), + dot(reference_direction, vtx->dp_du)); + const float current_theta = atan2(dot(reference_direction, dp_dv), + dot(reference_direction, dp_du)); + const float theta = reference_theta - current_theta; + + /* Rotate (dp_du,dp_dv) to be consistent with previous tangent frame. */ + float cos_theta, sin_theta; + fast_sincosf(theta, &sin_theta, &cos_theta); + vtx->dp_du = cos_theta * dp_du - sin_theta * dp_dv; + vtx->dp_dv = sin_theta * dp_du + cos_theta * dp_dv; + vtx->dn_du = cos_theta * dn_du - sin_theta * dn_dv; + vtx->dn_dv = sin_theta * dn_du + cos_theta * dn_dv; } - /* Orthonormalize (dp_du,dp_dv) using a linear transformation, which - * we use on (dn_du,dn_dv) as well so the new (u,v) are consistent. */ - const float inv_len_dp_du = 1.f / len(vtx->dp_du); - vtx->dp_du *= inv_len_dp_du; - vtx->dn_du *= inv_len_dp_du; - const float dpdu_dot_dpdv = dot(vtx->dp_du, vtx->dp_dv); - const float3 dp_dv = vtx->dp_dv - dpdu_dot_dpdv * vtx->dp_du; - const float3 dn_dv = vtx->dn_dv - dpdu_dot_dpdv * vtx->dn_du; - const float inv_len_dp_dv = 1.f / len(dp_dv); - vtx->dp_dv = dp_dv * inv_len_dp_dv; - vtx->dn_dv = dn_dv * inv_len_dp_dv; + /* Manifold vertex position. */ + vtx->p = sd_vtx->P; /* Initialize constraint and its derivates. */ vtx->a = vtx->c = zero_float4(); @@ -638,15 +563,28 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg, break; } + /* Initialize tangent frame, which will be used as reference. */ + ccl_private ManifoldVertex &tv = tentative[vi]; + tv.p = mv.p; + tv.dp_du = mv.dp_du; + tv.dp_dv = mv.dp_dv; + /* Setup corrected manifold vertex. */ mnee_setup_manifold_vertex(kg, - &tentative[vi], + &tv, mv.bsdf, mv.eta, mv.n_offset, &projection_ray, &projection_isect, - sd_vtx); + sd_vtx, + false); + + /* Fail newton solve if we are not making progress, probably stuck trying to move off the + * edge of the mesh. */ + const float distance = len(tv.p - mv.p); + if (distance < MNEE_MIN_PROGRESS_DISTANCE) + return false; } /* Check that tentative path is still transmissive. */ @@ -672,6 +610,11 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg, reduce_stepsize = false; resolve_constraint = false; beta *= .5f; + + /* Fail newton solve if the stepsize is too small. */ + if (beta < MNEE_MINIMUM_STEP_SIZE) + return false; + continue; } @@ -714,8 +657,7 @@ mnee_sample_bsdf_dh(ClosureType type, float alpha_x, float alpha_y, float sample if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { tan2_theta *= -logf(1.0f - sample_u); } - else { /* if (type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || type == - CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_FRESNEL_ID) */ + else { /* type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */ tan2_theta *= sample_u / (1.0f - sample_u); } float cos2_theta = 1.0f / (1.0f + tan2_theta); @@ -749,8 +691,7 @@ ccl_device_forceinline float3 mnee_eval_bsdf_contribution(ccl_private ShaderClos /* Eq. 26, 27: now calculate G1(i,m) and G1(o,m). */ G = bsdf_beckmann_G1(bsdf->alpha_x, cosNO) * bsdf_beckmann_G1(bsdf->alpha_x, cosNI); } - else { /* if (type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || type == - CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_FRESNEL_ID) */ + else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */ /* Eq. 34: now calculate G1(i,m) and G1(o,m). */ G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO)))) * (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))); @@ -929,7 +870,8 @@ ccl_device_forceinline bool mnee_path_contribution(KernelGlobals kg, /* Receiver bsdf eval above already contains |n.wo|. */ const float dw0_dx1 = fabsf(dot(wo, vertices[0].n)) / sqr(wo_len); - const float G = dw0_dx1 * dx1_dxlight; + /* Clamp since it has a tendency to be unstable. */ + const float G = fminf(dw0_dx1 * dx1_dxlight, 2.f); bsdf_eval_mul(throughput, G); /* Specular reflectance. */ @@ -1058,21 +1000,36 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg, if (vertex_count >= MNEE_MAX_CAUSTIC_CASTERS) return false; + /* Reject caster if it is not a triangles mesh. */ + if (!(probe_isect.type & PRIMITIVE_TRIANGLE)) + return false; + ccl_private ManifoldVertex &mv = vertices[vertex_count++]; /* Setup shader data on caustic caster and evaluate context. */ shader_setup_from_ray(kg, sd_mnee, &probe_ray, &probe_isect); + /* Reject caster if smooth normals are not available: Manifold exploration assumes local + * differential geometry can be created at any point on the surface which is not possible if + * normals are not smooth. */ + if (!(sd_mnee->shader & SHADER_SMOOTH_NORMAL)) + return false; + /* Last bool argument is the MNEE flag (for TINY_MAX_CLOSURE cap in kernel_shader.h). */ shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW>( kg, state, sd_mnee, NULL, PATH_RAY_DIFFUSE, true); - /* get and sample refraction bsdf. */ + /* Get and sample refraction bsdf */ bool found_transimissive_microfacet_bsdf = false; for (int ci = 0; ci < sd_mnee->num_closure; ci++) { ccl_private ShaderClosure *bsdf = &sd_mnee->closure[ci]; if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID) { + bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID || + bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID || + bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) { + /* Note that CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID and + * CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID are treated as + * CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID further below. */ found_transimissive_microfacet_bsdf = true; ccl_private MicrofacetBsdf *microfacet_bsdf = (ccl_private MicrofacetBsdf *)bsdf; @@ -1088,7 +1045,8 @@ ccl_device_forceinline bool kernel_path_mnee_sample(KernelGlobals kg, bsdf->type, microfacet_bsdf->alpha_x, microfacet_bsdf->alpha_y, bsdf_u, bsdf_v); /* Setup differential geometry on vertex. */ - mnee_setup_manifold_vertex(kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee); + mnee_setup_manifold_vertex( + kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee, true); break; } } diff --git a/intern/cycles/kernel/integrator/shader_eval.h b/intern/cycles/kernel/integrator/shader_eval.h index 3066fb661a1..4da92929366 100644 --- a/intern/cycles/kernel/integrator/shader_eval.h +++ b/intern/cycles/kernel/integrator/shader_eval.h @@ -831,6 +831,65 @@ ccl_device_inline void shader_eval_volume(KernelGlobals kg, /* todo: this is inefficient for motion blur, we should be * caching matrices instead of recomputing them each step */ shader_setup_object_transforms(kg, sd, sd->time); + + if ((sd->object_flag & SD_OBJECT_HAS_VOLUME_MOTION) != 0) { + AttributeDescriptor v_desc = find_attribute(kg, sd, ATTR_STD_VOLUME_VELOCITY); + kernel_assert(v_desc.offset != ATTR_STD_NOT_FOUND); + + const float3 P = sd->P; + const float velocity_scale = kernel_tex_fetch(__objects, sd->object).velocity_scale; + const float time_offset = kernel_data.cam.motion_position == MOTION_POSITION_CENTER ? + 0.5f : + 0.0f; + const float time = kernel_data.cam.motion_position == MOTION_POSITION_END ? + (1.0f - kernel_data.cam.shuttertime) + sd->time : + sd->time; + + /* Use a 1st order semi-lagrangian advection scheme to estimate what volume quantity + * existed, or will exist, at the given time: + * + * `phi(x, T) = phi(x - (T - t) * u(x, T), t)` + * + * where + * + * x : position + * T : super-sampled time (or ray time) + * t : current time of the simulation (in rendering we assume this is center frame with + * relative time = 0) + * phi : the volume quantity + * u : the velocity field + * + * But first we need to determine the velocity field `u(x, T)`, which we can estimate also + * using semi-lagrangian advection. + * + * `u(x, T) = u(x - (T - t) * u(x, T), t)` + * + * This is the typical way to model self-advection in fluid dynamics, however, we do not + * account for other forces affecting the velocity during simulation (pressure, buoyancy, + * etc.): this gives a linear interpolation when fluid are mostly "curvy". For better + * results, a higher order interpolation scheme can be used (at the cost of more lookups), + * or an interpolation of the velocity fields for the previous and next frames could also + * be used to estimate `u(x, T)` (which will cost more memory and lookups). + * + * References: + * "Eulerian Motion Blur", Kim and Ko, 2007 + * "Production Volume Rendering", Wreninge et al., 2012 + */ + + /* Find velocity. */ + float3 velocity = primitive_volume_attribute_float3(kg, sd, v_desc); + object_dir_transform(kg, sd, &velocity); + + /* Find advected P. */ + sd->P = P - (time - time_offset) * velocity_scale * velocity; + + /* Find advected velocity. */ + velocity = primitive_volume_attribute_float3(kg, sd, v_desc); + object_dir_transform(kg, sd, &velocity); + + /* Find advected P. */ + sd->P = P - (time - time_offset) * velocity_scale * velocity; + } # endif } diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 422285cd346..01df7948241 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -489,6 +489,18 @@ enum PanoramaType { PANORAMA_NUM_TYPES, }; +/* Specifies an offset for the shutter's time interval. */ +enum MotionPosition { + /* Shutter opens at the current frame. */ + MOTION_POSITION_START = 0, + /* Shutter is fully open at the current frame. */ + MOTION_POSITION_CENTER = 1, + /* Shutter closes at the current frame. */ + MOTION_POSITION_END = 2, + + MOTION_NUM_POSITIONS, +}; + /* Direct Light Sampling */ enum DirectLightSamplingType { @@ -635,6 +647,9 @@ typedef enum AttributeStandard { ATTR_STD_VOLUME_HEAT, ATTR_STD_VOLUME_TEMPERATURE, ATTR_STD_VOLUME_VELOCITY, + ATTR_STD_VOLUME_VELOCITY_X, + ATTR_STD_VOLUME_VELOCITY_Y, + ATTR_STD_VOLUME_VELOCITY_Z, ATTR_STD_POINTINESS, ATTR_STD_RANDOM_PER_ISLAND, ATTR_STD_SHADOW_TRANSPARENCY, @@ -808,6 +823,8 @@ enum ShaderDataObjectFlag { SD_OBJECT_CAUSTICS_CASTER = (1 << 9), /* object is caustics receiver */ SD_OBJECT_CAUSTICS_RECEIVER = (1 << 10), + /* object has attribute for volume motion */ + SD_OBJECT_HAS_VOLUME_MOTION = (1 << 11), /* object is using caustics */ SD_OBJECT_CAUSTICS = (SD_OBJECT_CAUSTICS_CASTER | SD_OBJECT_CAUSTICS_RECEIVER), @@ -815,7 +832,8 @@ enum ShaderDataObjectFlag { SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | SD_OBJECT_MOTION | SD_OBJECT_TRANSFORM_APPLIED | SD_OBJECT_NEGATIVE_SCALE_APPLIED | SD_OBJECT_HAS_VOLUME | SD_OBJECT_INTERSECTS_VOLUME | SD_OBJECT_SHADOW_CATCHER | - SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS) + SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS | + SD_OBJECT_HAS_VOLUME_MOTION) }; typedef struct ccl_align(16) ShaderData @@ -1040,7 +1058,7 @@ typedef struct KernelCamera { int rolling_shutter_type; float rolling_shutter_duration; - int pad; + int motion_position; } KernelCamera; static_assert_align(KernelCamera, 16); @@ -1386,7 +1404,8 @@ typedef struct KernelObject { uint visibility; int primitive_type; - int pad1; + /* Volume velocity scale. */ + float velocity_scale; } KernelObject; static_assert_align(KernelObject, 16); diff --git a/intern/cycles/scene/attribute.cpp b/intern/cycles/scene/attribute.cpp index 0ca602362bc..df01189a54b 100644 --- a/intern/cycles/scene/attribute.cpp +++ b/intern/cycles/scene/attribute.cpp @@ -360,6 +360,12 @@ const char *Attribute::standard_name(AttributeStandard std) return "temperature"; case ATTR_STD_VOLUME_VELOCITY: return "velocity"; + case ATTR_STD_VOLUME_VELOCITY_X: + return "velocity_x"; + case ATTR_STD_VOLUME_VELOCITY_Y: + return "velocity_y"; + case ATTR_STD_VOLUME_VELOCITY_Z: + return "velocity_z"; case ATTR_STD_POINTINESS: return "pointiness"; case ATTR_STD_RANDOM_PER_ISLAND: @@ -587,6 +593,9 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) case ATTR_STD_VOLUME_FLAME: case ATTR_STD_VOLUME_HEAT: case ATTR_STD_VOLUME_TEMPERATURE: + case ATTR_STD_VOLUME_VELOCITY_X: + case ATTR_STD_VOLUME_VELOCITY_Y: + case ATTR_STD_VOLUME_VELOCITY_Z: attr = add(name, TypeDesc::TypeFloat, ATTR_ELEMENT_VOXEL); break; case ATTR_STD_VOLUME_COLOR: diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index 6aca2fcbb81..710f1c5ee90 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -397,6 +397,7 @@ void Camera::update(Scene *scene) /* motion blur */ kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f; + kcam->motion_position = motion_position; /* type */ kcam->type = camera_type; diff --git a/intern/cycles/scene/camera.h b/intern/cycles/scene/camera.h index 97bee430588..c150405acc2 100644 --- a/intern/cycles/scene/camera.h +++ b/intern/cycles/scene/camera.h @@ -30,18 +30,6 @@ class Camera : public Node { public: NODE_DECLARE - /* Specifies an offset for the shutter's time interval. */ - enum MotionPosition { - /* Shutter opens at the current frame. */ - MOTION_POSITION_START = 0, - /* Shutter is fully open at the current frame. */ - MOTION_POSITION_CENTER = 1, - /* Shutter closes at the current frame. */ - MOTION_POSITION_END = 2, - - MOTION_NUM_POSITIONS, - }; - /* Specifies rolling shutter effect. */ enum RollingShutterType { /* No rolling shutter effect. */ diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 351ec4f09ae..349d8ad39c7 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -1541,7 +1541,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro } Volume *volume = static_cast<Volume *>(geom); - create_volume_mesh(volume, progress); + create_volume_mesh(scene, volume, progress); /* always reallocate when we have a volume, as we need to rebuild the BVH */ device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC; diff --git a/intern/cycles/scene/geometry.h b/intern/cycles/scene/geometry.h index 0c2e70d483d..6210a64509a 100644 --- a/intern/cycles/scene/geometry.h +++ b/intern/cycles/scene/geometry.h @@ -216,7 +216,7 @@ class GeometryManager { protected: bool displace(Device *device, Scene *scene, Mesh *mesh, Progress &progress); - void create_volume_mesh(Volume *volume, Progress &progress); + void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress); /* Attributes */ void update_osl_attributes(Device *device, diff --git a/intern/cycles/scene/image_vdb.cpp b/intern/cycles/scene/image_vdb.cpp index 9906606a959..b6f0911fa2c 100644 --- a/intern/cycles/scene/image_vdb.cpp +++ b/intern/cycles/scene/image_vdb.cpp @@ -64,6 +64,11 @@ struct ToNanoOp { } }; # endif + +VDBImageLoader::VDBImageLoader(openvdb::GridBase::ConstPtr grid_, const string &grid_name) + : grid_name(grid_name), grid(grid_) +{ +} #endif VDBImageLoader::VDBImageLoader(const string &grid_name) : grid_name(grid_name) diff --git a/intern/cycles/scene/image_vdb.h b/intern/cycles/scene/image_vdb.h index c851ef6250d..a5fd51915ef 100644 --- a/intern/cycles/scene/image_vdb.h +++ b/intern/cycles/scene/image_vdb.h @@ -17,6 +17,9 @@ CCL_NAMESPACE_BEGIN class VDBImageLoader : public ImageLoader { public: +#ifdef WITH_OPENVDB + VDBImageLoader(openvdb::GridBase::ConstPtr grid_, const string &grid_name); +#endif VDBImageLoader(const string &grid_name); ~VDBImageLoader(); diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index 55d89fc3673..676cc78a11f 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -439,6 +439,14 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s flag |= SD_OBJECT_HAS_VERTEX_MOTION; } } + else if (geom->is_volume()) { + Volume *volume = static_cast<Volume *>(geom); + if (volume->attributes.find(ATTR_STD_VOLUME_VELOCITY) && + volume->get_velocity_scale() != 0.0f) { + flag |= SD_OBJECT_HAS_VOLUME_MOTION; + kobject.velocity_scale = volume->get_velocity_scale(); + } + } if (state->need_motion == Scene::MOTION_PASS) { /* Clear motion array if there is no actual motion. */ diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp index b6b53004816..b35242139ea 100644 --- a/intern/cycles/scene/scene.cpp +++ b/intern/cycles/scene/scene.cpp @@ -381,7 +381,7 @@ void Scene::device_update(Device *device_, Progress &progress) } } -Scene::MotionType Scene::need_motion() +Scene::MotionType Scene::need_motion() const { if (integrator->get_motion_blur()) return MOTION_BLUR; @@ -407,6 +407,10 @@ bool Scene::need_global_attribute(AttributeStandard std) return need_motion() != MOTION_NONE; else if (std == ATTR_STD_MOTION_VERTEX_NORMAL) return need_motion() == MOTION_BLUR; + else if (std == ATTR_STD_VOLUME_VELOCITY || std == ATTR_STD_VOLUME_VELOCITY_X || + std == ATTR_STD_VOLUME_VELOCITY_Y || std == ATTR_STD_VOLUME_VELOCITY_Z) { + return need_motion() != MOTION_NONE; + } return false; } diff --git a/intern/cycles/scene/scene.h b/intern/cycles/scene/scene.h index 54c7d9d93ea..a0d2f4a6c06 100644 --- a/intern/cycles/scene/scene.h +++ b/intern/cycles/scene/scene.h @@ -257,7 +257,7 @@ class Scene : public NodeOwner { void need_global_attributes(AttributeRequestSet &attributes); enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR }; - MotionType need_motion(); + MotionType need_motion() const; float motion_shutter_time(); bool need_update(); diff --git a/intern/cycles/scene/volume.cpp b/intern/cycles/scene/volume.cpp index 0555fdd2fad..39e9b0bbbf4 100644 --- a/intern/cycles/scene/volume.cpp +++ b/intern/cycles/scene/volume.cpp @@ -10,9 +10,9 @@ # include <openvdb/tools/Dense.h> # include <openvdb/tools/GridTransformer.h> # include <openvdb/tools/Morphology.h> +# include <openvdb/tools/Statistics.h> #endif -#include "util/foreach.h" #include "util/hash.h" #include "util/log.h" #include "util/openvdb.h" @@ -28,6 +28,7 @@ NODE_DEFINE(Volume) SOCKET_FLOAT(clipping, "Clipping", 0.001f); SOCKET_FLOAT(step_size, "Step Size", 0.0f); SOCKET_BOOLEAN(object_space, "Object Space", false); + SOCKET_FLOAT(velocity_scale, "Velocity Scale", 1.0f); return type; } @@ -258,7 +259,8 @@ void VolumeMeshBuilder::add_grid(openvdb::GridBase::ConstPtr grid, void VolumeMeshBuilder::add_padding(int pad_size) { #ifdef WITH_OPENVDB - openvdb::tools::dilateVoxels(topology_grid->tree(), pad_size); + openvdb::tools::dilateActiveValues( + topology_grid->tree(), pad_size, openvdb::tools::NN_FACE, openvdb::tools::IGNORE_TILES); #else (void)pad_size; #endif @@ -482,11 +484,141 @@ static openvdb::GridBase::ConstPtr openvdb_grid_from_device_texture(device_textu return sparse; } + +static int estimate_required_velocity_padding(openvdb::GridBase::ConstPtr grid, + float velocity_scale) +{ + /* TODO: we may need to also find outliers and clamp them to avoid adding too much padding. */ + openvdb::math::Extrema extrema; + openvdb::Vec3d voxel_size; + + /* External .vdb files have a vec3 type for velocity, but the Blender exporter creates a vec4. */ + if (grid->isType<openvdb::Vec3fGrid>()) { + openvdb::Vec3fGrid::ConstPtr vel_grid = openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid); + extrema = openvdb::tools::extrema(vel_grid->cbeginValueOn()); + voxel_size = vel_grid->voxelSize(); + } + else if (grid->isType<openvdb::Vec4fGrid>()) { + openvdb::Vec4fGrid::ConstPtr vel_grid = openvdb::gridConstPtrCast<openvdb::Vec4fGrid>(grid); + extrema = openvdb::tools::extrema(vel_grid->cbeginValueOn()); + voxel_size = vel_grid->voxelSize(); + } + else { + assert(0); + return 0; + } + + /* We should only have uniform grids, so x = y = z, but we never know. */ + const double max_voxel_size = openvdb::math::Max(voxel_size.x(), voxel_size.y(), voxel_size.z()); + if (max_voxel_size == 0.0) { + return 0; + } + + const double estimated_padding = extrema.max() * static_cast<double>(velocity_scale) / + max_voxel_size; + + return static_cast<int>(std::ceil(estimated_padding)); +} + +static openvdb::FloatGrid::ConstPtr get_vdb_for_attribute(Volume *volume, AttributeStandard std) +{ + Attribute *attr = volume->attributes.find(std); + if (!attr) { + return nullptr; + } + + ImageHandle &handle = attr->data_voxel(); + VDBImageLoader *vdb_loader = handle.vdb_loader(); + if (!vdb_loader) { + return nullptr; + } + + openvdb::GridBase::ConstPtr grid = vdb_loader->get_grid(); + if (!grid) { + return nullptr; + } + + if (!grid->isType<openvdb::FloatGrid>()) { + return nullptr; + } + + return openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid); +} + +class MergeScalarGrids { + typedef openvdb::FloatTree ScalarTree; + + openvdb::tree::ValueAccessor<const ScalarTree> m_acc_x, m_acc_y, m_acc_z; + + public: + MergeScalarGrids(const ScalarTree *x_tree, const ScalarTree *y_tree, const ScalarTree *z_tree) + : m_acc_x(*x_tree), m_acc_y(*y_tree), m_acc_z(*z_tree) + { + } + + MergeScalarGrids(const MergeScalarGrids &other) + : m_acc_x(other.m_acc_x), m_acc_y(other.m_acc_y), m_acc_z(other.m_acc_z) + { + } + + void operator()(const openvdb::Vec3STree::ValueOnIter &it) const + { + using namespace openvdb; + + const math::Coord xyz = it.getCoord(); + float x = m_acc_x.getValue(xyz); + float y = m_acc_y.getValue(xyz); + float z = m_acc_z.getValue(xyz); + + it.setValue(math::Vec3s(x, y, z)); + } +}; + +static void merge_scalar_grids_for_velocity(const Scene *scene, Volume *volume) +{ + if (volume->attributes.find(ATTR_STD_VOLUME_VELOCITY)) { + /* A vector grid for velocity is already available. */ + return; + } + + openvdb::FloatGrid::ConstPtr vel_x_grid = get_vdb_for_attribute(volume, + ATTR_STD_VOLUME_VELOCITY_X); + openvdb::FloatGrid::ConstPtr vel_y_grid = get_vdb_for_attribute(volume, + ATTR_STD_VOLUME_VELOCITY_Y); + openvdb::FloatGrid::ConstPtr vel_z_grid = get_vdb_for_attribute(volume, + ATTR_STD_VOLUME_VELOCITY_Z); + + if (!(vel_x_grid && vel_y_grid && vel_z_grid)) { + return; + } + + openvdb::Vec3fGrid::Ptr vecgrid = openvdb::Vec3SGrid::create(openvdb::Vec3s(0.0f)); + + /* Activate voxels in the vector grid based on the scalar grids to ensure thread safety during + * the merge. */ + vecgrid->tree().topologyUnion(vel_x_grid->tree()); + vecgrid->tree().topologyUnion(vel_y_grid->tree()); + vecgrid->tree().topologyUnion(vel_z_grid->tree()); + + MergeScalarGrids op(&vel_x_grid->tree(), &vel_y_grid->tree(), &vel_z_grid->tree()); + openvdb::tools::foreach (vecgrid->beginValueOn(), op, true, false); + + /* Assume all grids have the same transformation. */ + openvdb::math::Transform::Ptr transform = openvdb::ConstPtrCast<openvdb::math::Transform>( + vel_x_grid->transformPtr()); + vecgrid->setTransform(transform); + + /* Make an attribute for it. */ + Attribute *attr = volume->attributes.add(ATTR_STD_VOLUME_VELOCITY); + ImageLoader *loader = new VDBImageLoader(vecgrid, "merged_velocity"); + ImageParams params; + attr->data_voxel() = scene->image_manager->add_image(loader, params); +} #endif /* ************************************************************************** */ -void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) +void GeometryManager::create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress) { string msg = string_printf("Computing Volume Mesh %s", volume->name.c_str()); progress.set_status("Updating Mesh", msg); @@ -495,7 +627,7 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) Shader *volume_shader = NULL; int pad_size = 0; - foreach (Node *node, volume->get_used_shaders()) { + for (Node *node : volume->get_used_shaders()) { Shader *shader = static_cast<Shader *>(node); if (!shader->has_volume) { @@ -529,7 +661,9 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) VolumeMeshBuilder builder; #ifdef WITH_OPENVDB - foreach (Attribute &attr, volume->attributes.attributes) { + merge_scalar_grids_for_velocity(scene, volume); + + for (Attribute &attr : volume->attributes.attributes) { if (attr.element != ATTR_ELEMENT_VOXEL) { continue; } @@ -567,9 +701,17 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) } if (grid) { + /* Add padding based on the maximum velocity vector. */ + if (attr.std == ATTR_STD_VOLUME_VELOCITY && scene->need_motion() != Scene::MOTION_NONE) { + pad_size = max(pad_size, + estimate_required_velocity_padding(grid, volume->get_velocity_scale())); + } + builder.add_grid(grid, do_clipping, volume->get_clipping()); } } +#else + (void)scene; #endif /* If nothing to build, early out. */ diff --git a/intern/cycles/scene/volume.h b/intern/cycles/scene/volume.h index cae0f5f5bce..2b94aaf5253 100644 --- a/intern/cycles/scene/volume.h +++ b/intern/cycles/scene/volume.h @@ -18,6 +18,7 @@ class Volume : public Mesh { NODE_SOCKET_API(float, clipping) NODE_SOCKET_API(float, step_size) NODE_SOCKET_API(bool, object_space) + NODE_SOCKET_API(float, velocity_scale) virtual void clear(bool preserve_shaders = false) override; }; diff --git a/intern/ghost/intern/GHOST_Wintab.cpp b/intern/ghost/intern/GHOST_Wintab.cpp index be1a0a4b314..974a07db9c3 100644 --- a/intern/ghost/intern/GHOST_Wintab.cpp +++ b/intern/ghost/intern/GHOST_Wintab.cpp @@ -116,7 +116,11 @@ GHOST_Wintab *GHOST_Wintab::loadWintab(HWND hwnd) } int sanityQueueSize = queueSizeGet(hctx.get()); - WINTAB_PRINTF("HCTX %p %s queueSize: %d, queueSizeGet: %d\n", hctx.get(), __func__, queueSize, sanityQueueSize); + WINTAB_PRINTF("HCTX %p %s queueSize: %d, queueSizeGet: %d\n", + hctx.get(), + __func__, + queueSize, + sanityQueueSize); WINTAB_PRINTF("Loaded Wintab context %p\n", hctx.get()); @@ -274,7 +278,11 @@ void GHOST_Wintab::updateCursorInfo() else { m_maxAzimuth = m_maxAltitude = 0; } - WINTAB_PRINTF("HCTX %p %s maxAzimuth: %d, maxAltitude: %d\n", m_context.get(), __func__, m_maxAzimuth, m_maxAltitude); + WINTAB_PRINTF("HCTX %p %s maxAzimuth: %d, maxAltitude: %d\n", + m_context.get(), + __func__, + m_maxAzimuth, + m_maxAltitude); } void GHOST_Wintab::processInfoChange(LPARAM lParam) @@ -531,10 +539,10 @@ void GHOST_Wintab::printContextDebugInfo() /* Print system information. */ printf("left: %d, top: %d, width: %d, height: %d\n", - ::GetSystemMetrics(SM_XVIRTUALSCREEN), - ::GetSystemMetrics(SM_YVIRTUALSCREEN), - ::GetSystemMetrics(SM_CXVIRTUALSCREEN), - ::GetSystemMetrics(SM_CYVIRTUALSCREEN)); + ::GetSystemMetrics(SM_XVIRTUALSCREEN), + ::GetSystemMetrics(SM_YVIRTUALSCREEN), + ::GetSystemMetrics(SM_CXVIRTUALSCREEN), + ::GetSystemMetrics(SM_CYVIRTUALSCREEN)); auto printContextRanges = [](LOGCONTEXT &lc) { printf("lcInOrgX: %d, lcInOrgY: %d, lcInExtX: %d, lcInExtY: %d\n", @@ -576,7 +584,7 @@ void GHOST_Wintab::printContextDebugInfo() m_fpInfo(WTI_DEFSYSCTX, CTX_SYSEXTY, &lc.lcSysExtY); printf("WTI_DEFSYSCTX CTX_*\n"); printContextRanges(lc); - + for (unsigned int i = 0; i < m_numDevices; i++) { /* Print individual device system context. */ m_fpInfo(WTI_DSCTXS + i, 0, &lc); @@ -604,13 +612,13 @@ void GHOST_Wintab::printContextDebugInfo() m_fpInfo(WTI_DEVICES + i, DVC_X, &axis_x); m_fpInfo(WTI_DEVICES + i, DVC_Y, &axis_y); printf("WTI_DEVICES %u axis_x org: %d, axis_y org: %d axis_x ext: %d, axis_y ext: %d\n", - i, - axis_x.axMin, - axis_y.axMin, - axis_x.axMax - axis_x.axMin + 1, - axis_y.axMax - axis_y.axMin + 1); + i, + axis_x.axMin, + axis_y.axMin, + axis_x.axMax - axis_x.axMin + 1, + axis_y.axMax - axis_y.axMin + 1); } - /* Other stuff while we have a logcontext. */ + /* Other stuff while we have a log-context. */ printf("sysmode %d\n", lc.lcSysMode); -}
\ No newline at end of file +} diff --git a/intern/mikktspace/mikktspace.c b/intern/mikktspace/mikktspace.c index 794590d30a4..e39ac4bb6ef 100644 --- a/intern/mikktspace/mikktspace.c +++ b/intern/mikktspace/mikktspace.c @@ -565,23 +565,26 @@ static void GenerateSharedVerticesIndexList(int piTriList_in_and_out[], break; } - for (int i = blockstart; i < blockend; i++) { - int index1 = piTriList_in_and_out[indices[i]]; - const SVec3 vP = GetPosition(pContext, index1); - const SVec3 vN = GetNormal(pContext, index1); - const SVec3 vT = GetTexCoord(pContext, index1); - for (int i2 = i + 1; i2 < blockend; i2++) { - int index2 = piTriList_in_and_out[indices[i2]]; - if (index1 == index2) - continue; - - if (veq(vP, GetPosition(pContext, index2)) && veq(vN, GetNormal(pContext, index2)) && - veq(vT, GetTexCoord(pContext, index2))) { - piTriList_in_and_out[indices[i2]] = index1; - /* Once i2>i has been identified as a duplicate, we can stop since any - * i3>i2>i that is a duplicate of i (and therefore also i2) will also be - * compared to i2 and therefore be identified there anyways. */ - break; + /* If there's only one vertex with this hash, we don't have anything to compare. */ + if (blockend > blockstart + 1) { + for (int i = blockstart; i < blockend; i++) { + int index1 = piTriList_in_and_out[indices[i]]; + const SVec3 vP = GetPosition(pContext, index1); + const SVec3 vN = GetNormal(pContext, index1); + const SVec3 vT = GetTexCoord(pContext, index1); + for (int i2 = i + 1; i2 < blockend; i2++) { + int index2 = piTriList_in_and_out[indices[i2]]; + if (index1 == index2) + continue; + + if (veq(vP, GetPosition(pContext, index2)) && veq(vN, GetNormal(pContext, index2)) && + veq(vT, GetTexCoord(pContext, index2))) { + piTriList_in_and_out[indices[i2]] = index1; + /* Once i2>i has been identified as a duplicate, we can stop since any + * i3>i2>i that is a duplicate of i (and therefore also i2) will also be + * compared to i2 and therefore be identified there anyways. */ + break; + } } } } @@ -645,7 +648,8 @@ static int GenerateInitialVerticesIndexList(STriInfo pTriInfos[], { int iTSpacesOffs = 0, f = 0, t = 0; int iDstTriIndex = 0; - for (f = 0; f < pContext->m_pInterface->m_getNumFaces(pContext); f++) { + const int iNrFaces = pContext->m_pInterface->m_getNumFaces(pContext); + for (f = 0; f < iNrFaces; f++) { const int verts = pContext->m_pInterface->m_getNumVerticesOfFace(pContext, f); if (verts != 3 && verts != 4) continue; diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000000..0b022dfeb34 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +[tool.autopep8] +# Configuratuion for `autopep8`, allowing the command: autopep8 . +# to reformat all source files. +# +# NOTE: the settings defined here map directly to commmand line arguments +# which will override these settings when passed in to autopep8. + +max_line_length = 120 + +ignore = [ + # Info: Use `isinstance()` instead of comparing types directly. + # Why disable? Changes code logic, in rare cases we want to compare exact types. + "E721", + # Info: Fix bare except. + # Why disable? Disruptive, leave our exceptions alone. + "E722", + # Info: Fix module level import not at top of file. + # Why disable? Re-ordering imports is disruptive and breaks some scripts + # that need to check if a module has already been loaded in the case of reloading. + "E402", + # Info: Fix various deprecated code (via lib2to3) + # Why disable? Does nothing besides incorrectly adding a duplicate import, + # could be reported as a bug except this is likely to be removed soon, see: + # https://github.com/python/cpython/issues/84540. + "W690", +] + +# Exclude: +# - `./extern/` because it's maintained separately. +# - `./release/scripts/addons*` & `./source/tools/` because they are external repositories +# which can contain their own configuration and be handled separately. +# - `./release/scripts/modules/rna_manual_reference.py` because it's a generated data-file. +exclude = """ +./extern/*, +./release/scripts/addons/*, +./release/scripts/addons_contrib/*, +./release/scripts/modules/rna_manual_reference.py, +./source/tools/*, +""" + +# Omit settings such as `jobs`, `in_place` & `recursive` as they can cause editor utilities that auto-format on save +# to fail if the STDIN/STDOUT is used for formatting (which isn't compatible with these options). diff --git a/release/datafiles/colormanagement/config.ocio b/release/datafiles/colormanagement/config.ocio index 55e52de7002..df359d6c86c 100644 --- a/release/datafiles/colormanagement/config.ocio +++ b/release/datafiles/colormanagement/config.ocio @@ -75,8 +75,6 @@ colorspaces: description: | Rec. 709 (Full Range), Blender native linear space isdata: false - allocation: lg2 - allocationvars: [-12.473931188, 12.526068812] - !<ColorSpace> name: Raw @@ -84,8 +82,6 @@ colorspaces: equalitygroup: bitdepth: 32f isdata: true - allocation: uniform - allocationvars: [0, 1] - !<ColorSpace> name: Linear ACES @@ -93,16 +89,27 @@ colorspaces: equalitygroup: bitdepth: 32f description: | - ACES linear space + ACES2065-1 linear space isdata: false - allocation: lg2 - allocationvars: [-8.5, 5] from_reference: !<GroupTransform> children: - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear} - !<BuiltinTransform> {style: "UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD", direction: inverse} - !<ColorSpace> + name: Linear ACEScg + family: linear + equalitygroup: + bitdepth: 32f + description: | + ACEScg linear space + isdata: false + from_reference: !<GroupTransform> + children: + - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear} + - !<BuiltinTransform> {style: "UTILITY - ACES-AP1_to_CIE-XYZ-D65_BFD", direction: inverse} + + - !<ColorSpace> name: nuke_rec709 family: display equalitygroup: @@ -110,8 +117,6 @@ colorspaces: description: | Rec. 709 (Full Range) Display Space isdata: false - allocation: uniform - allocationvars: [-0.125, 1.125] to_reference: !<GroupTransform> children: - !<FileTransform> {src: rec709.spi1d, interpolation: linear} @@ -122,8 +127,6 @@ colorspaces: equalitygroup: bitdepth: 32f isdata: false - allocation: lg2 - allocationvars: [-8.5, 5] from_reference: !<GroupTransform> children: - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear} @@ -136,8 +139,6 @@ colorspaces: description: | OpenDCP output LUT with DCI reference white and Gamma 2.6 isdata: false - allocation: uniform - allocationvars: [0, 1] from_reference: !<GroupTransform> children: - !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear} @@ -151,7 +152,6 @@ colorspaces: description: | conversion from film log isdata: false - allocation: uniform to_reference: !<GroupTransform> children: - !<FileTransform> {src: lg10.spi1d, interpolation: nearest} @@ -164,8 +164,6 @@ colorspaces: description: | Standard RGB Display Space isdata: false - allocation: uniform - allocationvars: [-0.125, 4.875] to_reference: !<FileTransform> {src: srgb.spi1d, interpolation: linear} from_reference: !<FileTransform> {src: srgb_inv.spi1d, interpolation: linear} @@ -177,8 +175,6 @@ colorspaces: equalitygroup: bitdepth: 32f isdata: true - allocation: uniform - allocationvars: [0, 1] - !<ColorSpace> name: Filmic Log @@ -188,8 +184,6 @@ colorspaces: description: | Log based filmic shaper with 16.5 stops of latitude, and 25 stops of dynamic range isdata: false - allocation: lg2 - allocationvars: [-12.473931188, 12.526068812] from_reference: !<GroupTransform> children: - !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 12.526068812]} @@ -205,8 +199,6 @@ colorspaces: description: | Filmic sRGB view transform isdata: false - allocation: lg2 - allocationvars: [-12.473931188, 12.526068812] from_reference: !<GroupTransform> children: - !<ColorSpaceTransform> {src: Linear, dst: Filmic Log} @@ -220,8 +212,6 @@ colorspaces: description: | Filmic false color view transform isdata: false - allocation: lg2 - allocationvars: [-12.473931188, 12.526068812] from_reference: !<GroupTransform> children: - !<ColorSpaceTransform> {src: Linear, dst: Filmic Log} diff --git a/release/datafiles/icons/brush.sculpt.paint.dat b/release/datafiles/icons/brush.sculpt.paint.dat Binary files differindex 1cee34c0dee..e499d33e867 100644 --- a/release/datafiles/icons/brush.sculpt.paint.dat +++ b/release/datafiles/icons/brush.sculpt.paint.dat diff --git a/release/datafiles/icons/brush.sculpt.smear.dat b/release/datafiles/icons/brush.sculpt.smear.dat Binary files differindex 3efba0b4cb1..a9867cef5a4 100644 --- a/release/datafiles/icons/brush.sculpt.smear.dat +++ b/release/datafiles/icons/brush.sculpt.smear.dat diff --git a/release/datafiles/icons/ops.sculpt.color_filter.dat b/release/datafiles/icons/ops.sculpt.color_filter.dat Binary files differindex 8a65043eb5f..d589b15a124 100644 --- a/release/datafiles/icons/ops.sculpt.color_filter.dat +++ b/release/datafiles/icons/ops.sculpt.color_filter.dat diff --git a/release/datafiles/icons/ops.sculpt.mask_by_color.dat b/release/datafiles/icons/ops.sculpt.mask_by_color.dat Binary files differindex 6194ce172d5..637c47d2d84 100644 --- a/release/datafiles/icons/ops.sculpt.mask_by_color.dat +++ b/release/datafiles/icons/ops.sculpt.mask_by_color.dat diff --git a/release/datafiles/locale b/release/datafiles/locale -Subproject 63699f968344db7dc853d2c5972325beea44900 +Subproject 716dc02ec30c0810513f7b4adc4ae865ae50c4e diff --git a/release/lts/create_download_urls.py b/release/lts/create_download_urls.py index b3e08fe36d0..753e05c98b4 100755 --- a/release/lts/create_download_urls.py +++ b/release/lts/create_download_urls.py @@ -18,6 +18,7 @@ class Version: Version class that extracts the major, minor and build from a version string """ + def __init__(self, version: str): self.version = version v = version.split(".") @@ -28,6 +29,7 @@ class Version: def __str__(self) -> str: return self.version + def get_download_file_names(version: Version): yield f"blender-{version}-linux-x64.tar.xz" yield f"blender-{version}-macos-x64.dmg" diff --git a/release/lts/create_release_notes.py b/release/lts/create_release_notes.py index 1e94936217c..a51721057bb 100755 --- a/release/lts/create_release_notes.py +++ b/release/lts/create_release_notes.py @@ -30,8 +30,9 @@ class ReleaseLogLine: backend. * url: (str) url of the ticket task or commit. """ + def __init__(self, line: str): - self.line=line + self.line = line items = line.split("|") self.task_id = None self.commit_id = None @@ -54,10 +55,10 @@ class ReleaseLogLine: self.title = "" self.url = f"https://developer.blender.org/{self.ref}" - def __format_as_html(self)-> str: + def __format_as_html(self) -> str: return f" <li>{self.title} [<a href=\"{self.url}\">{self.ref}</a>]</li>" - def __format_as_text(self) ->str: + def __format_as_text(self) -> str: return f"* {self.title} [{self.ref}]" def __format_as_steam(self) -> str: @@ -110,7 +111,7 @@ def extract_release_notes(version: str, task_id: int): description = task["description"] lines = description.split("\n") start_index = lines.index(f"## Blender {version} ##") - lines = lines[start_index+1:] + lines = lines[start_index + 1:] for line in lines: if not line.strip(): continue @@ -125,7 +126,7 @@ def extract_release_notes(version: str, task_id: int): log_line.title = format_title(issue_task.title) yield log_line elif log_line.commit_id: - commits = phab.diffusion.commit.search(constraints={"identifiers":[log_line.commit_id]}) + commits = phab.diffusion.commit.search(constraints={"identifiers": [log_line.commit_id]}) commit = commits.data[0] commit_message = commit['fields']['message'] commit_title = commit_message.split("\n")[0] diff --git a/release/scripts/addons b/release/scripts/addons -Subproject baa581415c7ed23d7c45ef87363174813567268 +Subproject 787ea78f7fa6f0373d80ba1247768402df93f8a diff --git a/release/scripts/freestyle/modules/freestyle/functions.py b/release/scripts/freestyle/modules/freestyle/functions.py index e9fa53c8b7e..4a4a2f036e1 100644 --- a/release/scripts/freestyle/modules/freestyle/functions.py +++ b/release/scripts/freestyle/modules/freestyle/functions.py @@ -91,7 +91,7 @@ __all__ = ( "pyViewMapGradientNormF0D", "pyViewMapGradientNormF1D", "pyViewMapGradientVectorF0D", - ) +) # module members @@ -147,7 +147,7 @@ from _freestyle import ( VertexOrientation3DF0D, ZDiscontinuityF0D, ZDiscontinuityF1D, - ) +) # constructs for function definition in Python from freestyle.types import ( @@ -157,7 +157,7 @@ from freestyle.types import ( UnaryFunction0DMaterial, UnaryFunction0DVec2f, UnaryFunction1DDouble, - ) +) from freestyle.utils import ContextFunctions as CF from freestyle.utils import integrate @@ -176,6 +176,7 @@ class CurveMaterialF0D(UnaryFunction0DMaterial): Notes: expects instances of CurvePoint to be iterated over can return None if no fedge can be found """ + def __call__(self, inter): fe = inter.object.fedge if fe is None: @@ -203,6 +204,7 @@ class pyCurvilinearLengthF0D(UnaryFunction0DDouble): class pyDensityAnisotropyF0D(UnaryFunction0DDouble): """Estimates the anisotropy of density.""" + def __init__(self, level): UnaryFunction0DDouble.__init__(self) self.IsoDensity = ReadCompleteViewMapPixelF0D(level) @@ -233,6 +235,7 @@ class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f): :arg level: the level at which to compute the gradient :type level: int """ + def __init__(self, level): UnaryFunction0DVec2f.__init__(self) self._l = level @@ -241,9 +244,9 @@ class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f): def __call__(self, iter): p = iter.object.point_2d gx = CF.read_complete_view_map_pixel(self._l, int(p.x + self._step), int(p.y)) - \ - CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) + CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y + self._step)) - \ - CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) + CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) return Vector((gx, gy)) @@ -256,9 +259,9 @@ class pyViewMapGradientNormF0D(UnaryFunction0DDouble): def __call__(self, iter): p = iter.object.point_2d gx = CF.read_complete_view_map_pixel(self._l, int(p.x + self._step), int(p.y)) - \ - CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) + CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) gy = CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y + self._step)) - \ - CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) + CF.read_complete_view_map_pixel(self._l, int(p.x), int(p.y)) return Vector((gx, gy)).length # -- Functions for 1D elements (curves) -- # @@ -286,7 +289,10 @@ class pyDensityAnisotropyF1D(UnaryFunction1DDouble): self._sampling = sampling def __call__(self, inter): - v = integrate(self._func, inter.points_begin(self._sampling), inter.points_end(self._sampling), self._integration) + v = integrate( + self._func, inter.points_begin( + self._sampling), inter.points_end( + self._sampling), self._integration) return v @@ -298,5 +304,8 @@ class pyViewMapGradientNormF1D(UnaryFunction1DDouble): self._sampling = sampling def __call__(self, inter): - v = integrate(self._func, inter.points_begin(self._sampling), inter.points_end(self._sampling), self._integration) + v = integrate( + self._func, inter.points_begin( + self._sampling), inter.points_end( + self._sampling), self._integration) return v diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py index 494722bad39..d2b10206b9f 100644 --- a/release/scripts/freestyle/modules/freestyle/shaders.py +++ b/release/scripts/freestyle/modules/freestyle/shaders.py @@ -71,7 +71,7 @@ __all__ = ( "pyTimeColorShader", "pyTipRemoverShader", "pyZDependingThicknessShader", - ) +) # module members @@ -94,7 +94,7 @@ from _freestyle import ( StrokeTextureStepShader, ThicknessNoiseShader, TipRemoverShader, - ) +) # constructs for shader definition in Python from freestyle.types import ( @@ -105,7 +105,7 @@ from freestyle.types import ( StrokeShader, StrokeVertexIterator, StrokeVertex, - ) +) from freestyle.functions import ( Curvature2DAngleF0D, DensityF0D, @@ -114,18 +114,18 @@ from freestyle.functions import ( Normal2DF0D, Orientation2DF1D, ZDiscontinuityF0D, - ) +) from freestyle.predicates import ( pyVertexNatureUP0D, pyUEqualsUP0D, - ) +) from freestyle.utils import ( bound, BoundingBox, pairwise, phase_to_direction, - ) +) from freestyle.utils import ContextFunctions as CF @@ -145,6 +145,7 @@ class pyDepthDiscontinuityThicknessShader(StrokeShader): Assigns a thickness to the stroke based on the stroke's distance to the camera (Z-value). """ + def __init__(self, min, max): StrokeShader.__init__(self) self.a = max - min @@ -163,6 +164,7 @@ class pyConstantThicknessShader(StrokeShader): """ Assigns a constant thickness along the stroke. """ + def __init__(self, thickness): StrokeShader.__init__(self) self._thickness = thickness / 2.0 @@ -176,6 +178,7 @@ class pyFXSVaryingThicknessWithDensityShader(StrokeShader): """ Assigns thickness to a stroke based on the density of the diffuse map. """ + def __init__(self, wsize, threshold_min, threshold_max, thicknessMin, thicknessMax): StrokeShader.__init__(self) self._func = DensityF0D(wsize) @@ -200,6 +203,7 @@ class pyIncreasingThicknessShader(StrokeShader): """ Increasingly thickens the stroke. """ + def __init__(self, thicknessMin, thicknessMax): StrokeShader.__init__(self) self._thicknessMin = thicknessMin @@ -221,6 +225,7 @@ class pyConstrainedIncreasingThicknessShader(StrokeShader): Increasingly thickens the stroke, constrained by a ratio of the stroke's length. """ + def __init__(self, thicknessMin, thicknessMax, ratio): StrokeShader.__init__(self) self._thicknessMin = thicknessMin @@ -248,6 +253,7 @@ class pyDecreasingThicknessShader(StrokeShader): """ Inverse of pyIncreasingThicknessShader, decreasingly thickens the stroke. """ + def __init__(self, thicknessMin, thicknessMax): StrokeShader.__init__(self) self._thicknessMin = thicknessMin @@ -269,6 +275,7 @@ class pyNonLinearVaryingThicknessShader(StrokeShader): """ Assigns thickness to a stroke based on an exponential function. """ + def __init__(self, thicknessExtremity, thicknessMiddle, exponent): self._thicknessMin = thicknessMiddle self._thicknessMax = thicknessExtremity @@ -288,6 +295,7 @@ class pySLERPThicknessShader(StrokeShader): """ Assigns thickness to a stroke based on spherical linear interpolation. """ + def __init__(self, thicknessMin, thicknessMax, omega=1.2): StrokeShader.__init__(self) self._thicknessMin = thicknessMin @@ -302,9 +310,9 @@ class pySLERPThicknessShader(StrokeShader): for i, svert in enumerate(stroke): c = i / n if i < (n * 0.5): - t = sin((1-c) * omega) / sinhyp * self._thicknessMin + sin(c * omega) / sinhyp * maxT + t = sin((1 - c) * omega) / sinhyp * self._thicknessMin + sin(c * omega) / sinhyp * maxT else: - t = sin((1-c) * omega) / sinhyp * maxT + sin(c * omega) / sinhyp * self._thicknessMin + t = sin((1 - c) * omega) / sinhyp * maxT + sin(c * omega) / sinhyp * self._thicknessMin svert.attribute.thickness = (t / 2.0, t / 2.0) @@ -312,6 +320,7 @@ class pyTVertexThickenerShader(StrokeShader): """ Thickens TVertices (visual intersections between two edges). """ + def __init__(self, a=1.5, n=3): StrokeShader.__init__(self) self._a = a @@ -342,6 +351,7 @@ class pyImportance2DThicknessShader(StrokeShader): the thickness is inverted, so the vertices closest to the specified point have the lowest thickness. """ + def __init__(self, x, y, w, kmin, kmax): StrokeShader.__init__(self) self._origin = Vector((x, y)) @@ -352,16 +362,17 @@ class pyImportance2DThicknessShader(StrokeShader): for svert in stroke: d = (svert.point_2d - self._origin).length k = (self._kmin if (d > self._w) else - (self._kmax * (self._w-d) + self._kmin * d) / self._w) + (self._kmax * (self._w - d) + self._kmin * d) / self._w) (tr, tl) = svert.attribute.thickness - svert.attribute.thickness = (k*tr/2.0, k*tl/2.0) + svert.attribute.thickness = (k * tr / 2.0, k * tl / 2.0) class pyImportance3DThicknessShader(StrokeShader): """ Assigns thickness based on distance to a given point in 3D space. """ + def __init__(self, x, y, z, w, kmin, kmax): StrokeShader.__init__(self) self._origin = Vector((x, y, z)) @@ -372,10 +383,10 @@ class pyImportance3DThicknessShader(StrokeShader): for svert in stroke: d = (svert.point_3d - self._origin).length k = (self._kmin if (d > self._w) else - (self._kmax * (self._w-d) + self._kmin * d) / self._w) + (self._kmax * (self._w - d) + self._kmin * d) / self._w) (tr, tl) = svert.attribute.thickness - svert.attribute.thickness = (k*tr/2.0, k*tl/2.0) + svert.attribute.thickness = (k * tr / 2.0, k * tl / 2.0) class pyZDependingThicknessShader(StrokeShader): @@ -383,6 +394,7 @@ class pyZDependingThicknessShader(StrokeShader): Assigns thickness based on an object's local Z depth (point closest to camera is 1, point furthest from camera is zero). """ + def __init__(self, min, max): StrokeShader.__init__(self) self.__min = min @@ -408,10 +420,12 @@ class pyConstantColorShader(StrokeShader): """ Assigns a constant color to the stroke. """ - def __init__(self,r,g,b, a = 1): + + def __init__(self, r, g, b, a=1): StrokeShader.__init__(self) self._color = (r, g, b) self._a = a + def shade(self, stroke): for svert in stroke: svert.attribute.color = self._color @@ -422,10 +436,11 @@ class pyIncreasingColorShader(StrokeShader): """ Fades from one color to another along the stroke. """ - def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2): + + def __init__(self, r1, g1, b1, a1, r2, g2, b2, a2): StrokeShader.__init__(self) # use 4d vector to simplify math - self._c1 = Vector((r1, g1 ,b1, a1)) + self._c1 = Vector((r1, g1, b1, a1)) self._c2 = Vector((r2, g2, b2, a2)) def shade(self, stroke): @@ -442,10 +457,11 @@ class pyInterpolateColorShader(StrokeShader): """ Fades from one color to another and back. """ - def __init__(self,r1,g1,b1,a1, r2,g2,b2,a2): + + def __init__(self, r1, g1, b1, a1, r2, g2, b2, a2): StrokeShader.__init__(self) # use 4d vector to simplify math - self._c1 = Vector((r1, g1 ,b1, a1)) + self._c1 = Vector((r1, g1, b1, a1)) self._c2 = Vector((r2, g2, b2, a2)) def shade(self, stroke): @@ -461,10 +477,12 @@ class pyModulateAlphaShader(StrokeShader): """ Limits the stroke's alpha between a min and max value. """ + def __init__(self, min=0, max=1): StrokeShader.__init__(self) self.__min = min self.__max = max + def shade(self, stroke): for svert in stroke: alpha = svert.attribute.alpha @@ -476,6 +494,7 @@ class pyMaterialColorShader(StrokeShader): """ Assigns the color of the underlying material to the stroke. """ + def __init__(self, threshold=50): StrokeShader.__init__(self) self._threshold = threshold @@ -504,7 +523,7 @@ class pyMaterialColorShader(StrokeShader): u = 4.0 * X / (X + 15.0 * Y + 3.0 * Z) v = 9.0 * Y / (X + 15.0 * Y + 3.0 * Z) - L= 116. * pow((Y/Yn),(1./3.)) - 16 + L = 116. * pow((Y / Yn), (1. / 3.)) - 16 U = 13. * L * (u - un) V = 13. * L * (v - vn) @@ -512,16 +531,16 @@ class pyMaterialColorShader(StrokeShader): L /= 1.3 U += 10. else: - L = L + 2.5 * (100-L) * 0.2 + L = L + 2.5 * (100 - L) * 0.2 U /= 3.0 V /= 3.0 u = U / (13.0 * L) + un v = V / (13.0 * L) + vn - Y = Yn * pow(((L+16.)/116.), 3.) - X = -9. * Y * u / ((u - 4.)* v - u * v) - Z = (9. * Y - 15*v*Y - v*X) /( 3. * v) + Y = Yn * pow(((L + 16.) / 116.), 3.) + X = -9. * Y * u / ((u - 4.) * v - u * v) + Z = (9. * Y - 15 * v * Y - v * X) / (3. * v) r = 3.240479 * X - 1.53715 * Y - 0.498535 * Z g = -0.969256 * X + 1.875991 * Y + 0.041556 * Z @@ -538,6 +557,7 @@ class pyRandomColorShader(StrokeShader): """ Assigns a color to the stroke based on given seed. """ + def __init__(self, s=1): StrokeShader.__init__(self) random.seed = s @@ -555,6 +575,7 @@ class py2DCurvatureColorShader(StrokeShader): Assigns a color (grayscale) to the stroke based on the curvature. A higher curvature will yield a brighter color. """ + def shade(self, stroke): func = Curvature2DAngleF0D() it = Interface0DIterator(stroke) @@ -571,9 +592,11 @@ class pyTimeColorShader(StrokeShader): Assigns a grayscale value that increases for every vertex. The brightness will increase along the stroke. """ + def __init__(self, step=0.01): StrokeShader.__init__(self) self._step = step + def shade(self, stroke): for i, svert in enumerate(stroke): c = i * self._step @@ -588,6 +611,7 @@ class pySamplingShader(StrokeShader): Resamples the stroke, which gives the stroke the amount of vertices specified. """ + def __init__(self, sampling): StrokeShader.__init__(self) self._sampling = sampling @@ -601,6 +625,7 @@ class pyBackboneStretcherShader(StrokeShader): """ Stretches the stroke's backbone by a given length (in pixels). """ + def __init__(self, l): StrokeShader.__init__(self) self._l = l @@ -610,7 +635,7 @@ class pyBackboneStretcherShader(StrokeShader): v0, vn = stroke[0], stroke[-1] p0, pn = v0.point, vn.point # get the direction - d1 = (p0 - stroke[ 1].point).normalized() + d1 = (p0 - stroke[1].point).normalized() dn = (pn - stroke[-2].point).normalized() v0.point += d1 * self._l vn.point += dn * self._l @@ -623,15 +648,17 @@ class pyLengthDependingBackboneStretcherShader(StrokeShader): NOTE: you'll probably want an l somewhere between (0.5 - 0). A value that is too high may yield unexpected results. """ + def __init__(self, l): StrokeShader.__init__(self) self._l = l + def shade(self, stroke): # get start and end points v0, vn = stroke[0], stroke[-1] p0, pn = v0.point, vn.point # get the direction - d1 = (p0 - stroke[ 1].point).normalized() + d1 = (p0 - stroke[1].point).normalized() dn = (pn - stroke[-2].point).normalized() v0.point += d1 * self._l * stroke.length_2d vn.point += dn * self._l * stroke.length_2d @@ -662,6 +689,7 @@ class pyBackboneStretcherNoCuspShader(StrokeShader): """ Stretches the stroke's backbone, excluding cusp vertices (end junctions). """ + def __init__(self, l): StrokeShader.__init__(self) self._l = l @@ -689,6 +717,7 @@ class pyDiffusion2Shader(StrokeShader): point. The offset is scaled by the 2D curvature (i.e. how quickly the stroke curve is) at the point. """ + def __init__(self, lambda1, nbIter): StrokeShader.__init__(self) self._lambda = lambda1 @@ -697,7 +726,7 @@ class pyDiffusion2Shader(StrokeShader): self._curvatureInfo = Curvature2DAngleF0D() def shade(self, stroke): - for i in range (1, self._nbIter): + for i in range(1, self._nbIter): it = Interface0DIterator(stroke) for svert in it: svert.point += self._normalInfo(it) * self._lambda * self._curvatureInfo(it) @@ -708,6 +737,7 @@ class pyTipRemoverShader(StrokeShader): """ Removes the tips of the stroke. """ + def __init__(self, l): StrokeShader.__init__(self) self._l = l @@ -716,7 +746,7 @@ class pyTipRemoverShader(StrokeShader): def check_vertex(v, length): # Returns True if the given strokevertex is less than self._l away # from the stroke's tip and therefore should be removed. - return (v.curvilinear_abscissa < length or v.stroke_length-v.curvilinear_abscissa < length) + return (v.curvilinear_abscissa < length or v.stroke_length - v.curvilinear_abscissa < length) def shade(self, stroke): n = len(stroke) @@ -747,6 +777,7 @@ class pyTVertexRemoverShader(StrokeShader): """ Removes t-vertices from the stroke. """ + def shade(self, stroke): if len(stroke) < 4: return @@ -764,6 +795,7 @@ class pyHLRShader(StrokeShader): Controls visibility based upon the quantitative invisibility (QI) based on hidden line removal (HLR). """ + def shade(self, stroke): if len(stroke) < 4: return @@ -779,6 +811,7 @@ class pySinusDisplacementShader(StrokeShader): """ Displaces the stroke in the shape of a sine wave. """ + def __init__(self, f, a): StrokeShader.__init__(self) self._f = f @@ -801,6 +834,7 @@ class pyPerlinNoise1DShader(StrokeShader): that lines with the same length and sampling interval will be identically distorded. """ + def __init__(self, freq=10, amp=10, oct=4, seed=-1): StrokeShader.__init__(self) self.__noise = Noise(seed) @@ -824,6 +858,7 @@ class pyPerlinNoise2DShader(StrokeShader): More information on the noise shaders can be found at: freestyleintegration.wordpress.com/2011/09/25/development-updates-on-september-25/ """ + def __init__(self, freq=10, amp=10, oct=4, seed=-1): StrokeShader.__init__(self) self.__noise = Noise(seed) @@ -842,6 +877,7 @@ class pyBluePrintCirclesShader(StrokeShader): """ Draws the silhouette of the object as a circle. """ + def __init__(self, turns=1, random_radius=3, random_center=5): StrokeShader.__init__(self) self.__turns = turns @@ -939,7 +975,7 @@ class pyBluePrintEllipsesShader(StrokeShader): class pyBluePrintSquaresShader(StrokeShader): def __init__(self, turns=1, bb_len=10, bb_rand=0): StrokeShader.__init__(self) - self.__turns = turns # does not have any effect atm + self.__turns = turns # does not have any effect atm self.__bb_len = bb_len self.__bb_rand = bb_rand @@ -968,7 +1004,7 @@ class pyBluePrintSquaresShader(StrokeShader): Vector((p_min.x - bb_len, p_max.y)), Vector((p_min.x, p_max.y + bb_len)), Vector((p_min.x, p_min.y - bb_len)), - ) + ) # add randomization to the points (if needed) if self.__bb_rand: @@ -983,12 +1019,11 @@ class pyBluePrintSquaresShader(StrokeShader): Vector((randint(-R, R), randint(-r, r))), Vector((randint(-r, r), randint(-R, R))), Vector((randint(-r, r), randint(-R, R))), - ) + ) # combine both tuples points = tuple(p + rand for (p, rand) in zip(points, randomization_mat)) - # subtract even from uneven; result is length four tuple of vectors it = iter(points) old_vecs = tuple(next(it) - current for current in it) @@ -1026,6 +1061,7 @@ class pyBluePrintDirectedSquaresShader(StrokeShader): """ Replaces the stroke with a directed square. """ + def __init__(self, turns=1, bb_len=10, mult=1): StrokeShader.__init__(self) self.__mult = mult @@ -1055,12 +1091,15 @@ class pyBluePrintDirectedSquaresShader(StrokeShader): lambda1, lambda2 = max(1e-12, lambda1), max(1e-12, lambda2) theta = atan(2 * p_var_xy / (p_var.x - p_var.y)) / 2 + # Keep alignment for readability. + # autopep8: off if p_var.y > p_var.x: e1 = Vector((cos(theta + pi / 2), sin(theta + pi / 2))) * sqrt(lambda1) * self.__mult e2 = Vector((cos(theta + pi ), sin(theta + pi ))) * sqrt(lambda2) * self.__mult else: e1 = Vector((cos(theta), sin(theta))) * sqrt(lambda1) * self.__mult e2 = Vector((cos(theta + pi / 2), sin(theta + pi / 2))) * sqrt(lambda2) * self.__mult + # autopep8: on # partition the stroke num_segments = len(stroke) // self.__turns @@ -1075,14 +1114,14 @@ class pyBluePrintDirectedSquaresShader(StrokeShader): p_mean - e1 * bb_len1 + e2, p_mean + e1 + e2 * bb_len2, p_mean + e1 * bb_len1 - e2, - ) + ) old_vecs = ( e2 * bb_len2 * 2, e1 * bb_len1 * 2, - -e2 * bb_len2 * 2, - -e1 * bb_len1 * 2, - ) + -e2 * bb_len2 * 2, + -e1 * bb_len1 * 2, + ) it = iter(stroke) verticesToRemove = list() diff --git a/release/scripts/freestyle/styles/backbone_stretcher.py b/release/scripts/freestyle/styles/backbone_stretcher.py index 0dd87001f1c..534dc8c8d79 100644 --- a/release/scripts/freestyle/styles/backbone_stretcher.py +++ b/release/scripts/freestyle/styles/backbone_stretcher.py @@ -10,11 +10,11 @@ from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, - ) +) from freestyle.shaders import ( BackboneStretcherShader, ConstantColorShader, - ) +) from freestyle.types import Operators @@ -23,5 +23,5 @@ Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInv shaders_list = [ ConstantColorShader(0.5, 0.5, 0.5), BackboneStretcherShader(20), - ] +] Operators.create(TrueUP1D(), shaders_list) diff --git a/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py b/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py index 4f1e9cc932e..9ed786c6549 100644 --- a/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py +++ b/release/scripts/freestyle/styles/split_at_highest_2d_curvatures.py @@ -14,11 +14,11 @@ from freestyle.predicates import ( TrueUP1D, pyHigherLengthUP1D, pyParameterUP0D, - ) +) from freestyle.shaders import ( ConstantThicknessShader, IncreasingColorShader, - ) +) from freestyle.types import Operators @@ -29,5 +29,5 @@ Operators.recursive_split(func, pyParameterUP0D(0.4, 0.6), NotUP1D(pyHigherLengt shaders_list = [ ConstantThicknessShader(10), IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1), - ] +] Operators.create(TrueUP1D(), shaders_list) diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index ef481a3eb19..58e7486b39b 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -192,6 +192,8 @@ PYGETTEXT_CONTEXTS_DEFSRC = os.path.join("source", "blender", "blentranslation", # XXX Not full-proof, but should be enough here! PYGETTEXT_CONTEXTS = "#define\\s+(BLT_I18NCONTEXT_[A-Z_0-9]+)\\s+\"([^\"]*)\"" +# autopep8: off + # Keywords' regex. # XXX Most unfortunately, we can't use named backreferences inside character sets, # which makes the regexes even more twisty... :/ @@ -251,11 +253,22 @@ PYGETTEXT_KEYWORDS = (() + tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it) for it in ("BKE_modifier_set_error",)) + + # bUnitDef unit names. + # NOTE: regex is a bit more complex than it would need too. Since the actual + # identifier (`B_UNIT_DEF_`) is at the end, if it's simpler/too general it + # becomes extremely slow to process some (unrelated) source files. + ((r"\{(?:(?:\s*\"[^\"',]+\"\s*,)|(?:\s*NULL\s*,)){4}\s*" + + _msg_re + r"\s*,(?:(?:\s*\"[^\"',]+\"\s*,)|(?:\s*NULL\s*,))(?:[^,]+,){2}" + + "\s*B_UNIT_DEF_[_A-Z]+\s*\}"),) + + tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" + r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it) for it in ("BLT_I18N_MSGID_MULTI_CTXT",)) ) +# autopep8: on + + # Check printf mismatches between msgid and msgstr. CHECK_PRINTF_FORMAT = ( r"(?!<%)(?:%%)*%" # Beginning, with handling for crazy things like '%%%%%s' @@ -286,6 +299,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "ascii", "author", # Addons' field. :/ "bItasc", + "color_index is invalid", "cos(A)", "cosh(A)", "dbl-", # Compacted for 'double', for keymap items. @@ -342,6 +356,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { # Sub-strings. "all", "all and invert unselected", + "and AMD driver version 22.10 or newer", "and AMD Radeon Pro 21.Q4 driver or newer", "and NVIDIA driver version 470 or newer", "available with", @@ -376,11 +391,14 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "normal", "or AMD with macOS 12.3 or newer", "performance impact!", + "read", + "remove", "right", "selected", "selected and lock unselected", "selected and unlock unselected", "the lazy dog", + "this legacy pose library to pose assets", "to the top level of the tree", "unable to load movie clip", "unable to load text", @@ -397,8 +415,8 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "verts only", "view", "virtual parents", - "and NVIDIA driver version 470 or newer", - "and AMD driver version ??? or newer", + "which was replaced by the Asset Browser", + "write", } WARN_MSGID_NOT_CAPITALIZED_ALLOWED |= set(lng[2] for lng in LANGUAGES) @@ -605,7 +623,10 @@ class I18nSettings: def to_json(self): # Only save the diff from default i18n_settings! glob = globals() - export_dict = {uid: val for uid, val in self.__dict__.items() if _check_valid_data(uid, val) and glob.get(uid) != val} + export_dict = { + uid: val for uid, val in self.__dict__.items() + if _check_valid_data(uid, val) and glob.get(uid) != val + } return json.dumps(export_dict) def load(self, fname, reset=False): diff --git a/release/scripts/modules/bl_i18n_utils/utils_cli.py b/release/scripts/modules/bl_i18n_utils/utils_cli.py index 7bab21ec05f..37fb1aa4dea 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_cli.py +++ b/release/scripts/modules/bl_i18n_utils/utils_cli.py @@ -61,7 +61,7 @@ def language_menu(args, settings): po_to_uid = {os.path.basename(po_path_branch): uid for can_use, uid, _num_id, _name, _isocode, po_path_branch - in utils_i18n.list_po_dir(settings.BRANCHES_DIR, settings) + in utils_i18n.list_po_dir(settings.BRANCHES_DIR, settings) if can_use} for po_dir in os.listdir(settings.BRANCHES_DIR): po_dir = os.path.join(settings.BRANCHES_DIR, po_dir) diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index c0e065bf050..31b9705e45c 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -136,6 +136,7 @@ class SpellChecker: "inscatter", "inscattering", "libdata", "lightcache", + "lightgroup", "lightgroups", "lightprobe", "lightprobes", "lightless", "lineset", @@ -394,9 +395,11 @@ class SpellChecker: "bitangent", "boid", "boids", "ceil", + "centum", # From 'centum weight' "compressibility", "coplanar", "curvilinear", + "dekameter", "dekameters", "equiangular", "equisolid", "euler", "eulers", @@ -414,8 +417,11 @@ class SpellChecker: "lambertian", "laplacian", "metadata", + "microwatt", "microwatts", + "milliwatt", "milliwatts", "msgfmt", "nand", "xnor", + "nanowatt", "nanowatts", "normals", "numpad", "octahedral", @@ -662,6 +668,7 @@ class SpellChecker: # Acronyms "aa", "msaa", + "acescg", # ACEScg color space. "ao", "aov", "aovs", "api", diff --git a/release/scripts/modules/bl_previews_utils/bl_previews_render.py b/release/scripts/modules/bl_previews_utils/bl_previews_render.py index 0153cf45ad8..bf2b9fe1a76 100644 --- a/release/scripts/modules/bl_previews_utils/bl_previews_render.py +++ b/release/scripts/modules/bl_previews_utils/bl_previews_render.py @@ -80,7 +80,7 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): backup_camera, backup_camera_data = [None] * 2 camera_data = bpy.data.cameras.new("TEMP_preview_render_camera") camera = bpy.data.objects.new("TEMP_preview_render_camera", camera_data) - camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0.0, 45.0) + camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0, 45) scene.camera = camera scene.collection.objects.link(camera) # TODO: add light if none found in scene? @@ -100,11 +100,11 @@ def do_previews(do_objects, do_collections, do_scenes, do_data_intern): scene.world = world - camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0.0, 45.0) + camera.rotation_euler = Euler((1.1635528802871704, 0.0, 0.7853981852531433), 'XYZ') # (66.67, 0, 45) scene.camera = camera scene.collection.objects.link(camera) - light.rotation_euler = Euler((0.7853981852531433, 0.0, 1.7453292608261108), 'XYZ') # (45.0, 0.0, 100.0) + light.rotation_euler = Euler((0.7853981852531433, 0.0, 1.7453292608261108), 'XYZ') # (45, 0, 100) light_data.falloff_type = 'CONSTANT' light_data.spot_size = 1.0471975803375244 # 60 scene.collection.objects.link(light) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 6d0ff66d478..9896bd3e281 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Do not edit this file. This file is auto generated from rna_manual_reference_updater.py +# autopep8: off import bpy manual_version = '%d.%d' % bpy.app.version[:2] @@ -37,2842 +38,2844 @@ if LANG is not None: url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG) url_manual_mapping = ( - ("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"), - ("bpy.types.spacesequesequencertimelineoverlaynceeditor.show_strip_offset*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequesequencertimelineoverlaynceeditor-show-strip-offset"), - ("bpy.types.movietrackingsettings.refine_intrinsics_radial_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-radial-distortion"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_max_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-trappedair"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_min_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-trappedair"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_max_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-wavecrest"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), - ("bpy.types.lineartgpencilmodifier.use_offset_towards_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-offset-towards-custom-camera"), - ("bpy.types.movietrackingsettings.refine_intrinsics_principal_point*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-principal-point"), - ("bpy.types.cyclesobjectsettings.shadow_terminator_geometry_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-geometry-offset"), - ("bpy.types.sequencertoolsettings.use_snap_current_frame_to_strips*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-use-snap-current-frame-to-strips"), - ("bpy.types.cycleslightsettings.use_multiple_importance_sampling*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-use-multiple-importance-sampling"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), - ("bpy.types.lineartgpencilmodifier.use_overlap_edge_type_support*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-overlap-edge-type-support"), - ("bpy.types.movietrackingsettings.refine_intrinsics_focal_length*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-focal-length"), - ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), - ("bpy.types.cyclesrendersettings.preview_denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-input-passes"), - ("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"), - ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), - ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), - ("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"), - ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), - ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), - ("bpy.types.cyclesrendersettings.adaptive_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-scrambling-distance"), - ("bpy.types.cyclesrendersettings.preview_adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-min-samples"), - ("bpy.types.lineartgpencilmodifier.use_face_mark_keep_contour*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-keep-contour"), - ("bpy.types.rendersettings.use_sequencer_override_scene_strip*", "editors/video_sequencer/preview/sidebar.html#bpy-types-rendersettings-use-sequencer-override-scene-strip"), - ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), - ("bpy.types.cyclesrendersettings.preview_denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-prefilter"), - ("bpy.types.cyclesrendersettings.preview_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-scrambling-distance"), - ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), - ("bpy.types.brushgpencilsettings.use_stroke_random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-strength"), - ("bpy.types.cyclesrendersettings.film_transparent_roughness*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-roughness"), - ("bpy.types.cyclesrendersettings.preview_adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-threshold"), - ("bpy.types.fluiddomainsettings.openvdb_cache_compress_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-cache-compress-type"), - ("bpy.types.fluiddomainsettings.sndparticle_bubble_buoyancy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-buoyancy"), - ("bpy.types.fluiddomainsettings.sndparticle_combined_export*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-combined-export"), - ("bpy.types.fluiddomainsettings.use_collision_border_bottom*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-bottom"), - ("bpy.types.fluiddomainsettings.vector_scale_with_magnitude*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale-with-magnitude"), - ("bpy.types.lineartgpencilmodifier.use_face_mark_boundaries*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-boundaries"), - ("bpy.types.movietrackingstabilization.use_2d_stabilization*", "movie_clip/tracking/clip/sidebar/stabilization/panel.html#bpy-types-movietrackingstabilization-use-2d-stabilization"), - ("bpy.types.spacespreadsheet.display_context_path_collapsed*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-display-context-path-collapsed"), - ("bpy.types.toolsettings.annotation_stroke_placement_view2d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view2d"), - ("bpy.types.toolsettings.annotation_stroke_placement_view3d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view3d"), - ("bpy.types.brushgpencilsettings.use_random_press_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-strength"), - ("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.sequencertimelineoverlay.waveform_display_type*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-waveform-display-type"), - ("bpy.types.view3doverlay.use_normals_constant_screen_size*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-use-normals-constant-screen-size"), - ("bpy.types.brushgpencilsettings.random_saturation_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-saturation-factor"), - ("bpy.types.brushgpencilsettings.use_settings_postprocess*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-postprocess"), - ("bpy.types.brushgpencilsettings.use_stroke_random_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-radius"), - ("bpy.types.cyclesmaterialsettings.use_transparent_shadow*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-use-transparent-shadow"), - ("bpy.types.cyclesobjectsettings.shadow_terminator_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-offset"), - ("bpy.types.cyclesobjectsettings.use_adaptive_subdivision*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-use-adaptive-subdivision"), - ("bpy.types.cyclesrendersettings.debug_use_spatial_splits*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-spatial-splits"), - ("bpy.types.cyclesrendersettings.light_sampling_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-light-sampling-threshold"), - ("bpy.types.cyclesrendersettings.rolling_shutter_duration*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-rolling-shutter-duration"), - ("bpy.types.cyclesrendersettings.volume_preview_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-preview-step-rate"), - ("bpy.types.fluiddomainsettings.sndparticle_update_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-update-radius"), - ("bpy.types.fluiddomainsettings.use_collision_border_back*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-back"), - ("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.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"), - ("bpy.types.brushgpencilsettings.use_random_press_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-radius"), - ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), - ("bpy.types.colormanagedsequencercolorspacesettings.name*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings-name"), - ("bpy.types.cyclesrendersettings.max_transparent_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-transparent-bounces"), - ("bpy.types.cyclesrendersettings.min_transparent_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-transparent-bounces"), - ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), - ("bpy.types.gpencilsculptsettings.intersection_threshold*", "grease_pencil/modes/draw/tools/cutter.html#bpy-types-gpencilsculptsettings-intersection-threshold"), - ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), - ("bpy.types.lineartgpencilmodifier.use_back_face_culling*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-back-face-culling"), - ("bpy.types.lineartgpencilmodifier.use_intersection_mask*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-mask"), - ("bpy.types.lineartgpencilmodifier.use_invert_collection*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-invert-collection"), - ("bpy.types.movietrackingsettings.use_keyframe_selection*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-keyframe-selection"), - ("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"), - ("bpy.types.sequencertimelineoverlay.show_strip_duration*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-duration"), - ("bpy.types.spaceoutliner.use_filter_lib_override_system*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override-system"), - ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"), - ("bpy.types.animvizmotionpaths.show_keyframe_action_all*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-action-all"), - ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), - ("bpy.types.brushgpencilsettings.eraser_strength_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-strength-factor"), - ("bpy.types.cyclesmaterialsettings.volume_interpolation*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-interpolation"), - ("bpy.types.cyclesrendersettings.denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-input-passes"), - ("bpy.types.cyclesrendersettings.film_transparent_glass*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-glass"), - ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), - ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), - ("bpy.types.lineartgpencilmodifier.use_crease_on_smooth*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-smooth"), - ("bpy.types.lineartgpencilmodifier.use_face_mark_invert*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-invert"), - ("bpy.types.linestylegeometrymodifier_backbonestretcher*", "render/freestyle/view_layer/line_style/modifiers/geometry/backbone_stretcher.html#bpy-types-linestylegeometrymodifier-backbonestretcher"), - ("bpy.types.linestylegeometrymodifier_sinusdisplacement*", "render/freestyle/view_layer/line_style/modifiers/geometry/sinus_displacement.html#bpy-types-linestylegeometrymodifier-sinusdisplacement"), - ("bpy.types.sequencertoolsettings.snap_to_current_frame*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-current-frame"), - ("bpy.ops.object.geometry_nodes_input_attribute_toggle*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-input-attribute-toggle"), - ("bpy.types.animvizmotionpaths.show_keyframe_highlight*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-highlight"), - ("bpy.types.brushgpencilsettings.pen_subdivision_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-subdivision-steps"), - ("bpy.types.brushgpencilsettings.use_strength_pressure*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-strength-pressure"), - ("bpy.types.brushgpencilsettings.use_stroke_random_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-hue"), - ("bpy.types.brushgpencilsettings.use_stroke_random_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-sat"), - ("bpy.types.brushgpencilsettings.use_stroke_random_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-val"), - ("bpy.types.colormanageddisplaysettings.display_device*", "render/color_management.html#bpy-types-colormanageddisplaysettings-display-device"), - ("bpy.types.colormanagedviewsettings.use_curve_mapping*", "render/color_management.html#bpy-types-colormanagedviewsettings-use-curve-mapping"), - ("bpy.types.cyclesrendersettings.sample_clamp_indirect*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-indirect"), - ("bpy.types.cyclesrendersettings.use_adaptive_sampling*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-adaptive-sampling"), - ("bpy.types.cyclesrendersettings.use_preview_denoising*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-preview-denoising"), - ("bpy.types.fluiddomainsettings.color_ramp_field_scale*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field-scale"), - ("bpy.types.fluiddomainsettings.use_adaptive_timesteps*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-adaptive-timesteps"), - ("bpy.types.fluiddomainsettings.use_dissolve_smoke_log*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke-log"), - ("bpy.types.freestylelineset.select_suggestive_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-suggestive-contour"), - ("bpy.types.gpencillayer.annotation_onion_before_color*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-before-color"), - ("bpy.types.gpencillayer.annotation_onion_before_range*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-before-range"), - ("bpy.types.gpencillayer.use_annotation_onion_skinning*", "interface/annotate_tool.html#bpy-types-gpencillayer-use-annotation-onion-skinning"), - ("bpy.types.greasepencil.use_adaptive_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-adaptive-curve-resolution"), - ("bpy.types.lineartgpencilmodifier.stroke_depth_offset*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-stroke-depth-offset"), - ("bpy.types.lineartgpencilmodifier.use_crease_on_sharp*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-sharp"), - ("bpy.types.linestylegeometrymodifier_polygonalization*", "render/freestyle/view_layer/line_style/modifiers/geometry/polygonization.html#bpy-types-linestylegeometrymodifier-polygonalization"), - ("bpy.types.sequencertimelineoverlay.show_strip_source*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-source"), - ("bpy.types.toolsettings.use_gpencil_automerge_strokes*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-automerge-strokes"), - ("bpy.types.toolsettings.use_proportional_edit_objects*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit-objects"), - ("bpy.ops.view3d.edit_mesh_extrude_move_shrink_fatten*", "modeling/meshes/editing/face/extrude_faces_normal.html#bpy-ops-view3d-edit-mesh-extrude-move-shrink-fatten"), - ("bpy.types.brushgpencilsettings.active_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-active-smooth-factor"), - ("bpy.types.brushgpencilsettings.extend_stroke_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-extend-stroke-factor"), - ("bpy.types.brushgpencilsettings.use_random_press_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-hue"), - ("bpy.types.brushgpencilsettings.use_random_press_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-sat"), - ("bpy.types.brushgpencilsettings.use_random_press_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-val"), - ("bpy.types.brushgpencilsettings.use_stroke_random_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-uv"), - ("bpy.types.cyclesmaterialsettings.homogeneous_volume*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-homogeneous-volume"), - ("bpy.types.cyclesobjectsettings.is_caustics_receiver*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-receiver"), - ("bpy.types.cyclesrendersettings.adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-min-samples"), - ("bpy.types.cyclesrendersettings.debug_bvh_time_steps*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-bvh-time-steps"), - ("bpy.types.cyclesrendersettings.distance_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-distance-cull-margin"), - ("bpy.types.cyclesrendersettings.motion_blur_position*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-motion-blur-position"), - ("bpy.types.cyclesrendersettings.rolling_shutter_type*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-rolling-shutter-type"), - ("bpy.types.cyclesrendersettings.transmission_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-transmission-bounces"), - ("bpy.types.cyclesworldsettings.sample_map_resolution*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sample-map-resolution"), - ("bpy.types.fluiddomainsettings.display_interpolation*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-interpolation"), - ("bpy.types.fluiddomainsettings.gridlines_cell_filter*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-cell-filter"), - ("bpy.types.fluiddomainsettings.gridlines_color_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-color-field"), - ("bpy.types.fluiddomainsettings.gridlines_lower_bound*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-lower-bound"), - ("bpy.types.fluiddomainsettings.gridlines_range_color*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-range-color"), - ("bpy.types.fluiddomainsettings.gridlines_upper_bound*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-upper-bound"), - ("bpy.types.freestylelineset.select_material_boundary*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-material-boundary"), - ("bpy.types.gpencillayer.annotation_onion_after_color*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-after-color"), - ("bpy.types.gpencillayer.annotation_onion_after_range*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-after-range"), - ("bpy.types.materialgpencilstyle.use_fill_texture_mix*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-texture-mix"), - ("bpy.types.rendersettings_simplify_gpencil_shader_fx*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-shader-fx"), - ("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"), - ("bpy.types.sequencertoolsettings.snap_to_hold_offset*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-hold-offset"), - ("bpy.types.toolsettings.use_mesh_automerge_and_split*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge-and-split"), - ("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"), - ("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"), - ("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"), - ("bpy.types.brushgpencilsettings.fill_simplify_level*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-simplify-level"), - ("bpy.types.brushgpencilsettings.random_value_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-value-factor"), - ("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-jitter-pressure"), - ("bpy.types.brushgpencilsettings.use_random_press_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-uv"), - ("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-random"), - ("bpy.types.collection.lineart_use_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-use-intersection-mask"), - ("bpy.types.colormanagedinputcolorspacesettings.name*", "editors/image/image_settings.html#bpy-types-colormanagedinputcolorspacesettings-name"), - ("bpy.types.cyclesrendersettings.denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-prefilter"), - ("bpy.types.cyclesrendersettings.preview_dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-preview-dicing-rate"), - ("bpy.types.cyclesrendersettings.sample_clamp_direct*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-direct"), - ("bpy.types.cyclesrendersettings.scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-scrambling-distance"), - ("bpy.types.cyclesworldsettings.volume_interpolation*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-interpolation"), - ("bpy.types.fluiddomainsettings.mesh_particle_radius*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-particle-radius"), - ("bpy.types.fluiddomainsettings.sndparticle_boundary*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-boundary"), - ("bpy.types.fluiddomainsettings.sndparticle_life_max*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-max"), - ("bpy.types.fluiddomainsettings.sndparticle_life_min*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-min"), - ("bpy.types.fluiddomainsettings.sys_particle_maximum*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-sys-particle-maximum"), - ("bpy.types.fluiddomainsettings.use_bubble_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-bubble-particles"), - ("bpy.types.freestylelineset.select_external_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-external-contour"), - ("bpy.types.lineartgpencilmodifier.use_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-custom-camera"), - ("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.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"), - ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), - ("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"), - ("bpy.ops.mesh.customdata_custom_splitnormals_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-clear"), - ("bpy.types.bakesettings.use_pass_ambient_occlusion*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-ambient-occlusion"), - ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), - ("bpy.types.brush.use_cloth_pin_simulation_boundary*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-pin-simulation-boundary"), - ("bpy.types.brushgpencilsettings.show_fill_boundary*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-boundary"), - ("bpy.types.brushgpencilsettings.use_default_eraser*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-default-eraser"), - ("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.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"), - ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), - ("bpy.types.cyclesrendersettings.debug_use_hair_bvh*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-hair-bvh"), - ("bpy.types.fileassetselectparams.asset_library_ref*", "editors/asset_browser.html#bpy-types-fileassetselectparams-asset-library-ref"), - ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), - ("bpy.types.fluiddomainsettings.fractions_threshold*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-threshold"), - ("bpy.types.fluiddomainsettings.particle_band_width*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-band-width"), - ("bpy.types.fluiddomainsettings.particle_randomness*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-randomness"), - ("bpy.types.fluiddomainsettings.use_adaptive_domain*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-use-adaptive-domain"), - ("bpy.types.fluiddomainsettings.use_resumable_cache*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-use-resumable-cache"), - ("bpy.types.fluiddomainsettings.use_spray_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-spray-particles"), - ("bpy.types.fluiddomainsettings.vector_display_type*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-display-type"), - ("bpy.types.freestylelineset.select_by_image_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-image-border"), - ("bpy.types.freestylesettings.kr_derivative_epsilon*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-kr-derivative-epsilon"), - ("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve_primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"), - ("bpy.types.geometrynodecurveprimitivequadrilateral*", "modeling/geometry_nodes/curve_primitives/quadrilateral.html#bpy-types-geometrynodecurveprimitivequadrilateral"), - ("bpy.types.lineartgpencilmodifier.smooth_tolerance*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-smooth-tolerance"), - ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), - ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), - ("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-stroke-holdout"), - ("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"), - ("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.sequencerpreviewoverlay.show_annotation*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-annotation"), - ("bpy.types.sequencerpreviewoverlay.show_safe_areas*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-safe-areas"), - ("bpy.types.sequencertoolsettings.snap_ignore_muted*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-ignore-muted"), - ("bpy.types.sequencertoolsettings.snap_ignore_sound*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-ignore-sound"), - ("bpy.types.spaceoutliner.use_filter_case_sensitive*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-case-sensitive"), - ("bpy.types.spaceoutliner.use_filter_object_content*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-content"), - ("bpy.types.spacesequenceeditor.show_gizmo_navigate*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-navigate"), - ("bpy.types.toolsettings.use_proportional_connected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-connected"), - ("bpy.types.toolsettings.use_proportional_projected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-projected"), - ("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"), - ("bpy.types.viewlayer.use_pass_cryptomatte_material*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-material"), - ("bpy.ops.gpencil.vertex_color_brightness_contrast*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-brightness-contrast"), - ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), - ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), - ("bpy.types.brushgpencilsettings.pen_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-factor"), - ("bpy.types.brushgpencilsettings.random_hue_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-hue-factor"), - ("bpy.types.cyclescurverendersettings.subdivisions*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-subdivisions"), - ("bpy.types.cyclesmaterialsettings.sample_as_light*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-sample-as-light"), - ("bpy.types.cyclesmaterialsettings.volume_sampling*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-sampling"), - ("bpy.types.cyclesobjectsettings.use_deform_motion*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-deform-motion"), - ("bpy.types.cyclesobjectsettings.use_distance_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-distance-cull"), - ("bpy.types.cyclesrendersettings.ao_bounces_render*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-ao-bounces-render"), - ("bpy.types.cyclesrendersettings.min_light_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-light-bounces"), - ("bpy.types.cyclesrendersettings.pixel_filter_type*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-pixel-filter-type"), - ("bpy.types.cyclesrendersettings.use_animated_seed*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-animated-seed"), - ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), - ("bpy.types.cyclesrendersettings.use_layer_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-layer-samples"), - ("bpy.types.cyclesworldsettings.homogeneous_volume*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-homogeneous-volume"), - ("bpy.types.fluiddomainsettings.cache_frame_offset*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-offset"), - ("bpy.types.fluiddomainsettings.delete_in_obstacle*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-delete-in-obstacle"), - ("bpy.types.fluiddomainsettings.fractions_distance*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-distance"), - ("bpy.types.fluiddomainsettings.mesh_concave_lower*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-lower"), - ("bpy.types.fluiddomainsettings.mesh_concave_upper*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-upper"), - ("bpy.types.fluiddomainsettings.openvdb_data_depth*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-data-depth"), - ("bpy.types.fluiddomainsettings.use_dissolve_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke"), - ("bpy.types.fluiddomainsettings.use_flip_particles*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-flip-particles"), - ("bpy.types.fluiddomainsettings.use_foam_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-foam-particles"), - ("bpy.types.fluiddomainsettings.viscosity_exponent*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-exponent"), - ("bpy.types.fluideffectorsettings.surface_distance*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-surface-distance"), - ("bpy.types.fluidflowsettings.density_vertex_group*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density-vertex-group"), - ("bpy.types.fluidflowsettings.use_initial_velocity*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-initial-velocity"), - ("bpy.types.linestylegeometrymodifier_guidinglines*", "render/freestyle/view_layer/line_style/modifiers/geometry/guiding_lines.html#bpy-types-linestylegeometrymodifier-guidinglines"), - ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/view_layer/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), - ("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.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.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"), - ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), - ("bpy.types.spaceoutliner.use_filter_object_camera*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-camera"), - ("bpy.types.spaceoutliner.use_filter_object_others*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-others"), - ("bpy.types.spacesequenceeditor.overlay_frame_type*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-overlay-frame-type"), - ("bpy.types.spacesequenceeditor.show_strip_overlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequenceeditor-show-strip-overlay"), - ("bpy.types.spaceuveditor.custom_grid_subdivisions*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-custom-grid-subdivisions"), - ("bpy.types.toolsettings.proportional_edit_falloff*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-edit-falloff"), - ("bpy.types.toolsettings.use_edge_path_live_unwrap*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-edge-path-live-unwrap"), - ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), - ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), - ("bpy.types.toolsettings.use_snap_uv_grid_absolute*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-use-snap-uv-grid-absolute"), - ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), - ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), - ("bpy.ops.mesh.customdata_custom_splitnormals_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-add"), - ("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-clear"), - ("bpy.types.animvizmotionpaths.show_frame_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-frame-numbers"), - ("bpy.types.brushgpencilsettings.pen_smooth_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-steps"), - ("bpy.types.brushgpencilsettings.show_fill_extend*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-extend"), - ("bpy.types.cycleslightsettings.is_caustics_light*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-is-caustics-light"), - ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), - ("bpy.types.cyclesrendersettings.preview_denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoiser"), - ("bpy.types.cyclesrendersettings.sampling_pattern*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sampling-pattern"), - ("bpy.types.cyclesrendersettings.volume_max_steps*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-max-steps"), - ("bpy.types.cyclesrendersettings.volume_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-step-rate"), - ("bpy.types.cyclesworldsettings.is_caustics_light*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-is-caustics-light"), - ("bpy.types.editbone.bbone_handle_use_scale_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-start"), - ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), - ("bpy.types.fluiddomainsettings.cache_frame_start*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-start"), - ("bpy.types.fluiddomainsettings.cache_mesh_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-mesh-format"), - ("bpy.types.fluiddomainsettings.display_thickness*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-thickness"), - ("bpy.types.fluiddomainsettings.flame_smoke_color*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke-color"), - ("bpy.types.fluiddomainsettings.mesh_smoothen_neg*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-neg"), - ("bpy.types.fluiddomainsettings.mesh_smoothen_pos*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-pos"), - ("bpy.types.fluiddomainsettings.simulation_method*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-simulation-method"), - ("bpy.types.fluiddomainsettings.use_speed_vectors*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-speed-vectors"), - ("bpy.types.fluiddomainsettings.vector_show_mac_x*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-x"), - ("bpy.types.fluiddomainsettings.vector_show_mac_y*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-y"), - ("bpy.types.fluiddomainsettings.vector_show_mac_z*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-z"), - ("bpy.types.fluideffectorsettings.velocity_factor*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-velocity-factor"), - ("bpy.types.freestylelineset.select_by_collection*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-collection"), - ("bpy.types.freestylelineset.select_by_edge_types*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-edge-types"), - ("bpy.types.freestylelineset.select_by_face_marks*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-face-marks"), - ("bpy.types.geometrynodeinputcurvehandlepositions*", "modeling/geometry_nodes/curve/curve_handle_position.html#bpy-types-geometrynodeinputcurvehandlepositions"), - ("bpy.types.linestyle*modifier_distancefromcamera*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_camera.html#bpy-types-linestyle-modifier-distancefromcamera"), - ("bpy.types.linestyle*modifier_distancefromobject*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_object.html#bpy-types-linestyle-modifier-distancefromobject"), - ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), - ("bpy.types.linestylegeometrymodifier_beziercurve*", "render/freestyle/view_layer/line_style/modifiers/geometry/bezier_curve.html#bpy-types-linestylegeometrymodifier-beziercurve"), - ("bpy.types.materialgpencilstyle.use_fill_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-holdout"), - ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), - ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), - ("bpy.types.sequenceeditor.use_overlay_frame_lock*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-frame-lock"), - ("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"), - ("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"), - ("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"), - ("bpy.types.spaceoutliner.use_filter_object_empty*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-empty"), - ("bpy.types.spaceoutliner.use_filter_object_light*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-light"), - ("bpy.types.spacesequenceeditor.proxy_render_size*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"), - ("bpy.types.spacespreadsheetrowfilter.column_name*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-column-name"), - ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), - ("bpy.types.toolsettings.use_keyframe_cycle_aware*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-cycle-aware"), - ("bpy.types.toolsettings.use_keyframe_insert_auto*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-insert-auto"), - ("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"), - ("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"), - ("bpy.ops.ed.lib_id_generate_preview_from_object*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview-from-object"), - ("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"), - ("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"), - ("bpy.types.brushgpencilsettings.simplify_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-simplify-factor"), - ("bpy.types.collection.lineart_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-mask"), - ("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"), - ("bpy.types.cyclesrendersettings.preview_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-samples"), - ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), - ("bpy.types.cyclesworldsettings.volume_step_size*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-step-size"), - ("bpy.types.editbone.bbone_handle_use_ease_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-start"), - ("bpy.types.fluiddomainsettings.color_ramp_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field"), - ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), - ("bpy.types.fluideffectorsettings.use_plane_init*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-plane-init"), - ("bpy.types.freestylelineset.collection_negation*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-collection-negation"), - ("bpy.types.freestylelineset.face_mark_condition*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-face-mark-condition"), - ("bpy.types.freestylelineset.select_ridge_valley*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-ridge-valley"), - ("bpy.types.freestylelinestyle.material_boundary*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-material-boundary"), - ("bpy.types.freestylelinestyle.use_split_pattern*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-pattern"), - ("bpy.types.freestylesettings.use_view_map_cache*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-view-map-cache"), - ("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"), - ("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"), - ("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"), - ("bpy.types.lineartgpencilmodifier.source_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-source-camera"), - ("bpy.types.lineartgpencilmodifier.use_face_mark*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark"), - ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/view_layer/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), - ("bpy.types.movieclipuser.use_render_undistorted*", "editors/clip/display/clip_display.html#bpy-types-movieclipuser-use-render-undistorted"), - ("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"), - ("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.spaceoutliner.lib_override_view_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-lib-override-view-mode"), - ("bpy.types.spaceoutliner.use_filter_object_mesh*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-mesh"), - ("bpy.types.spaceoutliner.use_filter_view_layers*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-view-layers"), - ("bpy.types.spacesequenceeditor.show_overexposed*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-show-overexposed"), - ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), - ("bpy.types.toolsettings.use_snap_align_rotation*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-align-rotation"), - ("bpy.types.viewlayer.use_pass_cryptomatte_asset*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-asset"), - ("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-set"), - ("bpy.ops.scene.freestyle_geometry_modifier_add*", "render/freestyle/view_layer/line_style/geometry.html#bpy-ops-scene-freestyle-geometry-modifier-add"), - ("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"), - ("bpy.types.bakesettings.use_selected_to_active*", "render/cycles/baking.html#bpy-types-bakesettings-use-selected-to-active"), - ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), - ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), - ("bpy.types.brushgpencilsettings.fill_direction*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-direction"), - ("bpy.types.brushgpencilsettings.fill_draw_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-draw-mode"), - ("bpy.types.brushgpencilsettings.fill_threshold*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-threshold"), - ("bpy.types.brushgpencilsettings.use_fill_limit*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-fill-limit"), - ("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.volume_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-volume-bounces"), - ("bpy.types.cyclesworldsettings.sampling_method*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sampling-method"), - ("bpy.types.cyclesworldsettings.volume_sampling*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-sampling"), - ("bpy.types.editbone.bbone_handle_use_scale_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-end"), - ("bpy.types.fluiddomainsettings.adapt_threshold*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-threshold"), - ("bpy.types.fluiddomainsettings.cache_directory*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-directory"), - ("bpy.types.fluiddomainsettings.cache_frame_end*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-end"), - ("bpy.types.fluiddomainsettings.flame_vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-vorticity"), - ("bpy.types.fluiddomainsettings.noise_pos_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-pos-scale"), - ("bpy.types.fluiddomainsettings.noise_time_anim*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-time-anim"), - ("bpy.types.fluiddomainsettings.particle_number*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-number"), - ("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.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"), - ("bpy.types.freestylelinestyle.integration_type*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-integration-type"), - ("bpy.types.freestylelinestyle.use_split_length*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-length"), - ("bpy.types.geometrynodedistributepointsonfaces*", "modeling/geometry_nodes/point/distribute_points_on_faces.html#bpy-types-geometrynodedistributepointsonfaces"), - ("bpy.types.geometrynodesetcurvehandlepositions*", "modeling/geometry_nodes/curve/set_handle_positions.html#bpy-types-geometrynodesetcurvehandlepositions"), - ("bpy.types.greasepencil.stroke_thickness_space*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-stroke-thickness-space"), - ("bpy.types.linestylegeometrymodifier_blueprint*", "render/freestyle/view_layer/line_style/modifiers/geometry/blueprint.html#bpy-types-linestylegeometrymodifier-blueprint"), - ("bpy.types.materialgpencilstyle.alignment_mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-alignment-mode"), - ("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.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"), - ("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"), - ("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"), - ("bpy.types.spacesequenceeditor.cursor_location*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-cursor-location"), - ("bpy.types.spacesequenceeditor.display_channel*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-display-channel"), - ("bpy.types.spacesequenceeditor.show_gizmo_tool*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-tool"), - ("bpy.types.spacesequenceeditor.show_region_hud*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-region-hud"), - ("bpy.types.spacespreadsheet.show_only_selected*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-show-only-selected"), - ("bpy.types.spacespreadsheetrowfilter.operation*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-operation"), - ("bpy.types.spacespreadsheetrowfilter.threshold*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-threshold"), - ("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"), - ("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"), - ("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"), - ("bpy.ops.object.multires_higher_levels_delete*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-higher-levels-delete"), - ("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"), - ("bpy.ops.outliner.collection_duplicate_linked*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate-linked"), - ("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"), - ("bpy.types.bakesettings.use_pass_transmission*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-transmission"), - ("bpy.types.brushgpencilsettings.input_samples*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-input-samples"), - ("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"), - ("bpy.types.cyclescamerasettings.panorama_type*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-panorama-type"), - ("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"), - ("bpy.types.cyclesrendersettings.film_exposure*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-exposure"), - ("bpy.types.cyclesrendersettings.sample_offset*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sample-offset"), - ("bpy.types.cyclesrendersettings.texture_limit*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-texture-limit"), - ("bpy.types.cyclesrendersettings.use_denoising*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-denoising"), - ("bpy.types.editbone.bbone_custom_handle_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-start"), - ("bpy.types.editbone.bbone_handle_use_ease_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-end"), - ("bpy.types.fluiddomainsettings.additional_res*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-additional-res"), - ("bpy.types.fluiddomainsettings.dissolve_speed*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-dissolve-speed"), - ("bpy.types.fluiddomainsettings.effector_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-effector-group"), - ("bpy.types.fluiddomainsettings.flame_ignition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-ignition"), - ("bpy.types.fluiddomainsettings.flame_max_temp*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-max-temp"), - ("bpy.types.fluiddomainsettings.mesh_generator*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-generator"), - ("bpy.types.fluiddomainsettings.noise_strength*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-strength"), - ("bpy.types.fluiddomainsettings.particle_scale*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-particle-scale"), - ("bpy.types.fluiddomainsettings.resolution_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-resolution-max"), - ("bpy.types.fluiddomainsettings.show_gridlines*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-gridlines"), - ("bpy.types.fluiddomainsettings.use_color_ramp*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-color-ramp"), - ("bpy.types.fluiddomainsettings.viscosity_base*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-base"), - ("bpy.types.fluideffectorsettings.use_effector*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-effector"), - ("bpy.types.fluidflowsettings.surface_distance*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-surface-distance"), - ("bpy.types.fluidflowsettings.texture_map_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-map-type"), - ("bpy.types.freestylelineset.select_silhouette*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-silhouette"), - ("bpy.types.freestylelinestyle.texture_spacing*", "render/freestyle/view_layer/line_style/texture.html#bpy-types-freestylelinestyle-texture-spacing"), - ("bpy.types.freestylelinestyle.use_chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chain-count"), - ("bpy.types.freestylelinestyle.use_dashed_line*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-dashed-line"), - ("bpy.types.freestylelinestyle.use_same_object*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-same-object"), - ("bpy.types.functionnodeinputspecialcharacters*", "modeling/geometry_nodes/text/special_characters.html#bpy-types-functionnodeinputspecialcharacters"), - ("bpy.types.geometrynodecurveendpointselection*", "modeling/geometry_nodes/curve/endpoint_selection.html#bpy-types-geometrynodecurveendpointselection"), - ("bpy.types.geometrynodeinputmeshedgeneighbors*", "modeling/geometry_nodes/mesh/edge_neighbors.html#bpy-types-geometrynodeinputmeshedgeneighbors"), - ("bpy.types.geometrynodeinputmeshfaceneighbors*", "modeling/geometry_nodes/mesh/face_neighbors.html#bpy-types-geometrynodeinputmeshfaceneighbors"), - ("bpy.types.gpencilsculptguide.reference_point*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-reference-point"), - ("bpy.types.greasepencil.edit_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-edit-curve-resolution"), - ("bpy.types.linestylegeometrymodifier_2doffset*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_offset.html#bpy-types-linestylegeometrymodifier-2doffset"), - ("bpy.types.linestylegeometrymodifier_sampling*", "render/freestyle/view_layer/line_style/modifiers/geometry/sampling.html#bpy-types-linestylegeometrymodifier-sampling"), - ("bpy.types.movietrackingdopesheet.sort_method*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-sort-method"), - ("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"), - ("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"), - ("bpy.types.rendersettings.use_persistent_data*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-persistent-data"), - ("bpy.types.sequencertimelineoverlay.show_grid*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-grid"), - ("bpy.types.sequencertoolsettings.overlap_mode*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-overlap-mode"), - ("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"), - ("bpy.types.spacenodeoverlay.show_context_path*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-context-path"), - ("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"), - ("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"), - ("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"), - ("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"), - ("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"), - ("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"), - ("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"), - ("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"), - ("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"), - ("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"), - ("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"), - ("bpy.types.colormanagedviewsettings.exposure*", "render/color_management.html#bpy-types-colormanagedviewsettings-exposure"), - ("bpy.types.cyclescamerasettings.fisheye_lens*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-lens"), - ("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"), - ("bpy.types.fluiddomainsettings.show_velocity*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-velocity"), - ("bpy.types.fluiddomainsettings.timesteps_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-max"), - ("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.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"), - ("bpy.types.freestylelineset.select_edge_mark*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-edge-mark"), - ("bpy.types.freestylelinestyle.use_length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-max"), - ("bpy.types.freestylelinestyle.use_length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-min"), - ("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"), - ("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"), - ("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"), - ("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"), - ("bpy.types.materiallineart.use_material_mask*", "render/materials/line_art.html#bpy-types-materiallineart-use-material-mask"), - ("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-crease-override"), - ("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.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"), - ("bpy.types.sequencertoolsettings.pivot_point*", "editors/video_sequencer/preview/controls/pivot_point.html#bpy-types-sequencertoolsettings-pivot-point"), - ("bpy.types.spaceclipeditor.annotation_source*", "movie_clip/tracking/clip/sidebar/view.html#bpy-types-spaceclipeditor-annotation-source"), - ("bpy.types.spaceclipeditor.show_blue_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-blue-channel"), - ("bpy.types.spacefilebrowser.system_bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-bookmarks"), - ("bpy.types.spaceoutliner.use_filter_children*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-children"), - ("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"), - ("bpy.types.spacespreadsheet.attribute_domain*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-attribute-domain"), - ("bpy.types.spacespreadsheetrowfilter.enabled*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-enabled"), - ("bpy.types.spaceuveditor.show_modified_edges*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-modified-edges"), - ("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"), - ("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"), - ("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"), - ("bpy.types.view3doverlay.fade_inactive_alpha*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-fade-inactive-alpha"), - ("bpy.types.view3doverlay.wireframe_threshold*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-threshold"), - ("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"), - ("bpy.ops.object.material_slot_remove_unused*", "scene_layout/object/editing/cleanup.html#bpy-ops-object-material-slot-remove-unused"), - ("bpy.ops.outliner.collection_disable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable-render"), - ("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"), - ("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"), - ("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"), - ("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"), - ("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"), - ("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"), - ("bpy.types.cyclescamerasettings.fisheye_fov*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-fov"), - ("bpy.types.cyclesobjectsettings.ao_distance*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-ao-distance"), - ("bpy.types.cyclesobjectsettings.dicing_rate*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-dicing-rate"), - ("bpy.types.cyclesrendersettings.blur_glossy*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-blur-glossy"), - ("bpy.types.cyclesrendersettings.dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-rate"), - ("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.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.fileselectparams.recursion_level*", "editors/file_browser.html#bpy-types-fileselectparams-recursion-level"), - ("bpy.types.fluiddomainsettings.adapt_margin*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-margin"), - ("bpy.types.fluiddomainsettings.burning_rate*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-burning-rate"), - ("bpy.types.fluiddomainsettings.guide_parent*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-parent"), - ("bpy.types.fluiddomainsettings.guide_source*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-source"), - ("bpy.types.fluiddomainsettings.particle_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-max"), - ("bpy.types.fluiddomainsettings.particle_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-min"), - ("bpy.types.fluiddomainsettings.vector_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-field"), - ("bpy.types.fluiddomainsettings.vector_scale*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale"), - ("bpy.types.fluideffectorsettings.guide_mode*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-guide-mode"), - ("bpy.types.fluidflowsettings.texture_offset*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-offset"), - ("bpy.types.fluidflowsettings.use_plane_init*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-plane-init"), - ("bpy.types.fluidflowsettings.velocity_coord*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-coord"), - ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), - ("bpy.types.freestylelinestyle.use_angle_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-angle-max"), - ("bpy.types.freestylelinestyle.use_angle_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-angle-min"), - ("bpy.types.freestylesettings.as_render_pass*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-as-render-pass"), - ("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"), - ("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve_primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"), - ("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"), - ("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"), - ("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"), - ("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"), - ("bpy.types.lineartgpencilmodifier.use_loose*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-loose"), - ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"), - ("bpy.types.mesh.use_customdata_vertex_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-vertex-bevel"), - ("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"), - ("bpy.types.movietrackingcamera.pixel_aspect*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-pixel-aspect"), - ("bpy.types.movietrackingcamera.sensor_width*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-sensor-width"), - ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), - ("bpy.types.rendersettings.use_bake_multires*", "render/cycles/baking.html#bpy-types-rendersettings-use-bake-multires"), - ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), - ("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"), - ("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"), - ("bpy.types.spacenodeoverlay.show_wire_color*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-wire-color"), - ("bpy.types.spacesequenceeditor.display_mode*", "editors/video_sequencer/preview/display/display_mode.html#bpy-types-spacesequenceeditor-display-mode"), - ("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"), - ("bpy.types.view3doverlay.show_fade_inactive*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-fade-inactive"), - ("bpy.types.viewlayer.pass_cryptomatte_depth*", "render/layers/passes.html#bpy-types-viewlayer-pass-cryptomatte-depth"), - ("bpy.ops.clip.stabilize_2d_rotation_select*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-stabilize-2d-rotation-select"), - ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), - ("bpy.ops.gpencil.stroke_reset_vertex_color*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-stroke-reset-vertex-color"), - ("bpy.ops.object.modifier_apply_as_shapekey*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-apply-as-shapekey"), - ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), - ("bpy.ops.outliner.collection_color_tag_set*", "editors/outliner/editing.html#bpy-ops-outliner-collection-color-tag-set"), - ("bpy.ops.outliner.collection_enable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable-render"), - ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/introduction.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/face_sets.html#bpy-ops-sculpt-face-set-change-visibility"), - ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"), - ("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"), - ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), - ("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"), - ("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"), - ("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"), - ("bpy.types.compositornodeconvertcolorspace*", "compositing/types/converter/color_space.html#bpy-types-compositornodeconvertcolorspace"), - ("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"), - ("bpy.types.cyclesrendersettings.ao_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-ao-bounces"), - ("bpy.types.cyclesrendersettings.time_limit*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-time-limit"), - ("bpy.types.cyclesvisibilitysettings.camera*", "render/cycles/world_settings.html#bpy-types-cyclesvisibilitysettings-camera"), - ("bpy.types.cyclesworldsettings.max_bounces*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-max-bounces"), - ("bpy.types.fluiddomainsettings.domain_type*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-domain-type"), - ("bpy.types.fluiddomainsettings.flame_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke"), - ("bpy.types.fluiddomainsettings.fluid_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-fluid-group"), - ("bpy.types.fluiddomainsettings.guide_alpha*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-alpha"), - ("bpy.types.fluiddomainsettings.noise_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-scale"), - ("bpy.types.fluiddomainsettings.slice_depth*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-depth"), - ("bpy.types.fluideffectorsettings.subframes*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-subframes"), - ("bpy.types.fluidflowsettings.flow_behavior*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-behavior"), - ("bpy.types.fluidflowsettings.noise_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-noise-texture"), - ("bpy.types.freestylelineset.select_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-contour"), - ("bpy.types.freestylelinestyle.split_length*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-length"), - ("bpy.types.freestylelinestyle.use_chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chaining"), - ("bpy.types.freestylesettings.sphere_radius*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-sphere-radius"), - ("bpy.types.geometrynodeattributedomainsize*", "modeling/geometry_nodes/attribute/domain_size.html#bpy-types-geometrynodeattributedomainsize"), - ("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"), - ("bpy.types.gpencillayer.annotation_opacity*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-opacity"), - ("bpy.types.gpencillayer.use_onion_skinning*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-onion-skinning"), - ("bpy.types.gpencilsculptguide.use_snapping*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-use-snapping"), - ("bpy.types.gpencilsculptsettings.lock_axis*", "grease_pencil/modes/draw/drawing_planes.html#bpy-types-gpencilsculptsettings-lock-axis"), - ("bpy.types.greasepencil.ghost_before_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-before-range"), - ("bpy.types.greasepencil.stroke_depth_order*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-stroke-depth-order"), - ("bpy.types.imageformatsettings.file_format*", "render/output/properties/output.html#bpy-types-imageformatsettings-file-format"), - ("bpy.types.imagepaint.use_backface_culling*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-backface-culling"), - ("bpy.types.lineartgpencilmodifier.overscan*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-overscan"), - ("bpy.types.linestyle*modifier_curvature_3d*", "render/freestyle/view_layer/line_style/modifiers/color/curvature_3d.html#bpy-types-linestyle-modifier-curvature-3d"), - ("bpy.types.materialgpencilstyle.fill_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-color"), - ("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.mesh.use_customdata_edge_crease*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-crease"), - ("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"), - ("bpy.types.rendersettings.use_render_cache*", "render/output/properties/output.html#bpy-types-rendersettings-use-render-cache"), - ("bpy.types.rendersettings.use_single_layer*", "render/layers/view_layer.html#bpy-types-rendersettings-use-single-layer"), - ("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"), - ("bpy.types.spaceclipeditor.cursor_location*", "editors/clip/sidebar.html#bpy-types-spaceclipeditor-cursor-location"), - ("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.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"), - ("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"), - ("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"), - ("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"), - ("bpy.types.toolsettings.use_auto_normalize*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-auto-normalize"), - ("bpy.types.toolsettings.use_mesh_automerge*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge"), - ("bpy.types.toolsettings.use_snap_sequencer*", "video_editing/edit/montage/editing.html#bpy-types-toolsettings-use-snap-sequencer"), - ("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"), - ("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"), - ("bpy.types.view3doverlay.wireframe_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-opacity"), - ("bpy.ops.asset.open_containing_blend_file*", "editors/asset_browser.html#bpy-ops-asset-open-containing-blend-file"), - ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), - ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), - ("bpy.ops.node.collapse_hide_unused_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-collapse-hide-unused-toggle"), - ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), - ("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"), - ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), - ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), - ("bpy.types.animvizmotionpaths.frame_after*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-after"), - ("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"), - ("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"), - ("bpy.types.brush.cloth_force_falloff_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-force-falloff-type"), - ("bpy.types.brushgpencilsettings.caps_type*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-caps-type"), - ("bpy.types.brushgpencilsettings.fill_leak*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-leak"), - ("bpy.types.brushgpencilsettings.show_fill*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill"), - ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-uv-random"), - ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), - ("bpy.types.colormanagedviewsettings.gamma*", "render/color_management.html#bpy-types-colormanagedviewsettings-gamma"), - ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), - ("bpy.types.curve.bevel_factor_mapping_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-end"), - ("bpy.types.cyclescamerasettings.longitude*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-longitude"), - ("bpy.types.editbone.bbone_handle_type_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-end"), - ("bpy.types.editbone.use_endroll_as_inroll*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-endroll-as-inroll"), - ("bpy.types.fileselectparams.filter_search*", "editors/file_browser.html#bpy-types-fileselectparams-filter-search"), - ("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"), - ("bpy.types.fluiddomainsettings.flip_ratio*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flip-ratio"), - ("bpy.types.fluiddomainsettings.guide_beta*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-beta"), - ("bpy.types.fluiddomainsettings.mesh_scale*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-scale"), - ("bpy.types.fluiddomainsettings.slice_axis*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-axis"), - ("bpy.types.fluiddomainsettings.time_scale*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-time-scale"), - ("bpy.types.fluidflowsettings.texture_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-size"), - ("bpy.types.fluidflowsettings.use_absolute*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-absolute"), - ("bpy.types.freestylelineset.select_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-border"), - ("bpy.types.freestylelineset.select_crease*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-crease"), - ("bpy.types.freestylelinestyle.chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chain-count"), - ("bpy.types.freestylelinestyle.use_sorting*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-sorting"), - ("bpy.types.freestylesettings.crease_angle*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-crease-angle"), - ("bpy.types.functionnodealigneulertovector*", "modeling/geometry_nodes/utilities/align_euler_to_vector.html#bpy-types-functionnodealigneulertovector"), - ("bpy.types.geometrynodeattributestatistic*", "modeling/geometry_nodes/attribute/attribute_statistic.html#bpy-types-geometrynodeattributestatistic"), - ("bpy.types.geometrynodecurveprimitiveline*", "modeling/geometry_nodes/curve_primitives/curve_line.html#bpy-types-geometrynodecurveprimitiveline"), - ("bpy.types.geometrynodegeometrytoinstance*", "modeling/geometry_nodes/geometry/geometry_to_instance.html#bpy-types-geometrynodegeometrytoinstance"), - ("bpy.types.geometrynodeinputmaterialindex*", "modeling/geometry_nodes/material/material_index.html#bpy-types-geometrynodeinputmaterialindex"), - ("bpy.types.geometrynodeinputmeshedgeangle*", "modeling/geometry_nodes/mesh/edge_angle.html#bpy-types-geometrynodeinputmeshedgeangle"), - ("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"), - ("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"), - ("bpy.types.geometrynodetranslateinstances*", "modeling/geometry_nodes/instances/translate_instances.html#bpy-types-geometrynodetranslateinstances"), - ("bpy.types.greasepencil.ghost_after_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-after-range"), - ("bpy.types.greasepencil.use_ghosts_always*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-ghosts-always"), - ("bpy.types.imageformatsettings.color_mode*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-mode"), - ("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/view_layer/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"), - ("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/view_layer/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"), - ("bpy.types.linestylecolormodifier_tangent*", "render/freestyle/view_layer/line_style/modifiers/color/tangent.html#bpy-types-linestylecolormodifier-tangent"), - ("bpy.types.materialgpencilstyle.mix_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-color"), - ("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-fill"), - ("bpy.types.mesh.use_customdata_edge_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-bevel"), - ("bpy.types.mesh.use_mirror_vertex_group_x*", "sculpt_paint/weight_paint/tool_settings/symmetry.html#bpy-types-mesh-use-mirror-vertex-group-x"), - ("bpy.types.movietrackingcamera.division_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-division-k"), - ("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.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.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"), - ("bpy.types.rendersettings.use_motion_blur*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-use-motion-blur"), - ("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"), - ("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"), - ("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/introduction.html#bpy-types-spaceclipeditor-lock-selection"), - ("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"), - ("bpy.types.spacenodeoverlay.show_overlays*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-overlays"), - ("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"), - ("bpy.types.spacesequenceeditor.show_gizmo*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo"), - ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), - ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), - ("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"), - ("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"), - ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), - ("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"), - ("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"), - ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), - ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), - ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), - ("bpy.ops.outliner.collection_exclude_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-exclude-set"), - ("bpy.ops.outliner.collection_hide_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide-inside"), - ("bpy.ops.outliner.collection_holdout_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-set"), - ("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"), - ("bpy.ops.poselib.restore_previous_action*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-restore-previous-action"), - ("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"), - ("bpy.ops.sequencer.strip_transform_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-strip-transform-clear"), - ("bpy.ops.spreadsheet.add_row_filter_rule*", "editors/spreadsheet.html#bpy-ops-spreadsheet-add-row-filter-rule"), - ("bpy.types.animdata.action_extrapolation*", "editors/nla/sidebar.html#bpy-types-animdata-action-extrapolation"), - ("bpy.types.animvizmotionpaths.frame_step*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-step"), - ("bpy.types.bakesettings.max_ray_distance*", "render/cycles/baking.html#bpy-types-bakesettings-max-ray-distance"), - ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), - ("bpy.types.brushgpencilsettings.hardness*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-hardness"), - ("bpy.types.brushgpencilsettings.use_trim*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-trim"), - ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), - ("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"), - ("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"), - ("bpy.types.compositornodecolorcorrection*", "compositing/types/color/color_correction.html#bpy-types-compositornodecolorcorrection"), - ("bpy.types.compositornodemoviedistortion*", "compositing/types/distort/movie_distortion.html#bpy-types-compositornodemoviedistortion"), - ("bpy.types.cyclescamerasettings.latitude*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-latitude"), - ("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"), - ("bpy.types.fileselectparams.display_size*", "editors/file_browser.html#bpy-types-fileselectparams-display-size"), - ("bpy.types.fileselectparams.display_type*", "editors/file_browser.html#bpy-types-fileselectparams-display-type"), - ("bpy.types.fluiddomainsettings.use_guide*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-use-guide"), - ("bpy.types.fluiddomainsettings.use_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-use-noise"), - ("bpy.types.fluiddomainsettings.use_slice*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-slice"), - ("bpy.types.fluiddomainsettings.vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-vorticity"), - ("bpy.types.fluidflowsettings.flow_source*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-source"), - ("bpy.types.fluidflowsettings.fuel_amount*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-fuel-amount"), - ("bpy.types.fluidflowsettings.smoke_color*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-smoke-color"), - ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), - ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), - ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), - ("bpy.types.freestylelinestyle.length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-length-max"), - ("bpy.types.freestylelinestyle.length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-length-min"), - ("bpy.types.freestylelinestyle.sort_order*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-order"), - ("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"), - ("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"), - ("bpy.types.geometrynodeattributetransfer*", "modeling/geometry_nodes/attribute/transfer_attribute.html#bpy-types-geometrynodeattributetransfer"), - ("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/face_area.html#bpy-types-geometrynodeinputmeshfacearea"), - ("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"), - ("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"), - ("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"), - ("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"), - ("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"), - ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), - ("bpy.types.materiallineart.mat_occlusion*", "render/materials/line_art.html#bpy-types-materiallineart-mat-occlusion"), - ("bpy.types.movietrackingcamera.principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-principal"), - ("bpy.types.object.use_camera_lock_parent*", "scene_layout/object/properties/relations.html#bpy-types-object-use-camera-lock-parent"), - ("bpy.types.object.visible_volume_scatter*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-volume-scatter"), - ("bpy.types.rendersettings.line_thickness*", "render/freestyle/render.html#bpy-types-rendersettings-line-thickness"), - ("bpy.types.rendersettings.pixel_aspect_x*", "render/output/properties/format.html#bpy-types-rendersettings-pixel-aspect-x"), - ("bpy.types.rendersettings.pixel_aspect_y*", "render/output/properties/format.html#bpy-types-rendersettings-pixel-aspect-y"), - ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), - ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), - ("bpy.types.spaceoutliner.use_sync_select*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sync-select"), - ("bpy.types.spaceproperties.outliner_sync*", "editors/properties_editor.html#bpy-types-spaceproperties-outliner-sync"), - ("bpy.types.spaceproperties.search_filter*", "editors/properties_editor.html#bpy-types-spaceproperties-search-filter"), - ("bpy.types.spacesequenceeditor.view_type*", "editors/video_sequencer/introduction.html#bpy-types-spacesequenceeditor-view-type"), - ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), - ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), - ("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"), - ("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-use-custom-grid"), - ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"), - ("bpy.types.toolsettings.double_threshold*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-double-threshold"), - ("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"), - ("bpy.types.toolsettings.mesh_select_mode*", "modeling/meshes/selecting/introduction.html#bpy-types-toolsettings-mesh-select-mode"), - ("bpy.types.toolsettings.use_snap_project*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-project"), - ("bpy.types.transformorientationslot.type*", "editors/3dview/controls/orientation.html#bpy-types-transformorientationslot-type"), - ("bpy.types.unitsettings.temperature_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-temperature-unit"), - ("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"), - ("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"), - ("bpy.types.view3dshading.background_type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-background-type"), - ("bpy.types.workspace.use_filter_by_owner*", "interface/window_system/workspaces.html#bpy-types-workspace-use-filter-by-owner"), - ("bpy.ops.gpencil.image_to_grease_pencil*", "editors/image/editing.html#bpy-ops-gpencil-image-to-grease-pencil"), - ("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"), - ("bpy.ops.object.multires_rebuild_subdiv*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-rebuild-subdiv"), - ("bpy.ops.sequencer.select_side_of_frame*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-side-of-frame"), - ("bpy.types.animvizmotionpaths.frame_end*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-end"), - ("bpy.types.armature.rigify_colors_index*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-index"), - ("bpy.types.armature.rigify_theme_to_add*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-theme-to-add"), - ("bpy.types.bakesettings.use_pass_direct*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-direct"), - ("bpy.types.bakesettings.use_pass_glossy*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-glossy"), - ("bpy.types.brush.pose_smooth_iterations*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-smooth-iterations"), - ("bpy.types.brush.snake_hook_deform_type*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-snake-hook-deform-type"), - ("bpy.types.brush.use_grab_active_vertex*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-active-vertex"), - ("bpy.types.brush.use_pose_lock_rotation*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-lock-rotation"), - ("bpy.types.compositornodebrightcontrast*", "compositing/types/color/bright_contrast.html#bpy-types-compositornodebrightcontrast"), - ("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"), - ("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.fileselectparams.show_hidden*", "editors/file_browser.html#bpy-types-fileselectparams-show-hidden"), - ("bpy.types.fileselectparams.sort_method*", "editors/file_browser.html#bpy-types-fileselectparams-sort-method"), - ("bpy.types.fluiddomainsettings.clipping*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-clipping"), - ("bpy.types.fluiddomainsettings.use_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-mesh"), - ("bpy.types.freestylelinestyle.angle_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-angle-max"), - ("bpy.types.freestylelinestyle.angle_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-angle-min"), - ("bpy.types.freestylelinestyle.split_gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-gap"), - ("bpy.types.freestylelinestyle.use_nodes*", "render/freestyle/view_layer/line_style/texture.html#bpy-types-freestylelinestyle-use-nodes"), - ("bpy.types.geometrynodecaptureattribute*", "modeling/geometry_nodes/attribute/capture_attribute.html#bpy-types-geometrynodecaptureattribute"), - ("bpy.types.geometrynodeinputshadesmooth*", "modeling/geometry_nodes/mesh/is_shade_smooth.html#bpy-types-geometrynodeinputshadesmooth"), - ("bpy.types.geometrynodeinstanceonpoints*", "modeling/geometry_nodes/instances/instance_on_points.html#bpy-types-geometrynodeinstanceonpoints"), - ("bpy.types.geometrynodepointstovertices*", "modeling/geometry_nodes/point/points_to_vertices.html#bpy-types-geometrynodepointstovertices"), - ("bpy.types.geometrynoderealizeinstances*", "modeling/geometry_nodes/instances/realize_instances.html#bpy-types-geometrynoderealizeinstances"), - ("bpy.types.geometrynodeseparategeometry*", "modeling/geometry_nodes/geometry/separate_geometry.html#bpy-types-geometrynodeseparategeometry"), - ("bpy.types.geometrynodesetmaterialindex*", "modeling/geometry_nodes/material/set_material_index.html#bpy-types-geometrynodesetmaterialindex"), - ("bpy.types.greasepencil.edit_line_color*", "grease_pencil/properties/display.html#bpy-types-greasepencil-edit-line-color"), - ("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.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"), - ("bpy.types.rendersettings.use_auto_tile*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-auto-tile"), - ("bpy.types.rendersettings.use_overwrite*", "render/output/properties/output.html#bpy-types-rendersettings-use-overwrite"), - ("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.shadernodebsdfhairprincipled*", "render/shader_nodes/shader/hair_principled.html#bpy-types-shadernodebsdfhairprincipled"), - ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), - ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), - ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/sidebar.html#bpy-types-spaceimageeditor-show-repeat"), - ("bpy.types.spaceoutliner.use_sort_alpha*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sort-alpha"), - ("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"), - ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), - ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), - ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), - ("bpy.types.toolsettings.snap_uv_element*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-snap-uv-element"), - ("bpy.types.toolsettings.use_snap_rotate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-rotate"), - ("bpy.types.unitsettings.system_rotation*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system-rotation"), - ("bpy.types.view3doverlay.display_handle*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-display-handle"), - ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), - ("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-editable-toggle"), - ("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"), - ("bpy.ops.ed.lib_id_load_custom_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-load-custom-preview"), - ("bpy.ops.gpencil.frame_clean_duplicate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-duplicate"), - ("bpy.ops.gpencil.stroke_simplify_fixed*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify-fixed"), - ("bpy.ops.mesh.faces_select_linked_flat*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-faces-select-linked-flat"), - ("bpy.ops.mesh.primitive_ico_sphere_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-ico-sphere-add"), - ("bpy.ops.object.gpencil_modifier_apply*", "grease_pencil/modifiers/introduction.html#bpy-ops-object-gpencil-modifier-apply"), - ("bpy.ops.object.material_slot_deselect*", "render/materials/assignment.html#bpy-ops-object-material-slot-deselect"), - ("bpy.ops.object.modifier_move_to_index*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-move-to-index"), - ("bpy.ops.object.multires_external_save*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-external-save"), - ("bpy.ops.object.vertex_group_normalize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize"), - ("bpy.ops.object.visual_transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-visual-transform-apply"), - ("bpy.ops.outliner.collection_duplicate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate"), - ("bpy.ops.pose.select_constraint_target*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-constraint-target"), - ("bpy.ops.sequencer.change_effect_input*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-effect-input"), - ("bpy.ops.sequencer.strip_color_tag_set*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-ops-sequencer-strip-color-tag-set"), - ("bpy.ops.sequencer.strip_transform_fit*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-strip-transform-fit"), - ("bpy.types.armature.rigify_colors_lock*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-lock"), - ("bpy.types.bakesettings.cage_extrusion*", "render/cycles/baking.html#bpy-types-bakesettings-cage-extrusion"), - ("bpy.types.bakesettings.use_pass_color*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-color"), - ("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"), - ("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"), - ("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"), - ("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"), - ("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random"), - ("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"), - ("bpy.types.colormanageddisplaysettings*", "render/color_management.html#bpy-types-colormanageddisplaysettings"), - ("bpy.types.colorramp.hue_interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-hue-interpolation"), - ("bpy.types.compositornodebilateralblur*", "compositing/types/filter/bilateral_blur.html#bpy-types-compositornodebilateralblur"), - ("bpy.types.compositornodecryptomattev2*", "compositing/types/matte/cryptomatte.html#bpy-types-compositornodecryptomattev2"), - ("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"), - ("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"), - ("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"), - ("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"), - ("bpy.types.fileselectparams.use_filter*", "editors/file_browser.html#bpy-types-fileselectparams-use-filter"), - ("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"), - ("bpy.types.fluidflowsettings.flow_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-type"), - ("bpy.types.fluidflowsettings.subframes*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-subframes"), - ("bpy.types.freestylelineset.collection*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-collection"), - ("bpy.types.freestylelineset.visibility*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-visibility"), - ("bpy.types.freestylelinestyle.chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chaining"), - ("bpy.types.freestylelinestyle.sort_key*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-key"), - ("bpy.types.geometrynodeaccumulatefield*", "modeling/geometry_nodes/utilities/accumulate_field.html#bpy-types-geometrynodeaccumulatefield"), - ("bpy.types.geometrynodecurvesethandles*", "modeling/geometry_nodes/curve/set_handle_type.html#bpy-types-geometrynodecurvesethandles"), - ("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"), - ("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/mesh_island.html#bpy-types-geometrynodeinputmeshisland"), - ("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/merge_by_distance.html#bpy-types-geometrynodemergebydistance"), - ("bpy.types.geometrynodereplacematerial*", "modeling/geometry_nodes/material/replace_material.html#bpy-types-geometrynodereplacematerial"), - ("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"), - ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), - ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/spline_parameter.html#bpy-types-geometrynodesplineparameter"), - ("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"), - ("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"), - ("bpy.types.greasepencil.use_onion_fade*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-onion-fade"), - ("bpy.types.greasepencil.use_onion_loop*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-onion-loop"), - ("bpy.types.imagepaint.screen_grab_size*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-screen-grab-size"), - ("bpy.types.linestyle*modifier_material*", "render/freestyle/view_layer/line_style/modifiers/color/material.html#bpy-types-linestyle-modifier-material"), - ("bpy.types.motionpath.use_custom_color*", "animation/motion_paths.html#bpy-types-motionpath-use-custom-color"), - ("bpy.types.movietrackingcamera.brown_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-k"), - ("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"), - ("bpy.types.object.visible_transmission*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-transmission"), - ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), - ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), - ("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"), - ("bpy.types.rendersettings.resolution_x*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-x"), - ("bpy.types.rendersettings.resolution_y*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-y"), - ("bpy.types.rendersettings.threads_mode*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-threads-mode"), - ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), - ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), - ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), - ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), - ("bpy.types.sculpt.detail_refine_method*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-refine-method"), - ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), - ("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.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"), - ("bpy.types.spaceoutliner.filter_invert*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-invert"), - ("bpy.types.spacetexteditor.show_margin*", "editors/text_editor.html#bpy-types-spacetexteditor-show-margin"), - ("bpy.types.spline.radius_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-radius-interpolation"), - ("bpy.types.toolsettings.use_multipaint*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-multipaint"), - ("bpy.types.toolsettings.use_snap_scale*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-scale"), - ("bpy.types.toolsettings.uv_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-select-mode"), - ("bpy.types.viewlayer.material_override*", "render/layers/introduction.html#bpy-types-viewlayer-material-override"), - ("bpy.ops.anim.channels_disable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-disable-toggle"), - ("bpy.ops.anim.channels_fcurves_enable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-fcurves-enable"), - ("bpy.ops.anim.channels_setting_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-toggle"), - ("bpy.ops.clip.set_viewport_background*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-viewport-background"), - ("bpy.ops.gpencil.interpolate_sequence*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate-sequence"), - ("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"), - ("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"), - ("bpy.ops.mesh.primitive_uv_sphere_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-uv-sphere-add"), - ("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplicate_linked.html#bpy-ops-object-duplicate-move-linked"), - ("bpy.ops.object.make_override_library*", "files/linked_libraries/library_overrides.html#bpy-ops-object-make-override-library"), - ("bpy.ops.object.parent_no_inverse_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-no-inverse-set"), - ("bpy.ops.object.vertex_group_quantize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-quantize"), - ("bpy.ops.outliner.collection_instance*", "editors/outliner/editing.html#bpy-ops-outliner-collection-instance"), - ("bpy.ops.sequencer.change_effect_type*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-effect-type"), - ("bpy.ops.transform.create_orientation*", "editors/3dview/controls/orientation.html#bpy-ops-transform-create-orientation"), - ("bpy.ops.transform.delete_orientation*", "editors/3dview/controls/orientation.html#bpy-ops-transform-delete-orientation"), - ("bpy.ops.view3d.localview_remove_from*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview-remove-from"), - ("bpy.types.animdata.action_blend_type*", "editors/nla/sidebar.html#bpy-types-animdata-action-blend-type"), - ("bpy.types.bakesettings.use_pass_emit*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-emit"), - ("bpy.types.bone.use_envelope_multiply*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-envelope-multiply"), - ("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"), - ("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"), - ("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"), - ("bpy.types.brush.smooth_stroke_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-factor"), - ("bpy.types.brush.smooth_stroke_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-radius"), - ("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"), - ("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"), - ("bpy.types.brushgpencilsettings.angle*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle"), - ("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"), - ("bpy.types.compositornodeantialiasing*", "compositing/types/filter/anti_aliasing.html#bpy-types-compositornodeantialiasing"), - ("bpy.types.compositornodechannelmatte*", "compositing/types/matte/channel_key.html#bpy-types-compositornodechannelmatte"), - ("bpy.types.compositornodecolorbalance*", "compositing/types/color/color_balance.html#bpy-types-compositornodecolorbalance"), - ("bpy.types.compositornodekeyingscreen*", "compositing/types/matte/keying_screen.html#bpy-types-compositornodekeyingscreen"), - ("bpy.types.dynamicpaintcanvassettings*", "physics/dynamic_paint/canvas.html#bpy-types-dynamicpaintcanvassettings"), - ("bpy.types.fileselectparams.directory*", "editors/file_browser.html#bpy-types-fileselectparams-directory"), - ("bpy.types.fluidflowsettings.use_flow*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-flow"), - ("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"), - ("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/collection_info.html#bpy-types-geometrynodecollectioninfo"), - ("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"), - ("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"), - ("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene_time.html#bpy-types-geometrynodeinputscenetime"), - ("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"), - ("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"), - ("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"), - ("bpy.types.geometrynodesetpointradius*", "modeling/geometry_nodes/point/set_point_radius.html#bpy-types-geometrynodesetpointradius"), - ("bpy.types.geometrynodesetshadesmooth*", "modeling/geometry_nodes/mesh/set_shade_smooth.html#bpy-types-geometrynodesetshadesmooth"), - ("bpy.types.geometrynodestringtocurves*", "modeling/geometry_nodes/text/string_to_curves.html#bpy-types-geometrynodestringtocurves"), - ("bpy.types.geometrynodesubdividecurve*", "modeling/geometry_nodes/curve/subdivide_curve.html#bpy-types-geometrynodesubdividecurve"), - ("bpy.types.gpencillayer.channel_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-channel-color"), - ("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"), - ("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"), - ("bpy.types.keyframe.handle_right_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right-type"), - ("bpy.types.materialgpencilstyle.color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-color"), - ("bpy.types.movietrackingcamera.nuke_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-nuke-k"), - ("bpy.types.movietrackingstabilization*", "movie_clip/tracking/clip/sidebar/stabilization/index.html#bpy-types-movietrackingstabilization"), - ("bpy.types.object.display_bounds_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-bounds-type"), - ("bpy.types.regionview3d.lock_rotation*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-lock-rotation"), - ("bpy.types.rendersettings.hair_subdiv*", "render/cycles/render_settings/hair.html#bpy-types-rendersettings-hair-subdiv"), - ("bpy.types.scene.audio_distance_model*", "scene_layout/scene/properties.html#bpy-types-scene-audio-distance-model"), - ("bpy.types.scene.audio_doppler_factor*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-factor"), - ("bpy.types.sequencetransform.rotation*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-rotation"), - ("bpy.types.shadernodeambientocclusion*", "render/shader_nodes/input/ao.html#bpy-types-shadernodeambientocclusion"), - ("bpy.types.shadernodevolumeabsorption*", "render/shader_nodes/shader/volume_absorption.html#bpy-types-shadernodevolumeabsorption"), - ("bpy.types.shadernodevolumeprincipled*", "render/shader_nodes/shader/volume_principled.html#bpy-types-shadernodevolumeprincipled"), - ("bpy.types.spacefilebrowser.bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-bookmarks"), - ("bpy.types.spaceoutliner.display_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-display-mode"), - ("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"), - ("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"), - ("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"), - ("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"), - ("bpy.types.toolsettings.use_snap_self*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-self"), - ("bpy.types.viewlayer.active_aov_index*", "render/layers/passes.html#bpy-types-viewlayer-active-aov-index"), - ("bpy.ops.anim.channels_enable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-enable-toggle"), - ("bpy.ops.constraint.copy_to_selected*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy-to-selected"), - ("bpy.ops.gpencil.bake_mesh_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-mesh-animation"), - ("bpy.ops.gpencil.select_vertex_color*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-vertex-color"), - ("bpy.ops.gpencil.set_active_material*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-set-active-material"), - ("bpy.ops.gpencil.stroke_change_color*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-change-color"), - ("bpy.ops.gpencil.stroke_cyclical_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-cyclical-set"), - ("bpy.ops.gpencil.vertex_color_invert*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-invert"), - ("bpy.ops.gpencil.vertex_color_levels*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-levels"), - ("bpy.ops.mesh.primitive_cylinder_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cylinder-add"), - ("bpy.ops.mesh.set_normals_from_faces*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-set-normals-from-faces"), - ("bpy.ops.mesh.shape_propagate_to_all*", "modeling/meshes/editing/vertex/propagate_shapes.html#bpy-ops-mesh-shape-propagate-to-all"), - ("bpy.ops.mesh.vert_connect_nonplanar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-nonplanar"), - ("bpy.ops.object.duplicates_make_real*", "scene_layout/object/editing/apply.html#bpy-ops-object-duplicates-make-real"), - ("bpy.ops.object.material_slot_assign*", "render/materials/assignment.html#bpy-ops-object-material-slot-assign"), - ("bpy.ops.object.material_slot_select*", "render/materials/assignment.html#bpy-ops-object-material-slot-select"), - ("bpy.ops.object.multires_unsubdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-unsubdivide"), - ("bpy.ops.object.paths_update_visible*", "animation/motion_paths.html#bpy-ops-object-paths-update-visible"), - ("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-transforms-to-deltas"), - ("bpy.ops.outliner.collection_disable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable"), - ("bpy.ops.outliner.collection_isolate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-isolate"), - ("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"), - ("bpy.ops.poselib.convert_old_poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-convert-old-poselib"), - ("bpy.ops.render.shutter_curve_preset*", "render/cycles/render_settings/motion_blur.html#bpy-ops-render-shutter-curve-preset"), - ("bpy.ops.sequencer.view_ghost_border*", "editors/video_sequencer/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"), - ("bpy.ops.ui.override_type_set_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-override-type-set-button"), - ("bpy.types.animdata.action_influence*", "editors/nla/sidebar.html#bpy-types-animdata-action-influence"), - ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), - ("bpy.types.assetmetadata.description*", "editors/asset_browser.html#bpy-types-assetmetadata-description"), - ("bpy.types.bakesettings.normal_space*", "render/cycles/baking.html#bpy-types-bakesettings-normal-space"), - ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), - ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), - ("bpy.types.brush.use_cloth_collision*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-collision"), - ("bpy.types.brush.use_grab_silhouette*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-silhouette"), - ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), - ("bpy.types.brushtextureslot.map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-map-mode"), - ("bpy.types.camera.passepartout_alpha*", "render/cameras.html#bpy-types-camera-passepartout-alpha"), - ("bpy.types.colorrampelement.position*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-position"), - ("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"), - ("bpy.types.compositornodecryptomatte*", "compositing/types/matte/cryptomatte_legacy.html#bpy-types-compositornodecryptomatte"), - ("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"), - ("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"), - ("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"), - ("bpy.types.editbone.use_scale_easing*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-scale-easing"), - ("bpy.types.fileselectparams.filename*", "editors/file_browser.html#bpy-types-fileselectparams-filename"), - ("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"), - ("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"), - ("bpy.types.freestylelineset.qi_start*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-start"), - ("bpy.types.freestylelinestyle.rounds*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-rounds"), - ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/text/replace_string.html#bpy-types-functionnodereplacestring"), - ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/text/value_to_string.html#bpy-types-functionnodevaluetostring"), - ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), - ("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"), - ("bpy.types.geometrynodeinputposition*", "modeling/geometry_nodes/input/position.html#bpy-types-geometrynodeinputposition"), - ("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"), - ("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"), - ("bpy.types.geometrynodescaleelements*", "modeling/geometry_nodes/mesh/scale_elements.html#bpy-types-geometrynodescaleelements"), - ("bpy.types.geometrynodesubdividemesh*", "modeling/geometry_nodes/mesh/subdivide_mesh.html#bpy-types-geometrynodesubdividemesh"), - ("bpy.types.greasepencil.before_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-before-color"), - ("bpy.types.greasepencil.onion_factor*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-factor"), - ("bpy.types.greasepencil.pixel_factor*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-pixel-factor"), - ("bpy.types.keyframe.handle_left_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left-type"), - ("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"), - ("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-flip"), - ("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mode"), - ("bpy.types.meshsequencecachemodifier*", "modeling/modifiers/modify/mesh_sequence_cache.html#bpy-types-meshsequencecachemodifier"), - ("bpy.types.modifier.show_in_editmode*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-in-editmode"), - ("bpy.types.motionpath.line_thickness*", "animation/motion_paths.html#bpy-types-motionpath-line-thickness"), - ("bpy.types.object.empty_display_size*", "modeling/empties.html#bpy-types-object-empty-display-size"), - ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), - ("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"), - ("bpy.types.rendersettings.use_border*", "render/output/properties/format.html#bpy-types-rendersettings-use-border"), - ("bpy.types.rigidbodyconstraint.limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-limit"), - ("bpy.types.rigidbodyobject.kinematic*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-kinematic"), - ("bpy.types.scene.audio_doppler_speed*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-speed"), - ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), - ("bpy.types.sculpt.detail_type_method*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-type-method"), - ("bpy.types.sculpt.use_smooth_shading*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-use-smooth-shading"), - ("bpy.types.sequenceeditor.show_cache*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-sequenceeditor-show-cache"), - ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), - ("bpy.types.shadernodebsdftranslucent*", "render/shader_nodes/shader/translucent.html#bpy-types-shadernodebsdftranslucent"), - ("bpy.types.shadernodebsdftransparent*", "render/shader_nodes/shader/transparent.html#bpy-types-shadernodebsdftransparent"), - ("bpy.types.shadernodetexpointdensity*", "render/shader_nodes/textures/point_density.html#bpy-types-shadernodetexpointdensity"), - ("bpy.types.shadernodevectortransform*", "render/shader_nodes/vector/transform.html#bpy-types-shadernodevectortransform"), - ("bpy.types.shrinkwrapgpencilmodifier*", "grease_pencil/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapgpencilmodifier"), - ("bpy.types.spaceclipeditor.show_grid*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-grid"), - ("bpy.types.spaceoutliner.filter_text*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-text"), - ("bpy.types.spacetexteditor.find_text*", "editors/text_editor.html#bpy-types-spacetexteditor-find-text"), - ("bpy.types.spacetexteditor.font_size*", "editors/text_editor.html#bpy-types-spacetexteditor-font-size"), - ("bpy.types.spacetexteditor.tab_width*", "editors/text_editor.html#bpy-types-spacetexteditor-tab-width"), - ("bpy.types.spaceuveditor.lock_bounds*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-lock-bounds"), - ("bpy.types.spline.tilt_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-tilt-interpolation"), - ("bpy.types.transformorientation.name*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation-name"), - ("bpy.types.unitsettings.scale_length*", "scene_layout/scene/properties.html#bpy-types-unitsettings-scale-length"), - ("bpy.types.unitsettings.use_separate*", "scene_layout/scene/properties.html#bpy-types-unitsettings-use-separate"), - ("bpy.types.viewlayer.use_motion_blur*", "render/layers/introduction.html#bpy-types-viewlayer-use-motion-blur"), - ("bpy.types.volumedisplay.slice_depth*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-depth"), - ("bpy.types.worldmistsettings.falloff*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-falloff"), - ("bpy.ops.clip.lock_selection_toggle*", "editors/clip/introduction.html#bpy-ops-clip-lock-selection-toggle"), - ("bpy.ops.ed.lib_id_generate_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview"), - ("bpy.ops.mesh.customdata_mask_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-mask-clear"), - ("bpy.ops.mesh.customdata_skin_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-clear"), - ("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"), - ("bpy.ops.mesh.mod_weighted_strength*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-mod-weighted-strength"), - ("bpy.ops.mesh.quads_convert_to_tris*", "modeling/meshes/editing/face/triangulate_faces.html#bpy-ops-mesh-quads-convert-to-tris"), - ("bpy.ops.mesh.select_interior_faces*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-interior-faces"), - ("bpy.ops.mesh.select_similar_region*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar-region"), - ("bpy.ops.mesh.tris_convert_to_quads*", "modeling/meshes/editing/face/triangles_quads.html#bpy-ops-mesh-tris-convert-to-quads"), - ("bpy.ops.object.datalayout_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data_layout.html#bpy-ops-object-datalayout-transfer"), - ("bpy.ops.object.multires_base_apply*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-base-apply"), - ("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/randomize.html#bpy-ops-object-randomize-transform"), - ("bpy.ops.object.vertex_group_invert*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-invert"), - ("bpy.ops.object.vertex_group_levels*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-levels"), - ("bpy.ops.object.vertex_group_mirror*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-mirror"), - ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), - ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), - ("bpy.ops.outliner.collection_enable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable"), - ("bpy.ops.palette.extract_from_image*", "editors/image/editing.html#bpy-ops-palette-extract-from-image"), - ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), - ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), - ("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.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"), - ("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"), - ("bpy.types.assetmetadata.active_tag*", "editors/asset_browser.html#bpy-types-assetmetadata-active-tag"), - ("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"), - ("bpy.types.bakesettings.margin_type*", "render/cycles/baking.html#bpy-types-bakesettings-margin-type"), - ("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"), - ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"), - ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), - ("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"), - ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"), - ("bpy.types.camera.show_passepartout*", "render/cameras.html#bpy-types-camera-show-passepartout"), - ("bpy.types.collection.lineart_usage*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-usage"), - ("bpy.types.colormanagedviewsettings*", "render/color_management.html#bpy-types-colormanagedviewsettings"), - ("bpy.types.compositornodebokehimage*", "compositing/types/input/bokeh_image.html#bpy-types-compositornodebokehimage"), - ("bpy.types.compositornodecolormatte*", "compositing/types/matte/color_key.html#bpy-types-compositornodecolormatte"), - ("bpy.types.compositornodecolorspill*", "compositing/types/matte/color_spill.html#bpy-types-compositornodecolorspill"), - ("bpy.types.compositornodehuecorrect*", "compositing/types/color/hue_correct.html#bpy-types-compositornodehuecorrect"), - ("bpy.types.compositornodeoutputfile*", "compositing/types/output/file.html#bpy-types-compositornodeoutputfile"), - ("bpy.types.compositornodeswitchview*", "compositing/types/converter/switch_view.html#bpy-types-compositornodeswitchview"), - ("bpy.types.copytransformsconstraint*", "animation/constraints/transform/copy_transforms.html#bpy-types-copytransformsconstraint"), - ("bpy.types.correctivesmoothmodifier*", "modeling/modifiers/deform/corrective_smooth.html#bpy-types-correctivesmoothmodifier"), - ("bpy.types.curve.bevel_factor_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-start"), - ("bpy.types.fluiddomainsettings.beta*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-beta"), - ("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"), - ("bpy.types.freestylelineset.exclude*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-exclude"), - ("bpy.types.freestylelinestyle.alpha*", "render/freestyle/view_layer/line_style/alpha.html#bpy-types-freestylelinestyle-alpha"), - ("bpy.types.freestylelinestyle.color*", "render/freestyle/view_layer/line_style/color.html#bpy-types-freestylelinestyle-color"), - ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/text/string_length.html#bpy-types-functionnodestringlength"), - ("bpy.types.geometrynodefieldatindex*", "modeling/geometry_nodes/utilities/field_at_index.html#bpy-types-geometrynodefieldatindex"), - ("bpy.types.geometrynodeimagetexture*", "modeling/geometry_nodes/texture/image.html#bpy-types-geometrynodeimagetexture"), - ("bpy.types.geometrynodeinputtangent*", "modeling/geometry_nodes/curve/curve_tangent.html#bpy-types-geometrynodeinputtangent"), - ("bpy.types.geometrynodejoingeometry*", "modeling/geometry_nodes/geometry/join_geometry.html#bpy-types-geometrynodejoingeometry"), - ("bpy.types.geometrynodemeshcylinder*", "modeling/geometry_nodes/mesh_primitives/cylinder.html#bpy-types-geometrynodemeshcylinder"), - ("bpy.types.geometrynodemeshtopoints*", "modeling/geometry_nodes/mesh/mesh_to_points.html#bpy-types-geometrynodemeshtopoints"), - ("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh_primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"), - ("bpy.types.geometrynodereversecurve*", "modeling/geometry_nodes/curve/reverse_curve.html#bpy-types-geometrynodereversecurve"), - ("bpy.types.geometrynodesetcurvetilt*", "modeling/geometry_nodes/curve/set_curve_tilt.html#bpy-types-geometrynodesetcurvetilt"), - ("bpy.types.geometrynodesplinelength*", "modeling/geometry_nodes/curve/spline_length.html#bpy-types-geometrynodesplinelength"), - ("bpy.types.geometrynodevolumetomesh*", "modeling/geometry_nodes/volume/volume_to_mesh.html#bpy-types-geometrynodevolumetomesh"), - ("bpy.types.gpencillayer.line_change*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-line-change"), - ("bpy.types.gpencillayer.parent_type*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent-type"), - ("bpy.types.gpencillayer.tint_factor*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-tint-factor"), - ("bpy.types.greasepencil.after_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-after-color"), - ("bpy.types.image.use_half_precision*", "editors/image/image_settings.html#bpy-types-image-use-half-precision"), - ("bpy.types.image.use_view_as_render*", "editors/image/image_settings.html#bpy-types-image-use-view-as-render"), - ("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"), - ("bpy.types.linestyle*modifier_noise*", "render/freestyle/view_layer/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"), - ("bpy.types.maintainvolumeconstraint*", "animation/constraints/transform/maintain_volume.html#bpy-types-maintainvolumeconstraint"), - ("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.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.sequencertimelineoverlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay"), - ("bpy.types.sequencetransform.offset*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-offset"), - ("bpy.types.shadernodebrightcontrast*", "render/shader_nodes/color/bright_contrast.html#bpy-types-shadernodebrightcontrast"), - ("bpy.types.shadernodebsdfprincipled*", "render/shader_nodes/shader/principled.html#bpy-types-shadernodebsdfprincipled"), - ("bpy.types.shadernodebsdfrefraction*", "render/shader_nodes/shader/refraction.html#bpy-types-shadernodebsdfrefraction"), - ("bpy.types.shadernodeoutputmaterial*", "render/shader_nodes/output/material.html#bpy-types-shadernodeoutputmaterial"), - ("bpy.types.shadernodetexenvironment*", "render/shader_nodes/textures/environment.html#bpy-types-shadernodetexenvironment"), - ("bpy.types.spacesequenceeditor.show*", "editors/video_sequencer/preview/header.html#bpy-types-spacesequenceeditor-show"), - ("bpy.types.spaceuveditor.show_faces*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-faces"), - ("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/overlays.html#bpy-types-spaceuveditor-uv-opacity"), - ("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"), - ("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"), - ("bpy.types.toolsettings.snap_target*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-target"), - ("bpy.types.transformcacheconstraint*", "animation/constraints/transform/transform_cache.html#bpy-types-transformcacheconstraint"), - ("bpy.types.unitsettings.length_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-length-unit"), - ("bpy.types.vertexweighteditmodifier*", "modeling/modifiers/modify/weight_edit.html#bpy-types-vertexweighteditmodifier"), - ("bpy.types.volumedisplay.slice_axis*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-axis"), - ("bpy.ops.action.markers_make_local*", "animation/markers.html#bpy-ops-action-markers-make-local"), - ("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"), - ("bpy.ops.armature.select_hierarchy*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-hierarchy"), - ("bpy.ops.armature.switch_direction*", "animation/armatures/bones/editing/switch_direction.html#bpy-ops-armature-switch-direction"), - ("bpy.ops.clip.apply_solution_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-apply-solution-scale"), - ("bpy.ops.clip.set_center_principal*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-center-principal"), - ("bpy.ops.clip.setup_tracking_scene*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-setup-tracking-scene"), - ("bpy.ops.curve.match_texture_space*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-ops-curve-match-texture-space"), - ("bpy.ops.font.text_paste_from_file*", "modeling/texts/editing.html#bpy-ops-font-text-paste-from-file"), - ("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.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"), - ("bpy.ops.mesh.primitive_circle_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-circle-add"), - ("bpy.ops.mesh.primitive_monkey_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-monkey-add"), - ("bpy.ops.mesh.select_face_by_sides*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-face-by-sides"), - ("bpy.ops.mesh.shortest_path_select*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-shortest-path-select"), - ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), - ("bpy.ops.object.multires_subdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-subdivide"), - ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), - ("bpy.ops.poselib.create_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-create-pose-asset"), - ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), - ("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.sequencer.image_strip_add*", "video_editing/edit/montage/strips/image.html#bpy-ops-sequencer-image-strip-add"), - ("bpy.ops.sequencer.movie_strip_add*", "video_editing/edit/montage/strips/movie.html#bpy-ops-sequencer-movie-strip-add"), - ("bpy.ops.sequencer.reassign_inputs*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-reassign-inputs"), - ("bpy.ops.sequencer.sound_strip_add*", "video_editing/edit/montage/strips/sound.html#bpy-ops-sequencer-sound-strip-add"), - ("bpy.ops.ui.remove_override_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-remove-override-button"), - ("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"), - ("bpy.types.animvizmotionpaths.type*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-type"), - ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), - ("bpy.types.brush.cloth_deform_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-deform-type"), - ("bpy.types.brush.cloth_sim_falloff*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-falloff"), - ("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"), - ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), - ("bpy.types.colorramp.interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-interpolation"), - ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), - ("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"), - ("bpy.types.compositornodecomposite*", "compositing/types/output/composite.html#bpy-types-compositornodecomposite"), - ("bpy.types.compositornodedespeckle*", "compositing/types/filter/despeckle.html#bpy-types-compositornodedespeckle"), - ("bpy.types.compositornodediffmatte*", "compositing/types/matte/difference_key.html#bpy-types-compositornodediffmatte"), - ("bpy.types.compositornodelumamatte*", "compositing/types/matte/luminance_key.html#bpy-types-compositornodelumamatte"), - ("bpy.types.compositornodemovieclip*", "compositing/types/input/movie_clip.html#bpy-types-compositornodemovieclip"), - ("bpy.types.compositornodenormalize*", "compositing/types/vector/normalize.html#bpy-types-compositornodenormalize"), - ("bpy.types.compositornodeposterize*", "compositing/types/color/posterize.html#bpy-types-compositornodeposterize"), - ("bpy.types.compositornodepremulkey*", "compositing/types/converter/alpha_convert.html#bpy-types-compositornodepremulkey"), - ("bpy.types.compositornodescenetime*", "compositing/types/input/scene_time.html#bpy-types-compositornodescenetime"), - ("bpy.types.compositornodestabilize*", "compositing/types/distort/stabilize_2d.html#bpy-types-compositornodestabilize"), - ("bpy.types.compositornodetransform*", "compositing/types/distort/transform.html#bpy-types-compositornodetransform"), - ("bpy.types.compositornodetranslate*", "compositing/types/distort/translate.html#bpy-types-compositornodetranslate"), - ("bpy.types.constraint.target_space*", "animation/constraints/interface/common.html#bpy-types-constraint-target-space"), - ("bpy.types.curve.use_deform_bounds*", "modeling/curves/properties/shape.html#bpy-types-curve-use-deform-bounds"), - ("bpy.types.editbone.bbone_curveinx*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinx"), - ("bpy.types.editbone.bbone_curveinz*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinz"), - ("bpy.types.editbone.bbone_scaleout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scaleout"), - ("bpy.types.editbone.bbone_segments*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-segments"), - ("bpy.types.envelopegpencilmodifier*", "grease_pencil/modifiers/generate/envelope.html#bpy-types-envelopegpencilmodifier"), - ("bpy.types.freestylelineset.qi_end*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-end"), - ("bpy.types.freestylelinestyle.caps*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-caps"), - ("bpy.types.freestylelinestyle.dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-dash"), - ("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"), - ("bpy.types.functionnodebooleanmath*", "modeling/geometry_nodes/utilities/boolean_math.html#bpy-types-functionnodebooleanmath"), - ("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/string.html#bpy-types-functionnodeinputstring"), - ("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/vector.html#bpy-types-functionnodeinputvector"), - ("bpy.types.functionnoderandomvalue*", "modeling/geometry_nodes/utilities/random_value.html#bpy-types-functionnoderandomvalue"), - ("bpy.types.functionnoderotateeuler*", "modeling/geometry_nodes/utilities/rotate_euler.html#bpy-types-functionnoderotateeuler"), - ("bpy.types.functionnodeslicestring*", "modeling/geometry_nodes/text/slice_string.html#bpy-types-functionnodeslicestring"), - ("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/curve_length.html#bpy-types-geometrynodecurvelength"), - ("bpy.types.geometrynodecurvespiral*", "modeling/geometry_nodes/curve_primitives/curve_spiral.html#bpy-types-geometrynodecurvespiral"), - ("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"), - ("bpy.types.geometrynodeextrudemesh*", "modeling/geometry_nodes/mesh/extrude_mesh.html#bpy-types-geometrynodeextrudemesh"), - ("bpy.types.geometrynodefilletcurve*", "modeling/geometry_nodes/curve/fillet_curve.html#bpy-types-geometrynodefilletcurve"), - ("bpy.types.geometrynodeinputnormal*", "modeling/geometry_nodes/input/normal.html#bpy-types-geometrynodeinputnormal"), - ("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/input/radius.html#bpy-types-geometrynodeinputradius"), - ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), - ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), - ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample_curve.html#bpy-types-geometrynodesamplecurve"), - ("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"), - ("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/set_position.html#bpy-types-geometrynodesetposition"), - ("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"), - ("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"), - ("bpy.types.gpencillayer.pass_index*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-pass-index"), - ("bpy.types.gpencillayer.tint_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-tint-color"), - ("bpy.types.gpencillayer.use_lights*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-lights"), - ("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"), - ("bpy.types.greasepencil.onion_mode*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-mode"), - ("bpy.types.greasepencilgrid.offset*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-offset"), - ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), - ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), - ("bpy.types.layercollection.exclude*", "editors/outliner/interface.html#bpy-types-layercollection-exclude"), - ("bpy.types.layercollection.holdout*", "editors/outliner/interface.html#bpy-types-layercollection-holdout"), - ("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.multiplygpencilmodifier*", "grease_pencil/modifiers/generate/multiple_strokes.html#bpy-types-multiplygpencilmodifier"), - ("bpy.types.rendersettings.filepath*", "render/output/properties/output.html#bpy-types-rendersettings-filepath"), - ("bpy.types.rendersettings.fps_base*", "render/output/properties/format.html#bpy-types-rendersettings-fps-base"), - ("bpy.types.rigidbodyobject.enabled*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-enabled"), - ("bpy.types.sceneeevee.use_overscan*", "render/eevee/render_settings/film.html#bpy-types-sceneeevee-use-overscan"), - ("bpy.types.sequencerpreviewoverlay*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay"), - ("bpy.types.sequencetransform.scale*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-scale"), - ("bpy.types.shadernodeeeveespecular*", "render/shader_nodes/shader/specular_bsdf.html#bpy-types-shadernodeeeveespecular"), - ("bpy.types.shadernodehuesaturation*", "render/shader_nodes/color/hue_saturation.html#bpy-types-shadernodehuesaturation"), - ("bpy.types.shadernodetexwhitenoise*", "render/shader_nodes/textures/white_noise.html#bpy-types-shadernodetexwhitenoise"), - ("bpy.types.shadernodevolumescatter*", "render/shader_nodes/shader/volume_scatter.html#bpy-types-shadernodevolumescatter"), - ("bpy.types.simplifygpencilmodifier*", "grease_pencil/modifiers/generate/simplify.html#bpy-types-simplifygpencilmodifier"), - ("bpy.types.spacegrapheditor.cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-cursor"), - ("bpy.types.texturenodetexdistnoise*", "editors/texture_node/types/textures/distorted_noise.html#bpy-types-texturenodetexdistnoise"), - ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), - ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer/freestyle.html#bpy-types-viewlayer-use-freestyle"), - ("bpy.types.volumedisplay.use_slice*", "modeling/volumes/properties.html#bpy-types-volumedisplay-use-slice"), - ("bpy.types.worldlighting.ao_factor*", "render/cycles/render_settings/light_paths.html#bpy-types-worldlighting-ao-factor"), - ("bpy.types.worldmistsettings.depth*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-depth"), - ("bpy.types.worldmistsettings.start*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-start"), - ("bpy.ops.armature.armature_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-armature-layers"), - ("bpy.ops.armature.select_linked()*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-linked"), - ("bpy.ops.clip.stabilize_2d_select*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-stabilize-2d-select"), - ("bpy.ops.constraint.move_to_index*", "animation/constraints/interface/header.html#bpy-ops-constraint-move-to-index"), - ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), - ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), - ("bpy.ops.gpencil.vertex_color_hsv*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-hsv"), - ("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.html#bpy-ops-graph-extrapolation-type"), - ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), - ("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"), - ("bpy.ops.mesh.face_split_by_edges*", "modeling/meshes/editing/face/weld_edges_faces.html#bpy-ops-mesh-face-split-by-edges"), - ("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_non_manifold*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-non-manifold"), - ("bpy.ops.object.attribute_convert*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-convert"), - ("bpy.ops.object.constraints_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-clear"), - ("bpy.ops.object.quadriflow_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-quadriflow-remesh"), - ("bpy.ops.object.vertex_group_copy*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy"), - ("bpy.ops.object.vertex_group_lock*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-lock"), - ("bpy.ops.object.vertex_group_move*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-move"), - ("bpy.ops.object.vertex_group_sort*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-sort"), - ("bpy.ops.object.vertex_parent_set*", "modeling/meshes/editing/vertex/make_vertex_parent.html#bpy-ops-object-vertex-parent-set"), - ("bpy.ops.outliner.collection_hide*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide"), - ("bpy.ops.outliner.collection_show*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show"), - ("bpy.ops.paint.mask_lasso_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-lasso-gesture"), - ("bpy.ops.rigidbody.mass_calculate*", "scene_layout/object/editing/rigid_body.html#bpy-ops-rigidbody-mass-calculate"), - ("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.sequencer.duplicate_move*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-duplicate-move"), - ("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.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), - ("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"), - ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), - ("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"), - ("bpy.types.bone.envelope_distance*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-distance"), - ("bpy.types.brightcontrastmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-brightcontrastmodifier"), - ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), - ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), - ("bpy.types.brush.pose_ik_segments*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-ik-segments"), - ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), - ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), - ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), - ("bpy.types.collection.hide_select*", "editors/outliner/interface.html#bpy-types-collection-hide-select"), - ("bpy.types.colorrampelement.color*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-color"), - ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), - ("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"), - ("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"), - ("bpy.types.compositornodeexposure*", "compositing/types/color/exposure.html#bpy-types-compositornodeexposure"), - ("bpy.types.compositornodelensdist*", "compositing/types/distort/lens_distortion.html#bpy-types-compositornodelensdist"), - ("bpy.types.compositornodemaprange*", "compositing/types/vector/map_range.html#bpy-types-compositornodemaprange"), - ("bpy.types.compositornodemapvalue*", "compositing/types/vector/map_value.html#bpy-types-compositornodemapvalue"), - ("bpy.types.compositornodepixelate*", "compositing/types/filter/pixelate.html#bpy-types-compositornodepixelate"), - ("bpy.types.compositornodesetalpha*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha"), - ("bpy.types.compositornodesunbeams*", "compositing/types/filter/sun_beams.html#bpy-types-compositornodesunbeams"), - ("bpy.types.compositornodetrackpos*", "compositing/types/input/track_position.html#bpy-types-compositornodetrackpos"), - ("bpy.types.compositornodezcombine*", "compositing/types/color/z_combine.html#bpy-types-compositornodezcombine"), - ("bpy.types.constraint.owner_space*", "animation/constraints/interface/common.html#bpy-types-constraint-owner-space"), - ("bpy.types.copylocationconstraint*", "animation/constraints/transform/copy_location.html#bpy-types-copylocationconstraint"), - ("bpy.types.copyrotationconstraint*", "animation/constraints/transform/copy_rotation.html#bpy-types-copyrotationconstraint"), - ("bpy.types.curve.bevel_factor_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-end"), - ("bpy.types.curve.bevel_resolution*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-resolution"), - ("bpy.types.cyclesmaterialsettings*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings"), - ("bpy.types.dopesheet.show_summary*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-summary"), - ("bpy.types.editbone.bbone_easeout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easeout"), - ("bpy.types.editbone.bbone_rollout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollout"), - ("bpy.types.editbone.bbone_scalein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scalein"), - ("bpy.types.editbone.inherit_scale*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-inherit-scale"), - ("bpy.types.freestylelinestyle.gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-gap"), - ("bpy.types.freestylesettings.mode*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-mode"), - ("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/float_to_integer.html#bpy-types-functionnodefloattoint"), - ("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/color.html#bpy-types-functionnodeinputcolor"), - ("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"), - ("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/input/input_index.html#bpy-types-geometrynodeinputindex"), - ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"), - ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), - ("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"), - ("bpy.types.geometrynodesplitedges*", "modeling/geometry_nodes/mesh/split_edges.html#bpy-types-geometrynodesplitedges"), - ("bpy.types.geometrynodestringjoin*", "modeling/geometry_nodes/text/join_strings.html#bpy-types-geometrynodestringjoin"), - ("bpy.types.greasepencilgrid.color*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-color"), - ("bpy.types.greasepencilgrid.lines*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-lines"), - ("bpy.types.greasepencilgrid.scale*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-scale"), - ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), - ("bpy.types.imagesequence.use_flip*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-imagesequence-use-flip"), - ("bpy.types.keyframe.interpolation*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-interpolation"), - ("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"), - ("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier"), - ("bpy.types.material.line_priority*", "render/freestyle/material.html#bpy-types-material-line-priority"), - ("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"), - ("bpy.types.modifier.show_viewport*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-viewport"), - ("bpy.types.motionpath.frame_start*", "animation/motion_paths.html#bpy-types-motionpath-frame-start"), - ("bpy.types.object.visible_diffuse*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-diffuse"), - ("bpy.types.objectsolverconstraint*", "animation/constraints/motion_tracking/object_solver.html#bpy-types-objectsolverconstraint"), - ("bpy.types.opacitygpencilmodifier*", "grease_pencil/modifiers/color/opacity.html#bpy-types-opacitygpencilmodifier"), - ("bpy.types.particlesystemmodifier*", "physics/particles/index.html#bpy-types-particlesystemmodifier"), - ("bpy.types.rendersettings.threads*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-threads"), - ("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.shadernodedisplacement*", "render/shader_nodes/vector/displacement.html#bpy-types-shadernodedisplacement"), - ("bpy.types.shadernodelightfalloff*", "render/shader_nodes/color/light_falloff.html#bpy-types-shadernodelightfalloff"), - ("bpy.types.shadernodeparticleinfo*", "render/shader_nodes/input/particle_info.html#bpy-types-shadernodeparticleinfo"), - ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), - ("bpy.types.sound.use_memory_cache*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-memory-cache"), - ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), - ("bpy.types.texturegpencilmodifier*", "grease_pencil/modifiers/modify/texture_mapping.html#bpy-types-texturegpencilmodifier"), - ("bpy.types.texturenodecoordinates*", "editors/texture_node/types/input/coordinates.html#bpy-types-texturenodecoordinates"), - ("bpy.types.texturenodetexmusgrave*", "editors/texture_node/types/textures/musgrave.html#bpy-types-texturenodetexmusgrave"), - ("bpy.types.unitsettings.mass_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-mass-unit"), - ("bpy.types.unitsettings.time_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-time-unit"), - ("bpy.types.volumedisplacemodifier*", "modeling/modifiers/deform/volume_displace.html#bpy-types-volumedisplacemodifier"), - ("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"), - ("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"), - ("bpy.types.worldlighting.distance*", "render/cycles/render_settings/light_paths.html#bpy-types-worldlighting-distance"), - ("bpy.ops.armature.autoside_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-autoside-names"), - ("bpy.ops.armature.calculate_roll*", "animation/armatures/bones/editing/bone_roll.html#bpy-ops-armature-calculate-roll"), - ("bpy.ops.armature.duplicate_move*", "animation/armatures/bones/editing/duplicate.html#bpy-ops-armature-duplicate-move"), - ("bpy.ops.armature.select_similar*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-similar"), - ("bpy.ops.clip.create_plane_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-create-plane-track"), - ("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"), - ("bpy.ops.gpencil.blank_frame_add*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-blank-frame-add"), - ("bpy.ops.gpencil.frame_duplicate*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-frame-duplicate"), - ("bpy.ops.gpencil.layer_duplicate*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-duplicate"), - ("bpy.ops.gpencil.recalc_geometry*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-recalc-geometry"), - ("bpy.ops.gpencil.stroke_caps_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-caps-set"), - ("bpy.ops.gpencil.stroke_separate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-separate"), - ("bpy.ops.gpencil.stroke_simplify*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify"), - ("bpy.ops.graph.blend_to_neighbor*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-neighbor"), - ("bpy.ops.graph.snap_cursor_value*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap-cursor-value"), - ("bpy.ops.image.save_all_modified*", "editors/image/editing.html#bpy-ops-image-save-all-modified"), - ("bpy.ops.marker.make_links_scene*", "animation/markers.html#bpy-ops-marker-make-links-scene"), - ("bpy.ops.mesh.extrude_edges_move*", "modeling/meshes/editing/edge/extrude_edges.html#bpy-ops-mesh-extrude-edges-move"), - ("bpy.ops.mesh.extrude_faces_move*", "modeling/meshes/editing/face/extrude_individual_faces.html#bpy-ops-mesh-extrude-faces-move"), - ("bpy.ops.mesh.faces_shade_smooth*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-faces-shade-smooth"), - ("bpy.ops.mesh.paint_mask_extract*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-mesh-paint-mask-extract"), - ("bpy.ops.mesh.primitive_cone_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cone-add"), - ("bpy.ops.mesh.primitive_cube_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cube-add"), - ("bpy.ops.mesh.primitive_grid_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-grid-add"), - ("bpy.ops.mesh.subdivide_edgering*", "modeling/meshes/editing/edge/subdivide_edge_ring.html#bpy-ops-mesh-subdivide-edgering"), - ("bpy.ops.node.hide_socket_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-hide-socket-toggle"), - ("bpy.ops.node.tree_socket_remove*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-remove"), - ("bpy.ops.object.attribute_remove*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-remove"), - ("bpy.ops.object.constraints_copy*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-copy"), - ("bpy.ops.object.gpencil_modifier*", "grease_pencil/modifiers/index.html#bpy-ops-object-gpencil-modifier"), - ("bpy.ops.object.make_links_scene*", "scene_layout/object/editing/link_transfer/link_scene.html#bpy-ops-object-make-links-scene"), - ("bpy.ops.object.make_single_user*", "scene_layout/object/editing/relations/make_single_user.html#bpy-ops-object-make-single-user"), - ("bpy.ops.object.multires_reshape*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-reshape"), - ("bpy.ops.object.select_hierarchy*", "scene_layout/object/selecting.html#bpy-ops-object-select-hierarchy"), - ("bpy.ops.object.vertex_group_add*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-add"), - ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), - ("bpy.ops.outliner.collection_new*", "editors/outliner/editing.html#bpy-ops-outliner-collection-new"), - ("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"), - ("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"), - ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), - ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), - ("bpy.ops.pose.blend_to_neighbour*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-blend-to-neighbour"), - ("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"), - ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), - ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), - ("bpy.ops.scene.view_layer_remove*", "render/layers/introduction.html#bpy-ops-scene-view-layer-remove"), - ("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.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"), - ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), - ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), - ("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"), - ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), - ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), - ("bpy.ops.wm.recover_last_session*", "files/blend/open_save.html#bpy-ops-wm-recover-last-session"), - ("bpy.types.armature.display_type*", "animation/armatures/properties/display.html#bpy-types-armature-display-type"), - ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), - ("bpy.types.bakesettings.normal_b*", "render/cycles/baking.html#bpy-types-bakesettings-normal-b"), - ("bpy.types.bakesettings.normal_g*", "render/cycles/baking.html#bpy-types-bakesettings-normal-g"), - ("bpy.types.bakesettings.normal_r*", "render/cycles/baking.html#bpy-types-bakesettings-normal-r"), - ("bpy.types.bakesettings.use_cage*", "render/cycles/baking.html#bpy-types-bakesettings-use-cage"), - ("bpy.types.brush.boundary_offset*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-offset"), - ("bpy.types.brush.cloth_sim_limit*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-limit"), - ("bpy.types.brush.use_custom_icon*", "sculpt_paint/brush/brush.html#bpy-types-brush-use-custom-icon"), - ("bpy.types.brushtextureslot.mask*", "sculpt_paint/brush/texture_mask.html#bpy-types-brushtextureslot-mask"), - ("bpy.types.camerabackgroundimage*", "render/cameras.html#bpy-types-camerabackgroundimage"), - ("bpy.types.compositornodeboxmask*", "compositing/types/matte/box_mask.html#bpy-types-compositornodeboxmask"), - ("bpy.types.compositornodedefocus*", "compositing/types/filter/defocus.html#bpy-types-compositornodedefocus"), - ("bpy.types.compositornodedenoise*", "compositing/types/filter/denoise.html#bpy-types-compositornodedenoise"), - ("bpy.types.compositornodeinpaint*", "compositing/types/filter/inpaint.html#bpy-types-compositornodeinpaint"), - ("bpy.types.compositornodergbtobw*", "compositing/types/converter/rgb_to_bw.html#bpy-types-compositornodergbtobw"), - ("bpy.types.compositornoderlayers*", "compositing/types/input/render_layers.html#bpy-types-compositornoderlayers"), - ("bpy.types.compositornodetexture*", "compositing/types/input/texture.html#bpy-types-compositornodetexture"), - ("bpy.types.compositornodetonemap*", "compositing/types/color/tone_map.html#bpy-types-compositornodetonemap"), - ("bpy.types.compositornodevecblur*", "compositing/types/filter/vector_blur.html#bpy-types-compositornodevecblur"), - ("bpy.types.curve.use_fill_deform*", "modeling/curves/properties/shape.html#bpy-types-curve-use-fill-deform"), - ("bpy.types.curve.use_path_follow*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-follow"), - ("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"), - ("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"), - ("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"), - ("bpy.types.editbone.bbone_easein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easein"), - ("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"), - ("bpy.types.fcurve.auto_smoothing*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-auto-smoothing"), - ("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), - ("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"), - ("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/boolean.html#bpy-types-functionnodeinputbool"), - ("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve_primitives/star.html#bpy-types-geometrynodecurvestar"), - ("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/fill_curve.html#bpy-types-geometrynodefillcurve"), - ("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/flip_faces.html#bpy-types-geometrynodeflipfaces"), - ("bpy.types.geometrynodeproximity*", "modeling/geometry_nodes/geometry/geometry_proximity.html#bpy-types-geometrynodeproximity"), - ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform.html#bpy-types-geometrynodetransform"), - ("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/trim_curve.html#bpy-types-geometrynodetrimcurve"), - ("bpy.types.gpencillayer.location*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-location"), - ("bpy.types.gpencillayer.rotation*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-rotation"), - ("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"), - ("bpy.types.keyframe.handle_right*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right"), - ("bpy.types.lengthgpencilmodifier*", "grease_pencil/modifiers/generate/length.html#bpy-types-lengthgpencilmodifier"), - ("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"), - ("bpy.types.lockedtrackconstraint*", "animation/constraints/tracking/locked_track.html#bpy-types-lockedtrackconstraint"), - ("bpy.types.material.blend_method*", "render/eevee/materials/settings.html#bpy-types-material-blend-method"), - ("bpy.types.mirrorgpencilmodifier*", "grease_pencil/modifiers/generate/mirror.html#bpy-types-mirrorgpencilmodifier"), - ("bpy.types.modifier.show_on_cage*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-on-cage"), - ("bpy.types.movietrackingcamera.k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-k"), - ("bpy.types.node.use_custom_color*", "interface/controls/nodes/sidebar.html#bpy-types-node-use-custom-color"), - ("bpy.types.object.visible_camera*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-camera"), - ("bpy.types.object.visible_glossy*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-glossy"), - ("bpy.types.object.visible_shadow*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-shadow"), - ("bpy.types.offsetgpencilmodifier*", "grease_pencil/modifiers/deform/offset.html#bpy-types-offsetgpencilmodifier"), - ("bpy.types.posebone.custom_shape*", "animation/armatures/bones/properties/display.html#bpy-types-posebone-custom-shape"), - ("bpy.types.rigifyselectioncolors*", "addons/rigging/rigify/metarigs.html#bpy-types-rigifyselectioncolors"), - ("bpy.types.sceneeevee.volumetric*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric"), - ("bpy.types.screen.show_statusbar*", "interface/window_system/topbar.html#bpy-types-screen-show-statusbar"), - ("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.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"), - ("bpy.types.shadernodeoutputlight*", "render/shader_nodes/output/light.html#bpy-types-shadernodeoutputlight"), - ("bpy.types.shadernodeoutputworld*", "render/shader_nodes/output/world.html#bpy-types-shadernodeoutputworld"), - ("bpy.types.shadernodeshadertorgb*", "render/shader_nodes/converter/shader_to_rgb.html#bpy-types-shadernodeshadertorgb"), - ("bpy.types.shadernodetexgradient*", "render/shader_nodes/textures/gradient.html#bpy-types-shadernodetexgradient"), - ("bpy.types.shadernodevectorcurve*", "render/shader_nodes/vector/curves.html#bpy-types-shadernodevectorcurve"), - ("bpy.types.shadernodevertexcolor*", "render/shader_nodes/input/vertex_color.html#bpy-types-shadernodevertexcolor"), - ("bpy.types.smoothgpencilmodifier*", "grease_pencil/modifiers/deform/smooth.html#bpy-types-smoothgpencilmodifier"), - ("bpy.types.spline.use_endpoint_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-endpoint-u"), - ("bpy.types.surfacedeformmodifier*", "modeling/modifiers/deform/surface_deform.html#bpy-types-surfacedeformmodifier"), - ("bpy.types.texturenodetexvoronoi*", "editors/texture_node/types/textures/voronoi.html#bpy-types-texturenodetexvoronoi"), - ("bpy.types.toolsettings.use_snap*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap"), - ("bpy.types.viewlayer.use_volumes*", "render/layers/introduction.html#bpy-types-viewlayer-use-volumes"), - ("bpy.types.volume.frame_duration*", "modeling/volumes/properties.html#bpy-types-volume-frame-duration"), - ("bpy.types.volumedisplay.density*", "modeling/volumes/properties.html#bpy-types-volumedisplay-density"), - ("bpy.types.volumerender.clipping*", "modeling/volumes/properties.html#bpy-types-volumerender-clipping"), - ("bpy.types.workspace.object_mode*", "interface/window_system/workspaces.html#bpy-types-workspace-object-mode"), - ("bpy.ops.anim.channels_collapse*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-collapse"), - ("bpy.ops.armature.select_mirror*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-mirror"), - ("bpy.ops.curve.switch_direction*", "modeling/curves/editing/segments.html#bpy-ops-curve-switch-direction"), - ("bpy.ops.geometry.attribute_add*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-geometry-attribute-add"), - ("bpy.ops.gpencil.duplicate_move*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-duplicate-move"), - ("bpy.ops.gpencil.stroke_arrange*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-arrange"), - ("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"), - ("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"), - ("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"), - ("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"), - ("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"), - ("bpy.ops.nla.action_sync_length*", "editors/nla/editing.html#bpy-ops-nla-action-sync-length"), - ("bpy.ops.object.make_links_data*", "scene_layout/object/editing/link_transfer/link_data.html#bpy-ops-object-make-links-data"), - ("bpy.ops.object.modifier_remove*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-remove"), - ("bpy.ops.object.paths_calculate*", "animation/motion_paths.html#bpy-ops-object-paths-calculate"), - ("bpy.ops.object.transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-transform-apply"), - ("bpy.ops.outliner.lib_operation*", "files/linked_libraries/link_append.html#bpy-ops-outliner-lib-operation"), - ("bpy.ops.outliner.orphans_purge*", "editors/outliner/interface.html#bpy-ops-outliner-orphans-purge"), - ("bpy.ops.paint.mask_box_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-box-gesture"), - ("bpy.ops.screen.region_quadview*", "editors/3dview/navigate/views.html#bpy-ops-screen-region-quadview"), - ("bpy.ops.screen.screenshot_area*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot-area"), - ("bpy.ops.sequencer.offset_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-offset-clear"), - ("bpy.ops.spreadsheet.toggle_pin*", "editors/spreadsheet.html#bpy-ops-spreadsheet-toggle-pin"), - ("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"), - ("bpy.types.arraygpencilmodifier*", "grease_pencil/modifiers/generate/array.html#bpy-types-arraygpencilmodifier"), - ("bpy.types.assetmetadata.author*", "editors/asset_browser.html#bpy-types-assetmetadata-author"), - ("bpy.types.bone.envelope_weight*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-weight"), - ("bpy.types.brush.use_persistent*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-use-persistent"), - ("bpy.types.brushgpencilsettings*", "grease_pencil/modes/draw/tools/index.html#bpy-types-brushgpencilsettings"), - ("bpy.types.buildgpencilmodifier*", "grease_pencil/modifiers/generate/build.html#bpy-types-buildgpencilmodifier"), - ("bpy.types.camera.sensor_height*", "render/cameras.html#bpy-types-camera-sensor-height"), - ("bpy.types.colorbalancemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-colorbalancemodifier"), - ("bpy.types.colorgpencilmodifier*", "grease_pencil/modifiers/color/hue_saturation.html#bpy-types-colorgpencilmodifier"), - ("bpy.types.colorramp.color_mode*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-color-mode"), - ("bpy.types.compositornodefilter*", "compositing/types/filter/filter_node.html#bpy-types-compositornodefilter"), - ("bpy.types.compositornodehuesat*", "compositing/types/color/hue_saturation.html#bpy-types-compositornodehuesat"), - ("bpy.types.compositornodeidmask*", "compositing/types/converter/id_mask.html#bpy-types-compositornodeidmask"), - ("bpy.types.compositornodeinvert*", "compositing/types/color/invert.html#bpy-types-compositornodeinvert"), - ("bpy.types.compositornodekeying*", "compositing/types/matte/keying.html#bpy-types-compositornodekeying"), - ("bpy.types.compositornodelevels*", "compositing/types/output/levels.html#bpy-types-compositornodelevels"), - ("bpy.types.compositornodemixrgb*", "compositing/types/color/mix.html#bpy-types-compositornodemixrgb"), - ("bpy.types.compositornodenormal*", "compositing/types/vector/normal.html#bpy-types-compositornodenormal"), - ("bpy.types.compositornoderotate*", "compositing/types/distort/rotate.html#bpy-types-compositornoderotate"), - ("bpy.types.compositornodeswitch*", "compositing/types/layout/switch.html#bpy-types-compositornodeswitch"), - ("bpy.types.compositornodeviewer*", "compositing/types/output/viewer.html#bpy-types-compositornodeviewer"), - ("bpy.types.constraint.influence*", "animation/constraints/interface/common.html#bpy-types-constraint-influence"), - ("bpy.types.curve.use_path_clamp*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-clamp"), - ("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"), - ("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"), - ("bpy.types.editbone.use_connect*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-connect"), - ("bpy.types.ffmpegsettings.audio*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio"), - ("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"), - ("bpy.types.functionnodeinputint*", "modeling/geometry_nodes/input/integer.html#bpy-types-functionnodeinputint"), - ("bpy.types.gaussianblursequence*", "video_editing/edit/montage/strips/effects/blur.html#bpy-types-gaussianblursequence"), - ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/bounding_box.html#bpy-types-geometrynodeboundbox"), - ("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve_primitives/arc.html#bpy-types-geometrynodecurvearc"), - ("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/dual_mesh.html#bpy-types-geometrynodedualmesh"), - ("bpy.types.geometrynodematerial*", "-1"), - ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh_primitives/cone.html#bpy-types-geometrynodemeshcone"), - ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh_primitives/cube.html#bpy-types-geometrynodemeshcube"), - ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh_primitives/grid.html#bpy-types-geometrynodemeshgrid"), - ("bpy.types.geometrynodemeshline*", "modeling/geometry_nodes/mesh_primitives/mesh_line.html#bpy-types-geometrynodemeshline"), - ("bpy.types.gpencillayer.opacity*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-opacity"), - ("bpy.types.image.display_aspect*", "editors/image/sidebar.html#bpy-types-image-display-aspect"), - ("bpy.types.keyframe.handle_left*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left"), - ("bpy.types.keyingsetsall.active*", "editors/timeline.html#bpy-types-keyingsetsall-active"), - ("bpy.types.limitscaleconstraint*", "animation/constraints/transform/limit_scale.html#bpy-types-limitscaleconstraint"), - ("bpy.types.materialgpencilstyle*", "grease_pencil/materials/index.html#bpy-types-materialgpencilstyle"), - ("bpy.types.mesh.use_auto_smooth*", "modeling/meshes/structure.html#bpy-types-mesh-use-auto-smooth"), - ("bpy.types.meshtovolumemodifier*", "modeling/modifiers/generate/mesh_to_volume.html#bpy-types-meshtovolumemodifier"), - ("bpy.types.modifier.show_render*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-render"), - ("bpy.types.motionpath.frame_end*", "animation/motion_paths.html#bpy-types-motionpath-frame-end"), - ("bpy.types.noisegpencilmodifier*", "grease_pencil/modifiers/deform/noise.html#bpy-types-noisegpencilmodifier"), - ("bpy.types.object.hide_viewport*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-viewport"), - ("bpy.types.object.rotation_mode*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation-mode"), - ("bpy.types.object.show_in_front*", "scene_layout/object/properties/display.html#bpy-types-object-show-in-front"), - ("bpy.types.posebone.rigify_type*", "addons/rigging/rigify/rig_types/index.html#bpy-types-posebone-rigify-type"), - ("bpy.types.preferencesfilepaths*", "editors/preferences/file_paths.html#bpy-types-preferencesfilepaths"), - ("bpy.types.rigidbodyobject.mass*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-mass"), - ("bpy.types.scene.background_set*", "scene_layout/scene/properties.html#bpy-types-scene-background-set"), - ("bpy.types.sequence.frame_start*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-start"), - ("bpy.types.shadernodebackground*", "render/shader_nodes/shader/background.html#bpy-types-shadernodebackground"), - ("bpy.types.shadernodebsdfglossy*", "render/shader_nodes/shader/glossy.html#bpy-types-shadernodebsdfglossy"), - ("bpy.types.shadernodebsdfvelvet*", "render/shader_nodes/shader/velvet.html#bpy-types-shadernodebsdfvelvet"), - ("bpy.types.shadernodecameradata*", "render/shader_nodes/input/camera_data.html#bpy-types-shadernodecameradata"), - ("bpy.types.shadernodefloatcurve*", "render/shader_nodes/converter/float_curve.html#bpy-types-shadernodefloatcurve"), - ("bpy.types.shadernodeobjectinfo*", "render/shader_nodes/input/object_info.html#bpy-types-shadernodeobjectinfo"), - ("bpy.types.shadernodetexchecker*", "render/shader_nodes/textures/checker.html#bpy-types-shadernodetexchecker"), - ("bpy.types.shadernodetexvoronoi*", "render/shader_nodes/textures/voronoi.html#bpy-types-shadernodetexvoronoi"), - ("bpy.types.shadernodevectormath*", "render/shader_nodes/converter/vector_math.html#bpy-types-shadernodevectormath"), - ("bpy.types.shadernodevolumeinfo*", "render/shader_nodes/input/volume_info.html#bpy-types-shadernodevolumeinfo"), - ("bpy.types.shadernodewavelength*", "render/shader_nodes/converter/wavelength.html#bpy-types-shadernodewavelength"), - ("bpy.types.shrinkwrapconstraint*", "animation/constraints/relationship/shrinkwrap.html#bpy-types-shrinkwrapconstraint"), - ("bpy.types.simpledeformmodifier*", "modeling/modifiers/deform/simple_deform.html#bpy-types-simpledeformmodifier"), - ("bpy.types.spaceclipeditor.show*", "editors/clip/display/index.html#bpy-types-spaceclipeditor-show"), - ("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"), - ("bpy.types.speedcontrolsequence*", "video_editing/edit/montage/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"), - ("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"), - ("bpy.types.texturenodetexclouds*", "editors/texture_node/types/textures/clouds.html#bpy-types-texturenodetexclouds"), - ("bpy.types.texturenodetexmarble*", "editors/texture_node/types/textures/marble.html#bpy-types-texturenodetexmarble"), - ("bpy.types.texturenodetexstucci*", "editors/texture_node/types/textures/stucci.html#bpy-types-texturenodetexstucci"), - ("bpy.types.texturenodetranslate*", "editors/texture_node/types/distort/translate.html#bpy-types-texturenodetranslate"), - ("bpy.types.transformorientation*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation"), - ("bpy.types.unifiedpaintsettings*", "sculpt_paint/brush/brush.html#bpy-types-unifiedpaintsettings"), - ("bpy.types.viewlayer.use_strand*", "render/layers/introduction.html#bpy-types-viewlayer-use-strand"), - ("bpy.types.volume.sequence_mode*", "modeling/volumes/properties.html#bpy-types-volume-sequence-mode"), - ("bpy.types.volumetomeshmodifier*", "modeling/modifiers/generate/volume_to_mesh.html#bpy-types-volumetomeshmodifier"), - ("bpy.types.whitebalancemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-whitebalancemodifier"), - ("bpy.ops.anim.channels_ungroup*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-ungroup"), - ("bpy.ops.armature.extrude_move*", "animation/armatures/bones/editing/extrude.html#bpy-ops-armature-extrude-move"), - ("bpy.ops.armature.parent_clear*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-clear"), - ("bpy.ops.clip.clear_track_path*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clear-track-path"), - ("bpy.ops.clip.set_scene_frames*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-scene-frames"), - ("bpy.ops.curve.handle_type_set*", "modeling/curves/editing/control_points.html#bpy-ops-curve-handle-type-set"), - ("bpy.ops.curve.spline_type_set*", "modeling/curves/editing/curve.html#bpy-ops-curve-spline-type-set"), - ("bpy.ops.file.unpack_libraries*", "files/blend/packed_data.html#bpy-ops-file-unpack-libraries"), - ("bpy.ops.gpencil.layer_isolate*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-isolate"), - ("bpy.ops.gpencil.move_to_layer*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-move-to-layer"), - ("bpy.ops.gpencil.stroke_sample*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-sample"), - ("bpy.ops.gpencil.stroke_smooth*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-smooth"), - ("bpy.ops.graph.keyframe_insert*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-keyframe-insert"), - ("bpy.ops.image.read_viewlayers*", "editors/image/editing.html#bpy-ops-image-read-viewlayers"), - ("bpy.ops.mesh.blend_from_shape*", "modeling/meshes/editing/vertex/blend_shape.html#bpy-ops-mesh-blend-from-shape"), - ("bpy.ops.mesh.dissolve_limited*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-limited"), - ("bpy.ops.mesh.face_make_planar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-face-make-planar"), - ("bpy.ops.mesh.face_set_extract*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-mesh-face-set-extract"), - ("bpy.ops.mesh.faces_shade_flat*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-faces-shade-flat"), - ("bpy.ops.mesh.paint_mask_slice*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-mesh-paint-mask-slice"), - ("bpy.ops.mesh.select_ungrouped*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-ungrouped"), - ("bpy.ops.node.delete_reconnect*", "interface/controls/nodes/editing.html#bpy-ops-node-delete-reconnect"), - ("bpy.ops.node.tree_path_parent*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-path-parent"), - ("bpy.ops.node.tree_socket_move*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-move"), - ("bpy.ops.object.duplicate_move*", "scene_layout/object/editing/duplicate.html#bpy-ops-object-duplicate-move"), - ("bpy.ops.object.hook_add_selob*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook-add-selob"), - ("bpy.ops.object.modifier_apply*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-apply"), - ("bpy.ops.object.select_by_type*", "scene_layout/object/selecting.html#bpy-ops-object-select-by-type"), - ("bpy.ops.object.select_grouped*", "scene_layout/object/selecting.html#bpy-ops-object-select-grouped"), - ("bpy.ops.object.select_pattern*", "scene_layout/object/selecting.html#bpy-ops-object-select-pattern"), - ("bpy.ops.outliner.id_operation*", "editors/outliner/editing.html#bpy-ops-outliner-id-operation"), - ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-flood-fill"), - ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), - ("bpy.ops.pose.select_hierarchy*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-hierarchy"), - ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), - ("bpy.ops.poselib.copy_as_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-copy-as-asset"), - ("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"), - ("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"), - ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), - ("bpy.ops.script.execute_preset*", "interface/window_system/tabs_panels.html#bpy-ops-script-execute-preset"), - ("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-init"), - ("bpy.ops.sequencer.change_path*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-path"), - ("bpy.ops.sequencer.refresh_all*", "editors/video_sequencer/sequencer/navigating.html#bpy-ops-sequencer-refresh-all"), - ("bpy.ops.sequencer.select_less*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-less"), - ("bpy.ops.sequencer.select_more*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-more"), - ("bpy.ops.sequencer.select_side*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-side"), - ("bpy.ops.sequencer.swap_inputs*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap-inputs"), - ("bpy.ops.surface.primitive*add*", "modeling/surfaces/primitives.html#bpy-ops-surface-primitive-add"), - ("bpy.ops.text.resolve_conflict*", "editors/text_editor.html#bpy-ops-text-resolve-conflict"), - ("bpy.ops.transform.edge_crease*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-crease"), - ("bpy.ops.transform.skin_resize*", "modeling/meshes/editing/mesh/transform/skin_resize.html#bpy-ops-transform-skin-resize"), - ("bpy.ops.uv.seams_from_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-seams-from-islands"), - ("bpy.types.bakesettings.margin*", "render/cycles/baking.html#bpy-types-bakesettings-margin"), - ("bpy.types.bakesettings.target*", "render/cycles/baking.html#bpy-types-bakesettings-target"), - ("bpy.types.brush.cloth_damping*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-damping"), - ("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"), - ("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"), - ("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"), - ("bpy.types.camera.sensor_width*", "render/cameras.html#bpy-types-camera-sensor-width"), - ("bpy.types.compositornodedblur*", "compositing/types/filter/directional_blur.html#bpy-types-compositornodedblur"), - ("bpy.types.compositornodegamma*", "compositing/types/color/gamma.html#bpy-types-compositornodegamma"), - ("bpy.types.compositornodeglare*", "compositing/types/filter/glare.html#bpy-types-compositornodeglare"), - ("bpy.types.compositornodegroup*", "compositing/types/groups.html#bpy-types-compositornodegroup"), - ("bpy.types.compositornodeimage*", "compositing/types/input/image.html#bpy-types-compositornodeimage"), - ("bpy.types.compositornodemapuv*", "compositing/types/distort/map_uv.html#bpy-types-compositornodemapuv"), - ("bpy.types.compositornodescale*", "compositing/types/distort/scale.html#bpy-types-compositornodescale"), - ("bpy.types.compositornodevalue*", "compositing/types/input/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"), - ("bpy.types.curve.use_fill_caps*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-fill-caps"), - ("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"), - ("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"), - ("bpy.types.dashgpencilmodifier*", "grease_pencil/modifiers/generate/dash.html#bpy-types-dashgpencilmodifier"), - ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), - ("bpy.types.functionnodecompare*", "modeling/geometry_nodes/utilities/compare.html#bpy-types-functionnodecompare"), - ("bpy.types.geometrynodeinputid*", "modeling/geometry_nodes/input/id.html#bpy-types-geometrynodeinputid"), - ("bpy.types.geometrynoderaycast*", "modeling/geometry_nodes/geometry/raycast.html#bpy-types-geometrynoderaycast"), - ("bpy.types.gpencillayer.parent*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent"), - ("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"), - ("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"), - ("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"), - ("bpy.types.material.line_color*", "render/freestyle/material.html#bpy-types-material-line-color"), - ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"), - ("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera"), - ("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"), - ("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"), - ("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"), - ("bpy.types.posebone.bone_group*", "animation/armatures/bones/properties/relations.html#bpy-types-posebone-bone-group"), - ("bpy.types.poseboneconstraints*", "animation/armatures/posing/bone_constraints/index.html#bpy-types-poseboneconstraints"), - ("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.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"), - ("bpy.types.shadernodebsdfglass*", "render/shader_nodes/shader/glass.html#bpy-types-shadernodebsdfglass"), - ("bpy.types.shadernodelightpath*", "render/shader_nodes/input/light_path.html#bpy-types-shadernodelightpath"), - ("bpy.types.shadernodemixshader*", "render/shader_nodes/shader/mix.html#bpy-types-shadernodemixshader"), - ("bpy.types.shadernodenormalmap*", "render/shader_nodes/vector/normal_map.html#bpy-types-shadernodenormalmap"), - ("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.spacesequenceeditor*", "editors/video_sequencer/index.html#bpy-types-spacesequenceeditor"), - ("bpy.types.spline.resolution_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-resolution-u"), - ("bpy.types.spline.use_bezier_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-bezier-u"), - ("bpy.types.spline.use_cyclic_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-cyclic-u"), - ("bpy.types.stretchtoconstraint*", "animation/constraints/tracking/stretch_to.html#bpy-types-stretchtoconstraint"), - ("bpy.types.texturenodecurvergb*", "editors/texture_node/types/color/rgb_curves.html#bpy-types-texturenodecurvergb"), - ("bpy.types.texturenodedistance*", "editors/texture_node/types/converter/distance.html#bpy-types-texturenodedistance"), - ("bpy.types.texturenodetexblend*", "editors/texture_node/types/textures/blend.html#bpy-types-texturenodetexblend"), - ("bpy.types.texturenodetexmagic*", "editors/texture_node/types/textures/magic.html#bpy-types-texturenodetexmagic"), - ("bpy.types.texturenodetexnoise*", "editors/texture_node/types/textures/noise.html#bpy-types-texturenodetexnoise"), - ("bpy.types.texturenodevaltonor*", "editors/texture_node/types/converter/value_to_normal.html#bpy-types-texturenodevaltonor"), - ("bpy.types.texturenodevaltorgb*", "editors/texture_node/types/converter/rgb_to_bw.html#bpy-types-texturenodevaltorgb"), - ("bpy.types.timegpencilmodifier*", "grease_pencil/modifiers/modify/time_offset.html#bpy-types-timegpencilmodifier"), - ("bpy.types.tintgpencilmodifier*", "grease_pencil/modifiers/color/tint.html#bpy-types-tintgpencilmodifier"), - ("bpy.types.transformconstraint*", "animation/constraints/transform/transformation.html#bpy-types-transformconstraint"), - ("bpy.types.triangulatemodifier*", "modeling/modifiers/generate/triangulate.html#bpy-types-triangulatemodifier"), - ("bpy.types.unitsettings.system*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system"), - ("bpy.types.viewlayer.use_solid*", "render/layers/introduction.html#bpy-types-viewlayer-use-solid"), - ("bpy.types.volume.frame_offset*", "modeling/volumes/properties.html#bpy-types-volume-frame-offset"), - ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), - ("bpy.ops.anim.channels_delete*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-delete"), - ("bpy.ops.anim.channels_expand*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-expand"), - ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), - ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), - ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), - ("bpy.ops.armature.select_less*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-less"), - ("bpy.ops.armature.select_more*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-more"), - ("bpy.ops.asset.bundle_install*", "editors/asset_browser.html#bpy-ops-asset-bundle-install"), - ("bpy.ops.clip.add_marker_move*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-add-marker-move"), - ("bpy.ops.clip.bundles_to_mesh*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-bundles-to-mesh"), - ("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"), - ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), - ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), - ("bpy.ops.curve.duplicate_move*", "modeling/curves/editing/curve.html#bpy-ops-curve-duplicate-move"), - ("bpy.ops.file.autopack_toggle*", "files/blend/packed_data.html#bpy-ops-file-autopack-toggle"), - ("bpy.ops.fluid.bake_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-bake-particles"), - ("bpy.ops.fluid.free_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-free-particles"), - ("bpy.ops.gpencil.extrude_move*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-extrude-move"), - ("bpy.ops.gpencil.stroke_merge*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-merge"), - ("bpy.ops.gpencil.stroke_split*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-split"), - ("bpy.ops.graph.duplicate_move*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-duplicate-move"), - ("bpy.ops.mesh.average_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-average-normals"), - ("bpy.ops.mesh.delete_edgeloop*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete-edgeloop"), - ("bpy.ops.mesh.vertices_smooth*", "modeling/meshes/editing/vertex/smooth_vertices.html#bpy-ops-mesh-vertices-smooth"), - ("bpy.ops.nla.make_single_user*", "editors/nla/editing.html#bpy-ops-nla-make-single-user"), - ("bpy.ops.node.clipboard_paste*", "interface/controls/nodes/editing.html#bpy-ops-node-clipboard-paste"), - ("bpy.ops.node.node_copy_color*", "interface/controls/nodes/sidebar.html#bpy-ops-node-node-copy-color"), - ("bpy.ops.node.read_viewlayers*", "interface/controls/nodes/editing.html#bpy-ops-node-read-viewlayers"), - ("bpy.ops.node.tree_socket_add*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-add"), - ("bpy.ops.object.attribute_add*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-add"), - ("bpy.ops.object.data_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data.html#bpy-ops-object-data-transfer"), - ("bpy.ops.object.modifier_copy*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy"), - ("bpy.ops.object.select_camera*", "scene_layout/object/selecting.html#bpy-ops-object-select-camera"), - ("bpy.ops.object.select_linked*", "scene_layout/object/selecting.html#bpy-ops-object-select-linked"), - ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), - ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), - ("bpy.ops.object.transfer_mode*", "editors/3dview/modes.html#bpy-ops-object-transfer-mode"), - ("bpy.ops.outliner.show_active*", "editors/outliner/editing.html#bpy-ops-outliner-show-active"), - ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), - ("bpy.ops.pose.paths_calculate*", "animation/motion_paths.html#bpy-ops-pose-paths-calculate"), - ("bpy.ops.pose.rigify_generate*", "addons/rigging/rigify/basics.html#bpy-ops-pose-rigify-generate"), - ("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"), - ("bpy.ops.scene.view_layer_add*", "render/layers/introduction.html#bpy-ops-scene-view-layer-add"), - ("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.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"), - ("bpy.ops.sound.bake_animation*", "scene_layout/scene/properties.html#bpy-ops-sound-bake-animation"), - ("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"), - ("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"), - ("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"), - ("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"), - ("bpy.ops.wm.recover_auto_save*", "files/blend/open_save.html#bpy-ops-wm-recover-auto-save"), - ("bpy.types.adjustmentsequence*", "video_editing/edit/montage/strips/adjustment.html#bpy-types-adjustmentsequence"), - ("bpy.types.alphaundersequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"), - ("bpy.types.animvizmotionpaths*", "animation/motion_paths.html#bpy-types-animvizmotionpaths"), - ("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"), - ("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"), - ("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"), - ("bpy.types.compositornodecomb*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodecomb"), - ("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"), - ("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"), - ("bpy.types.compositornodemask*", "compositing/types/input/mask.html#bpy-types-compositornodemask"), - ("bpy.types.compositornodemath*", "compositing/types/converter/math.html#bpy-types-compositornodemath"), - ("bpy.types.compositornodetime*", "compositing/types/input/time_curve.html#bpy-types-compositornodetime"), - ("bpy.types.constraint.enabled*", "animation/constraints/interface/header.html#bpy-types-constraint-enabled"), - ("bpy.types.curve.bevel_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-object"), - ("bpy.types.curve.resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-resolution-u"), - ("bpy.types.curve.resolution_v*", "modeling/surfaces/properties/shape.html#bpy-types-curve-resolution-v"), - ("bpy.types.curve.taper_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-taper-object"), - ("bpy.types.curve.twist_smooth*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-smooth"), - ("bpy.types.curvepaintsettings*", "modeling/curves/tools/draw.html#bpy-types-curvepaintsettings"), - ("bpy.types.fcurve.array_index*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-array-index"), - ("bpy.types.fileselectidfilter*", "editors/file_browser.html#bpy-types-fileselectidfilter"), - ("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiergenerator"), - ("bpy.types.freestylelinestyle*", "render/freestyle/view_layer/line_style/index.html#bpy-types-freestylelinestyle"), - ("bpy.types.gammacrosssequence*", "video_editing/edit/montage/strips/transitions/gamma_cross.html#bpy-types-gammacrosssequence"), - ("bpy.types.geometrynodeswitch*", "modeling/geometry_nodes/utilities/switch.html#bpy-types-geometrynodeswitch"), - ("bpy.types.geometrynodeviewer*", "modeling/geometry_nodes/output/viewer.html#bpy-types-geometrynodeviewer"), - ("bpy.types.gpencillayer.scale*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-scale"), - ("bpy.types.gpencilsculptguide*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide"), - ("bpy.types.huecorrectmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-huecorrectmodifier"), - ("bpy.types.image.is_multiview*", "editors/image/image_settings.html#bpy-types-image-is-multiview"), - ("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"), - ("bpy.types.meshdeformmodifier*", "modeling/modifiers/deform/mesh_deform.html#bpy-types-meshdeformmodifier"), - ("bpy.types.movietrackingtrack*", "movie_clip/tracking/clip/sidebar/track/index.html#bpy-types-movietrackingtrack"), - ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), - ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), - ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), - ("bpy.types.object.hide_render*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-render"), - ("bpy.types.object.hide_select*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-select"), - ("bpy.types.object.parent_type*", "scene_layout/object/properties/relations.html#bpy-types-object-parent-type"), - ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), - ("bpy.types.rendersettings.fps*", "render/output/properties/format.html#bpy-types-rendersettings-fps"), - ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), - ("bpy.types.sculpt.detail_size*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-size"), - ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), - ("bpy.types.shadernodebsdftoon*", "render/shader_nodes/shader/toon.html#bpy-types-shadernodebsdftoon"), - ("bpy.types.shadernodeemission*", "render/shader_nodes/shader/emission.html#bpy-types-shadernodeemission"), - ("bpy.types.shadernodehairinfo*", "render/shader_nodes/input/hair_info.html#bpy-types-shadernodehairinfo"), - ("bpy.types.shadernodemaprange*", "render/shader_nodes/converter/map_range.html#bpy-types-shadernodemaprange"), - ("bpy.types.shadernodergbcurve*", "modeling/geometry_nodes/color/rgb_curves.html#bpy-types-shadernodergbcurve"), - ("bpy.types.shadernodeseparate*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodeseparate"), - ("bpy.types.shadernodetexbrick*", "render/shader_nodes/textures/brick.html#bpy-types-shadernodetexbrick"), - ("bpy.types.shadernodetexcoord*", "render/shader_nodes/input/texture_coordinate.html#bpy-types-shadernodetexcoord"), - ("bpy.types.shadernodeteximage*", "render/shader_nodes/textures/image.html#bpy-types-shadernodeteximage"), - ("bpy.types.shadernodetexmagic*", "render/shader_nodes/textures/magic.html#bpy-types-shadernodetexmagic"), - ("bpy.types.shadernodetexnoise*", "render/shader_nodes/textures/noise.html#bpy-types-shadernodetexnoise"), - ("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"), - ("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"), - ("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"), - ("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"), - ("bpy.types.texturenodetexwood*", "editors/texture_node/types/textures/wood.html#bpy-types-texturenodetexwood"), - ("bpy.types.view3dshading.type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-type"), - ("bpy.types.volume.frame_start*", "modeling/volumes/properties.html#bpy-types-volume-frame-start"), - ("bpy.types.volume.is_sequence*", "modeling/volumes/properties.html#bpy-types-volume-is-sequence"), - ("bpy.types.volumerender.space*", "modeling/volumes/properties.html#bpy-types-volumerender-space"), - ("bpy.ops.anim.channels_group*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-group"), - ("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"), - ("bpy.ops.armature.flip_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-flip-names"), - ("bpy.ops.armature.parent_set*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-set"), - ("bpy.ops.armature.select_all*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-all"), - ("bpy.ops.armature.symmetrize*", "animation/armatures/bones/editing/symmetrize.html#bpy-ops-armature-symmetrize"), - ("bpy.ops.clip.average_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-average-tracks"), - ("bpy.ops.clip.refine_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-refine-markers"), - ("bpy.ops.clip.select_grouped*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-grouped"), - ("bpy.ops.clip.track_to_empty*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-track-to-empty"), - ("bpy.ops.curve.cyclic_toggle*", "modeling/curves/editing/curve.html#bpy-ops-curve-cyclic-toggle"), - ("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"), - ("bpy.ops.curve.smooth_radius*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-radius"), - ("bpy.ops.curve.smooth_weight*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-weight"), - ("bpy.ops.file.pack_libraries*", "files/blend/packed_data.html#bpy-ops-file-pack-libraries"), - ("bpy.ops.font.change_spacing*", "modeling/texts/editing.html#bpy-ops-font-change-spacing"), - ("bpy.ops.gpencil.layer_merge*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-merge"), - ("bpy.ops.gpencil.stroke_flip*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-flip"), - ("bpy.ops.gpencil.stroke_join*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-join"), - ("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.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"), - ("bpy.ops.mesh.dissolve_faces*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-faces"), - ("bpy.ops.mesh.dissolve_verts*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-verts"), - ("bpy.ops.mesh.duplicate_move*", "modeling/meshes/editing/mesh/duplicate.html#bpy-ops-mesh-duplicate-move"), - ("bpy.ops.mesh.extrude_region*", "modeling/meshes/tools/extrude_region.html#bpy-ops-mesh-extrude-region"), - ("bpy.ops.mesh.extrude_repeat*", "modeling/meshes/editing/mesh/extrude.html#bpy-ops-mesh-extrude-repeat"), - ("bpy.ops.mesh.loop_to_region*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-to-region"), - ("bpy.ops.mesh.region_to_loop*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-region-to-loop"), - ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), - ("bpy.ops.mesh.select_similar*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar"), - ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), - ("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"), - ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), - ("bpy.ops.node.clipboard_copy*", "interface/controls/nodes/editing.html#bpy-ops-node-clipboard-copy"), - ("bpy.ops.node.duplicate_move*", "interface/controls/nodes/editing.html#bpy-ops-node-duplicate-move"), - ("bpy.ops.node.options_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-options-toggle"), - ("bpy.ops.node.preview_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-preview-toggle"), - ("bpy.ops.object.origin_clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-origin-clear"), - ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), - ("bpy.ops.object.paths_update*", "animation/motion_paths.html#bpy-ops-object-paths-update"), - ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), - ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), - ("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"), - ("bpy.ops.pose.group_deselect*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-deselect"), - ("bpy.ops.pose.group_unassign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-unassign"), - ("bpy.ops.pose.select_grouped*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-grouped"), - ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), - ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), - ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), - ("bpy.ops.sequencer.swap_data*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap-data"), - ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), - ("bpy.ops.transform.seq_slide*", "video_editing/edit/montage/editing.html#bpy-ops-transform-seq-slide"), - ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-trackball"), - ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), - ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/move.html#bpy-ops-transform-translate"), - ("bpy.ops.ui.eyedropper_color*", "interface/controls/templates/color_picker.html#bpy-ops-ui-eyedropper-color"), - ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), - ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), - ("bpy.ops.uv.select_edge_ring*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-ring"), - ("bpy.ops.wm.save_as_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-as-mainfile"), - ("bpy.types.alphaoversequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), - ("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"), - ("bpy.types.brush.pose_offset*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-offset"), - ("bpy.types.brush.rake_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-rake-factor"), - ("bpy.types.camera.sensor_fit*", "render/cameras.html#bpy-types-camera-sensor-fit"), - ("bpy.types.cameradofsettings*", "render/cameras.html#bpy-types-cameradofsettings"), - ("bpy.types.childofconstraint*", "animation/constraints/relationship/child_of.html#bpy-types-childofconstraint"), - ("bpy.types.clamptoconstraint*", "animation/constraints/tracking/clamp_to.html#bpy-types-clamptoconstraint"), - ("bpy.types.collisionmodifier*", "physics/collision.html#bpy-types-collisionmodifier"), - ("bpy.types.collisionsettings*", "physics/collision.html#bpy-types-collisionsettings"), - ("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"), - ("bpy.types.compositornodesep*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodesep"), - ("bpy.types.curve.bevel_depth*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-depth"), - ("bpy.types.curve.use_stretch*", "modeling/curves/properties/shape.html#bpy-types-curve-use-stretch"), - ("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"), - ("bpy.types.fcurve.color_mode*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-color-mode"), - ("bpy.types.fluidflowsettings*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings"), - ("bpy.types.fmodifierenvelope*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelope"), - ("bpy.types.freestylesettings*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings"), - ("bpy.types.geometrynodegroup*", "modeling/geometry_nodes/group.html#bpy-types-geometrynodegroup"), - ("bpy.types.geometrynodesetid*", "modeling/geometry_nodes/geometry/set_id.html#bpy-types-geometrynodesetid"), - ("bpy.types.gpencillayer.hide*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-hide"), - ("bpy.types.gpencillayer.lock*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-lock"), - ("bpy.types.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"), - ("bpy.types.materialslot.link*", "render/materials/assignment.html#bpy-types-materialslot-link"), - ("bpy.types.mesh.texture_mesh*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-mesh-texture-mesh"), - ("bpy.types.mesh.use_mirror_x*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-x"), - ("bpy.types.mesh.use_mirror_y*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-y"), - ("bpy.types.mesh.use_mirror_z*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-z"), - ("bpy.types.meshcachemodifier*", "modeling/modifiers/modify/mesh_cache.html#bpy-types-meshcachemodifier"), - ("bpy.types.movieclipsequence*", "video_editing/edit/montage/strips/clip.html#bpy-types-movieclipsequence"), - ("bpy.types.object.dimensions*", "scene_layout/object/properties/transforms.html#bpy-types-object-dimensions"), - ("bpy.types.object.is_holdout*", "scene_layout/object/properties/visibility.html#bpy-types-object-is-holdout"), - ("bpy.types.object.pass_index*", "scene_layout/object/properties/relations.html#bpy-types-object-pass-index"), - ("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"), - ("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"), - ("bpy.types.preferencessystem*", "editors/preferences/system.html#bpy-types-preferencessystem"), - ("bpy.types.scene.active_clip*", "scene_layout/scene/properties.html#bpy-types-scene-active-clip"), - ("bpy.types.scene.frame_start*", "render/output/properties/frame_range.html#bpy-types-scene-frame-start"), - ("bpy.types.sceneeevee.shadow*", "render/eevee/render_settings/shadows.html#bpy-types-sceneeevee-shadow"), - ("bpy.types.screen.use_follow*", "editors/timeline.html#bpy-types-screen-use-follow"), - ("bpy.types.sequencetransform*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform"), - ("bpy.types.shadernodecombine*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodecombine"), - ("bpy.types.shadernodefresnel*", "render/shader_nodes/input/fresnel.html#bpy-types-shadernodefresnel"), - ("bpy.types.shadernodeholdout*", "render/shader_nodes/shader/holdout.html#bpy-types-shadernodeholdout"), - ("bpy.types.shadernodemapping*", "render/shader_nodes/vector/mapping.html#bpy-types-shadernodemapping"), - ("bpy.types.shadernodergbtobw*", "render/shader_nodes/converter/rgb_to_bw.html#bpy-types-shadernodergbtobw"), - ("bpy.types.shadernodetangent*", "render/shader_nodes/input/tangent.html#bpy-types-shadernodetangent"), - ("bpy.types.shadernodetexwave*", "render/shader_nodes/textures/wave.html#bpy-types-shadernodetexwave"), - ("bpy.types.spline.use_smooth*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-smooth"), - ("bpy.types.texturenodebricks*", "editors/texture_node/types/patterns/bricks.html#bpy-types-texturenodebricks"), - ("bpy.types.texturenodemixrgb*", "editors/texture_node/types/color/mix_rgb.html#bpy-types-texturenodemixrgb"), - ("bpy.types.texturenodeoutput*", "editors/texture_node/types/output/output.html#bpy-types-texturenodeoutput"), - ("bpy.types.texturenoderotate*", "editors/texture_node/types/distort/rotate.html#bpy-types-texturenoderotate"), - ("bpy.types.texturenodeviewer*", "editors/texture_node/types/output/viewer.html#bpy-types-texturenodeviewer"), - ("bpy.types.tracktoconstraint*", "animation/constraints/tracking/track_to.html#bpy-types-tracktoconstraint"), - ("bpy.types.transformsequence*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence"), - ("bpy.types.uvprojectmodifier*", "modeling/modifiers/modify/uv_project.html#bpy-types-uvprojectmodifier"), - ("bpy.types.viewlayer.samples*", "render/layers/introduction.html#bpy-types-viewlayer-samples"), - ("bpy.types.viewlayer.use_sky*", "render/layers/introduction.html#bpy-types-viewlayer-use-sky"), - ("bpy.types.wireframemodifier*", "modeling/modifiers/generate/wireframe.html#bpy-types-wireframemodifier"), - ("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"), - ("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"), - ("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"), - ("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"), - ("bpy.ops.clip.filter_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-filter-tracks"), - ("bpy.ops.clip.select_circle*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-circle"), - ("bpy.ops.clip.track_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-track-markers"), - ("bpy.ops.curve.extrude_move*", "modeling/curves/editing/control_points.html#bpy-ops-curve-extrude-move"), - ("bpy.ops.curve.make_segment*", "modeling/curves/editing/control_points.html#bpy-ops-curve-make-segment"), - ("bpy.ops.file.directory_new*", "editors/file_browser.html#bpy-ops-file-directory-new"), - ("bpy.ops.graph.euler_filter*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-euler-filter"), - ("bpy.ops.marker.camera_bind*", "animation/markers.html#bpy-ops-marker-camera-bind"), - ("bpy.ops.mask.select_circle*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-circle"), - ("bpy.ops.mask.select_linked*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-linked"), - ("bpy.ops.mesh.beautify_fill*", "modeling/meshes/editing/face/beautify_faces.html#bpy-ops-mesh-beautify-fill"), - ("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"), - ("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"), - ("bpy.ops.mesh.edge_face_add*", "modeling/meshes/editing/vertex/make_face_edge.html#bpy-ops-mesh-edge-face-add"), - ("bpy.ops.mesh.extrude_indiv*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-mesh-extrude-indiv"), - ("bpy.ops.mesh.knife_project*", "modeling/meshes/editing/mesh/knife_project.html#bpy-ops-mesh-knife-project"), - ("bpy.ops.mesh.loopcut_slide*", "modeling/meshes/editing/edge/loopcut_slide.html#bpy-ops-mesh-loopcut-slide"), - ("bpy.ops.mesh.merge_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-merge-normals"), - ("bpy.ops.mesh.normals_tools*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-tools"), - ("bpy.ops.mesh.point_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-point-normals"), - ("bpy.ops.mesh.rip_edge_move*", "modeling/meshes/editing/vertex/rip_vertices_extend.html#bpy-ops-mesh-rip-edge-move"), - ("bpy.ops.mesh.select_linked*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-select-linked"), - ("bpy.ops.mesh.select_random*", "modeling/meshes/selecting/random.html#bpy-ops-mesh-select-random"), - ("bpy.ops.mesh.sort_elements*", "modeling/meshes/editing/mesh/sort_elements.html#bpy-ops-mesh-sort-elements"), - ("bpy.ops.mesh.split_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-split-normals"), - ("bpy.ops.mesh.symmetry_snap*", "modeling/meshes/editing/mesh/snap_symmetry.html#bpy-ops-mesh-symmetry-snap"), - ("bpy.ops.node.group_ungroup*", "interface/controls/nodes/groups.html#bpy-ops-node-group-ungroup"), - ("bpy.ops.object.gpencil_add*", "grease_pencil/primitives.html#bpy-ops-object-gpencil-add"), - ("bpy.ops.object.paths_clear*", "animation/motion_paths.html#bpy-ops-object-paths-clear"), - ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), - ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), - ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), - ("bpy.ops.pose.select_linked*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-linked"), - ("bpy.ops.pose.select_mirror*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-mirror"), - ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), - ("bpy.ops.screen.marker_jump*", "animation/markers.html#bpy-ops-screen-marker-jump"), - ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), - ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-expand"), - ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-filter"), - ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), - ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), - ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), - ("bpy.ops.wm.properties_edit*", "files/data_blocks.html#bpy-ops-wm-properties-edit"), - ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), - ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), - ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), - ("bpy.types.arealight.spread*", "render/lights/light_object.html#bpy-types-arealight-spread"), - ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), - ("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"), - ("bpy.types.bone.tail_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-tail-radius"), - ("bpy.types.brush.cloth_mass*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-mass"), - ("bpy.types.brushtextureslot*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot"), - ("bpy.types.colormixsequence*", "video_editing/edit/montage/strips/effects/color_mix.html#bpy-types-colormixsequence"), - ("bpy.types.curve.dimensions*", "modeling/curves/properties/shape.html#bpy-types-curve-dimensions"), - ("bpy.types.curve.taper_mode*", "modeling/curves/properties/geometry.html#bpy-types-curve-taper-mode"), - ("bpy.types.curve.twist_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-mode"), - ("bpy.types.curve.use_radius*", "modeling/curves/properties/shape.html#bpy-types-curve-use-radius"), - ("bpy.types.decimatemodifier*", "modeling/modifiers/generate/decimate.html#bpy-types-decimatemodifier"), - ("bpy.types.displacemodifier*", "modeling/modifiers/deform/displace.html#bpy-types-displacemodifier"), - ("bpy.types.displaysafeareas*", "render/cameras.html#bpy-types-displaysafeareas"), - ("bpy.types.editbone.bbone_x*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-x"), - ("bpy.types.editbone.bbone_z*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-z"), - ("bpy.types.fcurve.data_path*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-data-path"), - ("bpy.types.fileselectparams*", "editors/file_browser.html#bpy-types-fileselectparams"), - ("bpy.types.fmodifierstepped*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierstepped"), - ("bpy.types.freestylelineset*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset"), - ("bpy.types.greasepencilgrid*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid"), - ("bpy.types.image.alpha_mode*", "editors/image/image_settings.html#bpy-types-image-alpha-mode"), - ("bpy.types.mask.frame_start*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-start"), - ("bpy.types.motionpath.color*", "animation/motion_paths.html#bpy-types-motionpath-color"), - ("bpy.types.motionpath.lines*", "animation/motion_paths.html#bpy-types-motionpath-lines"), - ("bpy.types.multicamsequence*", "video_editing/edit/montage/strips/effects/multicam.html#bpy-types-multicamsequence"), - ("bpy.types.multiplysequence*", "video_editing/edit/montage/strips/effects/multiply.html#bpy-types-multiplysequence"), - ("bpy.types.multiresmodifier*", "modeling/modifiers/generate/multiresolution.html#bpy-types-multiresmodifier"), - ("bpy.types.overdropsequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-overdropsequence"), - ("bpy.types.paint.show_brush*", "sculpt_paint/brush/cursor.html#bpy-types-paint-show-brush"), - ("bpy.types.paint.use_cavity*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-paint-use-cavity"), - ("bpy.types.particlesettings*", "physics/particles/index.html#bpy-types-particlesettings"), - ("bpy.types.pose.use_auto_ik*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-auto-ik"), - ("bpy.types.preferencesinput*", "editors/preferences/input.html#bpy-types-preferencesinput"), - ("bpy.types.rigifyparameters*", "addons/rigging/rigify/rig_types/index.html#bpy-types-rigifyparameters"), - ("bpy.types.scene.frame_step*", "render/output/properties/frame_range.html#bpy-types-scene-frame-step"), - ("bpy.types.sceneeevee.bloom*", "render/eevee/render_settings/bloom.html#bpy-types-sceneeevee-bloom"), - ("bpy.types.sculpt.show_mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-sculpt-show-mask"), - ("bpy.types.sequence.channel*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-channel"), - ("bpy.types.sequencemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier"), - ("bpy.types.shaderfxcolorize*", "grease_pencil/visual_effects/colorize.html#bpy-types-shaderfxcolorize"), - ("bpy.types.shaderfxpixelate*", "grease_pencil/visual_effects/pixelate.html#bpy-types-shaderfxpixelate"), - ("bpy.types.shadernodeinvert*", "render/shader_nodes/color/invert.html#bpy-types-shadernodeinvert"), - ("bpy.types.shadernodemixrgb*", "modeling/geometry_nodes/color/mix_rgb.html#bpy-types-shadernodemixrgb"), - ("bpy.types.shadernodenormal*", "render/shader_nodes/vector/normal.html#bpy-types-shadernodenormal"), - ("bpy.types.shadernodescript*", "render/shader_nodes/osl.html#bpy-types-shadernodescript"), - ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), - ("bpy.types.shadernodetexsky*", "render/shader_nodes/textures/sky.html#bpy-types-shadernodetexsky"), - ("bpy.types.softbodymodifier*", "physics/soft_body/index.html#bpy-types-softbodymodifier"), - ("bpy.types.softbodysettings*", "physics/soft_body/settings/index.html#bpy-types-softbodysettings"), - ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), - ("bpy.types.spacefilebrowser*", "editors/file_browser.html#bpy-types-spacefilebrowser"), - ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), - ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), - ("bpy.types.spacespreadsheet*", "editors/spreadsheet.html#bpy-types-spacespreadsheet"), - ("bpy.types.spaceview3d.lock*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock"), - ("bpy.types.spaceview3d.show*", "editors/3dview/display/index.html#bpy-types-spaceview3d-show"), - ("bpy.types.sphfluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-sphfluidsettings"), - ("bpy.types.subtractsequence*", "video_editing/edit/montage/strips/effects/subtract.html#bpy-types-subtractsequence"), - ("bpy.types.text.indentation*", "editors/text_editor.html#bpy-types-text-indentation"), - ("bpy.types.texture.contrast*", "render/materials/legacy_textures/colors.html#bpy-types-texture-contrast"), - ("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"), - ("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"), - ("bpy.types.texturenodescale*", "editors/texture_node/types/distort/scale.html#bpy-types-texturenodescale"), - ("bpy.types.viewlayer.use_ao*", "render/layers/introduction.html#bpy-types-viewlayer-use-ao"), - ("bpy.ops.armature.dissolve*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-dissolve"), - ("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"), - ("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"), - ("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"), - ("bpy.ops.clip.select_lasso*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-lasso"), - ("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"), - ("bpy.ops.constraint.delete*", "animation/constraints/interface/header.html#bpy-ops-constraint-delete"), - ("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"), - ("bpy.ops.file.reset_recent*", "editors/file_browser.html#bpy-ops-file-reset-recent"), - ("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"), - ("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"), - ("bpy.ops.font.style_toggle*", "modeling/texts/editing.html#bpy-ops-font-style-toggle"), - ("bpy.ops.gpencil.mesh_bake*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-mesh-bake"), - ("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"), - ("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.mask.parent_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-clear"), - ("bpy.ops.mask.select_lasso*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-lasso"), - ("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"), - ("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"), - ("bpy.ops.mesh.face_shading*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-face-shading"), - ("bpy.ops.mesh.flip_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-flip-normals"), - ("bpy.ops.mesh.select_loose*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-loose"), - ("bpy.ops.mesh.vert_connect*", "modeling/meshes/editing/vertex/connect_vertex_pairs.html#bpy-ops-mesh-vert-connect"), - ("bpy.ops.nla.tracks_delete*", "editors/nla/editing.html#bpy-ops-nla-tracks-delete"), - ("bpy.ops.node.group_insert*", "interface/controls/nodes/groups.html#bpy-ops-node-group-insert"), - ("bpy.ops.object.lightprobe*", "render/eevee/light_probes/index.html#bpy-ops-object-lightprobe"), - ("bpy.ops.object.make_local*", "files/linked_libraries/link_append.html#bpy-ops-object-make-local"), - ("bpy.ops.object.origin_set*", "scene_layout/object/origin.html#bpy-ops-object-origin-set"), - ("bpy.ops.object.parent_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-set"), - ("bpy.ops.object.pointcloud*", "modeling/point_cloud.html#bpy-ops-object-pointcloud"), - ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), - ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), - ("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"), - ("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"), - ("bpy.ops.pose.paths_update*", "animation/motion_paths.html#bpy-ops-pose-paths-update"), - ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), - ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), - ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), - ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), - ("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.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"), - ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), - ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), - ("bpy.ops.view3d.view_orbit*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-orbit"), - ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), - ("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"), - ("bpy.types.armature.rigify*", "addons/rigging/rigify/basics.html#bpy-types-armature-rigify"), - ("bpy.types.bone.use_deform*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-deform"), - ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), - ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), - ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), - ("bpy.types.constraint.name*", "animation/constraints/interface/header.html#bpy-types-constraint-name"), - ("bpy.types.curve.eval_time*", "modeling/curves/properties/path_animation.html#bpy-types-curve-eval-time"), - ("bpy.types.curve.fill_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-fill-mode"), - ("bpy.types.editbone.layers*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-layers"), - ("bpy.types.editbone.parent*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-parent"), - ("bpy.types.explodemodifier*", "modeling/modifiers/physics/explode.html#bpy-types-explodemodifier"), - ("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fcurvemodifiers"), - ("bpy.types.floorconstraint*", "animation/constraints/relationship/floor.html#bpy-types-floorconstraint"), - ("bpy.types.fmodifiercycles*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiercycles"), - ("bpy.types.fmodifierlimits*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierlimits"), - ("bpy.types.imagepaint.mode*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-mode"), - ("bpy.types.latticemodifier*", "modeling/modifiers/deform/lattice.html#bpy-types-latticemodifier"), - ("bpy.types.materiallineart*", "render/materials/line_art.html#bpy-types-materiallineart"), - ("bpy.types.musgravetexture*", "render/materials/legacy_textures/types/musgrave.html#bpy-types-musgravetexture"), - ("bpy.types.object.location*", "scene_layout/object/properties/transforms.html#bpy-types-object-location"), - ("bpy.types.object.rotation*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation"), - ("bpy.types.particlehairkey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlehairkey"), - ("bpy.types.pivotconstraint*", "animation/constraints/relationship/pivot.html#bpy-types-pivotconstraint"), - ("bpy.types.preferencesedit*", "editors/preferences/editing.html#bpy-types-preferencesedit"), - ("bpy.types.preferencesview*", "editors/preferences/interface.html#bpy-types-preferencesview"), - ("bpy.types.rigidbodyobject*", "physics/rigid_body/index.html#bpy-types-rigidbodyobject"), - ("bpy.types.scene.frame_end*", "render/output/properties/frame_range.html#bpy-types-scene-frame-end"), - ("bpy.types.sceneeevee.gtao*", "render/eevee/render_settings/ambient_occlusion.html#bpy-types-sceneeevee-gtao"), - ("bpy.types.screen.use_play*", "editors/timeline.html#bpy-types-screen-use-play"), - ("bpy.types.shadernodebevel*", "render/shader_nodes/input/bevel.html#bpy-types-shadernodebevel"), - ("bpy.types.shadernodeclamp*", "render/shader_nodes/converter/clamp.html#bpy-types-shadernodeclamp"), - ("bpy.types.shadernodegamma*", "render/shader_nodes/color/gamma.html#bpy-types-shadernodegamma"), - ("bpy.types.shadernodegroup*", "render/shader_nodes/groups.html#bpy-types-shadernodegroup"), - ("bpy.types.shadernodeuvmap*", "render/shader_nodes/input/uv_map.html#bpy-types-shadernodeuvmap"), - ("bpy.types.shadernodevalue*", "render/shader_nodes/input/value.html#bpy-types-shadernodevalue"), - ("bpy.types.spaceclipeditor*", "movie_clip/index.html#bpy-types-spaceclipeditor"), - ("bpy.types.spaceproperties*", "editors/properties_editor.html#bpy-types-spaceproperties"), - ("bpy.types.spacetexteditor*", "editors/text_editor.html#bpy-types-spacetexteditor"), - ("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"), - ("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"), - ("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"), - ("bpy.ops.asset.tag_remove*", "editors/asset_browser.html#bpy-ops-asset-tag-remove"), - ("bpy.ops.clip.join_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-join-tracks"), - ("bpy.ops.constraint.apply*", "animation/constraints/interface/header.html#bpy-ops-constraint-apply"), - ("bpy.ops.curve.select_row*", "modeling/surfaces/selecting.html#bpy-ops-curve-select-row"), - ("bpy.ops.curve.tilt_clear*", "modeling/curves/editing/control_points.html#bpy-ops-curve-tilt-clear"), - ("bpy.ops.curve.vertex_add*", "modeling/curves/editing/other.html#bpy-ops-curve-vertex-add"), - ("bpy.ops.fluid.bake_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-bake-noise"), - ("bpy.ops.fluid.free_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-free-noise"), - ("bpy.ops.font.move_select*", "modeling/texts/selecting.html#bpy-ops-font-move-select"), - ("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.sound_bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sound-bake"), - ("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"), - ("bpy.ops.mesh.convex_hull*", "modeling/meshes/editing/mesh/convex_hull.html#bpy-ops-mesh-convex-hull"), - ("bpy.ops.mesh.edge_rotate*", "modeling/meshes/editing/edge/rotate_edge.html#bpy-ops-mesh-edge-rotate"), - ("bpy.ops.mesh.unsubdivide*", "modeling/meshes/editing/edge/unsubdivide.html#bpy-ops-mesh-unsubdivide"), - ("bpy.ops.mesh.uvs_reverse*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-reverse"), - ("bpy.ops.node.hide_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-hide-toggle"), - ("bpy.ops.node.mute_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-mute-toggle"), - ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), - ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), - ("bpy.ops.pose.paths_clear*", "animation/motion_paths.html#bpy-ops-pose-paths-clear"), - ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), - ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), - ("bpy.ops.scene.view_layer*", "render/layers/introduction.html#bpy-ops-scene-view-layer"), - ("bpy.ops.screen.redo_last*", "interface/undo_redo.html#bpy-ops-screen-redo-last"), - ("bpy.ops.sculpt.mask_init*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-init"), - ("bpy.ops.sequencer.delete*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-delete"), - ("bpy.ops.sequencer.reload*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-reload"), - ("bpy.ops.sequencer.unlock*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-unlock"), - ("bpy.ops.sequencer.unmute*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-unmute"), - ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), - ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/scale.html#bpy-ops-transform-resize"), - ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-rotate"), - ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), - ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), - ("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"), - ("bpy.ops.view3d.localview*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview"), - ("bpy.ops.view3d.view_axis*", "editors/3dview/navigate/viewpoint.html#bpy-ops-view3d-view-axis"), - ("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.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"), - ("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"), - ("bpy.types.brush.hardness*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-hardness"), - ("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"), - ("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"), - ("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"), - ("bpy.types.image.filepath*", "editors/image/image_settings.html#bpy-types-image-filepath"), - ("bpy.types.keyframe.co_ui*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-co-ui"), - ("bpy.types.mask.frame_end*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-end"), - ("bpy.types.material.paint*", "sculpt_paint/texture_paint/index.html#bpy-types-material-paint"), - ("bpy.types.mirrormodifier*", "modeling/modifiers/generate/mirror.html#bpy-types-mirrormodifier"), - ("bpy.types.movieclipproxy*", "editors/clip/sidebar.html#bpy-types-movieclipproxy"), - ("bpy.types.object.up_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-up-axis"), - ("bpy.types.particlesystem*", "physics/particles/index.html#bpy-types-particlesystem"), - ("bpy.types.particletarget*", "physics/particles/emitter/physics/keyed.html#bpy-types-particletarget"), - ("bpy.types.remeshmodifier*", "modeling/modifiers/generate/remesh.html#bpy-types-remeshmodifier"), - ("bpy.types.rendersettings*", "render/index.html#bpy-types-rendersettings"), - ("bpy.types.rigidbodyworld*", "physics/rigid_body/world.html#bpy-types-rigidbodyworld"), - ("bpy.types.sceneeevee.ssr*", "render/eevee/render_settings/screen_space_reflections.html#bpy-types-sceneeevee-ssr"), - ("bpy.types.sceneeevee.sss*", "render/eevee/render_settings/subsurface_scattering.html#bpy-types-sceneeevee-sss"), - ("bpy.types.sculpt.gravity*", "sculpt_paint/sculpting/tool_settings/options.html#bpy-types-sculpt-gravity"), - ("bpy.types.shaderfxshadow*", "grease_pencil/visual_effects/shadow.html#bpy-types-shaderfxshadow"), - ("bpy.types.shadernodebump*", "render/shader_nodes/vector/bump.html#bpy-types-shadernodebump"), - ("bpy.types.shadernodemath*", "render/shader_nodes/converter/math.html#bpy-types-shadernodemath"), - ("bpy.types.smoothmodifier*", "modeling/modifiers/deform/smooth.html#bpy-types-smoothmodifier"), - ("bpy.types.sound.use_mono*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-mono"), - ("bpy.types.spline.order_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-order-u"), - ("bpy.types.timelinemarker*", "animation/markers.html#bpy-types-timelinemarker"), - ("bpy.types.usersolidlight*", "editors/preferences/lights.html#bpy-types-usersolidlight"), - ("bpy.types.uvwarpmodifier*", "modeling/modifiers/modify/uv_warp.html#bpy-types-uvwarpmodifier"), - ("bpy.types.viewlayer.name*", "render/layers/introduction.html#bpy-types-viewlayer-name"), - ("bpy.types.voronoitexture*", "render/materials/legacy_textures/types/voronoi.html#bpy-types-voronoitexture"), - ("bpy.types.walknavigation*", "editors/3dview/navigate/walk_fly.html#bpy-types-walknavigation"), - ("bpy.ops.*.select_circle*", "interface/selecting.html#bpy-ops-select-circle"), - ("bpy.ops.anim.keying_set*", "animation/keyframes/keying_sets.html#bpy-ops-anim-keying-set"), - ("bpy.ops.armature.delete*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-delete"), - ("bpy.ops.clip.select_all*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-all"), - ("bpy.ops.clip.select_box*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-box"), - ("bpy.ops.clip.set_origin*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-origin"), - ("bpy.ops.constraint.copy*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy"), - ("bpy.ops.curve.subdivide*", "modeling/curves/editing/segments.html#bpy-ops-curve-subdivide"), - ("bpy.ops.ed.undo_history*", "interface/undo_redo.html#bpy-ops-ed-undo-history"), - ("bpy.ops.file.unpack_all*", "files/blend/packed_data.html#bpy-ops-file-unpack-all"), - ("bpy.ops.fluid.bake_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-bake-data"), - ("bpy.ops.fluid.bake_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-bake-mesh"), - ("bpy.ops.fluid.free_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-free-data"), - ("bpy.ops.fluid.free_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-free-mesh"), - ("bpy.ops.font.select_all*", "modeling/texts/selecting.html#bpy-ops-font-select-all"), - ("bpy.ops.gpencil.convert*", "grease_pencil/modes/object/convert_to_geometry.html#bpy-ops-gpencil-convert"), - ("bpy.ops.graph.breakdown*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-breakdown"), - ("bpy.ops.mask.parent_set*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-set"), - ("bpy.ops.mask.select_all*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-all"), - ("bpy.ops.mask.select_box*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-box"), - ("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-edge-split"), - ("bpy.ops.mesh.fill_holes*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-fill-holes"), - ("bpy.ops.mesh.mark_sharp*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-sharp"), - ("bpy.ops.mesh.select_nth*", "modeling/meshes/selecting/checker_deselect.html#bpy-ops-mesh-select-nth"), - ("bpy.ops.mesh.symmetrize*", "modeling/meshes/editing/mesh/symmetrize.html#bpy-ops-mesh-symmetrize"), - ("bpy.ops.mesh.uvs_rotate*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-rotate"), - ("bpy.ops.nla.apply_scale*", "editors/nla/editing.html#bpy-ops-nla-apply-scale"), - ("bpy.ops.nla.clear_scale*", "editors/nla/editing.html#bpy-ops-nla-clear-scale"), - ("bpy.ops.nla.mute_toggle*", "editors/nla/editing.html#bpy-ops-nla-mute-toggle"), - ("bpy.ops.node.group_make*", "interface/controls/nodes/groups.html#bpy-ops-node-group-make"), - ("bpy.ops.node.links_mute*", "interface/controls/nodes/editing.html#bpy-ops-node-links-mute"), - ("bpy.ops.object.armature*", "animation/armatures/index.html#bpy-ops-object-armature"), - ("bpy.ops.object.face_map*", "modeling/meshes/properties/object_data.html#bpy-ops-object-face-map"), - ("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"), - ("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"), - ("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"), - ("bpy.ops.rigidbody.world*", "physics/rigid_body/world.html#bpy-ops-rigidbody-world"), - ("bpy.ops.sculpt.optimize*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-optimize"), - ("bpy.ops.sequencer.split*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-split"), - ("bpy.ops.transform.shear*", "modeling/meshes/editing/mesh/transform/shear.html#bpy-ops-transform-shear"), - ("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cube-project"), - ("bpy.ops.uv.pack_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pack-islands"), - ("bpy.ops.uv.select_split*", "modeling/meshes/uv/editing.html#bpy-ops-uv-select-split"), - ("bpy.ops.view3d.view_pan*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-pan"), - ("bpy.ops.wm.app_template*", "advanced/app_templates.html#bpy-ops-wm-app-template"), - ("bpy.ops.wm.batch_rename*", "files/blend/rename.html#bpy-ops-wm-batch-rename"), - ("bpy.ops.wm.owner_enable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-enable"), - ("bpy.ops.wm.redraw_timer*", "advanced/operators.html#bpy-ops-wm-redraw-timer"), - ("bpy.types.*light.shadow*", "render/eevee/lighting.html#bpy-types-light-shadow"), - ("bpy.types.armature.show*", "animation/armatures/properties/display.html#bpy-types-armature-show"), - ("bpy.types.armaturebones*", "animation/armatures/bones/index.html#bpy-types-armaturebones"), - ("bpy.types.arraymodifier*", "modeling/modifiers/generate/array.html#bpy-types-arraymodifier"), - ("bpy.types.assetmetadata*", "editors/asset_browser.html#bpy-types-assetmetadata"), - ("bpy.types.bevelmodifier*", "modeling/modifiers/generate/bevel.html#bpy-types-bevelmodifier"), - ("bpy.types.buildmodifier*", "modeling/modifiers/generate/build.html#bpy-types-buildmodifier"), - ("bpy.types.clothmodifier*", "physics/cloth/index.html#bpy-types-clothmodifier"), - ("bpy.types.clothsettings*", "physics/cloth/settings/index.html#bpy-types-clothsettings"), - ("bpy.types.cloudstexture*", "render/materials/legacy_textures/types/clouds.html#bpy-types-cloudstexture"), - ("bpy.types.colorsequence*", "video_editing/edit/montage/strips/color.html#bpy-types-colorsequence"), - ("bpy.types.crosssequence*", "video_editing/edit/montage/strips/transitions/cross.html#bpy-types-crosssequence"), - ("bpy.types.curve.extrude*", "modeling/curves/properties/geometry.html#bpy-types-curve-extrude"), - ("bpy.types.curvemodifier*", "modeling/modifiers/deform/curve.html#bpy-types-curvemodifier"), - ("bpy.types.editbone.head*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-head"), - ("bpy.types.editbone.lock*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-lock"), - ("bpy.types.editbone.roll*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-roll"), - ("bpy.types.editbone.tail*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-tail"), - ("bpy.types.fieldsettings*", "physics/forces/force_fields/index.html#bpy-types-fieldsettings"), - ("bpy.types.imagesequence*", "video_editing/edit/montage/strips/image.html#bpy-types-imagesequence"), - ("bpy.types.marbletexture*", "render/materials/legacy_textures/types/marble.html#bpy-types-marbletexture"), - ("bpy.types.modifier.name*", "modeling/modifiers/introduction.html#bpy-types-modifier-name"), - ("bpy.types.modifier.show*", "modeling/modifiers/introduction.html#bpy-types-modifier-show"), - ("bpy.types.moviesequence*", "video_editing/edit/montage/strips/movie.html#bpy-types-moviesequence"), - ("bpy.types.movietracking*", "movie_clip/tracking/index.html#bpy-types-movietracking"), - ("bpy.types.nlastrip.mute*", "editors/nla/sidebar.html#bpy-types-nlastrip-mute"), - ("bpy.types.nlastrip.name*", "editors/nla/sidebar.html#bpy-types-nlastrip-name"), - ("bpy.types.nodesmodifier*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier"), - ("bpy.types.object.parent*", "scene_layout/object/editing/parent.html#bpy-types-object-parent"), - ("bpy.types.objectlineart*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart"), - ("bpy.types.oceanmodifier*", "modeling/modifiers/physics/ocean.html#bpy-types-oceanmodifier"), - ("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"), - ("bpy.types.scene.gravity*", "physics/forces/gravity.html#bpy-types-scene-gravity"), - ("bpy.types.sceneeevee.gi*", "render/eevee/render_settings/indirect_lighting.html#bpy-types-sceneeevee-gi"), - ("bpy.types.scenesequence*", "video_editing/edit/montage/strips/scene.html#bpy-types-scenesequence"), - ("bpy.types.screwmodifier*", "modeling/modifiers/generate/screw.html#bpy-types-screwmodifier"), - ("bpy.types.sequence.name*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-name"), - ("bpy.types.sequenceproxy*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy"), - ("bpy.types.shaderfxswirl*", "grease_pencil/visual_effects/swirl.html#bpy-types-shaderfxswirl"), - ("bpy.types.shadernodergb*", "render/shader_nodes/input/rgb.html#bpy-types-shadernodergb"), - ("bpy.types.soundsequence*", "video_editing/edit/montage/strips/sound.html#bpy-types-soundsequence"), - ("bpy.types.spaceoutliner*", "editors/outliner/index.html#bpy-types-spaceoutliner"), - ("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"), - ("bpy.types.spaceuveditor*", "editors/uv/index.html#bpy-types-spaceuveditor"), - ("bpy.types.stuccitexture*", "render/materials/legacy_textures/types/stucci.html#bpy-types-stuccitexture"), - ("bpy.types.texturenodeat*", "editors/texture_node/types/distort/at.html#bpy-types-texturenodeat"), - ("bpy.types.view3doverlay*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay"), - ("bpy.types.viewlayer.use*", "render/layers/view_layer.html#bpy-types-viewlayer-use"), - ("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"), - ("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"), - ("bpy.types.worldlighting*", "render/cycles/world_settings.html#bpy-types-worldlighting"), - ("bpy.ops.*.select_lasso*", "interface/selecting.html#bpy-ops-select-lasso"), - ("bpy.ops.armature.align*", "animation/armatures/bones/editing/transform.html#bpy-ops-armature-align"), - ("bpy.ops.armature.split*", "animation/armatures/bones/editing/split.html#bpy-ops-armature-split"), - ("bpy.ops.clip.set_plane*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-plane"), - ("bpy.ops.clip.set_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-scale"), - ("bpy.ops.curve.decimate*", "modeling/curves/editing/curve.html#bpy-ops-curve-decimate"), - ("bpy.ops.curve.separate*", "modeling/curves/editing/curve.html#bpy-ops-curve-separate"), - ("bpy.ops.fluid.bake_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-bake-all"), - ("bpy.ops.fluid.free_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-free-all"), - ("bpy.ops.gpencil.delete*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-delete"), - ("bpy.ops.gpencil.reveal*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-reveal"), - ("bpy.ops.gpencil.select*", "grease_pencil/selecting.html#bpy-ops-gpencil-select"), - ("bpy.ops.graph.decimate*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-decimate"), - ("bpy.ops.material.paste*", "render/materials/assignment.html#bpy-ops-material-paste"), - ("bpy.ops.mesh.fill_grid*", "modeling/meshes/editing/face/grid_fill.html#bpy-ops-mesh-fill-grid"), - ("bpy.ops.mesh.intersect*", "modeling/meshes/editing/face/intersect_knife.html#bpy-ops-mesh-intersect"), - ("bpy.ops.mesh.mark_seam*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-seam"), - ("bpy.ops.mesh.polybuild*", "modeling/meshes/tools/poly_build.html#bpy-ops-mesh-polybuild"), - ("bpy.ops.mesh.subdivide*", "modeling/meshes/editing/edge/subdivide.html#bpy-ops-mesh-subdivide"), - ("bpy.ops.mesh.wireframe*", "modeling/meshes/editing/face/wireframe.html#bpy-ops-mesh-wireframe"), - ("bpy.ops.node.link_make*", "interface/controls/nodes/editing.html#bpy-ops-node-link-make"), - ("bpy.ops.node.links_cut*", "interface/controls/nodes/editing.html#bpy-ops-node-links-cut"), - ("bpy.ops.object.convert*", "scene_layout/object/editing/convert.html#bpy-ops-object-convert"), - ("bpy.ops.object.gpencil*", "grease_pencil/index.html#bpy-ops-object-gpencil"), - ("bpy.ops.object.speaker*", "render/output/audio/speaker.html#bpy-ops-object-speaker"), - ("bpy.ops.pose.breakdown*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-breakdown"), - ("bpy.ops.pose.loc_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-loc-clear"), - ("bpy.ops.pose.propagate*", "animation/armatures/posing/editing/propagate.html#bpy-ops-pose-propagate"), - ("bpy.ops.pose.push_rest*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-push-rest"), - ("bpy.ops.pose.rot_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-rot-clear"), - ("bpy.ops.sequencer.lock*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-lock"), - ("bpy.ops.sequencer.mute*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-mute"), - ("bpy.ops.sequencer.slip*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-slip"), - ("bpy.ops.sequencer.snap*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-snap"), - ("bpy.ops.sequencer.swap*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap"), - ("bpy.ops.transform.bend*", "modeling/meshes/editing/mesh/transform/bend.html#bpy-ops-transform-bend"), - ("bpy.ops.transform.tilt*", "modeling/curves/editing/control_points.html#bpy-ops-transform-tilt"), - ("bpy.ops.uv.snap_cursor*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-cursor"), - ("bpy.ops.wm.search_menu*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-menu"), - ("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"), - ("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"), - ("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"), - ("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"), - ("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"), - ("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"), - ("bpy.types.glowsequence*", "video_editing/edit/montage/strips/effects/glow.html#bpy-types-glowsequence"), - ("bpy.types.gpencillayer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer"), - ("bpy.types.hookmodifier*", "modeling/modifiers/deform/hooks.html#bpy-types-hookmodifier"), - ("bpy.types.image.source*", "editors/image/image_settings.html#bpy-types-image-source"), - ("bpy.types.imagetexture*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture"), - ("bpy.types.latticepoint*", "animation/lattice.html#bpy-types-latticepoint"), - ("bpy.types.magictexture*", "render/materials/legacy_textures/types/magic.html#bpy-types-magictexture"), - ("bpy.types.maskmodifier*", "modeling/modifiers/generate/mask.html#bpy-types-maskmodifier"), - ("bpy.types.masksequence*", "video_editing/edit/montage/strips/mask.html#bpy-types-masksequence"), - ("bpy.types.materialslot*", "render/materials/assignment.html#bpy-types-materialslot"), - ("bpy.types.metasequence*", "video_editing/edit/montage/meta.html#bpy-types-metasequence"), - ("bpy.types.object.color*", "scene_layout/object/properties/display.html#bpy-types-object-color"), - ("bpy.types.object.delta*", "scene_layout/object/properties/transforms.html#bpy-types-object-delta"), - ("bpy.types.object.empty*", "modeling/empties.html#bpy-types-object-empty"), - ("bpy.types.object.scale*", "scene_layout/object/properties/transforms.html#bpy-types-object-scale"), - ("bpy.types.particleedit*", "physics/particles/mode.html#bpy-types-particleedit"), - ("bpy.types.scene.camera*", "scene_layout/scene/properties.html#bpy-types-scene-camera"), - ("bpy.types.sequencecrop*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencecrop"), - ("bpy.types.shaderfxblur*", "grease_pencil/visual_effects/blur.html#bpy-types-shaderfxblur"), - ("bpy.types.shaderfxflip*", "grease_pencil/visual_effects/flip.html#bpy-types-shaderfxflip"), - ("bpy.types.shaderfxglow*", "grease_pencil/visual_effects/glow.html#bpy-types-shaderfxglow"), - ("bpy.types.shaderfxwave*", "grease_pencil/visual_effects/wave_distortion.html#bpy-types-shaderfxwave"), - ("bpy.types.skinmodifier*", "modeling/modifiers/generate/skin.html#bpy-types-skinmodifier"), - ("bpy.types.spaceconsole*", "editors/python_console.html#bpy-types-spaceconsole"), - ("bpy.types.textsequence*", "video_editing/edit/montage/strips/text.html#bpy-types-textsequence"), - ("bpy.types.unitsettings*", "scene_layout/scene/properties.html#bpy-types-unitsettings"), - ("bpy.types.vertexcolors*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexcolors"), - ("bpy.types.view3dcursor*", "editors/3dview/3d_cursor.html#bpy-types-view3dcursor"), - ("bpy.types.volumerender*", "modeling/volumes/properties.html#bpy-types-volumerender"), - ("bpy.types.warpmodifier*", "modeling/modifiers/deform/warp.html#bpy-types-warpmodifier"), - ("bpy.types.wavemodifier*", "modeling/modifiers/deform/wave.html#bpy-types-wavemodifier"), - ("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"), - ("bpy.types.wipesequence*", "video_editing/edit/montage/strips/transitions/wipe.html#bpy-types-wipesequence"), - ("bpy.ops.armature.fill*", "animation/armatures/bones/editing/fill_between_joints.html#bpy-ops-armature-fill"), - ("bpy.ops.asset.tag_add*", "editors/asset_browser.html#bpy-ops-asset-tag-add"), - ("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"), - ("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"), - ("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"), - ("bpy.ops.file.previous*", "editors/file_browser.html#bpy-ops-file-previous"), - ("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"), - ("bpy.ops.image.project*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-ops-image-project"), - ("bpy.ops.image.replace*", "editors/image/editing.html#bpy-ops-image-replace"), - ("bpy.ops.image.save_as*", "editors/image/editing.html#bpy-ops-image-save-as"), - ("bpy.ops.marker.delete*", "animation/markers.html#bpy-ops-marker-delete"), - ("bpy.ops.marker.rename*", "animation/markers.html#bpy-ops-marker-rename"), - ("bpy.ops.marker.select*", "animation/markers.html#bpy-ops-marker-select"), - ("bpy.ops.material.copy*", "render/materials/assignment.html#bpy-ops-material-copy"), - ("bpy.ops.mesh.decimate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-decimate"), - ("bpy.ops.mesh.dissolve*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve"), - ("bpy.ops.mesh.rip_move*", "modeling/meshes/editing/vertex/rip_vertices.html#bpy-ops-mesh-rip-move"), - ("bpy.ops.mesh.separate*", "modeling/meshes/editing/mesh/separate.html#bpy-ops-mesh-separate"), - ("bpy.ops.mesh.solidify*", "modeling/meshes/editing/face/solidify_faces.html#bpy-ops-mesh-solidify"), - ("bpy.ops.nla.duplicate*", "editors/nla/editing.html#bpy-ops-nla-duplicate"), - ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), - ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), - ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), - ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), - ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), - ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), - ("bpy.ops.sculpt.expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-expand"), - ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), - ("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"), - ("bpy.ops.wm.obj_export*", "files/import_export/obj.html#bpy-ops-wm-obj-export"), - ("bpy.ops.wm.properties*", "files/data_blocks.html#bpy-ops-wm-properties"), - ("bpy.ops.wm.usd_export*", "files/import_export/usd.html#bpy-ops-wm-usd-export"), - ("bpy.types.addsequence*", "video_editing/edit/montage/strips/effects/add.html#bpy-types-addsequence"), - ("bpy.types.brush.cloth*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth"), - ("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"), - ("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"), - ("bpy.types.curve.bevel*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel"), - ("bpy.types.mesh.remesh*", "modeling/meshes/retopology.html#bpy-types-mesh-remesh"), - ("bpy.types.meshstatvis*", "modeling/meshes/mesh_analysis.html#bpy-types-meshstatvis"), - ("bpy.types.nodesetting*", "interface/controls/nodes/parts.html#bpy-types-nodesetting"), - ("bpy.types.object.lock*", "scene_layout/object/properties/transforms.html#bpy-types-object-lock"), - ("bpy.types.object.show*", "scene_layout/object/properties/display.html#bpy-types-object-show"), - ("bpy.types.particlekey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlekey"), - ("bpy.types.posebone.ik*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik"), - ("bpy.types.preferences*", "editors/preferences/index.html#bpy-types-preferences"), - ("bpy.types.renderlayer*", "render/layers/passes.html#bpy-types-renderlayer"), - ("bpy.types.sculpt.lock*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-lock"), - ("bpy.types.shaderfxrim*", "grease_pencil/visual_effects/rim.html#bpy-types-shaderfxrim"), - ("bpy.types.spaceview3d*", "editors/3dview/index.html#bpy-types-spaceview3d"), - ("bpy.types.uipopupmenu*", "interface/controls/buttons/menus.html#bpy-types-uipopupmenu"), - ("bpy.types.vertexpaint*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexpaint"), - ("bpy.types.volumegrids*", "modeling/volumes/properties.html#bpy-types-volumegrids"), - ("bpy.types.woodtexture*", "render/materials/legacy_textures/types/wood.html#bpy-types-woodtexture"), - ("bpy.types.world.color*", "render/lights/world.html#bpy-types-world-color"), - ("bpy.ops.*.select_box*", "interface/selecting.html#bpy-ops-select-box"), - ("bpy.ops.curve.delete*", "modeling/curves/editing/curve.html#bpy-ops-curve-delete"), - ("bpy.ops.curve.reveal*", "modeling/curves/editing/curve.html#bpy-ops-curve-reveal"), - ("bpy.ops.curve.smooth*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth"), - ("bpy.ops.file.execute*", "editors/file_browser.html#bpy-ops-file-execute"), - ("bpy.ops.file.refresh*", "editors/file_browser.html#bpy-ops-file-refresh"), - ("bpy.ops.fluid.preset*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-ops-fluid-preset"), - ("bpy.ops.gpencil.copy*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-copy"), - ("bpy.ops.graph.delete*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-delete"), - ("bpy.ops.graph.mirror*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-mirror"), - ("bpy.ops.graph.reveal*", "editors/graph_editor/channels.html#bpy-ops-graph-reveal"), - ("bpy.ops.graph.sample*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sample"), - ("bpy.ops.graph.smooth*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-smooth"), - ("bpy.ops.graph.unbake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-unbake"), - ("bpy.ops.image.invert*", "editors/image/editing.html#bpy-ops-image-invert"), - ("bpy.ops.image.reload*", "editors/image/editing.html#bpy-ops-image-reload"), - ("bpy.ops.image.resize*", "editors/image/editing.html#bpy-ops-image-resize"), - ("bpy.ops.image.unpack*", "editors/image/editing.html#bpy-ops-image-unpack"), - ("bpy.ops.material.new*", "render/materials/assignment.html#bpy-ops-material-new"), - ("bpy.ops.object.align*", "scene_layout/object/editing/transform/align_objects.html#bpy-ops-object-align"), - ("bpy.ops.object.empty*", "modeling/empties.html#bpy-ops-object-empty"), - ("bpy.ops.object.quick*", "physics/introduction.html#bpy-ops-object-quick"), - ("bpy.ops.text.replace*", "editors/text_editor.html#bpy-ops-text-replace"), - ("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"), - ("bpy.ops.view3d.ruler*", "editors/3dview/toolbar/measure.html#bpy-ops-view3d-ruler"), - ("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"), - ("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"), - ("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"), - ("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"), - ("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"), - ("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"), - ("bpy.types.imagepaint*", "sculpt_paint/texture_paint/index.html#bpy-types-imagepaint"), - ("bpy.types.keymapitem*", "editors/preferences/keymap.html#bpy-types-keymapitem"), - ("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"), - ("bpy.types.maskparent*", "movie_clip/masking/sidebar.html#bpy-types-maskparent"), - ("bpy.types.maskspline*", "movie_clip/masking/sidebar.html#bpy-types-maskspline"), - ("bpy.types.motionpath*", "animation/motion_paths.html#bpy-types-motionpath"), - ("bpy.types.node.color*", "interface/controls/nodes/sidebar.html#bpy-types-node-color"), - ("bpy.types.node.label*", "interface/controls/nodes/sidebar.html#bpy-types-node-label"), - ("bpy.types.nodesocket*", "interface/controls/nodes/parts.html#bpy-types-nodesocket"), - ("bpy.types.paint.tile*", "sculpt_paint/texture_paint/tool_settings/tiling.html#bpy-types-paint-tile"), - ("bpy.types.pointcache*", "physics/baking.html#bpy-types-pointcache"), - ("bpy.types.pointlight*", "render/lights/light_object.html#bpy-types-pointlight"), - ("bpy.types.renderview*", "render/output/properties/stereoscopy/index.html#bpy-types-renderview"), - ("bpy.types.sceneeevee*", "render/eevee/index.html#bpy-types-sceneeevee"), - ("bpy.types.vectorfont*", "modeling/texts/index.html#bpy-types-vectorfont"), - ("bpy.ops.asset.clear*", "files/asset_libraries/introduction.html#bpy-ops-asset-clear"), - ("bpy.ops.clip.reload*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-reload"), - ("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"), - ("bpy.ops.file.cancel*", "editors/file_browser.html#bpy-ops-file-cancel"), - ("bpy.ops.file.parent*", "editors/file_browser.html#bpy-ops-file-parent"), - ("bpy.ops.graph.clean*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-clean"), - ("bpy.ops.graph.paste*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-paste"), - ("bpy.ops.marker.move*", "animation/markers.html#bpy-ops-marker-move"), - ("bpy.ops.mesh.bisect*", "modeling/meshes/editing/mesh/bisect.html#bpy-ops-mesh-bisect"), - ("bpy.ops.mesh.delete*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete"), - ("bpy.ops.nla.move_up*", "editors/nla/editing.html#bpy-ops-nla-move-up"), - ("bpy.ops.node.delete*", "interface/controls/nodes/editing.html#bpy-ops-node-delete"), - ("bpy.ops.object.bake*", "render/cycles/baking.html#bpy-ops-object-bake"), - ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), - ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), - ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), - ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), - ("bpy.ops.spreadsheet*", "editors/spreadsheet.html#bpy-ops-spreadsheet"), - ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), - ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), - ("bpy.ops.view3d.zoom*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom"), - ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), - ("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"), - ("bpy.types.blenddata*", "files/data_blocks.html#bpy-types-blenddata"), - ("bpy.types.bone.hide*", "animation/armatures/bones/properties/display.html#bpy-types-bone-hide"), - ("bpy.types.colorramp*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp"), - ("bpy.types.dopesheet*", "editors/dope_sheet/index.html#bpy-types-dopesheet"), - ("bpy.types.fmodifier*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifier"), - ("bpy.types.freestyle*", "render/freestyle/index.html#bpy-types-freestyle"), - ("bpy.types.masklayer*", "movie_clip/masking/sidebar.html#bpy-types-masklayer"), - ("bpy.types.movieclip*", "movie_clip/index.html#bpy-types-movieclip"), - ("bpy.types.node.name*", "interface/controls/nodes/sidebar.html#bpy-types-node-name"), - ("bpy.types.nodeframe*", "interface/controls/nodes/frame.html#bpy-types-nodeframe"), - ("bpy.types.nodegroup*", "interface/controls/nodes/groups.html#bpy-types-nodegroup"), - ("bpy.types.scene.muv*", "addons/uv/magic_uv.html#bpy-types-scene-muv"), - ("bpy.types.spotlight*", "render/lights/light_object.html#bpy-types-spotlight"), - ("bpy.types.textcurve*", "modeling/texts/index.html#bpy-types-textcurve"), - ("bpy.types.udimtiles*", "modeling/meshes/uv/workflows/udims.html#bpy-types-udimtiles"), - ("bpy.types.uipiemenu*", "interface/controls/buttons/menus.html#bpy-types-uipiemenu"), - ("bpy.types.uipopover*", "interface/controls/buttons/menus.html#bpy-types-uipopover"), - ("bpy.types.viewlayer*", "render/layers/introduction.html#bpy-types-viewlayer"), - ("bpy.ops.asset.mark*", "files/asset_libraries/introduction.html#bpy-ops-asset-mark"), - ("bpy.ops.collection*", "scene_layout/collections/collections.html#bpy-ops-collection"), - ("bpy.ops.constraint*", "animation/constraints/index.html#bpy-ops-constraint"), - ("bpy.ops.curve.draw*", "modeling/curves/tools/draw.html#bpy-ops-curve-draw"), - ("bpy.ops.curve.hide*", "modeling/curves/editing/curve.html#bpy-ops-curve-hide"), - ("bpy.ops.curve.spin*", "modeling/surfaces/editing/surface.html#bpy-ops-curve-spin"), - ("bpy.ops.graph.bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-bake"), - ("bpy.ops.graph.copy*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-copy"), - ("bpy.ops.graph.hide*", "editors/graph_editor/channels.html#bpy-ops-graph-hide"), - ("bpy.ops.graph.snap*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap"), - ("bpy.ops.image.flip*", "editors/image/editing.html#bpy-ops-image-flip"), - ("bpy.ops.image.open*", "editors/image/editing.html#bpy-ops-image-open"), - ("bpy.ops.image.pack*", "editors/image/editing.html#bpy-ops-image-pack"), - ("bpy.ops.image.save*", "editors/image/editing.html#bpy-ops-image-save"), - ("bpy.ops.image.tile*", "modeling/meshes/uv/workflows/udims.html#bpy-ops-image-tile"), - ("bpy.ops.marker.add*", "animation/markers.html#bpy-ops-marker-add"), - ("bpy.ops.mesh.bevel*", "modeling/meshes/editing/edge/bevel.html#bpy-ops-mesh-bevel"), - ("bpy.ops.mesh.inset*", "modeling/meshes/editing/face/inset_faces.html#bpy-ops-mesh-inset"), - ("bpy.ops.mesh.knife*", "modeling/meshes/tools/knife.html#bpy-ops-mesh-knife"), - ("bpy.ops.mesh.merge*", "modeling/meshes/editing/mesh/merge.html#bpy-ops-mesh-merge"), - ("bpy.ops.mesh.screw*", "modeling/meshes/editing/edge/screw.html#bpy-ops-mesh-screw"), - ("bpy.ops.mesh.split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-split"), - ("bpy.ops.nla.delete*", "editors/nla/editing.html#bpy-ops-nla-delete"), - ("bpy.ops.paint.mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask"), - ("bpy.ops.pose.paste*", "animation/armatures/posing/editing/copy_paste.html#bpy-ops-pose-paste"), - ("bpy.ops.pose.relax*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-relax"), - ("bpy.ops.safe_areas*", "render/cameras.html#bpy-ops-safe-areas"), - ("bpy.types.aov.type*", "render/layers/passes.html#bpy-types-aov-type"), - ("bpy.types.armature*", "animation/armatures/index.html#bpy-types-armature"), - ("bpy.types.editbone*", "animation/armatures/bones/editing/index.html#bpy-types-editbone"), - ("bpy.types.facemaps*", "modeling/meshes/properties/object_data.html#bpy-types-facemaps"), - ("bpy.types.keyframe*", "animation/keyframes/index.html#bpy-types-keyframe"), - ("bpy.types.linesets*", "render/freestyle/view_layer/line_set.html#bpy-types-linesets"), - ("bpy.types.metaball*", "modeling/metas/index.html#bpy-types-metaball"), - ("bpy.types.modifier*", "modeling/modifiers/index.html#bpy-types-modifier"), - ("bpy.types.nlastrip*", "editors/nla/strips.html#bpy-types-nlastrip"), - ("bpy.types.nlatrack*", "editors/nla/tracks.html#bpy-types-nlatrack"), - ("bpy.types.nodelink*", "interface/controls/nodes/parts.html#bpy-types-nodelink"), - ("bpy.types.nodetree*", "interface/controls/nodes/parts.html#bpy-types-nodetree"), - ("bpy.types.particle*", "physics/particles/index.html#bpy-types-particle"), - ("bpy.types.sequence*", "video_editing/index.html#bpy-types-sequence"), - ("bpy.types.shaderfx*", "grease_pencil/visual_effects/index.html#bpy-types-shaderfx"), - ("bpy.types.shapekey*", "animation/shape_keys/index.html#bpy-types-shapekey"), - ("bpy.types.spacenla*", "editors/nla/index.html#bpy-types-spacenla"), - ("bpy.types.sunlight*", "render/lights/light_object.html#bpy-types-sunlight"), - ("bpy.ops.clip.open*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-open"), - ("bpy.ops.file.next*", "editors/file_browser.html#bpy-ops-file-next"), - ("bpy.ops.image.new*", "editors/image/editing.html#bpy-ops-image-new"), - ("bpy.ops.mesh.fill*", "modeling/meshes/editing/face/fill.html#bpy-ops-mesh-fill"), - ("bpy.ops.mesh.poke*", "modeling/meshes/editing/face/poke_faces.html#bpy-ops-mesh-poke"), - ("bpy.ops.mesh.spin*", "modeling/meshes/tools/spin.html#bpy-ops-mesh-spin"), - ("bpy.ops.nla.split*", "editors/nla/editing.html#bpy-ops-nla-split"), - ("bpy.ops.pose.copy*", "animation/armatures/posing/editing/copy_paste.html#bpy-ops-pose-copy"), - ("bpy.ops.pose.push*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-push"), - ("bpy.ops.rigidbody*", "physics/rigid_body/index.html#bpy-ops-rigidbody"), - ("bpy.ops.sequencer*", "video_editing/index.html#bpy-ops-sequencer"), - ("bpy.ops.text.find*", "editors/text_editor.html#bpy-ops-text-find"), - ("bpy.ops.transform*", "scene_layout/object/editing/transform/index.html#bpy-ops-transform"), - ("bpy.ops.uv.select*", "editors/uv/selecting.html#bpy-ops-uv-select"), - ("bpy.ops.uv.stitch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-stitch"), - ("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap"), - ("bpy.ops.wm.append*", "files/linked_libraries/link_append.html#bpy-ops-wm-append"), - ("bpy.ops.wm.search*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search"), - ("bpy.types.lattice*", "animation/lattice.html#bpy-types-lattice"), - ("bpy.types.library*", "files/linked_libraries/index.html#bpy-types-library"), - ("bpy.types.speaker*", "render/output/audio/speaker.html#bpy-types-speaker"), - ("bpy.types.textbox*", "modeling/texts/properties.html#bpy-types-textbox"), - ("bpy.types.texture*", "render/materials/legacy_textures/index.html#bpy-types-texture"), - ("bpy.ops.armature*", "animation/armatures/index.html#bpy-ops-armature"), - ("bpy.ops.geometry*", "modeling/index.html#bpy-ops-geometry"), - ("bpy.ops.material*", "render/materials/index.html#bpy-ops-material"), - ("bpy.ops.nla.bake*", "animation/actions.html#bpy-ops-nla-bake"), - ("bpy.ops.nla.snap*", "editors/nla/editing.html#bpy-ops-nla-snap"), - ("bpy.ops.nla.swap*", "editors/nla/editing.html#bpy-ops-nla-swap"), - ("bpy.ops.outliner*", "editors/outliner/index.html#bpy-ops-outliner"), - ("bpy.ops.particle*", "physics/particles/index.html#bpy-ops-particle"), - ("bpy.ops.uv.align*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align"), - ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv.html#bpy-ops-uv-reset"), - ("bpy.ops.wm.addon*", "editors/preferences/addons.html#bpy-ops-wm-addon"), - ("bpy.types.action*", "animation/actions.html#bpy-types-action"), - ("bpy.types.camera*", "render/cameras.html#bpy-types-camera"), - ("bpy.types.cycles*", "render/cycles/index.html#bpy-types-cycles"), - ("bpy.types.driver*", "animation/drivers/index.html#bpy-types-driver"), - ("bpy.types.fcurve*", "editors/graph_editor/fcurves/index.html#bpy-types-fcurve"), - ("bpy.types.header*", "interface/window_system/regions.html#bpy-types-header"), - ("bpy.types.object*", "scene_layout/object/index.html#bpy-types-object"), - ("bpy.types.region*", "interface/window_system/regions.html#bpy-types-region"), - ("bpy.types.render*", "render/index.html#bpy-types-render"), - ("bpy.types.screen*", "interface/index.html#bpy-types-screen"), - ("bpy.types.sculpt*", "sculpt_paint/sculpting/index.html#bpy-types-sculpt"), - ("bpy.types.shader*", "render/shader_nodes/shader/index.html#bpy-types-shader"), - ("bpy.types.spline*", "modeling/curves/properties/active_spline.html#bpy-types-spline"), - ("bpy.types.volume*", "modeling/volumes/index.html#bpy-types-volume"), - ("bpy.types.window*", "interface/index.html#bpy-types-window"), - ("bpy.ops.buttons*", "interface/controls/buttons/buttons.html#bpy-ops-buttons"), - ("bpy.ops.console*", "editors/python_console.html#bpy-ops-console"), - ("bpy.ops.ed.redo*", "interface/undo_redo.html#bpy-ops-ed-redo"), - ("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"), - ("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"), - ("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"), - ("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"), - ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), - ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), - ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), - ("bpy.ops.uv.weld*", "modeling/meshes/uv/editing.html#bpy-ops-uv-weld"), - ("bpy.ops.wm.link*", "files/linked_libraries/link_append.html#bpy-ops-wm-link"), - ("bpy.ops.wm.tool*", "interface/tool_system.html#bpy-ops-wm-tool"), - ("bpy.types.addon*", "editors/preferences/addons.html#bpy-types-addon"), - ("bpy.types.brush*", "sculpt_paint/brush/brush.html#bpy-types-brush"), - ("bpy.types.curve*", "modeling/curves/index.html#bpy-types-curve"), - ("bpy.types.image*", "files/media/image_formats.html#bpy-types-image"), - ("bpy.types.itasc*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-itasc"), - ("bpy.types.nodes*", "interface/controls/nodes/index.html#bpy-types-nodes"), - ("bpy.types.paint*", "sculpt_paint/index.html#bpy-types-paint"), - ("bpy.types.panel*", "interface/window_system/tabs_panels.html#bpy-types-panel"), - ("bpy.types.scene*", "scene_layout/scene/index.html#bpy-types-scene"), - ("bpy.types.sound*", "render/output/audio/index.html#bpy-types-sound"), - ("bpy.types.space*", "editors/index.html#bpy-types-space"), - ("bpy.types.theme*", "editors/preferences/themes.html#bpy-types-theme"), - ("bpy.types.world*", "render/lights/world.html#bpy-types-world"), - ("bpy.ops.action*", "animation/actions.html#bpy-ops-action"), - ("bpy.ops.camera*", "render/cameras.html#bpy-ops-camera"), - ("bpy.ops.cycles*", "render/cycles/index.html#bpy-ops-cycles"), - ("bpy.ops.dpaint*", "physics/dynamic_paint/index.html#bpy-ops-dpaint"), - ("bpy.ops.export*", "files/import_export.html#bpy-ops-export"), - ("bpy.ops.import*", "files/import_export.html#bpy-ops-import"), - ("bpy.ops.marker*", "animation/markers.html#bpy-ops-marker"), - ("bpy.ops.object*", "scene_layout/object/index.html#bpy-ops-object"), - ("bpy.ops.render*", "render/index.html#bpy-ops-render"), - ("bpy.ops.script*", "advanced/scripting/index.html#bpy-ops-script"), - ("bpy.ops.sculpt*", "sculpt_paint/sculpting/index.html#bpy-ops-sculpt"), - ("bpy.ops.uv.muv*", "addons/uv/magic_uv.html#bpy-ops-uv-muv"), - ("bpy.ops.uv.pin*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pin"), - ("bpy.ops.uv.rip*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip"), - ("bpy.ops.view3d*", "editors/3dview/index.html#bpy-ops-view3d"), - ("bpy.types.area*", "interface/window_system/areas.html#bpy-types-area"), - ("bpy.types.boid*", "physics/particles/emitter/physics/boids.html#bpy-types-boid"), - ("bpy.types.bone*", "animation/armatures/bones/index.html#bpy-types-bone"), - ("bpy.types.mask*", "movie_clip/masking/index.html#bpy-types-mask"), - ("bpy.types.menu*", "interface/controls/buttons/menus.html#bpy-types-menu"), - ("bpy.types.mesh*", "modeling/meshes/index.html#bpy-types-mesh"), - ("bpy.types.node*", "interface/controls/nodes/index.html#bpy-types-node"), - ("bpy.types.pose*", "animation/armatures/posing/index.html#bpy-types-pose"), - ("bpy.types.text*", "editors/text_editor.html#bpy-types-text"), - ("bpy.ops.brush*", "sculpt_paint/brush/brush.html#bpy-ops-brush"), - ("bpy.ops.cloth*", "physics/cloth/index.html#bpy-ops-cloth"), - ("bpy.ops.curve*", "modeling/curves/index.html#bpy-ops-curve"), - ("bpy.ops.graph*", "editors/graph_editor/index.html#bpy-ops-graph"), - ("bpy.ops.image*", "files/media/image_formats.html#bpy-ops-image"), - ("bpy.ops.mball*", "modeling/metas/index.html#bpy-ops-mball"), - ("bpy.ops.paint*", "sculpt_paint/index.html#bpy-ops-paint"), - ("bpy.ops.scene*", "scene_layout/scene/index.html#bpy-ops-scene"), - ("bpy.ops.sound*", "render/output/audio/index.html#bpy-ops-sound"), - ("bpy.types.aov*", "render/layers/passes.html#bpy-types-aov"), - ("bpy.types.key*", "animation/shape_keys/index.html#bpy-types-key"), - ("bpy.ops.anim*", "animation/index.html#bpy-ops-anim"), - ("bpy.ops.boid*", "physics/particles/emitter/physics/boids.html#bpy-ops-boid"), - ("bpy.ops.clip*", "movie_clip/index.html#bpy-ops-clip"), - ("bpy.ops.file*", "editors/file_browser.html#bpy-ops-file"), - ("bpy.ops.font*", "modeling/texts/index.html#bpy-ops-font"), - ("bpy.ops.mask*", "movie_clip/masking/index.html#bpy-ops-mask"), - ("bpy.ops.mesh*", "modeling/meshes/index.html#bpy-ops-mesh"), - ("bpy.ops.node*", "interface/controls/nodes/index.html#bpy-ops-node"), - ("bpy.ops.pose*", "animation/armatures/posing/index.html#bpy-ops-pose"), - ("bpy.ops.text*", "editors/text_editor.html#bpy-ops-text"), - ("bpy.ops.time*", "editors/timeline.html#bpy-ops-time"), - ("bpy.types.id*", "files/data_blocks.html#bpy-types-id"), - ("bpy.ops.nla*", "editors/nla/index.html#bpy-ops-nla"), - ("bpy.ops.ed*", "interface/undo_redo.html#bpy-ops-ed"), - ("bpy.ops.ui*", "interface/index.html#bpy-ops-ui"), - ("bpy.ops.wm*", "interface/index.html#bpy-ops-wm"), + ("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"), + ("bpy.types.spacesequesequencertimelineoverlaynceeditor.show_strip_offset*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequesequencertimelineoverlaynceeditor-show-strip-offset"), + ("bpy.types.movietrackingsettings.refine_intrinsics_radial_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-radial-distortion"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-wavecrest"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"), + ("bpy.types.lineartgpencilmodifier.use_offset_towards_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-offset-towards-custom-camera"), + ("bpy.types.movietrackingsettings.refine_intrinsics_principal_point*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-principal-point"), + ("bpy.types.cyclesobjectsettings.shadow_terminator_geometry_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-geometry-offset"), + ("bpy.types.sequencertoolsettings.use_snap_current_frame_to_strips*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-use-snap-current-frame-to-strips"), + ("bpy.types.cycleslightsettings.use_multiple_importance_sampling*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-use-multiple-importance-sampling"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), + ("bpy.types.lineartgpencilmodifier.use_overlap_edge_type_support*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-overlap-edge-type-support"), + ("bpy.types.movietrackingsettings.refine_intrinsics_focal_length*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-focal-length"), + ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), + ("bpy.types.cyclesrendersettings.preview_denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-input-passes"), + ("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"), + ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), + ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"), + ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), + ("bpy.types.toolsettings.use_transform_correct_face_attributes*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-face-attributes"), + ("bpy.types.cyclesrendersettings.adaptive_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-scrambling-distance"), + ("bpy.types.cyclesrendersettings.preview_adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-min-samples"), + ("bpy.types.lineartgpencilmodifier.use_face_mark_keep_contour*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-keep-contour"), + ("bpy.types.rendersettings.use_sequencer_override_scene_strip*", "editors/video_sequencer/preview/sidebar.html#bpy-types-rendersettings-use-sequencer-override-scene-strip"), + ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), + ("bpy.types.cyclesrendersettings.preview_denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-prefilter"), + ("bpy.types.cyclesrendersettings.preview_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-scrambling-distance"), + ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), + ("bpy.types.brushgpencilsettings.use_stroke_random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-strength"), + ("bpy.types.cyclesrendersettings.film_transparent_roughness*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-roughness"), + ("bpy.types.cyclesrendersettings.preview_adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-threshold"), + ("bpy.types.fluiddomainsettings.openvdb_cache_compress_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-cache-compress-type"), + ("bpy.types.fluiddomainsettings.sndparticle_bubble_buoyancy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-buoyancy"), + ("bpy.types.fluiddomainsettings.sndparticle_combined_export*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-combined-export"), + ("bpy.types.fluiddomainsettings.use_collision_border_bottom*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-bottom"), + ("bpy.types.fluiddomainsettings.vector_scale_with_magnitude*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale-with-magnitude"), + ("bpy.types.lineartgpencilmodifier.use_face_mark_boundaries*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-boundaries"), + ("bpy.types.movietrackingstabilization.use_2d_stabilization*", "movie_clip/tracking/clip/sidebar/stabilization/panel.html#bpy-types-movietrackingstabilization-use-2d-stabilization"), + ("bpy.types.spacespreadsheet.display_context_path_collapsed*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-display-context-path-collapsed"), + ("bpy.types.toolsettings.annotation_stroke_placement_view2d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view2d"), + ("bpy.types.toolsettings.annotation_stroke_placement_view3d*", "interface/annotate_tool.html#bpy-types-toolsettings-annotation-stroke-placement-view3d"), + ("bpy.types.brushgpencilsettings.use_random_press_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-strength"), + ("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.sequencertimelineoverlay.waveform_display_type*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-waveform-display-type"), + ("bpy.types.view3doverlay.use_normals_constant_screen_size*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-use-normals-constant-screen-size"), + ("bpy.types.brushgpencilsettings.random_saturation_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-saturation-factor"), + ("bpy.types.brushgpencilsettings.use_settings_postprocess*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-postprocess"), + ("bpy.types.brushgpencilsettings.use_stroke_random_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-radius"), + ("bpy.types.cyclesmaterialsettings.use_transparent_shadow*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-use-transparent-shadow"), + ("bpy.types.cyclesobjectsettings.shadow_terminator_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-offset"), + ("bpy.types.cyclesobjectsettings.use_adaptive_subdivision*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-use-adaptive-subdivision"), + ("bpy.types.cyclesrendersettings.debug_use_spatial_splits*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-spatial-splits"), + ("bpy.types.cyclesrendersettings.light_sampling_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-light-sampling-threshold"), + ("bpy.types.cyclesrendersettings.rolling_shutter_duration*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-rolling-shutter-duration"), + ("bpy.types.cyclesrendersettings.volume_preview_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-preview-step-rate"), + ("bpy.types.fluiddomainsettings.sndparticle_update_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-update-radius"), + ("bpy.types.fluiddomainsettings.use_collision_border_back*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-back"), + ("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.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"), + ("bpy.types.brushgpencilsettings.use_random_press_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-radius"), + ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), + ("bpy.types.colormanagedsequencercolorspacesettings.name*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings-name"), + ("bpy.types.cyclesrendersettings.max_transparent_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-transparent-bounces"), + ("bpy.types.cyclesrendersettings.min_transparent_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-transparent-bounces"), + ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), + ("bpy.types.gpencilsculptsettings.intersection_threshold*", "grease_pencil/modes/draw/tools/cutter.html#bpy-types-gpencilsculptsettings-intersection-threshold"), + ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), + ("bpy.types.lineartgpencilmodifier.use_back_face_culling*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-back-face-culling"), + ("bpy.types.lineartgpencilmodifier.use_intersection_mask*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-mask"), + ("bpy.types.lineartgpencilmodifier.use_invert_collection*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-invert-collection"), + ("bpy.types.movietrackingsettings.use_keyframe_selection*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-keyframe-selection"), + ("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"), + ("bpy.types.sequencertimelineoverlay.show_strip_duration*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-duration"), + ("bpy.types.spaceoutliner.use_filter_lib_override_system*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override-system"), + ("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"), + ("bpy.types.animvizmotionpaths.show_keyframe_action_all*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-action-all"), + ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), + ("bpy.types.brushgpencilsettings.eraser_strength_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-strength-factor"), + ("bpy.types.cyclesmaterialsettings.volume_interpolation*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-interpolation"), + ("bpy.types.cyclesrendersettings.denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-input-passes"), + ("bpy.types.cyclesrendersettings.film_transparent_glass*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-glass"), + ("bpy.types.cyclesrendersettings.offscreen_dicing_scale*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-offscreen-dicing-scale"), + ("bpy.types.fluiddomainsettings.sndparticle_bubble_drag*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-bubble-drag"), + ("bpy.types.lineartgpencilmodifier.use_crease_on_smooth*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-smooth"), + ("bpy.types.lineartgpencilmodifier.use_face_mark_invert*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-invert"), + ("bpy.types.linestylegeometrymodifier_backbonestretcher*", "render/freestyle/view_layer/line_style/modifiers/geometry/backbone_stretcher.html#bpy-types-linestylegeometrymodifier-backbonestretcher"), + ("bpy.types.linestylegeometrymodifier_sinusdisplacement*", "render/freestyle/view_layer/line_style/modifiers/geometry/sinus_displacement.html#bpy-types-linestylegeometrymodifier-sinusdisplacement"), + ("bpy.types.sequencertoolsettings.snap_to_current_frame*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-current-frame"), + ("bpy.ops.object.geometry_nodes_input_attribute_toggle*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-input-attribute-toggle"), + ("bpy.types.animvizmotionpaths.show_keyframe_highlight*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-highlight"), + ("bpy.types.brushgpencilsettings.pen_subdivision_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-subdivision-steps"), + ("bpy.types.brushgpencilsettings.use_strength_pressure*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-strength-pressure"), + ("bpy.types.brushgpencilsettings.use_stroke_random_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-hue"), + ("bpy.types.brushgpencilsettings.use_stroke_random_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-sat"), + ("bpy.types.brushgpencilsettings.use_stroke_random_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-val"), + ("bpy.types.colormanageddisplaysettings.display_device*", "render/color_management.html#bpy-types-colormanageddisplaysettings-display-device"), + ("bpy.types.colormanagedviewsettings.use_curve_mapping*", "render/color_management.html#bpy-types-colormanagedviewsettings-use-curve-mapping"), + ("bpy.types.cyclesrendersettings.sample_clamp_indirect*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-indirect"), + ("bpy.types.cyclesrendersettings.use_adaptive_sampling*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-adaptive-sampling"), + ("bpy.types.cyclesrendersettings.use_preview_denoising*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-preview-denoising"), + ("bpy.types.fluiddomainsettings.color_ramp_field_scale*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field-scale"), + ("bpy.types.fluiddomainsettings.use_adaptive_timesteps*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-adaptive-timesteps"), + ("bpy.types.fluiddomainsettings.use_dissolve_smoke_log*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke-log"), + ("bpy.types.freestylelineset.select_suggestive_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-suggestive-contour"), + ("bpy.types.gpencillayer.annotation_onion_before_color*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-before-color"), + ("bpy.types.gpencillayer.annotation_onion_before_range*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-before-range"), + ("bpy.types.gpencillayer.use_annotation_onion_skinning*", "interface/annotate_tool.html#bpy-types-gpencillayer-use-annotation-onion-skinning"), + ("bpy.types.greasepencil.use_adaptive_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-adaptive-curve-resolution"), + ("bpy.types.lineartgpencilmodifier.stroke_depth_offset*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-stroke-depth-offset"), + ("bpy.types.lineartgpencilmodifier.use_crease_on_sharp*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease-on-sharp"), + ("bpy.types.linestylegeometrymodifier_polygonalization*", "render/freestyle/view_layer/line_style/modifiers/geometry/polygonization.html#bpy-types-linestylegeometrymodifier-polygonalization"), + ("bpy.types.sequencertimelineoverlay.show_strip_source*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-strip-source"), + ("bpy.types.toolsettings.use_gpencil_automerge_strokes*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-automerge-strokes"), + ("bpy.types.toolsettings.use_proportional_edit_objects*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit-objects"), + ("bpy.ops.view3d.edit_mesh_extrude_move_shrink_fatten*", "modeling/meshes/editing/face/extrude_faces_normal.html#bpy-ops-view3d-edit-mesh-extrude-move-shrink-fatten"), + ("bpy.types.brushgpencilsettings.active_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-active-smooth-factor"), + ("bpy.types.brushgpencilsettings.extend_stroke_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-extend-stroke-factor"), + ("bpy.types.brushgpencilsettings.use_random_press_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-hue"), + ("bpy.types.brushgpencilsettings.use_random_press_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-sat"), + ("bpy.types.brushgpencilsettings.use_random_press_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-val"), + ("bpy.types.brushgpencilsettings.use_stroke_random_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-uv"), + ("bpy.types.cyclesmaterialsettings.homogeneous_volume*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-homogeneous-volume"), + ("bpy.types.cyclesobjectsettings.is_caustics_receiver*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-receiver"), + ("bpy.types.cyclesrendersettings.adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-min-samples"), + ("bpy.types.cyclesrendersettings.debug_bvh_time_steps*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-bvh-time-steps"), + ("bpy.types.cyclesrendersettings.distance_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-distance-cull-margin"), + ("bpy.types.cyclesrendersettings.motion_blur_position*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-motion-blur-position"), + ("bpy.types.cyclesrendersettings.rolling_shutter_type*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-rolling-shutter-type"), + ("bpy.types.cyclesrendersettings.transmission_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-transmission-bounces"), + ("bpy.types.cyclesworldsettings.sample_map_resolution*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sample-map-resolution"), + ("bpy.types.fluiddomainsettings.display_interpolation*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-interpolation"), + ("bpy.types.fluiddomainsettings.gridlines_cell_filter*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-cell-filter"), + ("bpy.types.fluiddomainsettings.gridlines_color_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-color-field"), + ("bpy.types.fluiddomainsettings.gridlines_lower_bound*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-lower-bound"), + ("bpy.types.fluiddomainsettings.gridlines_range_color*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-range-color"), + ("bpy.types.fluiddomainsettings.gridlines_upper_bound*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-gridlines-upper-bound"), + ("bpy.types.freestylelineset.select_material_boundary*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-material-boundary"), + ("bpy.types.gpencillayer.annotation_onion_after_color*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-after-color"), + ("bpy.types.gpencillayer.annotation_onion_after_range*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-onion-after-range"), + ("bpy.types.materialgpencilstyle.use_fill_texture_mix*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-texture-mix"), + ("bpy.types.rendersettings_simplify_gpencil_shader_fx*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-shader-fx"), + ("bpy.types.rendersettings_simplify_gpencil_view_fill*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-view-fill"), + ("bpy.types.sequencertoolsettings.snap_to_hold_offset*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-hold-offset"), + ("bpy.types.toolsettings.use_mesh_automerge_and_split*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge-and-split"), + ("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"), + ("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"), + ("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"), + ("bpy.types.brushgpencilsettings.fill_simplify_level*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-simplify-level"), + ("bpy.types.brushgpencilsettings.random_value_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-value-factor"), + ("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-jitter-pressure"), + ("bpy.types.brushgpencilsettings.use_random_press_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-uv"), + ("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-random"), + ("bpy.types.collection.lineart_use_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-use-intersection-mask"), + ("bpy.types.colormanagedinputcolorspacesettings.name*", "editors/image/image_settings.html#bpy-types-colormanagedinputcolorspacesettings-name"), + ("bpy.types.cyclesrendersettings.denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-prefilter"), + ("bpy.types.cyclesrendersettings.preview_dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-preview-dicing-rate"), + ("bpy.types.cyclesrendersettings.sample_clamp_direct*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-direct"), + ("bpy.types.cyclesrendersettings.scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-scrambling-distance"), + ("bpy.types.cyclesworldsettings.volume_interpolation*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-interpolation"), + ("bpy.types.fluiddomainsettings.mesh_particle_radius*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-particle-radius"), + ("bpy.types.fluiddomainsettings.sndparticle_boundary*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-boundary"), + ("bpy.types.fluiddomainsettings.sndparticle_life_max*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-max"), + ("bpy.types.fluiddomainsettings.sndparticle_life_min*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-life-min"), + ("bpy.types.fluiddomainsettings.sys_particle_maximum*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-sys-particle-maximum"), + ("bpy.types.fluiddomainsettings.use_bubble_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-bubble-particles"), + ("bpy.types.freestylelineset.select_external_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-external-contour"), + ("bpy.types.lineartgpencilmodifier.use_custom_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-custom-camera"), + ("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.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"), + ("bpy.types.toolsettings.use_gpencil_weight_data_add*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-weight-data-add"), + ("bpy.types.view3doverlay.texture_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-texture-paint-mode-opacity"), + ("bpy.ops.mesh.customdata_custom_splitnormals_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-clear"), + ("bpy.types.bakesettings.use_pass_ambient_occlusion*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-ambient-occlusion"), + ("bpy.types.brush.surface_smooth_shape_preservation*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-shape-preservation"), + ("bpy.types.brush.use_cloth_pin_simulation_boundary*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-pin-simulation-boundary"), + ("bpy.types.brushgpencilsettings.show_fill_boundary*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-boundary"), + ("bpy.types.brushgpencilsettings.use_default_eraser*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-default-eraser"), + ("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.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"), + ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), + ("bpy.types.cyclesrendersettings.debug_use_hair_bvh*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-hair-bvh"), + ("bpy.types.fileassetselectparams.asset_library_ref*", "editors/asset_browser.html#bpy-types-fileassetselectparams-asset-library-ref"), + ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), + ("bpy.types.fluiddomainsettings.fractions_threshold*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-threshold"), + ("bpy.types.fluiddomainsettings.particle_band_width*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-band-width"), + ("bpy.types.fluiddomainsettings.particle_randomness*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-randomness"), + ("bpy.types.fluiddomainsettings.use_adaptive_domain*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-use-adaptive-domain"), + ("bpy.types.fluiddomainsettings.use_resumable_cache*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-use-resumable-cache"), + ("bpy.types.fluiddomainsettings.use_spray_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-spray-particles"), + ("bpy.types.fluiddomainsettings.vector_display_type*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-display-type"), + ("bpy.types.freestylelineset.select_by_image_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-image-border"), + ("bpy.types.freestylesettings.kr_derivative_epsilon*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-kr-derivative-epsilon"), + ("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve_primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"), + ("bpy.types.geometrynodecurveprimitivequadrilateral*", "modeling/geometry_nodes/curve_primitives/quadrilateral.html#bpy-types-geometrynodecurveprimitivequadrilateral"), + ("bpy.types.lineartgpencilmodifier.smooth_tolerance*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-smooth-tolerance"), + ("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"), + ("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/view_layer/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"), + ("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-stroke-holdout"), + ("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"), + ("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.sequencerpreviewoverlay.show_annotation*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-annotation"), + ("bpy.types.sequencerpreviewoverlay.show_safe_areas*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-safe-areas"), + ("bpy.types.sequencertoolsettings.snap_ignore_muted*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-ignore-muted"), + ("bpy.types.sequencertoolsettings.snap_ignore_sound*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-ignore-sound"), + ("bpy.types.spaceoutliner.use_filter_case_sensitive*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-case-sensitive"), + ("bpy.types.spaceoutliner.use_filter_object_content*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-content"), + ("bpy.types.spacesequenceeditor.show_gizmo_navigate*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-navigate"), + ("bpy.types.toolsettings.use_proportional_connected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-connected"), + ("bpy.types.toolsettings.use_proportional_projected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-projected"), + ("bpy.types.view3doverlay.vertex_paint_mode_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-vertex-paint-mode-opacity"), + ("bpy.types.viewlayer.use_pass_cryptomatte_material*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-material"), + ("bpy.ops.gpencil.vertex_color_brightness_contrast*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-brightness-contrast"), + ("bpy.ops.view3d.edit_mesh_extrude_individual_move*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-individual-move"), + ("bpy.ops.view3d.edit_mesh_extrude_manifold_normal*", "modeling/meshes/tools/extrude_manifold.html#bpy-ops-view3d-edit-mesh-extrude-manifold-normal"), + ("bpy.types.brushgpencilsettings.pen_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-factor"), + ("bpy.types.brushgpencilsettings.random_hue_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-hue-factor"), + ("bpy.types.cyclescurverendersettings.subdivisions*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-subdivisions"), + ("bpy.types.cyclesmaterialsettings.sample_as_light*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-sample-as-light"), + ("bpy.types.cyclesmaterialsettings.volume_sampling*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-sampling"), + ("bpy.types.cyclesobjectsettings.use_deform_motion*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-deform-motion"), + ("bpy.types.cyclesobjectsettings.use_distance_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-distance-cull"), + ("bpy.types.cyclesrendersettings.ao_bounces_render*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-ao-bounces-render"), + ("bpy.types.cyclesrendersettings.min_light_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-light-bounces"), + ("bpy.types.cyclesrendersettings.pixel_filter_type*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-pixel-filter-type"), + ("bpy.types.cyclesrendersettings.use_animated_seed*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-animated-seed"), + ("bpy.types.cyclesrendersettings.use_distance_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-distance-cull"), + ("bpy.types.cyclesrendersettings.use_layer_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-layer-samples"), + ("bpy.types.cyclesworldsettings.homogeneous_volume*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-homogeneous-volume"), + ("bpy.types.fluiddomainsettings.cache_frame_offset*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-offset"), + ("bpy.types.fluiddomainsettings.delete_in_obstacle*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-delete-in-obstacle"), + ("bpy.types.fluiddomainsettings.fractions_distance*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-distance"), + ("bpy.types.fluiddomainsettings.mesh_concave_lower*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-lower"), + ("bpy.types.fluiddomainsettings.mesh_concave_upper*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-concave-upper"), + ("bpy.types.fluiddomainsettings.openvdb_data_depth*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-data-depth"), + ("bpy.types.fluiddomainsettings.use_dissolve_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-dissolve-smoke"), + ("bpy.types.fluiddomainsettings.use_flip_particles*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-flip-particles"), + ("bpy.types.fluiddomainsettings.use_foam_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-use-foam-particles"), + ("bpy.types.fluiddomainsettings.viscosity_exponent*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-exponent"), + ("bpy.types.fluideffectorsettings.surface_distance*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-surface-distance"), + ("bpy.types.fluidflowsettings.density_vertex_group*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density-vertex-group"), + ("bpy.types.fluidflowsettings.use_initial_velocity*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-initial-velocity"), + ("bpy.types.linestylegeometrymodifier_guidinglines*", "render/freestyle/view_layer/line_style/modifiers/geometry/guiding_lines.html#bpy-types-linestylegeometrymodifier-guidinglines"), + ("bpy.types.linestylegeometrymodifier_spatialnoise*", "render/freestyle/view_layer/line_style/modifiers/geometry/spatial_noise.html#bpy-types-linestylegeometrymodifier-spatialnoise"), + ("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.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.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"), + ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), + ("bpy.types.spaceoutliner.use_filter_object_camera*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-camera"), + ("bpy.types.spaceoutliner.use_filter_object_others*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-others"), + ("bpy.types.spacesequenceeditor.overlay_frame_type*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-overlay-frame-type"), + ("bpy.types.spacesequenceeditor.show_strip_overlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-spacesequenceeditor-show-strip-overlay"), + ("bpy.types.spaceuveditor.custom_grid_subdivisions*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-custom-grid-subdivisions"), + ("bpy.types.toolsettings.proportional_edit_falloff*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-edit-falloff"), + ("bpy.types.toolsettings.use_edge_path_live_unwrap*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-edge-path-live-unwrap"), + ("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"), + ("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"), + ("bpy.types.toolsettings.use_snap_uv_grid_absolute*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-use-snap-uv-grid-absolute"), + ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), + ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), + ("bpy.ops.mesh.customdata_custom_splitnormals_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-add"), + ("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-clear"), + ("bpy.types.animvizmotionpaths.show_frame_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-frame-numbers"), + ("bpy.types.brushgpencilsettings.pen_smooth_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-steps"), + ("bpy.types.brushgpencilsettings.show_fill_extend*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-extend"), + ("bpy.types.cycleslightsettings.is_caustics_light*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-is-caustics-light"), + ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), + ("bpy.types.cyclesrendersettings.preview_denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoiser"), + ("bpy.types.cyclesrendersettings.sampling_pattern*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sampling-pattern"), + ("bpy.types.cyclesrendersettings.volume_max_steps*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-max-steps"), + ("bpy.types.cyclesrendersettings.volume_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-step-rate"), + ("bpy.types.cyclesworldsettings.is_caustics_light*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-is-caustics-light"), + ("bpy.types.editbone.bbone_handle_use_scale_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-start"), + ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), + ("bpy.types.fluiddomainsettings.cache_frame_start*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-start"), + ("bpy.types.fluiddomainsettings.cache_mesh_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-mesh-format"), + ("bpy.types.fluiddomainsettings.display_thickness*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-display-thickness"), + ("bpy.types.fluiddomainsettings.flame_smoke_color*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke-color"), + ("bpy.types.fluiddomainsettings.mesh_smoothen_neg*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-neg"), + ("bpy.types.fluiddomainsettings.mesh_smoothen_pos*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-smoothen-pos"), + ("bpy.types.fluiddomainsettings.simulation_method*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-simulation-method"), + ("bpy.types.fluiddomainsettings.use_speed_vectors*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-speed-vectors"), + ("bpy.types.fluiddomainsettings.vector_show_mac_x*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-x"), + ("bpy.types.fluiddomainsettings.vector_show_mac_y*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-y"), + ("bpy.types.fluiddomainsettings.vector_show_mac_z*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-show-mac-z"), + ("bpy.types.fluideffectorsettings.velocity_factor*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-velocity-factor"), + ("bpy.types.freestylelineset.select_by_collection*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-collection"), + ("bpy.types.freestylelineset.select_by_edge_types*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-edge-types"), + ("bpy.types.freestylelineset.select_by_face_marks*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-face-marks"), + ("bpy.types.geometrynodeinputcurvehandlepositions*", "modeling/geometry_nodes/curve/curve_handle_position.html#bpy-types-geometrynodeinputcurvehandlepositions"), + ("bpy.types.linestyle*modifier_distancefromcamera*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_camera.html#bpy-types-linestyle-modifier-distancefromcamera"), + ("bpy.types.linestyle*modifier_distancefromobject*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_object.html#bpy-types-linestyle-modifier-distancefromobject"), + ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), + ("bpy.types.linestylegeometrymodifier_beziercurve*", "render/freestyle/view_layer/line_style/modifiers/geometry/bezier_curve.html#bpy-types-linestylegeometrymodifier-beziercurve"), + ("bpy.types.materialgpencilstyle.use_fill_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-holdout"), + ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), + ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), + ("bpy.types.sequenceeditor.use_overlay_frame_lock*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-frame-lock"), + ("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"), + ("bpy.types.sequencertimelineoverlay.show_fcurves*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-fcurves"), + ("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"), + ("bpy.types.spaceoutliner.use_filter_object_empty*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-empty"), + ("bpy.types.spaceoutliner.use_filter_object_light*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-light"), + ("bpy.types.spacesequenceeditor.proxy_render_size*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-proxy-render-size"), + ("bpy.types.spacespreadsheetrowfilter.column_name*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-column-name"), + ("bpy.types.toolsettings.gpencil_stroke_placement*", "grease_pencil/modes/draw/stroke_placement.html#bpy-types-toolsettings-gpencil-stroke-placement"), + ("bpy.types.toolsettings.use_keyframe_cycle_aware*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-cycle-aware"), + ("bpy.types.toolsettings.use_keyframe_insert_auto*", "editors/timeline.html#bpy-types-toolsettings-use-keyframe-insert-auto"), + ("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"), + ("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"), + ("bpy.ops.ed.lib_id_generate_preview_from_object*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview-from-object"), + ("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"), + ("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"), + ("bpy.types.brushgpencilsettings.simplify_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-simplify-factor"), + ("bpy.types.collection.lineart_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-mask"), + ("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"), + ("bpy.types.cyclesrendersettings.preview_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-samples"), + ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), + ("bpy.types.cyclesworldsettings.volume_step_size*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-step-size"), + ("bpy.types.editbone.bbone_handle_use_ease_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-start"), + ("bpy.types.fluiddomainsettings.color_ramp_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field"), + ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), + ("bpy.types.fluideffectorsettings.use_plane_init*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-plane-init"), + ("bpy.types.freestylelineset.collection_negation*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-collection-negation"), + ("bpy.types.freestylelineset.face_mark_condition*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-face-mark-condition"), + ("bpy.types.freestylelineset.select_ridge_valley*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-ridge-valley"), + ("bpy.types.freestylelinestyle.material_boundary*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-material-boundary"), + ("bpy.types.freestylelinestyle.use_split_pattern*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-pattern"), + ("bpy.types.freestylesettings.use_view_map_cache*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-view-map-cache"), + ("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"), + ("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"), + ("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"), + ("bpy.types.lineartgpencilmodifier.source_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-source-camera"), + ("bpy.types.lineartgpencilmodifier.use_face_mark*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark"), + ("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/view_layer/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"), + ("bpy.types.movieclipuser.use_render_undistorted*", "editors/clip/display/clip_display.html#bpy-types-movieclipuser-use-render-undistorted"), + ("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"), + ("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.spaceoutliner.lib_override_view_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-lib-override-view-mode"), + ("bpy.types.spaceoutliner.use_filter_object_mesh*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-mesh"), + ("bpy.types.spaceoutliner.use_filter_view_layers*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-view-layers"), + ("bpy.types.spacesequenceeditor.show_overexposed*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-show-overexposed"), + ("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"), + ("bpy.types.toolsettings.use_snap_align_rotation*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-align-rotation"), + ("bpy.types.viewlayer.use_pass_cryptomatte_asset*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-asset"), + ("bpy.ops.outliner.collection_indirect_only_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-set"), + ("bpy.ops.scene.freestyle_geometry_modifier_add*", "render/freestyle/view_layer/line_style/geometry.html#bpy-ops-scene-freestyle-geometry-modifier-add"), + ("bpy.ops.sequencer.deinterlace_selected_movies*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-deinterlace-selected-movies"), + ("bpy.types.bakesettings.use_selected_to_active*", "render/cycles/baking.html#bpy-types-bakesettings-use-selected-to-active"), + ("bpy.types.brush.surface_smooth_current_vertex*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-current-vertex"), + ("bpy.types.brush.use_multiplane_scrape_dynamic*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-use-multiplane-scrape-dynamic"), + ("bpy.types.brushgpencilsettings.fill_direction*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-direction"), + ("bpy.types.brushgpencilsettings.fill_draw_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-draw-mode"), + ("bpy.types.brushgpencilsettings.fill_threshold*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-threshold"), + ("bpy.types.brushgpencilsettings.use_fill_limit*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-fill-limit"), + ("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.volume_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-volume-bounces"), + ("bpy.types.cyclesworldsettings.sampling_method*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sampling-method"), + ("bpy.types.cyclesworldsettings.volume_sampling*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-sampling"), + ("bpy.types.editbone.bbone_handle_use_scale_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-end"), + ("bpy.types.fluiddomainsettings.adapt_threshold*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-threshold"), + ("bpy.types.fluiddomainsettings.cache_directory*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-directory"), + ("bpy.types.fluiddomainsettings.cache_frame_end*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-end"), + ("bpy.types.fluiddomainsettings.flame_vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-vorticity"), + ("bpy.types.fluiddomainsettings.noise_pos_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-pos-scale"), + ("bpy.types.fluiddomainsettings.noise_time_anim*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-time-anim"), + ("bpy.types.fluiddomainsettings.particle_number*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-number"), + ("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.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"), + ("bpy.types.freestylelinestyle.integration_type*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-integration-type"), + ("bpy.types.freestylelinestyle.use_split_length*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-length"), + ("bpy.types.geometrynodedistributepointsonfaces*", "modeling/geometry_nodes/point/distribute_points_on_faces.html#bpy-types-geometrynodedistributepointsonfaces"), + ("bpy.types.geometrynodesetcurvehandlepositions*", "modeling/geometry_nodes/curve/set_handle_positions.html#bpy-types-geometrynodesetcurvehandlepositions"), + ("bpy.types.greasepencil.stroke_thickness_space*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-stroke-thickness-space"), + ("bpy.types.linestylegeometrymodifier_blueprint*", "render/freestyle/view_layer/line_style/modifiers/geometry/blueprint.html#bpy-types-linestylegeometrymodifier-blueprint"), + ("bpy.types.materialgpencilstyle.alignment_mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-alignment-mode"), + ("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.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"), + ("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"), + ("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"), + ("bpy.types.spacesequenceeditor.cursor_location*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-cursor-location"), + ("bpy.types.spacesequenceeditor.display_channel*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-display-channel"), + ("bpy.types.spacesequenceeditor.show_gizmo_tool*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo-tool"), + ("bpy.types.spacesequenceeditor.show_region_hud*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-region-hud"), + ("bpy.types.spacespreadsheet.show_only_selected*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-show-only-selected"), + ("bpy.types.spacespreadsheetrowfilter.operation*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-operation"), + ("bpy.types.spacespreadsheetrowfilter.threshold*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-threshold"), + ("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"), + ("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"), + ("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"), + ("bpy.ops.object.multires_higher_levels_delete*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-higher-levels-delete"), + ("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"), + ("bpy.ops.outliner.collection_duplicate_linked*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate-linked"), + ("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"), + ("bpy.types.bakesettings.use_pass_transmission*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-transmission"), + ("bpy.types.brushgpencilsettings.input_samples*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-input-samples"), + ("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"), + ("bpy.types.cyclescamerasettings.panorama_type*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-panorama-type"), + ("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"), + ("bpy.types.cyclesrendersettings.film_exposure*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-exposure"), + ("bpy.types.cyclesrendersettings.sample_offset*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sample-offset"), + ("bpy.types.cyclesrendersettings.texture_limit*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-texture-limit"), + ("bpy.types.cyclesrendersettings.use_denoising*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-denoising"), + ("bpy.types.editbone.bbone_custom_handle_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-start"), + ("bpy.types.editbone.bbone_handle_use_ease_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-end"), + ("bpy.types.fluiddomainsettings.additional_res*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-additional-res"), + ("bpy.types.fluiddomainsettings.dissolve_speed*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-dissolve-speed"), + ("bpy.types.fluiddomainsettings.effector_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-effector-group"), + ("bpy.types.fluiddomainsettings.flame_ignition*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-ignition"), + ("bpy.types.fluiddomainsettings.flame_max_temp*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-max-temp"), + ("bpy.types.fluiddomainsettings.mesh_generator*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-generator"), + ("bpy.types.fluiddomainsettings.noise_strength*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-strength"), + ("bpy.types.fluiddomainsettings.particle_scale*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-particle-scale"), + ("bpy.types.fluiddomainsettings.resolution_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-resolution-max"), + ("bpy.types.fluiddomainsettings.show_gridlines*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-gridlines"), + ("bpy.types.fluiddomainsettings.use_color_ramp*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-color-ramp"), + ("bpy.types.fluiddomainsettings.viscosity_base*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-viscosity-base"), + ("bpy.types.fluideffectorsettings.use_effector*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-effector"), + ("bpy.types.fluidflowsettings.surface_distance*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-surface-distance"), + ("bpy.types.fluidflowsettings.texture_map_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-map-type"), + ("bpy.types.freestylelineset.select_silhouette*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-silhouette"), + ("bpy.types.freestylelinestyle.texture_spacing*", "render/freestyle/view_layer/line_style/texture.html#bpy-types-freestylelinestyle-texture-spacing"), + ("bpy.types.freestylelinestyle.use_chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chain-count"), + ("bpy.types.freestylelinestyle.use_dashed_line*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-dashed-line"), + ("bpy.types.freestylelinestyle.use_same_object*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-same-object"), + ("bpy.types.functionnodeinputspecialcharacters*", "modeling/geometry_nodes/text/special_characters.html#bpy-types-functionnodeinputspecialcharacters"), + ("bpy.types.geometrynodecurveendpointselection*", "modeling/geometry_nodes/curve/endpoint_selection.html#bpy-types-geometrynodecurveendpointselection"), + ("bpy.types.geometrynodeinputmeshedgeneighbors*", "modeling/geometry_nodes/mesh/edge_neighbors.html#bpy-types-geometrynodeinputmeshedgeneighbors"), + ("bpy.types.geometrynodeinputmeshfaceneighbors*", "modeling/geometry_nodes/mesh/face_neighbors.html#bpy-types-geometrynodeinputmeshfaceneighbors"), + ("bpy.types.gpencilsculptguide.reference_point*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-reference-point"), + ("bpy.types.greasepencil.edit_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-edit-curve-resolution"), + ("bpy.types.linestylegeometrymodifier_2doffset*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_offset.html#bpy-types-linestylegeometrymodifier-2doffset"), + ("bpy.types.linestylegeometrymodifier_sampling*", "render/freestyle/view_layer/line_style/modifiers/geometry/sampling.html#bpy-types-linestylegeometrymodifier-sampling"), + ("bpy.types.movietrackingdopesheet.sort_method*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-sort-method"), + ("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"), + ("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"), + ("bpy.types.rendersettings.use_persistent_data*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-persistent-data"), + ("bpy.types.sequencertimelineoverlay.show_grid*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-grid"), + ("bpy.types.sequencertoolsettings.overlap_mode*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-overlap-mode"), + ("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"), + ("bpy.types.spacenodeoverlay.show_context_path*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-context-path"), + ("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"), + ("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"), + ("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"), + ("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"), + ("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"), + ("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"), + ("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"), + ("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"), + ("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"), + ("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"), + ("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"), + ("bpy.types.colormanagedviewsettings.exposure*", "render/color_management.html#bpy-types-colormanagedviewsettings-exposure"), + ("bpy.types.cyclescamerasettings.fisheye_lens*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-lens"), + ("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"), + ("bpy.types.fluiddomainsettings.show_velocity*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-show-velocity"), + ("bpy.types.fluiddomainsettings.timesteps_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-max"), + ("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.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"), + ("bpy.types.freestylelineset.select_edge_mark*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-edge-mark"), + ("bpy.types.freestylelinestyle.use_length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-max"), + ("bpy.types.freestylelinestyle.use_length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-min"), + ("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"), + ("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"), + ("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"), + ("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"), + ("bpy.types.materiallineart.use_material_mask*", "render/materials/line_art.html#bpy-types-materiallineart-use-material-mask"), + ("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-crease-override"), + ("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.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"), + ("bpy.types.sequencertoolsettings.pivot_point*", "editors/video_sequencer/preview/controls/pivot_point.html#bpy-types-sequencertoolsettings-pivot-point"), + ("bpy.types.spaceclipeditor.annotation_source*", "movie_clip/tracking/clip/sidebar/view.html#bpy-types-spaceclipeditor-annotation-source"), + ("bpy.types.spaceclipeditor.show_blue_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-blue-channel"), + ("bpy.types.spacefilebrowser.system_bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-bookmarks"), + ("bpy.types.spaceoutliner.use_filter_children*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-children"), + ("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"), + ("bpy.types.spacespreadsheet.attribute_domain*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-attribute-domain"), + ("bpy.types.spacespreadsheetrowfilter.enabled*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-enabled"), + ("bpy.types.spaceuveditor.show_modified_edges*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-modified-edges"), + ("bpy.types.spaceview3d.transform_orientation*", "editors/3dview/controls/orientation.html#bpy-types-spaceview3d-transform-orientation"), + ("bpy.types.spaceview3d.use_local_collections*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-collections"), + ("bpy.types.toolsettings.use_snap_peel_object*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-peel-object"), + ("bpy.types.view3doverlay.fade_inactive_alpha*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-fade-inactive-alpha"), + ("bpy.types.view3doverlay.wireframe_threshold*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-threshold"), + ("bpy.ops.object.constraint_add_with_targets*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraint-add-with-targets"), + ("bpy.ops.object.material_slot_remove_unused*", "scene_layout/object/editing/cleanup.html#bpy-ops-object-material-slot-remove-unused"), + ("bpy.ops.outliner.collection_disable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable-render"), + ("bpy.ops.scene.freestyle_alpha_modifier_add*", "render/freestyle/view_layer/line_style/alpha.html#bpy-ops-scene-freestyle-alpha-modifier-add"), + ("bpy.ops.scene.freestyle_color_modifier_add*", "render/freestyle/view_layer/line_style/color.html#bpy-ops-scene-freestyle-color-modifier-add"), + ("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"), + ("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"), + ("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"), + ("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"), + ("bpy.types.cyclescamerasettings.fisheye_fov*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-fov"), + ("bpy.types.cyclesobjectsettings.ao_distance*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-ao-distance"), + ("bpy.types.cyclesobjectsettings.dicing_rate*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-dicing-rate"), + ("bpy.types.cyclesrendersettings.blur_glossy*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-blur-glossy"), + ("bpy.types.cyclesrendersettings.dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-rate"), + ("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.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.fileselectparams.recursion_level*", "editors/file_browser.html#bpy-types-fileselectparams-recursion-level"), + ("bpy.types.fluiddomainsettings.adapt_margin*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-margin"), + ("bpy.types.fluiddomainsettings.burning_rate*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-burning-rate"), + ("bpy.types.fluiddomainsettings.guide_parent*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-parent"), + ("bpy.types.fluiddomainsettings.guide_source*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-source"), + ("bpy.types.fluiddomainsettings.particle_max*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-max"), + ("bpy.types.fluiddomainsettings.particle_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-min"), + ("bpy.types.fluiddomainsettings.vector_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-field"), + ("bpy.types.fluiddomainsettings.vector_scale*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale"), + ("bpy.types.fluideffectorsettings.guide_mode*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-guide-mode"), + ("bpy.types.fluidflowsettings.texture_offset*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-offset"), + ("bpy.types.fluidflowsettings.use_plane_init*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-plane-init"), + ("bpy.types.fluidflowsettings.velocity_coord*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-coord"), + ("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"), + ("bpy.types.freestylelinestyle.use_angle_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-angle-max"), + ("bpy.types.freestylelinestyle.use_angle_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-angle-min"), + ("bpy.types.freestylesettings.as_render_pass*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-as-render-pass"), + ("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"), + ("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve_primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"), + ("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"), + ("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"), + ("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"), + ("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"), + ("bpy.types.lineartgpencilmodifier.use_loose*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-loose"), + ("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-stroke"), + ("bpy.types.mesh.use_customdata_vertex_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-vertex-bevel"), + ("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"), + ("bpy.types.movietrackingcamera.pixel_aspect*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-pixel-aspect"), + ("bpy.types.movietrackingcamera.sensor_width*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-sensor-width"), + ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), + ("bpy.types.rendersettings.use_bake_multires*", "render/cycles/baking.html#bpy-types-rendersettings-use-bake-multires"), + ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), + ("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"), + ("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"), + ("bpy.types.spacenodeoverlay.show_wire_color*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-wire-color"), + ("bpy.types.spacesequenceeditor.display_mode*", "editors/video_sequencer/preview/display/display_mode.html#bpy-types-spacesequenceeditor-display-mode"), + ("bpy.types.spaceview3d.show_object_viewport*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-viewport"), + ("bpy.types.view3doverlay.show_fade_inactive*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-fade-inactive"), + ("bpy.types.viewlayer.pass_cryptomatte_depth*", "render/layers/passes.html#bpy-types-viewlayer-pass-cryptomatte-depth"), + ("bpy.ops.clip.stabilize_2d_rotation_select*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-stabilize-2d-rotation-select"), + ("bpy.ops.constraint.disable_keep_transform*", "animation/constraints/interface/common.html#bpy-ops-constraint-disable-keep-transform"), + ("bpy.ops.gpencil.stroke_reset_vertex_color*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-stroke-reset-vertex-color"), + ("bpy.ops.object.modifier_apply_as_shapekey*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-apply-as-shapekey"), + ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), + ("bpy.ops.outliner.collection_color_tag_set*", "editors/outliner/editing.html#bpy-ops-outliner-collection-color-tag-set"), + ("bpy.ops.outliner.collection_enable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable-render"), + ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/introduction.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/face_sets.html#bpy-ops-sculpt-face-set-change-visibility"), + ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"), + ("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"), + ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), + ("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"), + ("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"), + ("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"), + ("bpy.types.compositornodeconvertcolorspace*", "compositing/types/converter/color_space.html#bpy-types-compositornodeconvertcolorspace"), + ("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"), + ("bpy.types.cyclesrendersettings.ao_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-ao-bounces"), + ("bpy.types.cyclesrendersettings.time_limit*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-time-limit"), + ("bpy.types.cyclesvisibilitysettings.camera*", "render/cycles/world_settings.html#bpy-types-cyclesvisibilitysettings-camera"), + ("bpy.types.cyclesworldsettings.max_bounces*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-max-bounces"), + ("bpy.types.fluiddomainsettings.domain_type*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-domain-type"), + ("bpy.types.fluiddomainsettings.flame_smoke*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flame-smoke"), + ("bpy.types.fluiddomainsettings.fluid_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-fluid-group"), + ("bpy.types.fluiddomainsettings.guide_alpha*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-alpha"), + ("bpy.types.fluiddomainsettings.noise_scale*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-noise-scale"), + ("bpy.types.fluiddomainsettings.slice_depth*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-depth"), + ("bpy.types.fluideffectorsettings.subframes*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-subframes"), + ("bpy.types.fluidflowsettings.flow_behavior*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-behavior"), + ("bpy.types.fluidflowsettings.noise_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-noise-texture"), + ("bpy.types.freestylelineset.select_contour*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-contour"), + ("bpy.types.freestylelinestyle.split_length*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-length"), + ("bpy.types.freestylelinestyle.use_chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chaining"), + ("bpy.types.freestylesettings.sphere_radius*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-sphere-radius"), + ("bpy.types.geometrynodeattributedomainsize*", "modeling/geometry_nodes/attribute/domain_size.html#bpy-types-geometrynodeattributedomainsize"), + ("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"), + ("bpy.types.gpencillayer.annotation_opacity*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-opacity"), + ("bpy.types.gpencillayer.use_onion_skinning*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-onion-skinning"), + ("bpy.types.gpencilsculptguide.use_snapping*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-use-snapping"), + ("bpy.types.gpencilsculptsettings.lock_axis*", "grease_pencil/modes/draw/drawing_planes.html#bpy-types-gpencilsculptsettings-lock-axis"), + ("bpy.types.greasepencil.ghost_before_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-before-range"), + ("bpy.types.greasepencil.stroke_depth_order*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-stroke-depth-order"), + ("bpy.types.imageformatsettings.file_format*", "render/output/properties/output.html#bpy-types-imageformatsettings-file-format"), + ("bpy.types.imagepaint.use_backface_culling*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-backface-culling"), + ("bpy.types.lineartgpencilmodifier.overscan*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-overscan"), + ("bpy.types.linestyle*modifier_curvature_3d*", "render/freestyle/view_layer/line_style/modifiers/color/curvature_3d.html#bpy-types-linestyle-modifier-curvature-3d"), + ("bpy.types.materialgpencilstyle.fill_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-fill-color"), + ("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.mesh.use_customdata_edge_crease*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-crease"), + ("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"), + ("bpy.types.rendersettings.use_render_cache*", "render/output/properties/output.html#bpy-types-rendersettings-use-render-cache"), + ("bpy.types.rendersettings.use_single_layer*", "render/layers/view_layer.html#bpy-types-rendersettings-use-single-layer"), + ("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"), + ("bpy.types.spaceclipeditor.cursor_location*", "editors/clip/sidebar.html#bpy-types-spaceclipeditor-cursor-location"), + ("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.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"), + ("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"), + ("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"), + ("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"), + ("bpy.types.toolsettings.use_auto_normalize*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-auto-normalize"), + ("bpy.types.toolsettings.use_mesh_automerge*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-mesh-automerge"), + ("bpy.types.toolsettings.use_snap_sequencer*", "video_editing/edit/montage/editing.html#bpy-types-toolsettings-use-snap-sequencer"), + ("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"), + ("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"), + ("bpy.types.view3doverlay.wireframe_opacity*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-wireframe-opacity"), + ("bpy.ops.asset.open_containing_blend_file*", "editors/asset_browser.html#bpy-ops-asset-open-containing-blend-file"), + ("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"), + ("bpy.ops.gpencil.stroke_merge_by_distance*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-merge-by-distance"), + ("bpy.ops.node.collapse_hide_unused_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-collapse-hide-unused-toggle"), + ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), + ("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"), + ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), + ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), + ("bpy.types.animvizmotionpaths.frame_after*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-after"), + ("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"), + ("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"), + ("bpy.types.brush.cloth_force_falloff_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-force-falloff-type"), + ("bpy.types.brushgpencilsettings.caps_type*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-caps-type"), + ("bpy.types.brushgpencilsettings.fill_leak*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-leak"), + ("bpy.types.brushgpencilsettings.show_fill*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill"), + ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-uv-random"), + ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), + ("bpy.types.colormanagedviewsettings.gamma*", "render/color_management.html#bpy-types-colormanagedviewsettings-gamma"), + ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), + ("bpy.types.curve.bevel_factor_mapping_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-end"), + ("bpy.types.cyclescamerasettings.longitude*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-longitude"), + ("bpy.types.editbone.bbone_handle_type_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-end"), + ("bpy.types.editbone.use_endroll_as_inroll*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-endroll-as-inroll"), + ("bpy.types.fileselectparams.filter_search*", "editors/file_browser.html#bpy-types-fileselectparams-filter-search"), + ("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"), + ("bpy.types.fluiddomainsettings.flip_ratio*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flip-ratio"), + ("bpy.types.fluiddomainsettings.guide_beta*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-beta"), + ("bpy.types.fluiddomainsettings.mesh_scale*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-scale"), + ("bpy.types.fluiddomainsettings.slice_axis*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-axis"), + ("bpy.types.fluiddomainsettings.time_scale*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-time-scale"), + ("bpy.types.fluidflowsettings.texture_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-size"), + ("bpy.types.fluidflowsettings.use_absolute*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-absolute"), + ("bpy.types.freestylelineset.select_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-border"), + ("bpy.types.freestylelineset.select_crease*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-crease"), + ("bpy.types.freestylelinestyle.chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chain-count"), + ("bpy.types.freestylelinestyle.use_sorting*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-sorting"), + ("bpy.types.freestylesettings.crease_angle*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-crease-angle"), + ("bpy.types.functionnodealigneulertovector*", "modeling/geometry_nodes/utilities/align_euler_to_vector.html#bpy-types-functionnodealigneulertovector"), + ("bpy.types.geometrynodeattributestatistic*", "modeling/geometry_nodes/attribute/attribute_statistic.html#bpy-types-geometrynodeattributestatistic"), + ("bpy.types.geometrynodecurveprimitiveline*", "modeling/geometry_nodes/curve_primitives/curve_line.html#bpy-types-geometrynodecurveprimitiveline"), + ("bpy.types.geometrynodegeometrytoinstance*", "modeling/geometry_nodes/geometry/geometry_to_instance.html#bpy-types-geometrynodegeometrytoinstance"), + ("bpy.types.geometrynodeinputmaterialindex*", "modeling/geometry_nodes/material/material_index.html#bpy-types-geometrynodeinputmaterialindex"), + ("bpy.types.geometrynodeinputmeshedgeangle*", "modeling/geometry_nodes/mesh/edge_angle.html#bpy-types-geometrynodeinputmeshedgeangle"), + ("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"), + ("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"), + ("bpy.types.geometrynodetranslateinstances*", "modeling/geometry_nodes/instances/translate_instances.html#bpy-types-geometrynodetranslateinstances"), + ("bpy.types.greasepencil.ghost_after_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-after-range"), + ("bpy.types.greasepencil.use_ghosts_always*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-ghosts-always"), + ("bpy.types.imageformatsettings.color_mode*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-mode"), + ("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/view_layer/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"), + ("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/view_layer/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"), + ("bpy.types.linestylecolormodifier_tangent*", "render/freestyle/view_layer/line_style/modifiers/color/tangent.html#bpy-types-linestylecolormodifier-tangent"), + ("bpy.types.materialgpencilstyle.mix_color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mix-color"), + ("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-show-fill"), + ("bpy.types.mesh.use_customdata_edge_bevel*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-use-customdata-edge-bevel"), + ("bpy.types.mesh.use_mirror_vertex_group_x*", "sculpt_paint/weight_paint/tool_settings/symmetry.html#bpy-types-mesh-use-mirror-vertex-group-x"), + ("bpy.types.movietrackingcamera.division_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-division-k"), + ("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.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.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"), + ("bpy.types.rendersettings.use_motion_blur*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-use-motion-blur"), + ("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"), + ("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"), + ("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/introduction.html#bpy-types-spaceclipeditor-lock-selection"), + ("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"), + ("bpy.types.spacenodeoverlay.show_overlays*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-overlays"), + ("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"), + ("bpy.types.spacesequenceeditor.show_gizmo*", "editors/video_sequencer/preview/display/gizmos.html#bpy-types-spacesequenceeditor-show-gizmo"), + ("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"), + ("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"), + ("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"), + ("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"), + ("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"), + ("bpy.types.windowmanager.asset_path_dummy*", "editors/asset_browser.html#bpy-types-windowmanager-asset-path-dummy"), + ("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"), + ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), + ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), + ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), + ("bpy.ops.outliner.collection_exclude_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-exclude-set"), + ("bpy.ops.outliner.collection_hide_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide-inside"), + ("bpy.ops.outliner.collection_holdout_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-set"), + ("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"), + ("bpy.ops.poselib.restore_previous_action*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-restore-previous-action"), + ("bpy.ops.preferences.reset_default_theme*", "editors/preferences/themes.html#bpy-ops-preferences-reset-default-theme"), + ("bpy.ops.sequencer.strip_transform_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-strip-transform-clear"), + ("bpy.ops.spreadsheet.add_row_filter_rule*", "editors/spreadsheet.html#bpy-ops-spreadsheet-add-row-filter-rule"), + ("bpy.types.animdata.action_extrapolation*", "editors/nla/sidebar.html#bpy-types-animdata-action-extrapolation"), + ("bpy.types.animvizmotionpaths.frame_step*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-step"), + ("bpy.types.bakesettings.max_ray_distance*", "render/cycles/baking.html#bpy-types-bakesettings-max-ray-distance"), + ("bpy.types.brush.multiplane_scrape_angle*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-multiplane-scrape-angle"), + ("bpy.types.brushgpencilsettings.hardness*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-hardness"), + ("bpy.types.brushgpencilsettings.use_trim*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-trim"), + ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), + ("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"), + ("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"), + ("bpy.types.compositornodecolorcorrection*", "compositing/types/color/color_correction.html#bpy-types-compositornodecolorcorrection"), + ("bpy.types.compositornodemoviedistortion*", "compositing/types/distort/movie_distortion.html#bpy-types-compositornodemoviedistortion"), + ("bpy.types.cyclescamerasettings.latitude*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-latitude"), + ("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"), + ("bpy.types.fileselectparams.display_size*", "editors/file_browser.html#bpy-types-fileselectparams-display-size"), + ("bpy.types.fileselectparams.display_type*", "editors/file_browser.html#bpy-types-fileselectparams-display-type"), + ("bpy.types.fluiddomainsettings.use_guide*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-use-guide"), + ("bpy.types.fluiddomainsettings.use_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-use-noise"), + ("bpy.types.fluiddomainsettings.use_slice*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-slice"), + ("bpy.types.fluiddomainsettings.vorticity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-vorticity"), + ("bpy.types.fluidflowsettings.flow_source*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-source"), + ("bpy.types.fluidflowsettings.fuel_amount*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-fuel-amount"), + ("bpy.types.fluidflowsettings.smoke_color*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-smoke-color"), + ("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"), + ("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"), + ("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"), + ("bpy.types.freestylelinestyle.length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-length-max"), + ("bpy.types.freestylelinestyle.length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-length-min"), + ("bpy.types.freestylelinestyle.sort_order*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-order"), + ("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"), + ("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"), + ("bpy.types.geometrynodeattributetransfer*", "modeling/geometry_nodes/attribute/transfer_attribute.html#bpy-types-geometrynodeattributetransfer"), + ("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/face_area.html#bpy-types-geometrynodeinputmeshfacearea"), + ("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"), + ("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"), + ("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"), + ("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"), + ("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"), + ("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"), + ("bpy.types.materiallineart.mat_occlusion*", "render/materials/line_art.html#bpy-types-materiallineart-mat-occlusion"), + ("bpy.types.movietrackingcamera.principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-principal"), + ("bpy.types.object.use_camera_lock_parent*", "scene_layout/object/properties/relations.html#bpy-types-object-use-camera-lock-parent"), + ("bpy.types.object.visible_volume_scatter*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-volume-scatter"), + ("bpy.types.rendersettings.line_thickness*", "render/freestyle/render.html#bpy-types-rendersettings-line-thickness"), + ("bpy.types.rendersettings.pixel_aspect_x*", "render/output/properties/format.html#bpy-types-rendersettings-pixel-aspect-x"), + ("bpy.types.rendersettings.pixel_aspect_y*", "render/output/properties/format.html#bpy-types-rendersettings-pixel-aspect-y"), + ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), + ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), + ("bpy.types.spaceoutliner.use_sync_select*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sync-select"), + ("bpy.types.spaceproperties.outliner_sync*", "editors/properties_editor.html#bpy-types-spaceproperties-outliner-sync"), + ("bpy.types.spaceproperties.search_filter*", "editors/properties_editor.html#bpy-types-spaceproperties-search-filter"), + ("bpy.types.spacesequenceeditor.view_type*", "editors/video_sequencer/introduction.html#bpy-types-spacesequenceeditor-view-type"), + ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), + ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), + ("bpy.types.spaceuveditor.pixel_snap_mode*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-pixel-snap-mode"), + ("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-use-custom-grid"), + ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"), + ("bpy.types.toolsettings.double_threshold*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-double-threshold"), + ("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"), + ("bpy.types.toolsettings.mesh_select_mode*", "modeling/meshes/selecting/introduction.html#bpy-types-toolsettings-mesh-select-mode"), + ("bpy.types.toolsettings.use_snap_project*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-project"), + ("bpy.types.transformorientationslot.type*", "editors/3dview/controls/orientation.html#bpy-types-transformorientationslot-type"), + ("bpy.types.unitsettings.temperature_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-temperature-unit"), + ("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"), + ("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"), + ("bpy.types.view3dshading.background_type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-background-type"), + ("bpy.types.workspace.use_filter_by_owner*", "interface/window_system/workspaces.html#bpy-types-workspace-use-filter-by-owner"), + ("bpy.ops.gpencil.image_to_grease_pencil*", "editors/image/editing.html#bpy-ops-gpencil-image-to-grease-pencil"), + ("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"), + ("bpy.ops.object.multires_rebuild_subdiv*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-rebuild-subdiv"), + ("bpy.ops.sequencer.select_side_of_frame*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-side-of-frame"), + ("bpy.types.animvizmotionpaths.frame_end*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-end"), + ("bpy.types.armature.rigify_colors_index*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-index"), + ("bpy.types.armature.rigify_theme_to_add*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-theme-to-add"), + ("bpy.types.bakesettings.use_pass_direct*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-direct"), + ("bpy.types.bakesettings.use_pass_glossy*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-glossy"), + ("bpy.types.brush.pose_smooth_iterations*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-smooth-iterations"), + ("bpy.types.brush.snake_hook_deform_type*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-snake-hook-deform-type"), + ("bpy.types.brush.use_grab_active_vertex*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-active-vertex"), + ("bpy.types.brush.use_pose_lock_rotation*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-lock-rotation"), + ("bpy.types.compositornodebrightcontrast*", "compositing/types/color/bright_contrast.html#bpy-types-compositornodebrightcontrast"), + ("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"), + ("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.fileselectparams.show_hidden*", "editors/file_browser.html#bpy-types-fileselectparams-show-hidden"), + ("bpy.types.fileselectparams.sort_method*", "editors/file_browser.html#bpy-types-fileselectparams-sort-method"), + ("bpy.types.fluiddomainsettings.clipping*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-clipping"), + ("bpy.types.fluiddomainsettings.use_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-mesh"), + ("bpy.types.freestylelinestyle.angle_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-angle-max"), + ("bpy.types.freestylelinestyle.angle_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-angle-min"), + ("bpy.types.freestylelinestyle.split_gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-gap"), + ("bpy.types.freestylelinestyle.use_nodes*", "render/freestyle/view_layer/line_style/texture.html#bpy-types-freestylelinestyle-use-nodes"), + ("bpy.types.geometrynodecaptureattribute*", "modeling/geometry_nodes/attribute/capture_attribute.html#bpy-types-geometrynodecaptureattribute"), + ("bpy.types.geometrynodeinputshadesmooth*", "modeling/geometry_nodes/mesh/is_shade_smooth.html#bpy-types-geometrynodeinputshadesmooth"), + ("bpy.types.geometrynodeinstanceonpoints*", "modeling/geometry_nodes/instances/instance_on_points.html#bpy-types-geometrynodeinstanceonpoints"), + ("bpy.types.geometrynodepointstovertices*", "modeling/geometry_nodes/point/points_to_vertices.html#bpy-types-geometrynodepointstovertices"), + ("bpy.types.geometrynoderealizeinstances*", "modeling/geometry_nodes/instances/realize_instances.html#bpy-types-geometrynoderealizeinstances"), + ("bpy.types.geometrynodeseparategeometry*", "modeling/geometry_nodes/geometry/separate_geometry.html#bpy-types-geometrynodeseparategeometry"), + ("bpy.types.geometrynodesetmaterialindex*", "modeling/geometry_nodes/material/set_material_index.html#bpy-types-geometrynodesetmaterialindex"), + ("bpy.types.greasepencil.edit_line_color*", "grease_pencil/properties/display.html#bpy-types-greasepencil-edit-line-color"), + ("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.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"), + ("bpy.types.rendersettings.use_auto_tile*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-auto-tile"), + ("bpy.types.rendersettings.use_overwrite*", "render/output/properties/output.html#bpy-types-rendersettings-use-overwrite"), + ("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.shadernodebsdfhairprincipled*", "render/shader_nodes/shader/hair_principled.html#bpy-types-shadernodebsdfhairprincipled"), + ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), + ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), + ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/sidebar.html#bpy-types-spaceimageeditor-show-repeat"), + ("bpy.types.spaceoutliner.use_sort_alpha*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sort-alpha"), + ("bpy.types.spacepreferences.filter_text*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-text"), + ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), + ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), + ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), + ("bpy.types.toolsettings.snap_uv_element*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-snap-uv-element"), + ("bpy.types.toolsettings.use_snap_rotate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-rotate"), + ("bpy.types.unitsettings.system_rotation*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system-rotation"), + ("bpy.types.view3doverlay.display_handle*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-display-handle"), + ("bpy.types.volumedisplay.wireframe_type*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-type"), + ("bpy.ops.anim.channels_editable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-editable-toggle"), + ("bpy.ops.curve.normals_make_consistent*", "modeling/curves/editing/control_points.html#bpy-ops-curve-normals-make-consistent"), + ("bpy.ops.ed.lib_id_load_custom_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-load-custom-preview"), + ("bpy.ops.gpencil.frame_clean_duplicate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-duplicate"), + ("bpy.ops.gpencil.stroke_simplify_fixed*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify-fixed"), + ("bpy.ops.mesh.faces_select_linked_flat*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-faces-select-linked-flat"), + ("bpy.ops.mesh.primitive_ico_sphere_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-ico-sphere-add"), + ("bpy.ops.object.gpencil_modifier_apply*", "grease_pencil/modifiers/introduction.html#bpy-ops-object-gpencil-modifier-apply"), + ("bpy.ops.object.material_slot_deselect*", "render/materials/assignment.html#bpy-ops-object-material-slot-deselect"), + ("bpy.ops.object.modifier_move_to_index*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-move-to-index"), + ("bpy.ops.object.multires_external_save*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-external-save"), + ("bpy.ops.object.vertex_group_normalize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize"), + ("bpy.ops.object.visual_transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-visual-transform-apply"), + ("bpy.ops.outliner.collection_duplicate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate"), + ("bpy.ops.pose.select_constraint_target*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-constraint-target"), + ("bpy.ops.sequencer.change_effect_input*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-effect-input"), + ("bpy.ops.sequencer.strip_color_tag_set*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-ops-sequencer-strip-color-tag-set"), + ("bpy.ops.sequencer.strip_transform_fit*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-strip-transform-fit"), + ("bpy.types.armature.rigify_colors_lock*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-lock"), + ("bpy.types.bakesettings.cage_extrusion*", "render/cycles/baking.html#bpy-types-bakesettings-cage-extrusion"), + ("bpy.types.bakesettings.use_pass_color*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-color"), + ("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"), + ("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"), + ("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"), + ("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"), + ("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random"), + ("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"), + ("bpy.types.colormanageddisplaysettings*", "render/color_management.html#bpy-types-colormanageddisplaysettings"), + ("bpy.types.colorramp.hue_interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-hue-interpolation"), + ("bpy.types.compositornodebilateralblur*", "compositing/types/filter/bilateral_blur.html#bpy-types-compositornodebilateralblur"), + ("bpy.types.compositornodecryptomattev2*", "compositing/types/matte/cryptomatte.html#bpy-types-compositornodecryptomattev2"), + ("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"), + ("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"), + ("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"), + ("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"), + ("bpy.types.fileselectparams.use_filter*", "editors/file_browser.html#bpy-types-fileselectparams-use-filter"), + ("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"), + ("bpy.types.fluidflowsettings.flow_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-type"), + ("bpy.types.fluidflowsettings.subframes*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-subframes"), + ("bpy.types.freestylelineset.collection*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-collection"), + ("bpy.types.freestylelineset.visibility*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-visibility"), + ("bpy.types.freestylelinestyle.chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chaining"), + ("bpy.types.freestylelinestyle.sort_key*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-key"), + ("bpy.types.geometrynodeaccumulatefield*", "modeling/geometry_nodes/utilities/accumulate_field.html#bpy-types-geometrynodeaccumulatefield"), + ("bpy.types.geometrynodecurvesethandles*", "modeling/geometry_nodes/curve/set_handle_type.html#bpy-types-geometrynodecurvesethandles"), + ("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"), + ("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/mesh_island.html#bpy-types-geometrynodeinputmeshisland"), + ("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/merge_by_distance.html#bpy-types-geometrynodemergebydistance"), + ("bpy.types.geometrynodereplacematerial*", "modeling/geometry_nodes/material/replace_material.html#bpy-types-geometrynodereplacematerial"), + ("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"), + ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), + ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/spline_parameter.html#bpy-types-geometrynodesplineparameter"), + ("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"), + ("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"), + ("bpy.types.greasepencil.use_onion_fade*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-onion-fade"), + ("bpy.types.greasepencil.use_onion_loop*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-onion-loop"), + ("bpy.types.imagepaint.screen_grab_size*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-screen-grab-size"), + ("bpy.types.linestyle*modifier_material*", "render/freestyle/view_layer/line_style/modifiers/color/material.html#bpy-types-linestyle-modifier-material"), + ("bpy.types.motionpath.use_custom_color*", "animation/motion_paths.html#bpy-types-motionpath-use-custom-color"), + ("bpy.types.movietrackingcamera.brown_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-k"), + ("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"), + ("bpy.types.object.visible_transmission*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-transmission"), + ("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"), + ("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"), + ("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"), + ("bpy.types.rendersettings.resolution_x*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-x"), + ("bpy.types.rendersettings.resolution_y*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-y"), + ("bpy.types.rendersettings.threads_mode*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-threads-mode"), + ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), + ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), + ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), + ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), + ("bpy.types.sculpt.detail_refine_method*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-refine-method"), + ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), + ("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.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"), + ("bpy.types.spaceoutliner.filter_invert*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-invert"), + ("bpy.types.spacetexteditor.show_margin*", "editors/text_editor.html#bpy-types-spacetexteditor-show-margin"), + ("bpy.types.spline.radius_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-radius-interpolation"), + ("bpy.types.toolsettings.use_multipaint*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-multipaint"), + ("bpy.types.toolsettings.use_snap_scale*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-scale"), + ("bpy.types.toolsettings.uv_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-select-mode"), + ("bpy.types.viewlayer.material_override*", "render/layers/introduction.html#bpy-types-viewlayer-material-override"), + ("bpy.ops.anim.channels_disable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-disable-toggle"), + ("bpy.ops.anim.channels_fcurves_enable*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-fcurves-enable"), + ("bpy.ops.anim.channels_setting_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-setting-toggle"), + ("bpy.ops.clip.set_viewport_background*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-viewport-background"), + ("bpy.ops.gpencil.interpolate_sequence*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-interpolate-sequence"), + ("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"), + ("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"), + ("bpy.ops.mesh.primitive_uv_sphere_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-uv-sphere-add"), + ("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplicate_linked.html#bpy-ops-object-duplicate-move-linked"), + ("bpy.ops.object.make_override_library*", "files/linked_libraries/library_overrides.html#bpy-ops-object-make-override-library"), + ("bpy.ops.object.parent_no_inverse_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-no-inverse-set"), + ("bpy.ops.object.vertex_group_quantize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-quantize"), + ("bpy.ops.outliner.collection_instance*", "editors/outliner/editing.html#bpy-ops-outliner-collection-instance"), + ("bpy.ops.sequencer.change_effect_type*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-effect-type"), + ("bpy.ops.transform.create_orientation*", "editors/3dview/controls/orientation.html#bpy-ops-transform-create-orientation"), + ("bpy.ops.transform.delete_orientation*", "editors/3dview/controls/orientation.html#bpy-ops-transform-delete-orientation"), + ("bpy.ops.view3d.localview_remove_from*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview-remove-from"), + ("bpy.types.animdata.action_blend_type*", "editors/nla/sidebar.html#bpy-types-animdata-action-blend-type"), + ("bpy.types.bakesettings.use_pass_emit*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-emit"), + ("bpy.types.bone.use_envelope_multiply*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-envelope-multiply"), + ("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"), + ("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"), + ("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"), + ("bpy.types.brush.smooth_stroke_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-factor"), + ("bpy.types.brush.smooth_stroke_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brush-smooth-stroke-radius"), + ("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"), + ("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"), + ("bpy.types.brushgpencilsettings.angle*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle"), + ("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"), + ("bpy.types.compositornodeantialiasing*", "compositing/types/filter/anti_aliasing.html#bpy-types-compositornodeantialiasing"), + ("bpy.types.compositornodechannelmatte*", "compositing/types/matte/channel_key.html#bpy-types-compositornodechannelmatte"), + ("bpy.types.compositornodecolorbalance*", "compositing/types/color/color_balance.html#bpy-types-compositornodecolorbalance"), + ("bpy.types.compositornodekeyingscreen*", "compositing/types/matte/keying_screen.html#bpy-types-compositornodekeyingscreen"), + ("bpy.types.dynamicpaintcanvassettings*", "physics/dynamic_paint/canvas.html#bpy-types-dynamicpaintcanvassettings"), + ("bpy.types.fileselectparams.directory*", "editors/file_browser.html#bpy-types-fileselectparams-directory"), + ("bpy.types.fluidflowsettings.use_flow*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-flow"), + ("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"), + ("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/collection_info.html#bpy-types-geometrynodecollectioninfo"), + ("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"), + ("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"), + ("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene_time.html#bpy-types-geometrynodeinputscenetime"), + ("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"), + ("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"), + ("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"), + ("bpy.types.geometrynodesetpointradius*", "modeling/geometry_nodes/point/set_point_radius.html#bpy-types-geometrynodesetpointradius"), + ("bpy.types.geometrynodesetshadesmooth*", "modeling/geometry_nodes/mesh/set_shade_smooth.html#bpy-types-geometrynodesetshadesmooth"), + ("bpy.types.geometrynodestringtocurves*", "modeling/geometry_nodes/text/string_to_curves.html#bpy-types-geometrynodestringtocurves"), + ("bpy.types.geometrynodesubdividecurve*", "modeling/geometry_nodes/curve/subdivide_curve.html#bpy-types-geometrynodesubdividecurve"), + ("bpy.types.gpencillayer.channel_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-channel-color"), + ("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"), + ("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"), + ("bpy.types.keyframe.handle_right_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right-type"), + ("bpy.types.materialgpencilstyle.color*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-color"), + ("bpy.types.movietrackingcamera.nuke_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-nuke-k"), + ("bpy.types.movietrackingstabilization*", "movie_clip/tracking/clip/sidebar/stabilization/index.html#bpy-types-movietrackingstabilization"), + ("bpy.types.object.display_bounds_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-bounds-type"), + ("bpy.types.regionview3d.lock_rotation*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-lock-rotation"), + ("bpy.types.rendersettings.hair_subdiv*", "render/cycles/render_settings/hair.html#bpy-types-rendersettings-hair-subdiv"), + ("bpy.types.scene.audio_distance_model*", "scene_layout/scene/properties.html#bpy-types-scene-audio-distance-model"), + ("bpy.types.scene.audio_doppler_factor*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-factor"), + ("bpy.types.sequencetransform.rotation*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-rotation"), + ("bpy.types.shadernodeambientocclusion*", "render/shader_nodes/input/ao.html#bpy-types-shadernodeambientocclusion"), + ("bpy.types.shadernodevolumeabsorption*", "render/shader_nodes/shader/volume_absorption.html#bpy-types-shadernodevolumeabsorption"), + ("bpy.types.shadernodevolumeprincipled*", "render/shader_nodes/shader/volume_principled.html#bpy-types-shadernodevolumeprincipled"), + ("bpy.types.spacefilebrowser.bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-bookmarks"), + ("bpy.types.spaceoutliner.display_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-display-mode"), + ("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"), + ("bpy.types.spaceuveditor.show_stretch*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-stretch"), + ("bpy.types.toolsettings.keyframe_type*", "editors/timeline.html#bpy-types-toolsettings-keyframe-type"), + ("bpy.types.toolsettings.snap_elements*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-elements"), + ("bpy.types.toolsettings.use_snap_self*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-self"), + ("bpy.types.viewlayer.active_aov_index*", "render/layers/passes.html#bpy-types-viewlayer-active-aov-index"), + ("bpy.ops.anim.channels_enable_toggle*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-enable-toggle"), + ("bpy.ops.constraint.copy_to_selected*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy-to-selected"), + ("bpy.ops.gpencil.bake_mesh_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-mesh-animation"), + ("bpy.ops.gpencil.select_vertex_color*", "grease_pencil/selecting.html#bpy-ops-gpencil-select-vertex-color"), + ("bpy.ops.gpencil.set_active_material*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-set-active-material"), + ("bpy.ops.gpencil.stroke_change_color*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-change-color"), + ("bpy.ops.gpencil.stroke_cyclical_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-cyclical-set"), + ("bpy.ops.gpencil.vertex_color_invert*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-invert"), + ("bpy.ops.gpencil.vertex_color_levels*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-levels"), + ("bpy.ops.mesh.primitive_cylinder_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cylinder-add"), + ("bpy.ops.mesh.set_normals_from_faces*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-set-normals-from-faces"), + ("bpy.ops.mesh.shape_propagate_to_all*", "modeling/meshes/editing/vertex/propagate_shapes.html#bpy-ops-mesh-shape-propagate-to-all"), + ("bpy.ops.mesh.vert_connect_nonplanar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-nonplanar"), + ("bpy.ops.object.duplicates_make_real*", "scene_layout/object/editing/apply.html#bpy-ops-object-duplicates-make-real"), + ("bpy.ops.object.material_slot_assign*", "render/materials/assignment.html#bpy-ops-object-material-slot-assign"), + ("bpy.ops.object.material_slot_select*", "render/materials/assignment.html#bpy-ops-object-material-slot-select"), + ("bpy.ops.object.multires_unsubdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-unsubdivide"), + ("bpy.ops.object.paths_update_visible*", "animation/motion_paths.html#bpy-ops-object-paths-update-visible"), + ("bpy.ops.object.transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-transforms-to-deltas"), + ("bpy.ops.outliner.collection_disable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-disable"), + ("bpy.ops.outliner.collection_isolate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-isolate"), + ("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"), + ("bpy.ops.poselib.convert_old_poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-convert-old-poselib"), + ("bpy.ops.render.shutter_curve_preset*", "render/cycles/render_settings/motion_blur.html#bpy-ops-render-shutter-curve-preset"), + ("bpy.ops.sequencer.view_ghost_border*", "editors/video_sequencer/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"), + ("bpy.ops.ui.override_type_set_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-override-type-set-button"), + ("bpy.types.animdata.action_influence*", "editors/nla/sidebar.html#bpy-types-animdata-action-influence"), + ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), + ("bpy.types.assetmetadata.description*", "editors/asset_browser.html#bpy-types-assetmetadata-description"), + ("bpy.types.bakesettings.normal_space*", "render/cycles/baking.html#bpy-types-bakesettings-normal-space"), + ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), + ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), + ("bpy.types.brush.use_cloth_collision*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-collision"), + ("bpy.types.brush.use_grab_silhouette*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-silhouette"), + ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), + ("bpy.types.brushtextureslot.map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-map-mode"), + ("bpy.types.camera.passepartout_alpha*", "render/cameras.html#bpy-types-camera-passepartout-alpha"), + ("bpy.types.colorrampelement.position*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-position"), + ("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"), + ("bpy.types.compositornodecryptomatte*", "compositing/types/matte/cryptomatte_legacy.html#bpy-types-compositornodecryptomatte"), + ("bpy.types.compositornodedilateerode*", "compositing/types/filter/dilate_erode.html#bpy-types-compositornodedilateerode"), + ("bpy.types.compositornodeellipsemask*", "compositing/types/matte/ellipse_mask.html#bpy-types-compositornodeellipsemask"), + ("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"), + ("bpy.types.editbone.use_scale_easing*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-scale-easing"), + ("bpy.types.fileselectparams.filename*", "editors/file_browser.html#bpy-types-fileselectparams-filename"), + ("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"), + ("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"), + ("bpy.types.freestylelineset.qi_start*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-start"), + ("bpy.types.freestylelinestyle.rounds*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-rounds"), + ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/text/replace_string.html#bpy-types-functionnodereplacestring"), + ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/text/value_to_string.html#bpy-types-functionnodevaluetostring"), + ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), + ("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"), + ("bpy.types.geometrynodeinputposition*", "modeling/geometry_nodes/input/position.html#bpy-types-geometrynodeinputposition"), + ("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"), + ("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"), + ("bpy.types.geometrynodescaleelements*", "modeling/geometry_nodes/mesh/scale_elements.html#bpy-types-geometrynodescaleelements"), + ("bpy.types.geometrynodesubdividemesh*", "modeling/geometry_nodes/mesh/subdivide_mesh.html#bpy-types-geometrynodesubdividemesh"), + ("bpy.types.greasepencil.before_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-before-color"), + ("bpy.types.greasepencil.onion_factor*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-factor"), + ("bpy.types.greasepencil.pixel_factor*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-pixel-factor"), + ("bpy.types.keyframe.handle_left_type*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left-type"), + ("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"), + ("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-flip"), + ("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mode"), + ("bpy.types.meshsequencecachemodifier*", "modeling/modifiers/modify/mesh_sequence_cache.html#bpy-types-meshsequencecachemodifier"), + ("bpy.types.modifier.show_in_editmode*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-in-editmode"), + ("bpy.types.motionpath.line_thickness*", "animation/motion_paths.html#bpy-types-motionpath-line-thickness"), + ("bpy.types.object.empty_display_size*", "modeling/empties.html#bpy-types-object-empty-display-size"), + ("bpy.types.object.empty_display_type*", "modeling/empties.html#bpy-types-object-empty-display-type"), + ("bpy.types.regionview3d.use_box_clip*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-use-box-clip"), + ("bpy.types.rendersettings.use_border*", "render/output/properties/format.html#bpy-types-rendersettings-use-border"), + ("bpy.types.rigidbodyconstraint.limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-limit"), + ("bpy.types.rigidbodyobject.kinematic*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-kinematic"), + ("bpy.types.scene.audio_doppler_speed*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-speed"), + ("bpy.types.sceneeevee.bokeh_max_size*", "render/eevee/render_settings/depth_of_field.html#bpy-types-sceneeevee-bokeh-max-size"), + ("bpy.types.sculpt.detail_type_method*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-type-method"), + ("bpy.types.sculpt.use_smooth_shading*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-use-smooth-shading"), + ("bpy.types.sequenceeditor.show_cache*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-sequenceeditor-show-cache"), + ("bpy.types.shadernodebsdfanisotropic*", "render/shader_nodes/shader/anisotropic.html#bpy-types-shadernodebsdfanisotropic"), + ("bpy.types.shadernodebsdftranslucent*", "render/shader_nodes/shader/translucent.html#bpy-types-shadernodebsdftranslucent"), + ("bpy.types.shadernodebsdftransparent*", "render/shader_nodes/shader/transparent.html#bpy-types-shadernodebsdftransparent"), + ("bpy.types.shadernodetexpointdensity*", "render/shader_nodes/textures/point_density.html#bpy-types-shadernodetexpointdensity"), + ("bpy.types.shadernodevectortransform*", "render/shader_nodes/vector/transform.html#bpy-types-shadernodevectortransform"), + ("bpy.types.shrinkwrapgpencilmodifier*", "grease_pencil/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapgpencilmodifier"), + ("bpy.types.spaceclipeditor.show_grid*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-grid"), + ("bpy.types.spaceoutliner.filter_text*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-text"), + ("bpy.types.spacetexteditor.find_text*", "editors/text_editor.html#bpy-types-spacetexteditor-find-text"), + ("bpy.types.spacetexteditor.font_size*", "editors/text_editor.html#bpy-types-spacetexteditor-font-size"), + ("bpy.types.spacetexteditor.tab_width*", "editors/text_editor.html#bpy-types-spacetexteditor-tab-width"), + ("bpy.types.spaceuveditor.lock_bounds*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-lock-bounds"), + ("bpy.types.spline.tilt_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-tilt-interpolation"), + ("bpy.types.transformorientation.name*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation-name"), + ("bpy.types.unitsettings.scale_length*", "scene_layout/scene/properties.html#bpy-types-unitsettings-scale-length"), + ("bpy.types.unitsettings.use_separate*", "scene_layout/scene/properties.html#bpy-types-unitsettings-use-separate"), + ("bpy.types.viewlayer.use_motion_blur*", "render/layers/introduction.html#bpy-types-viewlayer-use-motion-blur"), + ("bpy.types.volumedisplay.slice_depth*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-depth"), + ("bpy.types.worldmistsettings.falloff*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-falloff"), + ("bpy.ops.clip.lock_selection_toggle*", "editors/clip/introduction.html#bpy-ops-clip-lock-selection-toggle"), + ("bpy.ops.ed.lib_id_generate_preview*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview"), + ("bpy.ops.mesh.customdata_mask_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-mask-clear"), + ("bpy.ops.mesh.customdata_skin_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-skin-clear"), + ("bpy.ops.mesh.extrude_vertices_move*", "modeling/meshes/editing/vertex/extrude_vertices.html#bpy-ops-mesh-extrude-vertices-move"), + ("bpy.ops.mesh.mod_weighted_strength*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-mod-weighted-strength"), + ("bpy.ops.mesh.quads_convert_to_tris*", "modeling/meshes/editing/face/triangulate_faces.html#bpy-ops-mesh-quads-convert-to-tris"), + ("bpy.ops.mesh.select_interior_faces*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-interior-faces"), + ("bpy.ops.mesh.select_similar_region*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar-region"), + ("bpy.ops.mesh.tris_convert_to_quads*", "modeling/meshes/editing/face/triangles_quads.html#bpy-ops-mesh-tris-convert-to-quads"), + ("bpy.ops.object.datalayout_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data_layout.html#bpy-ops-object-datalayout-transfer"), + ("bpy.ops.object.multires_base_apply*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-base-apply"), + ("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/randomize.html#bpy-ops-object-randomize-transform"), + ("bpy.ops.object.vertex_group_invert*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-invert"), + ("bpy.ops.object.vertex_group_levels*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-levels"), + ("bpy.ops.object.vertex_group_mirror*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-mirror"), + ("bpy.ops.object.vertex_group_remove*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove"), + ("bpy.ops.object.vertex_group_smooth*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-smooth"), + ("bpy.ops.outliner.collection_enable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable"), + ("bpy.ops.palette.extract_from_image*", "editors/image/editing.html#bpy-ops-palette-extract-from-image"), + ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), + ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), + ("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.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"), + ("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"), + ("bpy.types.assetmetadata.active_tag*", "editors/asset_browser.html#bpy-types-assetmetadata-active-tag"), + ("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"), + ("bpy.types.bakesettings.margin_type*", "render/cycles/baking.html#bpy-types-bakesettings-margin-type"), + ("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"), + ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"), + ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), + ("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"), + ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"), + ("bpy.types.camera.show_passepartout*", "render/cameras.html#bpy-types-camera-show-passepartout"), + ("bpy.types.collection.lineart_usage*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-usage"), + ("bpy.types.colormanagedviewsettings*", "render/color_management.html#bpy-types-colormanagedviewsettings"), + ("bpy.types.compositornodebokehimage*", "compositing/types/input/bokeh_image.html#bpy-types-compositornodebokehimage"), + ("bpy.types.compositornodecolormatte*", "compositing/types/matte/color_key.html#bpy-types-compositornodecolormatte"), + ("bpy.types.compositornodecolorspill*", "compositing/types/matte/color_spill.html#bpy-types-compositornodecolorspill"), + ("bpy.types.compositornodehuecorrect*", "compositing/types/color/hue_correct.html#bpy-types-compositornodehuecorrect"), + ("bpy.types.compositornodeoutputfile*", "compositing/types/output/file.html#bpy-types-compositornodeoutputfile"), + ("bpy.types.compositornodeswitchview*", "compositing/types/converter/switch_view.html#bpy-types-compositornodeswitchview"), + ("bpy.types.copytransformsconstraint*", "animation/constraints/transform/copy_transforms.html#bpy-types-copytransformsconstraint"), + ("bpy.types.correctivesmoothmodifier*", "modeling/modifiers/deform/corrective_smooth.html#bpy-types-correctivesmoothmodifier"), + ("bpy.types.curve.bevel_factor_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-start"), + ("bpy.types.fluiddomainsettings.beta*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-beta"), + ("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"), + ("bpy.types.freestylelineset.exclude*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-exclude"), + ("bpy.types.freestylelinestyle.alpha*", "render/freestyle/view_layer/line_style/alpha.html#bpy-types-freestylelinestyle-alpha"), + ("bpy.types.freestylelinestyle.color*", "render/freestyle/view_layer/line_style/color.html#bpy-types-freestylelinestyle-color"), + ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/text/string_length.html#bpy-types-functionnodestringlength"), + ("bpy.types.geometrynodefieldatindex*", "modeling/geometry_nodes/utilities/field_at_index.html#bpy-types-geometrynodefieldatindex"), + ("bpy.types.geometrynodeimagetexture*", "modeling/geometry_nodes/texture/image.html#bpy-types-geometrynodeimagetexture"), + ("bpy.types.geometrynodeinputtangent*", "modeling/geometry_nodes/curve/curve_tangent.html#bpy-types-geometrynodeinputtangent"), + ("bpy.types.geometrynodejoingeometry*", "modeling/geometry_nodes/geometry/join_geometry.html#bpy-types-geometrynodejoingeometry"), + ("bpy.types.geometrynodemeshcylinder*", "modeling/geometry_nodes/mesh_primitives/cylinder.html#bpy-types-geometrynodemeshcylinder"), + ("bpy.types.geometrynodemeshtopoints*", "modeling/geometry_nodes/mesh/mesh_to_points.html#bpy-types-geometrynodemeshtopoints"), + ("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh_primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"), + ("bpy.types.geometrynodereversecurve*", "modeling/geometry_nodes/curve/reverse_curve.html#bpy-types-geometrynodereversecurve"), + ("bpy.types.geometrynodesetcurvetilt*", "modeling/geometry_nodes/curve/set_curve_tilt.html#bpy-types-geometrynodesetcurvetilt"), + ("bpy.types.geometrynodesplinelength*", "modeling/geometry_nodes/curve/spline_length.html#bpy-types-geometrynodesplinelength"), + ("bpy.types.geometrynodevolumetomesh*", "modeling/geometry_nodes/volume/volume_to_mesh.html#bpy-types-geometrynodevolumetomesh"), + ("bpy.types.gpencillayer.line_change*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-line-change"), + ("bpy.types.gpencillayer.parent_type*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent-type"), + ("bpy.types.gpencillayer.tint_factor*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-tint-factor"), + ("bpy.types.greasepencil.after_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-after-color"), + ("bpy.types.image.use_half_precision*", "editors/image/image_settings.html#bpy-types-image-use-half-precision"), + ("bpy.types.image.use_view_as_render*", "editors/image/image_settings.html#bpy-types-image-use-view-as-render"), + ("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"), + ("bpy.types.linestyle*modifier_noise*", "render/freestyle/view_layer/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"), + ("bpy.types.maintainvolumeconstraint*", "animation/constraints/transform/maintain_volume.html#bpy-types-maintainvolumeconstraint"), + ("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.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.sequencertimelineoverlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay"), + ("bpy.types.sequencetransform.offset*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-offset"), + ("bpy.types.shadernodebrightcontrast*", "render/shader_nodes/color/bright_contrast.html#bpy-types-shadernodebrightcontrast"), + ("bpy.types.shadernodebsdfprincipled*", "render/shader_nodes/shader/principled.html#bpy-types-shadernodebsdfprincipled"), + ("bpy.types.shadernodebsdfrefraction*", "render/shader_nodes/shader/refraction.html#bpy-types-shadernodebsdfrefraction"), + ("bpy.types.shadernodeoutputmaterial*", "render/shader_nodes/output/material.html#bpy-types-shadernodeoutputmaterial"), + ("bpy.types.shadernodetexenvironment*", "render/shader_nodes/textures/environment.html#bpy-types-shadernodetexenvironment"), + ("bpy.types.spacesequenceeditor.show*", "editors/video_sequencer/preview/header.html#bpy-types-spacesequenceeditor-show"), + ("bpy.types.spaceuveditor.show_faces*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-faces"), + ("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/overlays.html#bpy-types-spaceuveditor-uv-opacity"), + ("bpy.types.subdividegpencilmodifier*", "grease_pencil/modifiers/generate/subdivide.html#bpy-types-subdividegpencilmodifier"), + ("bpy.types.thicknessgpencilmodifier*", "grease_pencil/modifiers/deform/thickness.html#bpy-types-thicknessgpencilmodifier"), + ("bpy.types.toolsettings.snap_target*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-snap-target"), + ("bpy.types.transformcacheconstraint*", "animation/constraints/transform/transform_cache.html#bpy-types-transformcacheconstraint"), + ("bpy.types.unitsettings.length_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-length-unit"), + ("bpy.types.vertexweighteditmodifier*", "modeling/modifiers/modify/weight_edit.html#bpy-types-vertexweighteditmodifier"), + ("bpy.types.volumedisplay.slice_axis*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-axis"), + ("bpy.ops.action.markers_make_local*", "animation/markers.html#bpy-ops-action-markers-make-local"), + ("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"), + ("bpy.ops.armature.select_hierarchy*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-hierarchy"), + ("bpy.ops.armature.switch_direction*", "animation/armatures/bones/editing/switch_direction.html#bpy-ops-armature-switch-direction"), + ("bpy.ops.clip.apply_solution_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-apply-solution-scale"), + ("bpy.ops.clip.set_center_principal*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-center-principal"), + ("bpy.ops.clip.setup_tracking_scene*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-setup-tracking-scene"), + ("bpy.ops.curve.match_texture_space*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-ops-curve-match-texture-space"), + ("bpy.ops.font.text_paste_from_file*", "modeling/texts/editing.html#bpy-ops-font-text-paste-from-file"), + ("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.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"), + ("bpy.ops.mesh.primitive_circle_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-circle-add"), + ("bpy.ops.mesh.primitive_monkey_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-monkey-add"), + ("bpy.ops.mesh.select_face_by_sides*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-face-by-sides"), + ("bpy.ops.mesh.shortest_path_select*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-shortest-path-select"), + ("bpy.ops.mesh.vert_connect_concave*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-vert-connect-concave"), + ("bpy.ops.object.multires_subdivide*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-subdivide"), + ("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"), + ("bpy.ops.poselib.create_pose_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-create-pose-asset"), + ("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"), + ("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.sequencer.image_strip_add*", "video_editing/edit/montage/strips/image.html#bpy-ops-sequencer-image-strip-add"), + ("bpy.ops.sequencer.movie_strip_add*", "video_editing/edit/montage/strips/movie.html#bpy-ops-sequencer-movie-strip-add"), + ("bpy.ops.sequencer.reassign_inputs*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-reassign-inputs"), + ("bpy.ops.sequencer.sound_strip_add*", "video_editing/edit/montage/strips/sound.html#bpy-ops-sequencer-sound-strip-add"), + ("bpy.ops.ui.remove_override_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-remove-override-button"), + ("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"), + ("bpy.types.animvizmotionpaths.type*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-type"), + ("bpy.types.armaturegpencilmodifier*", "grease_pencil/modifiers/deform/armature.html#bpy-types-armaturegpencilmodifier"), + ("bpy.types.brush.cloth_deform_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-deform-type"), + ("bpy.types.brush.cloth_sim_falloff*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-falloff"), + ("bpy.types.brush.slide_deform_type*", "sculpt_paint/sculpting/tools/slide_relax.html#bpy-types-brush-slide-deform-type"), + ("bpy.types.camera.show_composition*", "render/cameras.html#bpy-types-camera-show-composition"), + ("bpy.types.colorramp.interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-interpolation"), + ("bpy.types.compositornodealphaover*", "compositing/types/color/alpha_over.html#bpy-types-compositornodealphaover"), + ("bpy.types.compositornodebokehblur*", "compositing/types/filter/bokeh_blur.html#bpy-types-compositornodebokehblur"), + ("bpy.types.compositornodecomposite*", "compositing/types/output/composite.html#bpy-types-compositornodecomposite"), + ("bpy.types.compositornodedespeckle*", "compositing/types/filter/despeckle.html#bpy-types-compositornodedespeckle"), + ("bpy.types.compositornodediffmatte*", "compositing/types/matte/difference_key.html#bpy-types-compositornodediffmatte"), + ("bpy.types.compositornodelumamatte*", "compositing/types/matte/luminance_key.html#bpy-types-compositornodelumamatte"), + ("bpy.types.compositornodemovieclip*", "compositing/types/input/movie_clip.html#bpy-types-compositornodemovieclip"), + ("bpy.types.compositornodenormalize*", "compositing/types/vector/normalize.html#bpy-types-compositornodenormalize"), + ("bpy.types.compositornodeposterize*", "compositing/types/color/posterize.html#bpy-types-compositornodeposterize"), + ("bpy.types.compositornodepremulkey*", "compositing/types/converter/alpha_convert.html#bpy-types-compositornodepremulkey"), + ("bpy.types.compositornodescenetime*", "compositing/types/input/scene_time.html#bpy-types-compositornodescenetime"), + ("bpy.types.compositornodestabilize*", "compositing/types/distort/stabilize_2d.html#bpy-types-compositornodestabilize"), + ("bpy.types.compositornodetransform*", "compositing/types/distort/transform.html#bpy-types-compositornodetransform"), + ("bpy.types.compositornodetranslate*", "compositing/types/distort/translate.html#bpy-types-compositornodetranslate"), + ("bpy.types.constraint.target_space*", "animation/constraints/interface/common.html#bpy-types-constraint-target-space"), + ("bpy.types.curve.use_deform_bounds*", "modeling/curves/properties/shape.html#bpy-types-curve-use-deform-bounds"), + ("bpy.types.editbone.bbone_curveinx*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinx"), + ("bpy.types.editbone.bbone_curveinz*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinz"), + ("bpy.types.editbone.bbone_scaleout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scaleout"), + ("bpy.types.editbone.bbone_segments*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-segments"), + ("bpy.types.envelopegpencilmodifier*", "grease_pencil/modifiers/generate/envelope.html#bpy-types-envelopegpencilmodifier"), + ("bpy.types.freestylelineset.qi_end*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-end"), + ("bpy.types.freestylelinestyle.caps*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-caps"), + ("bpy.types.freestylelinestyle.dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-dash"), + ("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"), + ("bpy.types.functionnodebooleanmath*", "modeling/geometry_nodes/utilities/boolean_math.html#bpy-types-functionnodebooleanmath"), + ("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/string.html#bpy-types-functionnodeinputstring"), + ("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/vector.html#bpy-types-functionnodeinputvector"), + ("bpy.types.functionnoderandomvalue*", "modeling/geometry_nodes/utilities/random_value.html#bpy-types-functionnoderandomvalue"), + ("bpy.types.functionnoderotateeuler*", "modeling/geometry_nodes/utilities/rotate_euler.html#bpy-types-functionnoderotateeuler"), + ("bpy.types.functionnodeslicestring*", "modeling/geometry_nodes/text/slice_string.html#bpy-types-functionnodeslicestring"), + ("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/curve_length.html#bpy-types-geometrynodecurvelength"), + ("bpy.types.geometrynodecurvespiral*", "modeling/geometry_nodes/curve_primitives/curve_spiral.html#bpy-types-geometrynodecurvespiral"), + ("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"), + ("bpy.types.geometrynodeextrudemesh*", "modeling/geometry_nodes/mesh/extrude_mesh.html#bpy-types-geometrynodeextrudemesh"), + ("bpy.types.geometrynodefilletcurve*", "modeling/geometry_nodes/curve/fillet_curve.html#bpy-types-geometrynodefilletcurve"), + ("bpy.types.geometrynodeinputnormal*", "modeling/geometry_nodes/input/normal.html#bpy-types-geometrynodeinputnormal"), + ("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/input/radius.html#bpy-types-geometrynodeinputradius"), + ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), + ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), + ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample_curve.html#bpy-types-geometrynodesamplecurve"), + ("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"), + ("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/set_position.html#bpy-types-geometrynodesetposition"), + ("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"), + ("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"), + ("bpy.types.gpencillayer.pass_index*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-pass-index"), + ("bpy.types.gpencillayer.tint_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-tint-color"), + ("bpy.types.gpencillayer.use_lights*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-lights"), + ("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"), + ("bpy.types.greasepencil.onion_mode*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-mode"), + ("bpy.types.greasepencilgrid.offset*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-offset"), + ("bpy.types.laplaciandeformmodifier*", "modeling/modifiers/deform/laplacian_deform.html#bpy-types-laplaciandeformmodifier"), + ("bpy.types.laplaciansmoothmodifier*", "modeling/modifiers/deform/laplacian_smooth.html#bpy-types-laplaciansmoothmodifier"), + ("bpy.types.layercollection.exclude*", "editors/outliner/interface.html#bpy-types-layercollection-exclude"), + ("bpy.types.layercollection.holdout*", "editors/outliner/interface.html#bpy-types-layercollection-holdout"), + ("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.multiplygpencilmodifier*", "grease_pencil/modifiers/generate/multiple_strokes.html#bpy-types-multiplygpencilmodifier"), + ("bpy.types.rendersettings.filepath*", "render/output/properties/output.html#bpy-types-rendersettings-filepath"), + ("bpy.types.rendersettings.fps_base*", "render/output/properties/format.html#bpy-types-rendersettings-fps-base"), + ("bpy.types.rigidbodyobject.enabled*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-enabled"), + ("bpy.types.sceneeevee.use_overscan*", "render/eevee/render_settings/film.html#bpy-types-sceneeevee-use-overscan"), + ("bpy.types.sequencerpreviewoverlay*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay"), + ("bpy.types.sequencetransform.scale*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-scale"), + ("bpy.types.shadernodeeeveespecular*", "render/shader_nodes/shader/specular_bsdf.html#bpy-types-shadernodeeeveespecular"), + ("bpy.types.shadernodehuesaturation*", "render/shader_nodes/color/hue_saturation.html#bpy-types-shadernodehuesaturation"), + ("bpy.types.shadernodetexwhitenoise*", "render/shader_nodes/textures/white_noise.html#bpy-types-shadernodetexwhitenoise"), + ("bpy.types.shadernodevolumescatter*", "render/shader_nodes/shader/volume_scatter.html#bpy-types-shadernodevolumescatter"), + ("bpy.types.simplifygpencilmodifier*", "grease_pencil/modifiers/generate/simplify.html#bpy-types-simplifygpencilmodifier"), + ("bpy.types.spacegrapheditor.cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-cursor"), + ("bpy.types.texturenodetexdistnoise*", "editors/texture_node/types/textures/distorted_noise.html#bpy-types-texturenodetexdistnoise"), + ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), + ("bpy.types.viewlayer.use_freestyle*", "render/freestyle/view_layer/freestyle.html#bpy-types-viewlayer-use-freestyle"), + ("bpy.types.volumedisplay.use_slice*", "modeling/volumes/properties.html#bpy-types-volumedisplay-use-slice"), + ("bpy.types.worldlighting.ao_factor*", "render/cycles/render_settings/light_paths.html#bpy-types-worldlighting-ao-factor"), + ("bpy.types.worldmistsettings.depth*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-depth"), + ("bpy.types.worldmistsettings.start*", "render/cycles/world_settings.html#bpy-types-worldmistsettings-start"), + ("bpy.ops.armature.armature_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-armature-layers"), + ("bpy.ops.armature.select_linked()*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-linked"), + ("bpy.ops.clip.stabilize_2d_select*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-stabilize-2d-select"), + ("bpy.ops.constraint.move_to_index*", "animation/constraints/interface/header.html#bpy-ops-constraint-move-to-index"), + ("bpy.ops.gpencil.frame_clean_fill*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-fill"), + ("bpy.ops.gpencil.stroke_subdivide*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-subdivide"), + ("bpy.ops.gpencil.vertex_color_hsv*", "grease_pencil/modes/vertex_paint/editing.html#bpy-ops-gpencil-vertex-color-hsv"), + ("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.html#bpy-ops-graph-extrapolation-type"), + ("bpy.ops.graph.interpolation_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-interpolation-type"), + ("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"), + ("bpy.ops.mesh.face_split_by_edges*", "modeling/meshes/editing/face/weld_edges_faces.html#bpy-ops-mesh-face-split-by-edges"), + ("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_non_manifold*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-non-manifold"), + ("bpy.ops.object.attribute_convert*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-convert"), + ("bpy.ops.object.constraints_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-clear"), + ("bpy.ops.object.quadriflow_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-quadriflow-remesh"), + ("bpy.ops.object.vertex_group_copy*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy"), + ("bpy.ops.object.vertex_group_lock*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-lock"), + ("bpy.ops.object.vertex_group_move*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-move"), + ("bpy.ops.object.vertex_group_sort*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-sort"), + ("bpy.ops.object.vertex_parent_set*", "modeling/meshes/editing/vertex/make_vertex_parent.html#bpy-ops-object-vertex-parent-set"), + ("bpy.ops.outliner.collection_hide*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide"), + ("bpy.ops.outliner.collection_show*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show"), + ("bpy.ops.paint.mask_lasso_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-lasso-gesture"), + ("bpy.ops.rigidbody.mass_calculate*", "scene_layout/object/editing/rigid_body.html#bpy-ops-rigidbody-mass-calculate"), + ("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.sequencer.duplicate_move*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-duplicate-move"), + ("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.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), + ("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"), + ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), + ("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"), + ("bpy.types.bone.envelope_distance*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-distance"), + ("bpy.types.brightcontrastmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-brightcontrastmodifier"), + ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), + ("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"), + ("bpy.types.brush.pose_ik_segments*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-ik-segments"), + ("bpy.types.brush.pose_origin_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-origin-type"), + ("bpy.types.camerasolverconstraint*", "animation/constraints/motion_tracking/camera_solver.html#bpy-types-camerasolverconstraint"), + ("bpy.types.clothcollisionsettings*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings"), + ("bpy.types.collection.hide_select*", "editors/outliner/interface.html#bpy-types-collection-hide-select"), + ("bpy.types.colorrampelement.color*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-color"), + ("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"), + ("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"), + ("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"), + ("bpy.types.compositornodeexposure*", "compositing/types/color/exposure.html#bpy-types-compositornodeexposure"), + ("bpy.types.compositornodelensdist*", "compositing/types/distort/lens_distortion.html#bpy-types-compositornodelensdist"), + ("bpy.types.compositornodemaprange*", "compositing/types/vector/map_range.html#bpy-types-compositornodemaprange"), + ("bpy.types.compositornodemapvalue*", "compositing/types/vector/map_value.html#bpy-types-compositornodemapvalue"), + ("bpy.types.compositornodepixelate*", "compositing/types/filter/pixelate.html#bpy-types-compositornodepixelate"), + ("bpy.types.compositornodesetalpha*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha"), + ("bpy.types.compositornodesunbeams*", "compositing/types/filter/sun_beams.html#bpy-types-compositornodesunbeams"), + ("bpy.types.compositornodetrackpos*", "compositing/types/input/track_position.html#bpy-types-compositornodetrackpos"), + ("bpy.types.compositornodezcombine*", "compositing/types/color/z_combine.html#bpy-types-compositornodezcombine"), + ("bpy.types.constraint.owner_space*", "animation/constraints/interface/common.html#bpy-types-constraint-owner-space"), + ("bpy.types.copylocationconstraint*", "animation/constraints/transform/copy_location.html#bpy-types-copylocationconstraint"), + ("bpy.types.copyrotationconstraint*", "animation/constraints/transform/copy_rotation.html#bpy-types-copyrotationconstraint"), + ("bpy.types.curve.bevel_factor_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-end"), + ("bpy.types.curve.bevel_resolution*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-resolution"), + ("bpy.types.cyclesmaterialsettings*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings"), + ("bpy.types.dopesheet.show_summary*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-summary"), + ("bpy.types.editbone.bbone_easeout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easeout"), + ("bpy.types.editbone.bbone_rollout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollout"), + ("bpy.types.editbone.bbone_scalein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scalein"), + ("bpy.types.editbone.inherit_scale*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-inherit-scale"), + ("bpy.types.freestylelinestyle.gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-gap"), + ("bpy.types.freestylesettings.mode*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-mode"), + ("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/float_to_integer.html#bpy-types-functionnodefloattoint"), + ("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/color.html#bpy-types-functionnodeinputcolor"), + ("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"), + ("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/input/input_index.html#bpy-types-geometrynodeinputindex"), + ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"), + ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), + ("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"), + ("bpy.types.geometrynodesplitedges*", "modeling/geometry_nodes/mesh/split_edges.html#bpy-types-geometrynodesplitedges"), + ("bpy.types.geometrynodestringjoin*", "modeling/geometry_nodes/text/join_strings.html#bpy-types-geometrynodestringjoin"), + ("bpy.types.greasepencilgrid.color*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-color"), + ("bpy.types.greasepencilgrid.lines*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-lines"), + ("bpy.types.greasepencilgrid.scale*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-scale"), + ("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"), + ("bpy.types.imagesequence.use_flip*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-imagesequence-use-flip"), + ("bpy.types.keyframe.interpolation*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-interpolation"), + ("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"), + ("bpy.types.lineartgpencilmodifier*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier"), + ("bpy.types.material.line_priority*", "render/freestyle/material.html#bpy-types-material-line-priority"), + ("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"), + ("bpy.types.modifier.show_viewport*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-viewport"), + ("bpy.types.motionpath.frame_start*", "animation/motion_paths.html#bpy-types-motionpath-frame-start"), + ("bpy.types.object.visible_diffuse*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-diffuse"), + ("bpy.types.objectsolverconstraint*", "animation/constraints/motion_tracking/object_solver.html#bpy-types-objectsolverconstraint"), + ("bpy.types.opacitygpencilmodifier*", "grease_pencil/modifiers/color/opacity.html#bpy-types-opacitygpencilmodifier"), + ("bpy.types.particlesystemmodifier*", "physics/particles/index.html#bpy-types-particlesystemmodifier"), + ("bpy.types.rendersettings.threads*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-threads"), + ("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.shadernodedisplacement*", "render/shader_nodes/vector/displacement.html#bpy-types-shadernodedisplacement"), + ("bpy.types.shadernodelightfalloff*", "render/shader_nodes/color/light_falloff.html#bpy-types-shadernodelightfalloff"), + ("bpy.types.shadernodeparticleinfo*", "render/shader_nodes/input/particle_info.html#bpy-types-shadernodeparticleinfo"), + ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), + ("bpy.types.sound.use_memory_cache*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-memory-cache"), + ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), + ("bpy.types.texturegpencilmodifier*", "grease_pencil/modifiers/modify/texture_mapping.html#bpy-types-texturegpencilmodifier"), + ("bpy.types.texturenodecoordinates*", "editors/texture_node/types/input/coordinates.html#bpy-types-texturenodecoordinates"), + ("bpy.types.texturenodetexmusgrave*", "editors/texture_node/types/textures/musgrave.html#bpy-types-texturenodetexmusgrave"), + ("bpy.types.unitsettings.mass_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-mass-unit"), + ("bpy.types.unitsettings.time_unit*", "scene_layout/scene/properties.html#bpy-types-unitsettings-time-unit"), + ("bpy.types.volumedisplacemodifier*", "modeling/modifiers/deform/volume_displace.html#bpy-types-volumedisplacemodifier"), + ("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"), + ("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"), + ("bpy.types.worldlighting.distance*", "render/cycles/render_settings/light_paths.html#bpy-types-worldlighting-distance"), + ("bpy.ops.armature.autoside_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-autoside-names"), + ("bpy.ops.armature.calculate_roll*", "animation/armatures/bones/editing/bone_roll.html#bpy-ops-armature-calculate-roll"), + ("bpy.ops.armature.duplicate_move*", "animation/armatures/bones/editing/duplicate.html#bpy-ops-armature-duplicate-move"), + ("bpy.ops.armature.select_similar*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-similar"), + ("bpy.ops.clip.create_plane_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-create-plane-track"), + ("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"), + ("bpy.ops.gpencil.blank_frame_add*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-blank-frame-add"), + ("bpy.ops.gpencil.frame_duplicate*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-frame-duplicate"), + ("bpy.ops.gpencil.layer_duplicate*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-duplicate"), + ("bpy.ops.gpencil.recalc_geometry*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-recalc-geometry"), + ("bpy.ops.gpencil.stroke_caps_set*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-caps-set"), + ("bpy.ops.gpencil.stroke_separate*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-separate"), + ("bpy.ops.gpencil.stroke_simplify*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-simplify"), + ("bpy.ops.graph.blend_to_neighbor*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-blend-to-neighbor"), + ("bpy.ops.graph.snap_cursor_value*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap-cursor-value"), + ("bpy.ops.image.save_all_modified*", "editors/image/editing.html#bpy-ops-image-save-all-modified"), + ("bpy.ops.marker.make_links_scene*", "animation/markers.html#bpy-ops-marker-make-links-scene"), + ("bpy.ops.mesh.extrude_edges_move*", "modeling/meshes/editing/edge/extrude_edges.html#bpy-ops-mesh-extrude-edges-move"), + ("bpy.ops.mesh.extrude_faces_move*", "modeling/meshes/editing/face/extrude_individual_faces.html#bpy-ops-mesh-extrude-faces-move"), + ("bpy.ops.mesh.faces_shade_smooth*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-faces-shade-smooth"), + ("bpy.ops.mesh.paint_mask_extract*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-mesh-paint-mask-extract"), + ("bpy.ops.mesh.primitive_cone_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cone-add"), + ("bpy.ops.mesh.primitive_cube_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-cube-add"), + ("bpy.ops.mesh.primitive_grid_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-grid-add"), + ("bpy.ops.mesh.subdivide_edgering*", "modeling/meshes/editing/edge/subdivide_edge_ring.html#bpy-ops-mesh-subdivide-edgering"), + ("bpy.ops.node.hide_socket_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-hide-socket-toggle"), + ("bpy.ops.node.tree_socket_remove*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-remove"), + ("bpy.ops.object.attribute_remove*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-remove"), + ("bpy.ops.object.constraints_copy*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-constraints-copy"), + ("bpy.ops.object.gpencil_modifier*", "grease_pencil/modifiers/index.html#bpy-ops-object-gpencil-modifier"), + ("bpy.ops.object.make_links_scene*", "scene_layout/object/editing/link_transfer/link_scene.html#bpy-ops-object-make-links-scene"), + ("bpy.ops.object.make_single_user*", "scene_layout/object/editing/relations/make_single_user.html#bpy-ops-object-make-single-user"), + ("bpy.ops.object.multires_reshape*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-reshape"), + ("bpy.ops.object.select_hierarchy*", "scene_layout/object/selecting.html#bpy-ops-object-select-hierarchy"), + ("bpy.ops.object.vertex_group_add*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-add"), + ("bpy.ops.object.vertex_group_fix*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-fix"), + ("bpy.ops.outliner.collection_new*", "editors/outliner/editing.html#bpy-ops-outliner-collection-new"), + ("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"), + ("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"), + ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), + ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), + ("bpy.ops.pose.blend_to_neighbour*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-blend-to-neighbour"), + ("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"), + ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), + ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), + ("bpy.ops.scene.view_layer_remove*", "render/layers/introduction.html#bpy-ops-scene-view-layer-remove"), + ("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.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"), + ("bpy.ops.transform.shrink_fatten*", "modeling/meshes/editing/mesh/transform/shrink-fatten.html#bpy-ops-transform-shrink-fatten"), + ("bpy.ops.transform.vertex_random*", "modeling/meshes/editing/mesh/transform/randomize.html#bpy-ops-transform-vertex-random"), + ("bpy.ops.uv.shortest_path_select*", "editors/uv/selecting.html#bpy-ops-uv-shortest-path-select"), + ("bpy.ops.wm.operator_cheat_sheet*", "advanced/operators.html#bpy-ops-wm-operator-cheat-sheet"), + ("bpy.ops.wm.previews_batch_clear*", "files/blend/previews.html#bpy-ops-wm-previews-batch-clear"), + ("bpy.ops.wm.recover_last_session*", "files/blend/open_save.html#bpy-ops-wm-recover-last-session"), + ("bpy.types.armature.display_type*", "animation/armatures/properties/display.html#bpy-types-armature-display-type"), + ("bpy.types.armature.use_mirror_x*", "animation/armatures/bones/tools/tool_settings.html#bpy-types-armature-use-mirror-x"), + ("bpy.types.bakesettings.normal_b*", "render/cycles/baking.html#bpy-types-bakesettings-normal-b"), + ("bpy.types.bakesettings.normal_g*", "render/cycles/baking.html#bpy-types-bakesettings-normal-g"), + ("bpy.types.bakesettings.normal_r*", "render/cycles/baking.html#bpy-types-bakesettings-normal-r"), + ("bpy.types.bakesettings.use_cage*", "render/cycles/baking.html#bpy-types-bakesettings-use-cage"), + ("bpy.types.brush.boundary_offset*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-offset"), + ("bpy.types.brush.cloth_sim_limit*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-limit"), + ("bpy.types.brush.use_custom_icon*", "sculpt_paint/brush/brush.html#bpy-types-brush-use-custom-icon"), + ("bpy.types.brushtextureslot.mask*", "sculpt_paint/brush/texture_mask.html#bpy-types-brushtextureslot-mask"), + ("bpy.types.camerabackgroundimage*", "render/cameras.html#bpy-types-camerabackgroundimage"), + ("bpy.types.compositornodeboxmask*", "compositing/types/matte/box_mask.html#bpy-types-compositornodeboxmask"), + ("bpy.types.compositornodedefocus*", "compositing/types/filter/defocus.html#bpy-types-compositornodedefocus"), + ("bpy.types.compositornodedenoise*", "compositing/types/filter/denoise.html#bpy-types-compositornodedenoise"), + ("bpy.types.compositornodeinpaint*", "compositing/types/filter/inpaint.html#bpy-types-compositornodeinpaint"), + ("bpy.types.compositornodergbtobw*", "compositing/types/converter/rgb_to_bw.html#bpy-types-compositornodergbtobw"), + ("bpy.types.compositornoderlayers*", "compositing/types/input/render_layers.html#bpy-types-compositornoderlayers"), + ("bpy.types.compositornodetexture*", "compositing/types/input/texture.html#bpy-types-compositornodetexture"), + ("bpy.types.compositornodetonemap*", "compositing/types/color/tone_map.html#bpy-types-compositornodetonemap"), + ("bpy.types.compositornodevecblur*", "compositing/types/filter/vector_blur.html#bpy-types-compositornodevecblur"), + ("bpy.types.curve.use_fill_deform*", "modeling/curves/properties/shape.html#bpy-types-curve-use-fill-deform"), + ("bpy.types.curve.use_path_follow*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-follow"), + ("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"), + ("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"), + ("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"), + ("bpy.types.editbone.bbone_easein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easein"), + ("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"), + ("bpy.types.fcurve.auto_smoothing*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-auto-smoothing"), + ("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), + ("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"), + ("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/boolean.html#bpy-types-functionnodeinputbool"), + ("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve_primitives/star.html#bpy-types-geometrynodecurvestar"), + ("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/fill_curve.html#bpy-types-geometrynodefillcurve"), + ("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/flip_faces.html#bpy-types-geometrynodeflipfaces"), + ("bpy.types.geometrynodeproximity*", "modeling/geometry_nodes/geometry/geometry_proximity.html#bpy-types-geometrynodeproximity"), + ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform.html#bpy-types-geometrynodetransform"), + ("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/trim_curve.html#bpy-types-geometrynodetrimcurve"), + ("bpy.types.gpencillayer.location*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-location"), + ("bpy.types.gpencillayer.rotation*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-rotation"), + ("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"), + ("bpy.types.keyframe.handle_right*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-right"), + ("bpy.types.lengthgpencilmodifier*", "grease_pencil/modifiers/generate/length.html#bpy-types-lengthgpencilmodifier"), + ("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"), + ("bpy.types.lockedtrackconstraint*", "animation/constraints/tracking/locked_track.html#bpy-types-lockedtrackconstraint"), + ("bpy.types.material.blend_method*", "render/eevee/materials/settings.html#bpy-types-material-blend-method"), + ("bpy.types.mirrorgpencilmodifier*", "grease_pencil/modifiers/generate/mirror.html#bpy-types-mirrorgpencilmodifier"), + ("bpy.types.modifier.show_on_cage*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-on-cage"), + ("bpy.types.movietrackingcamera.k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-k"), + ("bpy.types.node.use_custom_color*", "interface/controls/nodes/sidebar.html#bpy-types-node-use-custom-color"), + ("bpy.types.object.visible_camera*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-camera"), + ("bpy.types.object.visible_glossy*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-glossy"), + ("bpy.types.object.visible_shadow*", "render/cycles/object_settings/object_data.html#bpy-types-object-visible-shadow"), + ("bpy.types.offsetgpencilmodifier*", "grease_pencil/modifiers/deform/offset.html#bpy-types-offsetgpencilmodifier"), + ("bpy.types.posebone.custom_shape*", "animation/armatures/bones/properties/display.html#bpy-types-posebone-custom-shape"), + ("bpy.types.rigifyselectioncolors*", "addons/rigging/rigify/metarigs.html#bpy-types-rigifyselectioncolors"), + ("bpy.types.sceneeevee.volumetric*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric"), + ("bpy.types.screen.show_statusbar*", "interface/window_system/topbar.html#bpy-types-screen-show-statusbar"), + ("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.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"), + ("bpy.types.shadernodeoutputlight*", "render/shader_nodes/output/light.html#bpy-types-shadernodeoutputlight"), + ("bpy.types.shadernodeoutputworld*", "render/shader_nodes/output/world.html#bpy-types-shadernodeoutputworld"), + ("bpy.types.shadernodeshadertorgb*", "render/shader_nodes/converter/shader_to_rgb.html#bpy-types-shadernodeshadertorgb"), + ("bpy.types.shadernodetexgradient*", "render/shader_nodes/textures/gradient.html#bpy-types-shadernodetexgradient"), + ("bpy.types.shadernodevectorcurve*", "render/shader_nodes/vector/curves.html#bpy-types-shadernodevectorcurve"), + ("bpy.types.shadernodevertexcolor*", "render/shader_nodes/input/vertex_color.html#bpy-types-shadernodevertexcolor"), + ("bpy.types.smoothgpencilmodifier*", "grease_pencil/modifiers/deform/smooth.html#bpy-types-smoothgpencilmodifier"), + ("bpy.types.spline.use_endpoint_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-endpoint-u"), + ("bpy.types.surfacedeformmodifier*", "modeling/modifiers/deform/surface_deform.html#bpy-types-surfacedeformmodifier"), + ("bpy.types.texturenodetexvoronoi*", "editors/texture_node/types/textures/voronoi.html#bpy-types-texturenodetexvoronoi"), + ("bpy.types.toolsettings.use_snap*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap"), + ("bpy.types.viewlayer.use_volumes*", "render/layers/introduction.html#bpy-types-viewlayer-use-volumes"), + ("bpy.types.volume.frame_duration*", "modeling/volumes/properties.html#bpy-types-volume-frame-duration"), + ("bpy.types.volumedisplay.density*", "modeling/volumes/properties.html#bpy-types-volumedisplay-density"), + ("bpy.types.volumerender.clipping*", "modeling/volumes/properties.html#bpy-types-volumerender-clipping"), + ("bpy.types.workspace.object_mode*", "interface/window_system/workspaces.html#bpy-types-workspace-object-mode"), + ("bpy.ops.anim.channels_collapse*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-collapse"), + ("bpy.ops.armature.select_mirror*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-mirror"), + ("bpy.ops.curve.switch_direction*", "modeling/curves/editing/segments.html#bpy-ops-curve-switch-direction"), + ("bpy.ops.geometry.attribute_add*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-geometry-attribute-add"), + ("bpy.ops.gpencil.duplicate_move*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-duplicate-move"), + ("bpy.ops.gpencil.stroke_arrange*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-arrange"), + ("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"), + ("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"), + ("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"), + ("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"), + ("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"), + ("bpy.ops.nla.action_sync_length*", "editors/nla/editing.html#bpy-ops-nla-action-sync-length"), + ("bpy.ops.object.make_links_data*", "scene_layout/object/editing/link_transfer/link_data.html#bpy-ops-object-make-links-data"), + ("bpy.ops.object.modifier_remove*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-remove"), + ("bpy.ops.object.paths_calculate*", "animation/motion_paths.html#bpy-ops-object-paths-calculate"), + ("bpy.ops.object.transform_apply*", "scene_layout/object/editing/apply.html#bpy-ops-object-transform-apply"), + ("bpy.ops.outliner.lib_operation*", "files/linked_libraries/link_append.html#bpy-ops-outliner-lib-operation"), + ("bpy.ops.outliner.orphans_purge*", "editors/outliner/interface.html#bpy-ops-outliner-orphans-purge"), + ("bpy.ops.paint.mask_box_gesture*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-box-gesture"), + ("bpy.ops.screen.region_quadview*", "editors/3dview/navigate/views.html#bpy-ops-screen-region-quadview"), + ("bpy.ops.screen.screenshot_area*", "interface/window_system/topbar.html#bpy-ops-screen-screenshot-area"), + ("bpy.ops.sequencer.offset_clear*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-offset-clear"), + ("bpy.ops.spreadsheet.toggle_pin*", "editors/spreadsheet.html#bpy-ops-spreadsheet-toggle-pin"), + ("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"), + ("bpy.types.arraygpencilmodifier*", "grease_pencil/modifiers/generate/array.html#bpy-types-arraygpencilmodifier"), + ("bpy.types.assetmetadata.author*", "editors/asset_browser.html#bpy-types-assetmetadata-author"), + ("bpy.types.bone.envelope_weight*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-weight"), + ("bpy.types.brush.use_persistent*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-use-persistent"), + ("bpy.types.brushgpencilsettings*", "grease_pencil/modes/draw/tools/index.html#bpy-types-brushgpencilsettings"), + ("bpy.types.buildgpencilmodifier*", "grease_pencil/modifiers/generate/build.html#bpy-types-buildgpencilmodifier"), + ("bpy.types.camera.sensor_height*", "render/cameras.html#bpy-types-camera-sensor-height"), + ("bpy.types.colorbalancemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-colorbalancemodifier"), + ("bpy.types.colorgpencilmodifier*", "grease_pencil/modifiers/color/hue_saturation.html#bpy-types-colorgpencilmodifier"), + ("bpy.types.colorramp.color_mode*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-color-mode"), + ("bpy.types.compositornodefilter*", "compositing/types/filter/filter_node.html#bpy-types-compositornodefilter"), + ("bpy.types.compositornodehuesat*", "compositing/types/color/hue_saturation.html#bpy-types-compositornodehuesat"), + ("bpy.types.compositornodeidmask*", "compositing/types/converter/id_mask.html#bpy-types-compositornodeidmask"), + ("bpy.types.compositornodeinvert*", "compositing/types/color/invert.html#bpy-types-compositornodeinvert"), + ("bpy.types.compositornodekeying*", "compositing/types/matte/keying.html#bpy-types-compositornodekeying"), + ("bpy.types.compositornodelevels*", "compositing/types/output/levels.html#bpy-types-compositornodelevels"), + ("bpy.types.compositornodemixrgb*", "compositing/types/color/mix.html#bpy-types-compositornodemixrgb"), + ("bpy.types.compositornodenormal*", "compositing/types/vector/normal.html#bpy-types-compositornodenormal"), + ("bpy.types.compositornoderotate*", "compositing/types/distort/rotate.html#bpy-types-compositornoderotate"), + ("bpy.types.compositornodeswitch*", "compositing/types/layout/switch.html#bpy-types-compositornodeswitch"), + ("bpy.types.compositornodeviewer*", "compositing/types/output/viewer.html#bpy-types-compositornodeviewer"), + ("bpy.types.constraint.influence*", "animation/constraints/interface/common.html#bpy-types-constraint-influence"), + ("bpy.types.curve.use_path_clamp*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-clamp"), + ("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"), + ("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"), + ("bpy.types.editbone.use_connect*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-connect"), + ("bpy.types.ffmpegsettings.audio*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio"), + ("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"), + ("bpy.types.functionnodeinputint*", "modeling/geometry_nodes/input/integer.html#bpy-types-functionnodeinputint"), + ("bpy.types.gaussianblursequence*", "video_editing/edit/montage/strips/effects/blur.html#bpy-types-gaussianblursequence"), + ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/bounding_box.html#bpy-types-geometrynodeboundbox"), + ("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve_primitives/arc.html#bpy-types-geometrynodecurvearc"), + ("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/dual_mesh.html#bpy-types-geometrynodedualmesh"), + ("bpy.types.geometrynodematerial*", "-1"), + ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh_primitives/cone.html#bpy-types-geometrynodemeshcone"), + ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh_primitives/cube.html#bpy-types-geometrynodemeshcube"), + ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh_primitives/grid.html#bpy-types-geometrynodemeshgrid"), + ("bpy.types.geometrynodemeshline*", "modeling/geometry_nodes/mesh_primitives/mesh_line.html#bpy-types-geometrynodemeshline"), + ("bpy.types.gpencillayer.opacity*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-opacity"), + ("bpy.types.image.display_aspect*", "editors/image/sidebar.html#bpy-types-image-display-aspect"), + ("bpy.types.keyframe.handle_left*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left"), + ("bpy.types.keyingsetsall.active*", "editors/timeline.html#bpy-types-keyingsetsall-active"), + ("bpy.types.limitscaleconstraint*", "animation/constraints/transform/limit_scale.html#bpy-types-limitscaleconstraint"), + ("bpy.types.materialgpencilstyle*", "grease_pencil/materials/index.html#bpy-types-materialgpencilstyle"), + ("bpy.types.mesh.use_auto_smooth*", "modeling/meshes/structure.html#bpy-types-mesh-use-auto-smooth"), + ("bpy.types.meshtovolumemodifier*", "modeling/modifiers/generate/mesh_to_volume.html#bpy-types-meshtovolumemodifier"), + ("bpy.types.modifier.show_render*", "modeling/modifiers/introduction.html#bpy-types-modifier-show-render"), + ("bpy.types.motionpath.frame_end*", "animation/motion_paths.html#bpy-types-motionpath-frame-end"), + ("bpy.types.noisegpencilmodifier*", "grease_pencil/modifiers/deform/noise.html#bpy-types-noisegpencilmodifier"), + ("bpy.types.object.hide_viewport*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-viewport"), + ("bpy.types.object.rotation_mode*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation-mode"), + ("bpy.types.object.show_in_front*", "scene_layout/object/properties/display.html#bpy-types-object-show-in-front"), + ("bpy.types.posebone.rigify_type*", "addons/rigging/rigify/rig_types/index.html#bpy-types-posebone-rigify-type"), + ("bpy.types.preferencesfilepaths*", "editors/preferences/file_paths.html#bpy-types-preferencesfilepaths"), + ("bpy.types.rigidbodyobject.mass*", "physics/rigid_body/properties/settings.html#bpy-types-rigidbodyobject-mass"), + ("bpy.types.scene.background_set*", "scene_layout/scene/properties.html#bpy-types-scene-background-set"), + ("bpy.types.sequence.frame_start*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-start"), + ("bpy.types.shadernodebackground*", "render/shader_nodes/shader/background.html#bpy-types-shadernodebackground"), + ("bpy.types.shadernodebsdfglossy*", "render/shader_nodes/shader/glossy.html#bpy-types-shadernodebsdfglossy"), + ("bpy.types.shadernodebsdfvelvet*", "render/shader_nodes/shader/velvet.html#bpy-types-shadernodebsdfvelvet"), + ("bpy.types.shadernodecameradata*", "render/shader_nodes/input/camera_data.html#bpy-types-shadernodecameradata"), + ("bpy.types.shadernodefloatcurve*", "render/shader_nodes/converter/float_curve.html#bpy-types-shadernodefloatcurve"), + ("bpy.types.shadernodeobjectinfo*", "render/shader_nodes/input/object_info.html#bpy-types-shadernodeobjectinfo"), + ("bpy.types.shadernodetexchecker*", "render/shader_nodes/textures/checker.html#bpy-types-shadernodetexchecker"), + ("bpy.types.shadernodetexvoronoi*", "render/shader_nodes/textures/voronoi.html#bpy-types-shadernodetexvoronoi"), + ("bpy.types.shadernodevectormath*", "render/shader_nodes/converter/vector_math.html#bpy-types-shadernodevectormath"), + ("bpy.types.shadernodevolumeinfo*", "render/shader_nodes/input/volume_info.html#bpy-types-shadernodevolumeinfo"), + ("bpy.types.shadernodewavelength*", "render/shader_nodes/converter/wavelength.html#bpy-types-shadernodewavelength"), + ("bpy.types.shrinkwrapconstraint*", "animation/constraints/relationship/shrinkwrap.html#bpy-types-shrinkwrapconstraint"), + ("bpy.types.simpledeformmodifier*", "modeling/modifiers/deform/simple_deform.html#bpy-types-simpledeformmodifier"), + ("bpy.types.spaceclipeditor.show*", "editors/clip/display/index.html#bpy-types-spaceclipeditor-show"), + ("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"), + ("bpy.types.speedcontrolsequence*", "video_editing/edit/montage/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"), + ("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"), + ("bpy.types.texturenodetexclouds*", "editors/texture_node/types/textures/clouds.html#bpy-types-texturenodetexclouds"), + ("bpy.types.texturenodetexmarble*", "editors/texture_node/types/textures/marble.html#bpy-types-texturenodetexmarble"), + ("bpy.types.texturenodetexstucci*", "editors/texture_node/types/textures/stucci.html#bpy-types-texturenodetexstucci"), + ("bpy.types.texturenodetranslate*", "editors/texture_node/types/distort/translate.html#bpy-types-texturenodetranslate"), + ("bpy.types.transformorientation*", "editors/3dview/controls/orientation.html#bpy-types-transformorientation"), + ("bpy.types.unifiedpaintsettings*", "sculpt_paint/brush/brush.html#bpy-types-unifiedpaintsettings"), + ("bpy.types.viewlayer.use_strand*", "render/layers/introduction.html#bpy-types-viewlayer-use-strand"), + ("bpy.types.volume.sequence_mode*", "modeling/volumes/properties.html#bpy-types-volume-sequence-mode"), + ("bpy.types.volumetomeshmodifier*", "modeling/modifiers/generate/volume_to_mesh.html#bpy-types-volumetomeshmodifier"), + ("bpy.types.whitebalancemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-whitebalancemodifier"), + ("bpy.ops.anim.channels_ungroup*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-ungroup"), + ("bpy.ops.armature.extrude_move*", "animation/armatures/bones/editing/extrude.html#bpy-ops-armature-extrude-move"), + ("bpy.ops.armature.parent_clear*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-clear"), + ("bpy.ops.clip.clear_track_path*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clear-track-path"), + ("bpy.ops.clip.set_scene_frames*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-set-scene-frames"), + ("bpy.ops.curve.handle_type_set*", "modeling/curves/editing/control_points.html#bpy-ops-curve-handle-type-set"), + ("bpy.ops.curve.spline_type_set*", "modeling/curves/editing/curve.html#bpy-ops-curve-spline-type-set"), + ("bpy.ops.file.unpack_libraries*", "files/blend/packed_data.html#bpy-ops-file-unpack-libraries"), + ("bpy.ops.gpencil.layer_isolate*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-isolate"), + ("bpy.ops.gpencil.move_to_layer*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-move-to-layer"), + ("bpy.ops.gpencil.stroke_sample*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-sample"), + ("bpy.ops.gpencil.stroke_smooth*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-smooth"), + ("bpy.ops.graph.keyframe_insert*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-keyframe-insert"), + ("bpy.ops.image.read_viewlayers*", "editors/image/editing.html#bpy-ops-image-read-viewlayers"), + ("bpy.ops.mesh.blend_from_shape*", "modeling/meshes/editing/vertex/blend_shape.html#bpy-ops-mesh-blend-from-shape"), + ("bpy.ops.mesh.dissolve_limited*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-limited"), + ("bpy.ops.mesh.face_make_planar*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-face-make-planar"), + ("bpy.ops.mesh.face_set_extract*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-mesh-face-set-extract"), + ("bpy.ops.mesh.faces_shade_flat*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-faces-shade-flat"), + ("bpy.ops.mesh.paint_mask_slice*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-mesh-paint-mask-slice"), + ("bpy.ops.mesh.select_ungrouped*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-ungrouped"), + ("bpy.ops.node.delete_reconnect*", "interface/controls/nodes/editing.html#bpy-ops-node-delete-reconnect"), + ("bpy.ops.node.tree_path_parent*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-path-parent"), + ("bpy.ops.node.tree_socket_move*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-move"), + ("bpy.ops.object.duplicate_move*", "scene_layout/object/editing/duplicate.html#bpy-ops-object-duplicate-move"), + ("bpy.ops.object.hook_add_selob*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook-add-selob"), + ("bpy.ops.object.modifier_apply*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-apply"), + ("bpy.ops.object.select_by_type*", "scene_layout/object/selecting.html#bpy-ops-object-select-by-type"), + ("bpy.ops.object.select_grouped*", "scene_layout/object/selecting.html#bpy-ops-object-select-grouped"), + ("bpy.ops.object.select_pattern*", "scene_layout/object/selecting.html#bpy-ops-object-select-pattern"), + ("bpy.ops.outliner.id_operation*", "editors/outliner/editing.html#bpy-ops-outliner-id-operation"), + ("bpy.ops.paint.mask_flood_fill*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask-flood-fill"), + ("bpy.ops.pose.quaternions_flip*", "animation/armatures/posing/editing/flip_quats.html#bpy-ops-pose-quaternions-flip"), + ("bpy.ops.pose.select_hierarchy*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-hierarchy"), + ("bpy.ops.pose.transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-transforms-clear"), + ("bpy.ops.poselib.copy_as_asset*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-copy-as-asset"), + ("bpy.ops.preferences.copy_prev*", "editors/preferences/introduction.html#bpy-ops-preferences-copy-prev"), + ("bpy.ops.preferences.keyconfig*", "editors/preferences/keymap.html#bpy-ops-preferences-keyconfig"), + ("bpy.ops.screen.repeat_history*", "interface/undo_redo.html#bpy-ops-screen-repeat-history"), + ("bpy.ops.script.execute_preset*", "interface/window_system/tabs_panels.html#bpy-ops-script-execute-preset"), + ("bpy.ops.sculpt.face_sets_init*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-init"), + ("bpy.ops.sequencer.change_path*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-change-path"), + ("bpy.ops.sequencer.refresh_all*", "editors/video_sequencer/sequencer/navigating.html#bpy-ops-sequencer-refresh-all"), + ("bpy.ops.sequencer.select_less*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-less"), + ("bpy.ops.sequencer.select_more*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-more"), + ("bpy.ops.sequencer.select_side*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-side"), + ("bpy.ops.sequencer.swap_inputs*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap-inputs"), + ("bpy.ops.surface.primitive*add*", "modeling/surfaces/primitives.html#bpy-ops-surface-primitive-add"), + ("bpy.ops.text.resolve_conflict*", "editors/text_editor.html#bpy-ops-text-resolve-conflict"), + ("bpy.ops.transform.edge_crease*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-crease"), + ("bpy.ops.transform.skin_resize*", "modeling/meshes/editing/mesh/transform/skin_resize.html#bpy-ops-transform-skin-resize"), + ("bpy.ops.uv.seams_from_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-seams-from-islands"), + ("bpy.types.bakesettings.margin*", "render/cycles/baking.html#bpy-types-bakesettings-margin"), + ("bpy.types.bakesettings.target*", "render/cycles/baking.html#bpy-types-bakesettings-target"), + ("bpy.types.brush.cloth_damping*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-damping"), + ("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"), + ("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"), + ("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"), + ("bpy.types.camera.sensor_width*", "render/cameras.html#bpy-types-camera-sensor-width"), + ("bpy.types.compositornodedblur*", "compositing/types/filter/directional_blur.html#bpy-types-compositornodedblur"), + ("bpy.types.compositornodegamma*", "compositing/types/color/gamma.html#bpy-types-compositornodegamma"), + ("bpy.types.compositornodeglare*", "compositing/types/filter/glare.html#bpy-types-compositornodeglare"), + ("bpy.types.compositornodegroup*", "compositing/types/groups.html#bpy-types-compositornodegroup"), + ("bpy.types.compositornodeimage*", "compositing/types/input/image.html#bpy-types-compositornodeimage"), + ("bpy.types.compositornodemapuv*", "compositing/types/distort/map_uv.html#bpy-types-compositornodemapuv"), + ("bpy.types.compositornodescale*", "compositing/types/distort/scale.html#bpy-types-compositornodescale"), + ("bpy.types.compositornodevalue*", "compositing/types/input/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"), + ("bpy.types.curve.use_fill_caps*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-fill-caps"), + ("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"), + ("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"), + ("bpy.types.dashgpencilmodifier*", "grease_pencil/modifiers/generate/dash.html#bpy-types-dashgpencilmodifier"), + ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), + ("bpy.types.functionnodecompare*", "modeling/geometry_nodes/utilities/compare.html#bpy-types-functionnodecompare"), + ("bpy.types.geometrynodeinputid*", "modeling/geometry_nodes/input/id.html#bpy-types-geometrynodeinputid"), + ("bpy.types.geometrynoderaycast*", "modeling/geometry_nodes/geometry/raycast.html#bpy-types-geometrynoderaycast"), + ("bpy.types.gpencillayer.parent*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent"), + ("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"), + ("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"), + ("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"), + ("bpy.types.material.line_color*", "render/freestyle/material.html#bpy-types-material-line-color"), + ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"), + ("bpy.types.movietrackingcamera*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera"), + ("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"), + ("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"), + ("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"), + ("bpy.types.posebone.bone_group*", "animation/armatures/bones/properties/relations.html#bpy-types-posebone-bone-group"), + ("bpy.types.poseboneconstraints*", "animation/armatures/posing/bone_constraints/index.html#bpy-types-poseboneconstraints"), + ("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.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"), + ("bpy.types.shadernodebsdfglass*", "render/shader_nodes/shader/glass.html#bpy-types-shadernodebsdfglass"), + ("bpy.types.shadernodelightpath*", "render/shader_nodes/input/light_path.html#bpy-types-shadernodelightpath"), + ("bpy.types.shadernodemixshader*", "render/shader_nodes/shader/mix.html#bpy-types-shadernodemixshader"), + ("bpy.types.shadernodenormalmap*", "render/shader_nodes/vector/normal_map.html#bpy-types-shadernodenormalmap"), + ("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.spacesequenceeditor*", "editors/video_sequencer/index.html#bpy-types-spacesequenceeditor"), + ("bpy.types.spline.resolution_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-resolution-u"), + ("bpy.types.spline.use_bezier_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-bezier-u"), + ("bpy.types.spline.use_cyclic_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-cyclic-u"), + ("bpy.types.stretchtoconstraint*", "animation/constraints/tracking/stretch_to.html#bpy-types-stretchtoconstraint"), + ("bpy.types.texturenodecurvergb*", "editors/texture_node/types/color/rgb_curves.html#bpy-types-texturenodecurvergb"), + ("bpy.types.texturenodedistance*", "editors/texture_node/types/converter/distance.html#bpy-types-texturenodedistance"), + ("bpy.types.texturenodetexblend*", "editors/texture_node/types/textures/blend.html#bpy-types-texturenodetexblend"), + ("bpy.types.texturenodetexmagic*", "editors/texture_node/types/textures/magic.html#bpy-types-texturenodetexmagic"), + ("bpy.types.texturenodetexnoise*", "editors/texture_node/types/textures/noise.html#bpy-types-texturenodetexnoise"), + ("bpy.types.texturenodevaltonor*", "editors/texture_node/types/converter/value_to_normal.html#bpy-types-texturenodevaltonor"), + ("bpy.types.texturenodevaltorgb*", "editors/texture_node/types/converter/rgb_to_bw.html#bpy-types-texturenodevaltorgb"), + ("bpy.types.timegpencilmodifier*", "grease_pencil/modifiers/modify/time_offset.html#bpy-types-timegpencilmodifier"), + ("bpy.types.tintgpencilmodifier*", "grease_pencil/modifiers/color/tint.html#bpy-types-tintgpencilmodifier"), + ("bpy.types.transformconstraint*", "animation/constraints/transform/transformation.html#bpy-types-transformconstraint"), + ("bpy.types.triangulatemodifier*", "modeling/modifiers/generate/triangulate.html#bpy-types-triangulatemodifier"), + ("bpy.types.unitsettings.system*", "scene_layout/scene/properties.html#bpy-types-unitsettings-system"), + ("bpy.types.viewlayer.use_solid*", "render/layers/introduction.html#bpy-types-viewlayer-use-solid"), + ("bpy.types.volume.frame_offset*", "modeling/volumes/properties.html#bpy-types-volume-frame-offset"), + ("bpy.types.windowmanager.addon*", "editors/preferences/addons.html#bpy-types-windowmanager-addon"), + ("bpy.ops.anim.channels_delete*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-delete"), + ("bpy.ops.anim.channels_expand*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-expand"), + ("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"), + ("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"), + ("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"), + ("bpy.ops.armature.select_less*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-less"), + ("bpy.ops.armature.select_more*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-more"), + ("bpy.ops.asset.bundle_install*", "editors/asset_browser.html#bpy-ops-asset-bundle-install"), + ("bpy.ops.clip.add_marker_move*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-add-marker-move"), + ("bpy.ops.clip.bundles_to_mesh*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-bundles-to-mesh"), + ("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"), + ("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"), + ("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"), + ("bpy.ops.curve.duplicate_move*", "modeling/curves/editing/curve.html#bpy-ops-curve-duplicate-move"), + ("bpy.ops.file.autopack_toggle*", "files/blend/packed_data.html#bpy-ops-file-autopack-toggle"), + ("bpy.ops.fluid.bake_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-bake-particles"), + ("bpy.ops.fluid.free_particles*", "physics/fluid/type/domain/liquid/particles.html#bpy-ops-fluid-free-particles"), + ("bpy.ops.gpencil.extrude_move*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-extrude-move"), + ("bpy.ops.gpencil.stroke_merge*", "grease_pencil/modes/edit/point_menu.html#bpy-ops-gpencil-stroke-merge"), + ("bpy.ops.gpencil.stroke_split*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-stroke-split"), + ("bpy.ops.graph.duplicate_move*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-duplicate-move"), + ("bpy.ops.mesh.average_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-average-normals"), + ("bpy.ops.mesh.delete_edgeloop*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete-edgeloop"), + ("bpy.ops.mesh.vertices_smooth*", "modeling/meshes/editing/vertex/smooth_vertices.html#bpy-ops-mesh-vertices-smooth"), + ("bpy.ops.nla.make_single_user*", "editors/nla/editing.html#bpy-ops-nla-make-single-user"), + ("bpy.ops.node.clipboard_paste*", "interface/controls/nodes/editing.html#bpy-ops-node-clipboard-paste"), + ("bpy.ops.node.node_copy_color*", "interface/controls/nodes/sidebar.html#bpy-ops-node-node-copy-color"), + ("bpy.ops.node.read_viewlayers*", "interface/controls/nodes/editing.html#bpy-ops-node-read-viewlayers"), + ("bpy.ops.node.tree_socket_add*", "interface/controls/nodes/groups.html#bpy-ops-node-tree-socket-add"), + ("bpy.ops.object.attribute_add*", "modeling/geometry_nodes/attributes_reference.html#bpy-ops-object-attribute-add"), + ("bpy.ops.object.data_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data.html#bpy-ops-object-data-transfer"), + ("bpy.ops.object.modifier_copy*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy"), + ("bpy.ops.object.select_camera*", "scene_layout/object/selecting.html#bpy-ops-object-select-camera"), + ("bpy.ops.object.select_linked*", "scene_layout/object/selecting.html#bpy-ops-object-select-linked"), + ("bpy.ops.object.select_mirror*", "scene_layout/object/selecting.html#bpy-ops-object-select-mirror"), + ("bpy.ops.object.select_random*", "scene_layout/object/selecting.html#bpy-ops-object-select-random"), + ("bpy.ops.object.transfer_mode*", "editors/3dview/modes.html#bpy-ops-object-transfer-mode"), + ("bpy.ops.outliner.show_active*", "editors/outliner/editing.html#bpy-ops-outliner-show-active"), + ("bpy.ops.paint.add_simple_uvs*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-ops-paint-add-simple-uvs"), + ("bpy.ops.pose.paths_calculate*", "animation/motion_paths.html#bpy-ops-pose-paths-calculate"), + ("bpy.ops.pose.rigify_generate*", "addons/rigging/rigify/basics.html#bpy-ops-pose-rigify-generate"), + ("bpy.ops.preferences.autoexec*", "editors/preferences/save_load.html#bpy-ops-preferences-autoexec"), + ("bpy.ops.scene.view_layer_add*", "render/layers/introduction.html#bpy-ops-scene-view-layer-add"), + ("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.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"), + ("bpy.ops.sound.bake_animation*", "scene_layout/scene/properties.html#bpy-ops-sound-bake-animation"), + ("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"), + ("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"), + ("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"), + ("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"), + ("bpy.ops.wm.recover_auto_save*", "files/blend/open_save.html#bpy-ops-wm-recover-auto-save"), + ("bpy.types.adjustmentsequence*", "video_editing/edit/montage/strips/adjustment.html#bpy-types-adjustmentsequence"), + ("bpy.types.alphaundersequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"), + ("bpy.types.animvizmotionpaths*", "animation/motion_paths.html#bpy-types-animvizmotionpaths"), + ("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"), + ("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"), + ("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"), + ("bpy.types.compositornodecomb*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodecomb"), + ("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"), + ("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"), + ("bpy.types.compositornodemask*", "compositing/types/input/mask.html#bpy-types-compositornodemask"), + ("bpy.types.compositornodemath*", "compositing/types/converter/math.html#bpy-types-compositornodemath"), + ("bpy.types.compositornodetime*", "compositing/types/input/time_curve.html#bpy-types-compositornodetime"), + ("bpy.types.constraint.enabled*", "animation/constraints/interface/header.html#bpy-types-constraint-enabled"), + ("bpy.types.curve.bevel_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-object"), + ("bpy.types.curve.resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-resolution-u"), + ("bpy.types.curve.resolution_v*", "modeling/surfaces/properties/shape.html#bpy-types-curve-resolution-v"), + ("bpy.types.curve.taper_object*", "modeling/curves/properties/geometry.html#bpy-types-curve-taper-object"), + ("bpy.types.curve.twist_smooth*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-smooth"), + ("bpy.types.curvepaintsettings*", "modeling/curves/tools/draw.html#bpy-types-curvepaintsettings"), + ("bpy.types.fcurve.array_index*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-array-index"), + ("bpy.types.fileselectidfilter*", "editors/file_browser.html#bpy-types-fileselectidfilter"), + ("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiergenerator"), + ("bpy.types.freestylelinestyle*", "render/freestyle/view_layer/line_style/index.html#bpy-types-freestylelinestyle"), + ("bpy.types.gammacrosssequence*", "video_editing/edit/montage/strips/transitions/gamma_cross.html#bpy-types-gammacrosssequence"), + ("bpy.types.geometrynodeswitch*", "modeling/geometry_nodes/utilities/switch.html#bpy-types-geometrynodeswitch"), + ("bpy.types.geometrynodeviewer*", "modeling/geometry_nodes/output/viewer.html#bpy-types-geometrynodeviewer"), + ("bpy.types.gpencillayer.scale*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-scale"), + ("bpy.types.gpencilsculptguide*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide"), + ("bpy.types.huecorrectmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-huecorrectmodifier"), + ("bpy.types.image.is_multiview*", "editors/image/image_settings.html#bpy-types-image-is-multiview"), + ("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"), + ("bpy.types.meshdeformmodifier*", "modeling/modifiers/deform/mesh_deform.html#bpy-types-meshdeformmodifier"), + ("bpy.types.movietrackingtrack*", "movie_clip/tracking/clip/sidebar/track/index.html#bpy-types-movietrackingtrack"), + ("bpy.types.nodeoutputfileslot*", "compositing/types/output/file.html#bpy-types-nodeoutputfileslot"), + ("bpy.types.normaleditmodifier*", "modeling/modifiers/modify/normal_edit.html#bpy-types-normaleditmodifier"), + ("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"), + ("bpy.types.object.hide_render*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-render"), + ("bpy.types.object.hide_select*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-select"), + ("bpy.types.object.parent_type*", "scene_layout/object/properties/relations.html#bpy-types-object-parent-type"), + ("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"), + ("bpy.types.rendersettings.fps*", "render/output/properties/format.html#bpy-types-rendersettings-fps"), + ("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"), + ("bpy.types.sculpt.detail_size*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-size"), + ("bpy.types.shadernodebsdfhair*", "render/shader_nodes/shader/hair.html#bpy-types-shadernodebsdfhair"), + ("bpy.types.shadernodebsdftoon*", "render/shader_nodes/shader/toon.html#bpy-types-shadernodebsdftoon"), + ("bpy.types.shadernodeemission*", "render/shader_nodes/shader/emission.html#bpy-types-shadernodeemission"), + ("bpy.types.shadernodehairinfo*", "render/shader_nodes/input/hair_info.html#bpy-types-shadernodehairinfo"), + ("bpy.types.shadernodemaprange*", "render/shader_nodes/converter/map_range.html#bpy-types-shadernodemaprange"), + ("bpy.types.shadernodergbcurve*", "modeling/geometry_nodes/color/rgb_curves.html#bpy-types-shadernodergbcurve"), + ("bpy.types.shadernodeseparate*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodeseparate"), + ("bpy.types.shadernodetexbrick*", "render/shader_nodes/textures/brick.html#bpy-types-shadernodetexbrick"), + ("bpy.types.shadernodetexcoord*", "render/shader_nodes/input/texture_coordinate.html#bpy-types-shadernodetexcoord"), + ("bpy.types.shadernodeteximage*", "render/shader_nodes/textures/image.html#bpy-types-shadernodeteximage"), + ("bpy.types.shadernodetexmagic*", "render/shader_nodes/textures/magic.html#bpy-types-shadernodetexmagic"), + ("bpy.types.shadernodetexnoise*", "render/shader_nodes/textures/noise.html#bpy-types-shadernodetexnoise"), + ("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"), + ("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"), + ("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"), + ("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"), + ("bpy.types.texturenodetexwood*", "editors/texture_node/types/textures/wood.html#bpy-types-texturenodetexwood"), + ("bpy.types.view3dshading.type*", "editors/3dview/display/shading.html#bpy-types-view3dshading-type"), + ("bpy.types.volume.frame_start*", "modeling/volumes/properties.html#bpy-types-volume-frame-start"), + ("bpy.types.volume.is_sequence*", "modeling/volumes/properties.html#bpy-types-volume-is-sequence"), + ("bpy.types.volumerender.space*", "modeling/volumes/properties.html#bpy-types-volumerender-space"), + ("bpy.ops.anim.channels_group*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-group"), + ("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"), + ("bpy.ops.armature.flip_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-flip-names"), + ("bpy.ops.armature.parent_set*", "animation/armatures/bones/editing/parenting.html#bpy-ops-armature-parent-set"), + ("bpy.ops.armature.select_all*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-all"), + ("bpy.ops.armature.symmetrize*", "animation/armatures/bones/editing/symmetrize.html#bpy-ops-armature-symmetrize"), + ("bpy.ops.clip.average_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-average-tracks"), + ("bpy.ops.clip.refine_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-refine-markers"), + ("bpy.ops.clip.select_grouped*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-grouped"), + ("bpy.ops.clip.track_to_empty*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-track-to-empty"), + ("bpy.ops.curve.cyclic_toggle*", "modeling/curves/editing/curve.html#bpy-ops-curve-cyclic-toggle"), + ("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"), + ("bpy.ops.curve.smooth_radius*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-radius"), + ("bpy.ops.curve.smooth_weight*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-weight"), + ("bpy.ops.file.pack_libraries*", "files/blend/packed_data.html#bpy-ops-file-pack-libraries"), + ("bpy.ops.font.change_spacing*", "modeling/texts/editing.html#bpy-ops-font-change-spacing"), + ("bpy.ops.gpencil.layer_merge*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-layer-merge"), + ("bpy.ops.gpencil.stroke_flip*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-flip"), + ("bpy.ops.gpencil.stroke_join*", "grease_pencil/modes/edit/stroke_menu.html#bpy-ops-gpencil-stroke-join"), + ("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.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"), + ("bpy.ops.mesh.dissolve_faces*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-faces"), + ("bpy.ops.mesh.dissolve_verts*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve-verts"), + ("bpy.ops.mesh.duplicate_move*", "modeling/meshes/editing/mesh/duplicate.html#bpy-ops-mesh-duplicate-move"), + ("bpy.ops.mesh.extrude_region*", "modeling/meshes/tools/extrude_region.html#bpy-ops-mesh-extrude-region"), + ("bpy.ops.mesh.extrude_repeat*", "modeling/meshes/editing/mesh/extrude.html#bpy-ops-mesh-extrude-repeat"), + ("bpy.ops.mesh.loop_to_region*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-to-region"), + ("bpy.ops.mesh.region_to_loop*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-region-to-loop"), + ("bpy.ops.mesh.remove_doubles*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-remove-doubles"), + ("bpy.ops.mesh.select_similar*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar"), + ("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"), + ("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"), + ("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"), + ("bpy.ops.node.clipboard_copy*", "interface/controls/nodes/editing.html#bpy-ops-node-clipboard-copy"), + ("bpy.ops.node.duplicate_move*", "interface/controls/nodes/editing.html#bpy-ops-node-duplicate-move"), + ("bpy.ops.node.options_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-options-toggle"), + ("bpy.ops.node.preview_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-preview-toggle"), + ("bpy.ops.object.origin_clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-origin-clear"), + ("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"), + ("bpy.ops.object.paths_update*", "animation/motion_paths.html#bpy-ops-object-paths-update"), + ("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"), + ("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"), + ("bpy.ops.pose.armature_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-armature-apply"), + ("bpy.ops.pose.group_deselect*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-deselect"), + ("bpy.ops.pose.group_unassign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-unassign"), + ("bpy.ops.pose.select_grouped*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-grouped"), + ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), + ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), + ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), + ("bpy.ops.sequencer.swap_data*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap-data"), + ("bpy.ops.transform.push_pull*", "modeling/meshes/editing/mesh/transform/push_pull.html#bpy-ops-transform-push-pull"), + ("bpy.ops.transform.seq_slide*", "video_editing/edit/montage/editing.html#bpy-ops-transform-seq-slide"), + ("bpy.ops.transform.trackball*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-trackball"), + ("bpy.ops.transform.transform*", "scene_layout/object/editing/transform/align_transform_orientation.html#bpy-ops-transform-transform"), + ("bpy.ops.transform.translate*", "scene_layout/object/editing/transform/move.html#bpy-ops-transform-translate"), + ("bpy.ops.ui.eyedropper_color*", "interface/controls/templates/color_picker.html#bpy-ops-ui-eyedropper-color"), + ("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"), + ("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"), + ("bpy.ops.uv.select_edge_ring*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-ring"), + ("bpy.ops.wm.save_as_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-as-mainfile"), + ("bpy.types.alphaoversequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"), + ("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"), + ("bpy.types.brush.pose_offset*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-offset"), + ("bpy.types.brush.rake_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-rake-factor"), + ("bpy.types.camera.sensor_fit*", "render/cameras.html#bpy-types-camera-sensor-fit"), + ("bpy.types.cameradofsettings*", "render/cameras.html#bpy-types-cameradofsettings"), + ("bpy.types.childofconstraint*", "animation/constraints/relationship/child_of.html#bpy-types-childofconstraint"), + ("bpy.types.clamptoconstraint*", "animation/constraints/tracking/clamp_to.html#bpy-types-clamptoconstraint"), + ("bpy.types.collisionmodifier*", "physics/collision.html#bpy-types-collisionmodifier"), + ("bpy.types.collisionsettings*", "physics/collision.html#bpy-types-collisionsettings"), + ("bpy.types.compositornodergb*", "compositing/types/input/rgb.html#bpy-types-compositornodergb"), + ("bpy.types.compositornodesep*", "editors/texture_node/types/color/combine_separate.html#bpy-types-compositornodesep"), + ("bpy.types.curve.bevel_depth*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-depth"), + ("bpy.types.curve.use_stretch*", "modeling/curves/properties/shape.html#bpy-types-curve-use-stretch"), + ("bpy.types.edgesplitmodifier*", "modeling/modifiers/generate/edge_split.html#bpy-types-edgesplitmodifier"), + ("bpy.types.fcurve.color_mode*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-color-mode"), + ("bpy.types.fluidflowsettings*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings"), + ("bpy.types.fmodifierenvelope*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelope"), + ("bpy.types.freestylesettings*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings"), + ("bpy.types.geometrynodegroup*", "modeling/geometry_nodes/group.html#bpy-types-geometrynodegroup"), + ("bpy.types.geometrynodesetid*", "modeling/geometry_nodes/geometry/set_id.html#bpy-types-geometrynodesetid"), + ("bpy.types.gpencillayer.hide*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-hide"), + ("bpy.types.gpencillayer.lock*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-lock"), + ("bpy.types.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"), + ("bpy.types.materialslot.link*", "render/materials/assignment.html#bpy-types-materialslot-link"), + ("bpy.types.mesh.texture_mesh*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-mesh-texture-mesh"), + ("bpy.types.mesh.use_mirror_x*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-x"), + ("bpy.types.mesh.use_mirror_y*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-y"), + ("bpy.types.mesh.use_mirror_z*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-z"), + ("bpy.types.meshcachemodifier*", "modeling/modifiers/modify/mesh_cache.html#bpy-types-meshcachemodifier"), + ("bpy.types.movieclipsequence*", "video_editing/edit/montage/strips/clip.html#bpy-types-movieclipsequence"), + ("bpy.types.object.dimensions*", "scene_layout/object/properties/transforms.html#bpy-types-object-dimensions"), + ("bpy.types.object.is_holdout*", "scene_layout/object/properties/visibility.html#bpy-types-object-is-holdout"), + ("bpy.types.object.pass_index*", "scene_layout/object/properties/relations.html#bpy-types-object-pass-index"), + ("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"), + ("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"), + ("bpy.types.preferencessystem*", "editors/preferences/system.html#bpy-types-preferencessystem"), + ("bpy.types.scene.active_clip*", "scene_layout/scene/properties.html#bpy-types-scene-active-clip"), + ("bpy.types.scene.frame_start*", "render/output/properties/frame_range.html#bpy-types-scene-frame-start"), + ("bpy.types.sceneeevee.shadow*", "render/eevee/render_settings/shadows.html#bpy-types-sceneeevee-shadow"), + ("bpy.types.screen.use_follow*", "editors/timeline.html#bpy-types-screen-use-follow"), + ("bpy.types.sequencetransform*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform"), + ("bpy.types.shadernodecombine*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodecombine"), + ("bpy.types.shadernodefresnel*", "render/shader_nodes/input/fresnel.html#bpy-types-shadernodefresnel"), + ("bpy.types.shadernodeholdout*", "render/shader_nodes/shader/holdout.html#bpy-types-shadernodeholdout"), + ("bpy.types.shadernodemapping*", "render/shader_nodes/vector/mapping.html#bpy-types-shadernodemapping"), + ("bpy.types.shadernodergbtobw*", "render/shader_nodes/converter/rgb_to_bw.html#bpy-types-shadernodergbtobw"), + ("bpy.types.shadernodetangent*", "render/shader_nodes/input/tangent.html#bpy-types-shadernodetangent"), + ("bpy.types.shadernodetexwave*", "render/shader_nodes/textures/wave.html#bpy-types-shadernodetexwave"), + ("bpy.types.spline.use_smooth*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-smooth"), + ("bpy.types.texturenodebricks*", "editors/texture_node/types/patterns/bricks.html#bpy-types-texturenodebricks"), + ("bpy.types.texturenodemixrgb*", "editors/texture_node/types/color/mix_rgb.html#bpy-types-texturenodemixrgb"), + ("bpy.types.texturenodeoutput*", "editors/texture_node/types/output/output.html#bpy-types-texturenodeoutput"), + ("bpy.types.texturenoderotate*", "editors/texture_node/types/distort/rotate.html#bpy-types-texturenoderotate"), + ("bpy.types.texturenodeviewer*", "editors/texture_node/types/output/viewer.html#bpy-types-texturenodeviewer"), + ("bpy.types.tracktoconstraint*", "animation/constraints/tracking/track_to.html#bpy-types-tracktoconstraint"), + ("bpy.types.transformsequence*", "video_editing/edit/montage/strips/effects/transform.html#bpy-types-transformsequence"), + ("bpy.types.uvprojectmodifier*", "modeling/modifiers/modify/uv_project.html#bpy-types-uvprojectmodifier"), + ("bpy.types.viewlayer.samples*", "render/layers/introduction.html#bpy-types-viewlayer-samples"), + ("bpy.types.viewlayer.use_sky*", "render/layers/introduction.html#bpy-types-viewlayer-use-sky"), + ("bpy.types.wireframemodifier*", "modeling/modifiers/generate/wireframe.html#bpy-types-wireframemodifier"), + ("bpy.types.worldmistsettings*", "render/cycles/world_settings.html#bpy-types-worldmistsettings"), + ("bpy.ops.anim.channels_move*", "editors/graph_editor/channels.html#bpy-ops-anim-channels-move"), + ("bpy.ops.armature.subdivide*", "animation/armatures/bones/editing/subdivide.html#bpy-ops-armature-subdivide"), + ("bpy.ops.buttons.toggle_pin*", "editors/properties_editor.html#bpy-ops-buttons-toggle-pin"), + ("bpy.ops.clip.filter_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-filter-tracks"), + ("bpy.ops.clip.select_circle*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-circle"), + ("bpy.ops.clip.track_markers*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-track-markers"), + ("bpy.ops.curve.extrude_move*", "modeling/curves/editing/control_points.html#bpy-ops-curve-extrude-move"), + ("bpy.ops.curve.make_segment*", "modeling/curves/editing/control_points.html#bpy-ops-curve-make-segment"), + ("bpy.ops.file.directory_new*", "editors/file_browser.html#bpy-ops-file-directory-new"), + ("bpy.ops.graph.euler_filter*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-euler-filter"), + ("bpy.ops.marker.camera_bind*", "animation/markers.html#bpy-ops-marker-camera-bind"), + ("bpy.ops.mask.select_circle*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-circle"), + ("bpy.ops.mask.select_linked*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-linked"), + ("bpy.ops.mesh.beautify_fill*", "modeling/meshes/editing/face/beautify_faces.html#bpy-ops-mesh-beautify-fill"), + ("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"), + ("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"), + ("bpy.ops.mesh.edge_face_add*", "modeling/meshes/editing/vertex/make_face_edge.html#bpy-ops-mesh-edge-face-add"), + ("bpy.ops.mesh.extrude_indiv*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-mesh-extrude-indiv"), + ("bpy.ops.mesh.knife_project*", "modeling/meshes/editing/mesh/knife_project.html#bpy-ops-mesh-knife-project"), + ("bpy.ops.mesh.loopcut_slide*", "modeling/meshes/editing/edge/loopcut_slide.html#bpy-ops-mesh-loopcut-slide"), + ("bpy.ops.mesh.merge_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-merge-normals"), + ("bpy.ops.mesh.normals_tools*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-tools"), + ("bpy.ops.mesh.point_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-point-normals"), + ("bpy.ops.mesh.rip_edge_move*", "modeling/meshes/editing/vertex/rip_vertices_extend.html#bpy-ops-mesh-rip-edge-move"), + ("bpy.ops.mesh.select_linked*", "modeling/meshes/selecting/linked.html#bpy-ops-mesh-select-linked"), + ("bpy.ops.mesh.select_random*", "modeling/meshes/selecting/random.html#bpy-ops-mesh-select-random"), + ("bpy.ops.mesh.sort_elements*", "modeling/meshes/editing/mesh/sort_elements.html#bpy-ops-mesh-sort-elements"), + ("bpy.ops.mesh.split_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-split-normals"), + ("bpy.ops.mesh.symmetry_snap*", "modeling/meshes/editing/mesh/snap_symmetry.html#bpy-ops-mesh-symmetry-snap"), + ("bpy.ops.node.group_ungroup*", "interface/controls/nodes/groups.html#bpy-ops-node-group-ungroup"), + ("bpy.ops.object.gpencil_add*", "grease_pencil/primitives.html#bpy-ops-object-gpencil-add"), + ("bpy.ops.object.paths_clear*", "animation/motion_paths.html#bpy-ops-object-paths-clear"), + ("bpy.ops.object.select_less*", "scene_layout/object/selecting.html#bpy-ops-object-select-less"), + ("bpy.ops.object.select_more*", "scene_layout/object/selecting.html#bpy-ops-object-select-more"), + ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), + ("bpy.ops.pose.select_linked*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-linked"), + ("bpy.ops.pose.select_mirror*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-mirror"), + ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), + ("bpy.ops.screen.marker_jump*", "animation/markers.html#bpy-ops-screen-marker-jump"), + ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), + ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-expand"), + ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-filter"), + ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), + ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), + ("bpy.ops.wm.previews_ensure*", "files/blend/previews.html#bpy-ops-wm-previews-ensure"), + ("bpy.ops.wm.properties_edit*", "files/data_blocks.html#bpy-ops-wm-properties-edit"), + ("bpy.ops.wm.search_operator*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-operator"), + ("bpy.types.actionconstraint*", "animation/constraints/relationship/action.html#bpy-types-actionconstraint"), + ("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"), + ("bpy.types.arealight.spread*", "render/lights/light_object.html#bpy-types-arealight-spread"), + ("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"), + ("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"), + ("bpy.types.bone.tail_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-tail-radius"), + ("bpy.types.brush.cloth_mass*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-mass"), + ("bpy.types.brushtextureslot*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot"), + ("bpy.types.colormixsequence*", "video_editing/edit/montage/strips/effects/color_mix.html#bpy-types-colormixsequence"), + ("bpy.types.curve.dimensions*", "modeling/curves/properties/shape.html#bpy-types-curve-dimensions"), + ("bpy.types.curve.taper_mode*", "modeling/curves/properties/geometry.html#bpy-types-curve-taper-mode"), + ("bpy.types.curve.twist_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-twist-mode"), + ("bpy.types.curve.use_radius*", "modeling/curves/properties/shape.html#bpy-types-curve-use-radius"), + ("bpy.types.decimatemodifier*", "modeling/modifiers/generate/decimate.html#bpy-types-decimatemodifier"), + ("bpy.types.displacemodifier*", "modeling/modifiers/deform/displace.html#bpy-types-displacemodifier"), + ("bpy.types.displaysafeareas*", "render/cameras.html#bpy-types-displaysafeareas"), + ("bpy.types.editbone.bbone_x*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-x"), + ("bpy.types.editbone.bbone_z*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-z"), + ("bpy.types.fcurve.data_path*", "editors/graph_editor/fcurves/properties.html#bpy-types-fcurve-data-path"), + ("bpy.types.fileselectparams*", "editors/file_browser.html#bpy-types-fileselectparams"), + ("bpy.types.fmodifierstepped*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierstepped"), + ("bpy.types.freestylelineset*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset"), + ("bpy.types.greasepencilgrid*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid"), + ("bpy.types.image.alpha_mode*", "editors/image/image_settings.html#bpy-types-image-alpha-mode"), + ("bpy.types.mask.frame_start*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-start"), + ("bpy.types.motionpath.color*", "animation/motion_paths.html#bpy-types-motionpath-color"), + ("bpy.types.motionpath.lines*", "animation/motion_paths.html#bpy-types-motionpath-lines"), + ("bpy.types.multicamsequence*", "video_editing/edit/montage/strips/effects/multicam.html#bpy-types-multicamsequence"), + ("bpy.types.multiplysequence*", "video_editing/edit/montage/strips/effects/multiply.html#bpy-types-multiplysequence"), + ("bpy.types.multiresmodifier*", "modeling/modifiers/generate/multiresolution.html#bpy-types-multiresmodifier"), + ("bpy.types.overdropsequence*", "video_editing/edit/montage/strips/effects/alpha_over_under_overdrop.html#bpy-types-overdropsequence"), + ("bpy.types.paint.show_brush*", "sculpt_paint/brush/cursor.html#bpy-types-paint-show-brush"), + ("bpy.types.paint.use_cavity*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-paint-use-cavity"), + ("bpy.types.particlesettings*", "physics/particles/index.html#bpy-types-particlesettings"), + ("bpy.types.pose.use_auto_ik*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-auto-ik"), + ("bpy.types.preferencesinput*", "editors/preferences/input.html#bpy-types-preferencesinput"), + ("bpy.types.rigifyparameters*", "addons/rigging/rigify/rig_types/index.html#bpy-types-rigifyparameters"), + ("bpy.types.scene.frame_step*", "render/output/properties/frame_range.html#bpy-types-scene-frame-step"), + ("bpy.types.sceneeevee.bloom*", "render/eevee/render_settings/bloom.html#bpy-types-sceneeevee-bloom"), + ("bpy.types.sculpt.show_mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-sculpt-show-mask"), + ("bpy.types.sequence.channel*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-channel"), + ("bpy.types.sequencemodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier"), + ("bpy.types.shaderfxcolorize*", "grease_pencil/visual_effects/colorize.html#bpy-types-shaderfxcolorize"), + ("bpy.types.shaderfxpixelate*", "grease_pencil/visual_effects/pixelate.html#bpy-types-shaderfxpixelate"), + ("bpy.types.shadernodeinvert*", "render/shader_nodes/color/invert.html#bpy-types-shadernodeinvert"), + ("bpy.types.shadernodemixrgb*", "modeling/geometry_nodes/color/mix_rgb.html#bpy-types-shadernodemixrgb"), + ("bpy.types.shadernodenormal*", "render/shader_nodes/vector/normal.html#bpy-types-shadernodenormal"), + ("bpy.types.shadernodescript*", "render/shader_nodes/osl.html#bpy-types-shadernodescript"), + ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), + ("bpy.types.shadernodetexsky*", "render/shader_nodes/textures/sky.html#bpy-types-shadernodetexsky"), + ("bpy.types.softbodymodifier*", "physics/soft_body/index.html#bpy-types-softbodymodifier"), + ("bpy.types.softbodysettings*", "physics/soft_body/settings/index.html#bpy-types-softbodysettings"), + ("bpy.types.solidifymodifier*", "modeling/modifiers/generate/solidify.html#bpy-types-solidifymodifier"), + ("bpy.types.spacefilebrowser*", "editors/file_browser.html#bpy-types-spacefilebrowser"), + ("bpy.types.spacegrapheditor*", "editors/graph_editor/index.html#bpy-types-spacegrapheditor"), + ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), + ("bpy.types.spacespreadsheet*", "editors/spreadsheet.html#bpy-types-spacespreadsheet"), + ("bpy.types.spaceview3d.lock*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock"), + ("bpy.types.spaceview3d.show*", "editors/3dview/display/index.html#bpy-types-spaceview3d-show"), + ("bpy.types.sphfluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-sphfluidsettings"), + ("bpy.types.subtractsequence*", "video_editing/edit/montage/strips/effects/subtract.html#bpy-types-subtractsequence"), + ("bpy.types.text.indentation*", "editors/text_editor.html#bpy-types-text-indentation"), + ("bpy.types.texture.contrast*", "render/materials/legacy_textures/colors.html#bpy-types-texture-contrast"), + ("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"), + ("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"), + ("bpy.types.texturenodescale*", "editors/texture_node/types/distort/scale.html#bpy-types-texturenodescale"), + ("bpy.types.viewlayer.use_ao*", "render/layers/introduction.html#bpy-types-viewlayer-use-ao"), + ("bpy.ops.armature.dissolve*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-dissolve"), + ("bpy.ops.armature.separate*", "animation/armatures/bones/editing/separate_bones.html#bpy-ops-armature-separate"), + ("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"), + ("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"), + ("bpy.ops.clip.select_lasso*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-lasso"), + ("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"), + ("bpy.ops.constraint.delete*", "animation/constraints/interface/header.html#bpy-ops-constraint-delete"), + ("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"), + ("bpy.ops.file.reset_recent*", "editors/file_browser.html#bpy-ops-file-reset-recent"), + ("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"), + ("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"), + ("bpy.ops.font.style_toggle*", "modeling/texts/editing.html#bpy-ops-font-style-toggle"), + ("bpy.ops.gpencil.mesh_bake*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-mesh-bake"), + ("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"), + ("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.mask.parent_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-clear"), + ("bpy.ops.mask.select_lasso*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-lasso"), + ("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"), + ("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"), + ("bpy.ops.mesh.face_shading*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-face-shading"), + ("bpy.ops.mesh.flip_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-flip-normals"), + ("bpy.ops.mesh.select_loose*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-loose"), + ("bpy.ops.mesh.vert_connect*", "modeling/meshes/editing/vertex/connect_vertex_pairs.html#bpy-ops-mesh-vert-connect"), + ("bpy.ops.nla.tracks_delete*", "editors/nla/editing.html#bpy-ops-nla-tracks-delete"), + ("bpy.ops.node.group_insert*", "interface/controls/nodes/groups.html#bpy-ops-node-group-insert"), + ("bpy.ops.object.lightprobe*", "render/eevee/light_probes/index.html#bpy-ops-object-lightprobe"), + ("bpy.ops.object.make_local*", "files/linked_libraries/link_append.html#bpy-ops-object-make-local"), + ("bpy.ops.object.origin_set*", "scene_layout/object/origin.html#bpy-ops-object-origin-set"), + ("bpy.ops.object.parent_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-set"), + ("bpy.ops.object.pointcloud*", "modeling/point_cloud.html#bpy-ops-object-pointcloud"), + ("bpy.ops.object.select_all*", "scene_layout/object/selecting.html#bpy-ops-object-select-all"), + ("bpy.ops.object.shade_flat*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-flat"), + ("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"), + ("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"), + ("bpy.ops.pose.paths_update*", "animation/motion_paths.html#bpy-ops-pose-paths-update"), + ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), + ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), + ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), + ("bpy.ops.screen.area_dupli*", "interface/window_system/areas.html#bpy-ops-screen-area-dupli"), + ("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.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"), + ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), + ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), + ("bpy.ops.view3d.view_orbit*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-orbit"), + ("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"), + ("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"), + ("bpy.types.armature.rigify*", "addons/rigging/rigify/basics.html#bpy-types-armature-rigify"), + ("bpy.types.bone.use_deform*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-deform"), + ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), + ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), + ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), + ("bpy.types.constraint.name*", "animation/constraints/interface/header.html#bpy-types-constraint-name"), + ("bpy.types.curve.eval_time*", "modeling/curves/properties/path_animation.html#bpy-types-curve-eval-time"), + ("bpy.types.curve.fill_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-fill-mode"), + ("bpy.types.editbone.layers*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-layers"), + ("bpy.types.editbone.parent*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-parent"), + ("bpy.types.explodemodifier*", "modeling/modifiers/physics/explode.html#bpy-types-explodemodifier"), + ("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fcurvemodifiers"), + ("bpy.types.floorconstraint*", "animation/constraints/relationship/floor.html#bpy-types-floorconstraint"), + ("bpy.types.fmodifiercycles*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiercycles"), + ("bpy.types.fmodifierlimits*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierlimits"), + ("bpy.types.imagepaint.mode*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-mode"), + ("bpy.types.latticemodifier*", "modeling/modifiers/deform/lattice.html#bpy-types-latticemodifier"), + ("bpy.types.materiallineart*", "render/materials/line_art.html#bpy-types-materiallineart"), + ("bpy.types.musgravetexture*", "render/materials/legacy_textures/types/musgrave.html#bpy-types-musgravetexture"), + ("bpy.types.object.location*", "scene_layout/object/properties/transforms.html#bpy-types-object-location"), + ("bpy.types.object.rotation*", "scene_layout/object/properties/transforms.html#bpy-types-object-rotation"), + ("bpy.types.particlehairkey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlehairkey"), + ("bpy.types.pivotconstraint*", "animation/constraints/relationship/pivot.html#bpy-types-pivotconstraint"), + ("bpy.types.preferencesedit*", "editors/preferences/editing.html#bpy-types-preferencesedit"), + ("bpy.types.preferencesview*", "editors/preferences/interface.html#bpy-types-preferencesview"), + ("bpy.types.rigidbodyobject*", "physics/rigid_body/index.html#bpy-types-rigidbodyobject"), + ("bpy.types.scene.frame_end*", "render/output/properties/frame_range.html#bpy-types-scene-frame-end"), + ("bpy.types.sceneeevee.gtao*", "render/eevee/render_settings/ambient_occlusion.html#bpy-types-sceneeevee-gtao"), + ("bpy.types.screen.use_play*", "editors/timeline.html#bpy-types-screen-use-play"), + ("bpy.types.shadernodebevel*", "render/shader_nodes/input/bevel.html#bpy-types-shadernodebevel"), + ("bpy.types.shadernodeclamp*", "render/shader_nodes/converter/clamp.html#bpy-types-shadernodeclamp"), + ("bpy.types.shadernodegamma*", "render/shader_nodes/color/gamma.html#bpy-types-shadernodegamma"), + ("bpy.types.shadernodegroup*", "render/shader_nodes/groups.html#bpy-types-shadernodegroup"), + ("bpy.types.shadernodeuvmap*", "render/shader_nodes/input/uv_map.html#bpy-types-shadernodeuvmap"), + ("bpy.types.shadernodevalue*", "render/shader_nodes/input/value.html#bpy-types-shadernodevalue"), + ("bpy.types.spaceclipeditor*", "movie_clip/index.html#bpy-types-spaceclipeditor"), + ("bpy.types.spaceproperties*", "editors/properties_editor.html#bpy-types-spaceproperties"), + ("bpy.types.spacetexteditor*", "editors/text_editor.html#bpy-types-spacetexteditor"), + ("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"), + ("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"), + ("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"), + ("bpy.ops.asset.tag_remove*", "editors/asset_browser.html#bpy-ops-asset-tag-remove"), + ("bpy.ops.clip.join_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-join-tracks"), + ("bpy.ops.constraint.apply*", "animation/constraints/interface/header.html#bpy-ops-constraint-apply"), + ("bpy.ops.curve.select_row*", "modeling/surfaces/selecting.html#bpy-ops-curve-select-row"), + ("bpy.ops.curve.tilt_clear*", "modeling/curves/editing/control_points.html#bpy-ops-curve-tilt-clear"), + ("bpy.ops.curve.vertex_add*", "modeling/curves/editing/other.html#bpy-ops-curve-vertex-add"), + ("bpy.ops.fluid.bake_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-bake-noise"), + ("bpy.ops.fluid.free_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-ops-fluid-free-noise"), + ("bpy.ops.font.move_select*", "modeling/texts/selecting.html#bpy-ops-font-move-select"), + ("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.sound_bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sound-bake"), + ("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"), + ("bpy.ops.mesh.convex_hull*", "modeling/meshes/editing/mesh/convex_hull.html#bpy-ops-mesh-convex-hull"), + ("bpy.ops.mesh.edge_rotate*", "modeling/meshes/editing/edge/rotate_edge.html#bpy-ops-mesh-edge-rotate"), + ("bpy.ops.mesh.unsubdivide*", "modeling/meshes/editing/edge/unsubdivide.html#bpy-ops-mesh-unsubdivide"), + ("bpy.ops.mesh.uvs_reverse*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-reverse"), + ("bpy.ops.node.hide_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-hide-toggle"), + ("bpy.ops.node.mute_toggle*", "interface/controls/nodes/editing.html#bpy-ops-node-mute-toggle"), + ("bpy.ops.object.hide_view*", "scene_layout/object/editing/show_hide.html#bpy-ops-object-hide-view"), + ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), + ("bpy.ops.pose.paths_clear*", "animation/motion_paths.html#bpy-ops-pose-paths-clear"), + ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), + ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), + ("bpy.ops.scene.view_layer*", "render/layers/introduction.html#bpy-ops-scene-view-layer"), + ("bpy.ops.screen.redo_last*", "interface/undo_redo.html#bpy-ops-screen-redo-last"), + ("bpy.ops.sculpt.mask_init*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-init"), + ("bpy.ops.sequencer.delete*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-delete"), + ("bpy.ops.sequencer.reload*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-reload"), + ("bpy.ops.sequencer.unlock*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-unlock"), + ("bpy.ops.sequencer.unmute*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-unmute"), + ("bpy.ops.transform.mirror*", "scene_layout/object/editing/mirror.html#bpy-ops-transform-mirror"), + ("bpy.ops.transform.resize*", "scene_layout/object/editing/transform/scale.html#bpy-ops-transform-resize"), + ("bpy.ops.transform.rotate*", "scene_layout/object/editing/transform/rotate.html#bpy-ops-transform-rotate"), + ("bpy.ops.uv.lightmap_pack*", "modeling/meshes/editing/uv.html#bpy-ops-uv-lightmap-pack"), + ("bpy.ops.uv.smart_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-smart-project"), + ("bpy.ops.uv.snap_selected*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-selected"), + ("bpy.ops.view3d.localview*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview"), + ("bpy.ops.view3d.view_axis*", "editors/3dview/navigate/viewpoint.html#bpy-ops-view3d-view-axis"), + ("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.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"), + ("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"), + ("bpy.types.brush.hardness*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-hardness"), + ("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"), + ("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"), + ("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifiernoise"), + ("bpy.types.image.filepath*", "editors/image/image_settings.html#bpy-types-image-filepath"), + ("bpy.types.keyframe.co_ui*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-co-ui"), + ("bpy.types.mask.frame_end*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-end"), + ("bpy.types.material.paint*", "sculpt_paint/texture_paint/index.html#bpy-types-material-paint"), + ("bpy.types.mirrormodifier*", "modeling/modifiers/generate/mirror.html#bpy-types-mirrormodifier"), + ("bpy.types.movieclipproxy*", "editors/clip/sidebar.html#bpy-types-movieclipproxy"), + ("bpy.types.object.up_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-up-axis"), + ("bpy.types.particlesystem*", "physics/particles/index.html#bpy-types-particlesystem"), + ("bpy.types.particletarget*", "physics/particles/emitter/physics/keyed.html#bpy-types-particletarget"), + ("bpy.types.remeshmodifier*", "modeling/modifiers/generate/remesh.html#bpy-types-remeshmodifier"), + ("bpy.types.rendersettings*", "render/index.html#bpy-types-rendersettings"), + ("bpy.types.rigidbodyworld*", "physics/rigid_body/world.html#bpy-types-rigidbodyworld"), + ("bpy.types.sceneeevee.ssr*", "render/eevee/render_settings/screen_space_reflections.html#bpy-types-sceneeevee-ssr"), + ("bpy.types.sceneeevee.sss*", "render/eevee/render_settings/subsurface_scattering.html#bpy-types-sceneeevee-sss"), + ("bpy.types.sculpt.gravity*", "sculpt_paint/sculpting/tool_settings/options.html#bpy-types-sculpt-gravity"), + ("bpy.types.shaderfxshadow*", "grease_pencil/visual_effects/shadow.html#bpy-types-shaderfxshadow"), + ("bpy.types.shadernodebump*", "render/shader_nodes/vector/bump.html#bpy-types-shadernodebump"), + ("bpy.types.shadernodemath*", "render/shader_nodes/converter/math.html#bpy-types-shadernodemath"), + ("bpy.types.smoothmodifier*", "modeling/modifiers/deform/smooth.html#bpy-types-smoothmodifier"), + ("bpy.types.sound.use_mono*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-mono"), + ("bpy.types.spline.order_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-order-u"), + ("bpy.types.timelinemarker*", "animation/markers.html#bpy-types-timelinemarker"), + ("bpy.types.usersolidlight*", "editors/preferences/lights.html#bpy-types-usersolidlight"), + ("bpy.types.uvwarpmodifier*", "modeling/modifiers/modify/uv_warp.html#bpy-types-uvwarpmodifier"), + ("bpy.types.viewlayer.name*", "render/layers/introduction.html#bpy-types-viewlayer-name"), + ("bpy.types.voronoitexture*", "render/materials/legacy_textures/types/voronoi.html#bpy-types-voronoitexture"), + ("bpy.types.walknavigation*", "editors/3dview/navigate/walk_fly.html#bpy-types-walknavigation"), + ("bpy.ops.*.select_circle*", "interface/selecting.html#bpy-ops-select-circle"), + ("bpy.ops.anim.keying_set*", "animation/keyframes/keying_sets.html#bpy-ops-anim-keying-set"), + ("bpy.ops.armature.delete*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-delete"), + ("bpy.ops.clip.select_all*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-all"), + ("bpy.ops.clip.select_box*", "movie_clip/tracking/clip/selecting.html#bpy-ops-clip-select-box"), + ("bpy.ops.clip.set_origin*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-origin"), + ("bpy.ops.constraint.copy*", "animation/constraints/interface/header.html#bpy-ops-constraint-copy"), + ("bpy.ops.curve.subdivide*", "modeling/curves/editing/segments.html#bpy-ops-curve-subdivide"), + ("bpy.ops.ed.undo_history*", "interface/undo_redo.html#bpy-ops-ed-undo-history"), + ("bpy.ops.file.unpack_all*", "files/blend/packed_data.html#bpy-ops-file-unpack-all"), + ("bpy.ops.fluid.bake_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-bake-data"), + ("bpy.ops.fluid.bake_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-bake-mesh"), + ("bpy.ops.fluid.free_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-free-data"), + ("bpy.ops.fluid.free_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-free-mesh"), + ("bpy.ops.font.select_all*", "modeling/texts/selecting.html#bpy-ops-font-select-all"), + ("bpy.ops.gpencil.convert*", "grease_pencil/modes/object/convert_to_geometry.html#bpy-ops-gpencil-convert"), + ("bpy.ops.graph.breakdown*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-breakdown"), + ("bpy.ops.mask.parent_set*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-set"), + ("bpy.ops.mask.select_all*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-all"), + ("bpy.ops.mask.select_box*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-box"), + ("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-edge-split"), + ("bpy.ops.mesh.fill_holes*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-fill-holes"), + ("bpy.ops.mesh.mark_sharp*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-sharp"), + ("bpy.ops.mesh.select_nth*", "modeling/meshes/selecting/checker_deselect.html#bpy-ops-mesh-select-nth"), + ("bpy.ops.mesh.symmetrize*", "modeling/meshes/editing/mesh/symmetrize.html#bpy-ops-mesh-symmetrize"), + ("bpy.ops.mesh.uvs_rotate*", "modeling/meshes/uv/editing.html#bpy-ops-mesh-uvs-rotate"), + ("bpy.ops.nla.apply_scale*", "editors/nla/editing.html#bpy-ops-nla-apply-scale"), + ("bpy.ops.nla.clear_scale*", "editors/nla/editing.html#bpy-ops-nla-clear-scale"), + ("bpy.ops.nla.mute_toggle*", "editors/nla/editing.html#bpy-ops-nla-mute-toggle"), + ("bpy.ops.node.group_make*", "interface/controls/nodes/groups.html#bpy-ops-node-group-make"), + ("bpy.ops.node.links_mute*", "interface/controls/nodes/editing.html#bpy-ops-node-links-mute"), + ("bpy.ops.object.armature*", "animation/armatures/index.html#bpy-ops-object-armature"), + ("bpy.ops.object.face_map*", "modeling/meshes/properties/object_data.html#bpy-ops-object-face-map"), + ("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"), + ("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"), + ("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"), + ("bpy.ops.rigidbody.world*", "physics/rigid_body/world.html#bpy-ops-rigidbody-world"), + ("bpy.ops.sculpt.optimize*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-optimize"), + ("bpy.ops.sequencer.split*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-split"), + ("bpy.ops.transform.shear*", "modeling/meshes/editing/mesh/transform/shear.html#bpy-ops-transform-shear"), + ("bpy.ops.uv.cube_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cube-project"), + ("bpy.ops.uv.pack_islands*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pack-islands"), + ("bpy.ops.uv.select_split*", "modeling/meshes/uv/editing.html#bpy-ops-uv-select-split"), + ("bpy.ops.view3d.view_pan*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-pan"), + ("bpy.ops.wm.app_template*", "advanced/app_templates.html#bpy-ops-wm-app-template"), + ("bpy.ops.wm.batch_rename*", "files/blend/rename.html#bpy-ops-wm-batch-rename"), + ("bpy.ops.wm.owner_enable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-enable"), + ("bpy.ops.wm.redraw_timer*", "advanced/operators.html#bpy-ops-wm-redraw-timer"), + ("bpy.types.*light.shadow*", "render/eevee/lighting.html#bpy-types-light-shadow"), + ("bpy.types.armature.show*", "animation/armatures/properties/display.html#bpy-types-armature-show"), + ("bpy.types.armaturebones*", "animation/armatures/bones/index.html#bpy-types-armaturebones"), + ("bpy.types.arraymodifier*", "modeling/modifiers/generate/array.html#bpy-types-arraymodifier"), + ("bpy.types.assetmetadata*", "editors/asset_browser.html#bpy-types-assetmetadata"), + ("bpy.types.bevelmodifier*", "modeling/modifiers/generate/bevel.html#bpy-types-bevelmodifier"), + ("bpy.types.buildmodifier*", "modeling/modifiers/generate/build.html#bpy-types-buildmodifier"), + ("bpy.types.clothmodifier*", "physics/cloth/index.html#bpy-types-clothmodifier"), + ("bpy.types.clothsettings*", "physics/cloth/settings/index.html#bpy-types-clothsettings"), + ("bpy.types.cloudstexture*", "render/materials/legacy_textures/types/clouds.html#bpy-types-cloudstexture"), + ("bpy.types.colorsequence*", "video_editing/edit/montage/strips/color.html#bpy-types-colorsequence"), + ("bpy.types.crosssequence*", "video_editing/edit/montage/strips/transitions/cross.html#bpy-types-crosssequence"), + ("bpy.types.curve.extrude*", "modeling/curves/properties/geometry.html#bpy-types-curve-extrude"), + ("bpy.types.curvemodifier*", "modeling/modifiers/deform/curve.html#bpy-types-curvemodifier"), + ("bpy.types.editbone.head*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-head"), + ("bpy.types.editbone.lock*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-lock"), + ("bpy.types.editbone.roll*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-roll"), + ("bpy.types.editbone.tail*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-tail"), + ("bpy.types.fieldsettings*", "physics/forces/force_fields/index.html#bpy-types-fieldsettings"), + ("bpy.types.imagesequence*", "video_editing/edit/montage/strips/image.html#bpy-types-imagesequence"), + ("bpy.types.marbletexture*", "render/materials/legacy_textures/types/marble.html#bpy-types-marbletexture"), + ("bpy.types.modifier.name*", "modeling/modifiers/introduction.html#bpy-types-modifier-name"), + ("bpy.types.modifier.show*", "modeling/modifiers/introduction.html#bpy-types-modifier-show"), + ("bpy.types.moviesequence*", "video_editing/edit/montage/strips/movie.html#bpy-types-moviesequence"), + ("bpy.types.movietracking*", "movie_clip/tracking/index.html#bpy-types-movietracking"), + ("bpy.types.nlastrip.mute*", "editors/nla/sidebar.html#bpy-types-nlastrip-mute"), + ("bpy.types.nlastrip.name*", "editors/nla/sidebar.html#bpy-types-nlastrip-name"), + ("bpy.types.nodesmodifier*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier"), + ("bpy.types.object.parent*", "scene_layout/object/editing/parent.html#bpy-types-object-parent"), + ("bpy.types.objectlineart*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart"), + ("bpy.types.oceanmodifier*", "modeling/modifiers/physics/ocean.html#bpy-types-oceanmodifier"), + ("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"), + ("bpy.types.scene.gravity*", "physics/forces/gravity.html#bpy-types-scene-gravity"), + ("bpy.types.sceneeevee.gi*", "render/eevee/render_settings/indirect_lighting.html#bpy-types-sceneeevee-gi"), + ("bpy.types.scenesequence*", "video_editing/edit/montage/strips/scene.html#bpy-types-scenesequence"), + ("bpy.types.screwmodifier*", "modeling/modifiers/generate/screw.html#bpy-types-screwmodifier"), + ("bpy.types.sequence.name*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-name"), + ("bpy.types.sequenceproxy*", "editors/video_sequencer/sequencer/sidebar/proxy.html#bpy-types-sequenceproxy"), + ("bpy.types.shaderfxswirl*", "grease_pencil/visual_effects/swirl.html#bpy-types-shaderfxswirl"), + ("bpy.types.shadernodergb*", "render/shader_nodes/input/rgb.html#bpy-types-shadernodergb"), + ("bpy.types.soundsequence*", "video_editing/edit/montage/strips/sound.html#bpy-types-soundsequence"), + ("bpy.types.spaceoutliner*", "editors/outliner/index.html#bpy-types-spaceoutliner"), + ("bpy.types.spacetimeline*", "editors/timeline.html#bpy-types-spacetimeline"), + ("bpy.types.spaceuveditor*", "editors/uv/index.html#bpy-types-spaceuveditor"), + ("bpy.types.stuccitexture*", "render/materials/legacy_textures/types/stucci.html#bpy-types-stuccitexture"), + ("bpy.types.texturenodeat*", "editors/texture_node/types/distort/at.html#bpy-types-texturenodeat"), + ("bpy.types.view3doverlay*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay"), + ("bpy.types.viewlayer.use*", "render/layers/view_layer.html#bpy-types-viewlayer-use"), + ("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"), + ("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"), + ("bpy.types.worldlighting*", "render/cycles/world_settings.html#bpy-types-worldlighting"), + ("bpy.ops.*.select_lasso*", "interface/selecting.html#bpy-ops-select-lasso"), + ("bpy.ops.armature.align*", "animation/armatures/bones/editing/transform.html#bpy-ops-armature-align"), + ("bpy.ops.armature.split*", "animation/armatures/bones/editing/split.html#bpy-ops-armature-split"), + ("bpy.ops.clip.set_plane*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-plane"), + ("bpy.ops.clip.set_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-scale"), + ("bpy.ops.curve.decimate*", "modeling/curves/editing/curve.html#bpy-ops-curve-decimate"), + ("bpy.ops.curve.separate*", "modeling/curves/editing/curve.html#bpy-ops-curve-separate"), + ("bpy.ops.fluid.bake_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-bake-all"), + ("bpy.ops.fluid.free_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-free-all"), + ("bpy.ops.gpencil.delete*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-delete"), + ("bpy.ops.gpencil.reveal*", "grease_pencil/properties/layers.html#bpy-ops-gpencil-reveal"), + ("bpy.ops.gpencil.select*", "grease_pencil/selecting.html#bpy-ops-gpencil-select"), + ("bpy.ops.graph.decimate*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-decimate"), + ("bpy.ops.material.paste*", "render/materials/assignment.html#bpy-ops-material-paste"), + ("bpy.ops.mesh.fill_grid*", "modeling/meshes/editing/face/grid_fill.html#bpy-ops-mesh-fill-grid"), + ("bpy.ops.mesh.intersect*", "modeling/meshes/editing/face/intersect_knife.html#bpy-ops-mesh-intersect"), + ("bpy.ops.mesh.mark_seam*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-mesh-mark-seam"), + ("bpy.ops.mesh.polybuild*", "modeling/meshes/tools/poly_build.html#bpy-ops-mesh-polybuild"), + ("bpy.ops.mesh.subdivide*", "modeling/meshes/editing/edge/subdivide.html#bpy-ops-mesh-subdivide"), + ("bpy.ops.mesh.wireframe*", "modeling/meshes/editing/face/wireframe.html#bpy-ops-mesh-wireframe"), + ("bpy.ops.node.link_make*", "interface/controls/nodes/editing.html#bpy-ops-node-link-make"), + ("bpy.ops.node.links_cut*", "interface/controls/nodes/editing.html#bpy-ops-node-links-cut"), + ("bpy.ops.object.convert*", "scene_layout/object/editing/convert.html#bpy-ops-object-convert"), + ("bpy.ops.object.gpencil*", "grease_pencil/index.html#bpy-ops-object-gpencil"), + ("bpy.ops.object.speaker*", "render/output/audio/speaker.html#bpy-ops-object-speaker"), + ("bpy.ops.pose.breakdown*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-breakdown"), + ("bpy.ops.pose.loc_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-loc-clear"), + ("bpy.ops.pose.propagate*", "animation/armatures/posing/editing/propagate.html#bpy-ops-pose-propagate"), + ("bpy.ops.pose.push_rest*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-push-rest"), + ("bpy.ops.pose.rot_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-rot-clear"), + ("bpy.ops.sequencer.lock*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-lock"), + ("bpy.ops.sequencer.mute*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-mute"), + ("bpy.ops.sequencer.slip*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-slip"), + ("bpy.ops.sequencer.snap*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-snap"), + ("bpy.ops.sequencer.swap*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-swap"), + ("bpy.ops.transform.bend*", "modeling/meshes/editing/mesh/transform/bend.html#bpy-ops-transform-bend"), + ("bpy.ops.transform.tilt*", "modeling/curves/editing/control_points.html#bpy-ops-transform-tilt"), + ("bpy.ops.uv.snap_cursor*", "modeling/meshes/uv/editing.html#bpy-ops-uv-snap-cursor"), + ("bpy.ops.wm.search_menu*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search-menu"), + ("bpy.types.bakesettings*", "render/cycles/baking.html#bpy-types-bakesettings"), + ("bpy.types.blendtexture*", "render/materials/legacy_textures/types/blend.html#bpy-types-blendtexture"), + ("bpy.types.brush.height*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-height"), + ("bpy.types.castmodifier*", "modeling/modifiers/deform/cast.html#bpy-types-castmodifier"), + ("bpy.types.curve.offset*", "modeling/curves/properties/geometry.html#bpy-types-curve-offset"), + ("bpy.types.geometrynode*", "modeling/geometry_nodes/index.html#bpy-types-geometrynode"), + ("bpy.types.glowsequence*", "video_editing/edit/montage/strips/effects/glow.html#bpy-types-glowsequence"), + ("bpy.types.gpencillayer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer"), + ("bpy.types.hookmodifier*", "modeling/modifiers/deform/hooks.html#bpy-types-hookmodifier"), + ("bpy.types.image.source*", "editors/image/image_settings.html#bpy-types-image-source"), + ("bpy.types.imagetexture*", "render/materials/legacy_textures/types/image_movie.html#bpy-types-imagetexture"), + ("bpy.types.latticepoint*", "animation/lattice.html#bpy-types-latticepoint"), + ("bpy.types.magictexture*", "render/materials/legacy_textures/types/magic.html#bpy-types-magictexture"), + ("bpy.types.maskmodifier*", "modeling/modifiers/generate/mask.html#bpy-types-maskmodifier"), + ("bpy.types.masksequence*", "video_editing/edit/montage/strips/mask.html#bpy-types-masksequence"), + ("bpy.types.materialslot*", "render/materials/assignment.html#bpy-types-materialslot"), + ("bpy.types.metasequence*", "video_editing/edit/montage/meta.html#bpy-types-metasequence"), + ("bpy.types.object.color*", "scene_layout/object/properties/display.html#bpy-types-object-color"), + ("bpy.types.object.delta*", "scene_layout/object/properties/transforms.html#bpy-types-object-delta"), + ("bpy.types.object.empty*", "modeling/empties.html#bpy-types-object-empty"), + ("bpy.types.object.scale*", "scene_layout/object/properties/transforms.html#bpy-types-object-scale"), + ("bpy.types.particleedit*", "physics/particles/mode.html#bpy-types-particleedit"), + ("bpy.types.scene.camera*", "scene_layout/scene/properties.html#bpy-types-scene-camera"), + ("bpy.types.sequencecrop*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencecrop"), + ("bpy.types.shaderfxblur*", "grease_pencil/visual_effects/blur.html#bpy-types-shaderfxblur"), + ("bpy.types.shaderfxflip*", "grease_pencil/visual_effects/flip.html#bpy-types-shaderfxflip"), + ("bpy.types.shaderfxglow*", "grease_pencil/visual_effects/glow.html#bpy-types-shaderfxglow"), + ("bpy.types.shaderfxwave*", "grease_pencil/visual_effects/wave_distortion.html#bpy-types-shaderfxwave"), + ("bpy.types.skinmodifier*", "modeling/modifiers/generate/skin.html#bpy-types-skinmodifier"), + ("bpy.types.spaceconsole*", "editors/python_console.html#bpy-types-spaceconsole"), + ("bpy.types.textsequence*", "video_editing/edit/montage/strips/text.html#bpy-types-textsequence"), + ("bpy.types.unitsettings*", "scene_layout/scene/properties.html#bpy-types-unitsettings"), + ("bpy.types.vertexcolors*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexcolors"), + ("bpy.types.view3dcursor*", "editors/3dview/3d_cursor.html#bpy-types-view3dcursor"), + ("bpy.types.volumerender*", "modeling/volumes/properties.html#bpy-types-volumerender"), + ("bpy.types.warpmodifier*", "modeling/modifiers/deform/warp.html#bpy-types-warpmodifier"), + ("bpy.types.wavemodifier*", "modeling/modifiers/deform/wave.html#bpy-types-wavemodifier"), + ("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"), + ("bpy.types.wipesequence*", "video_editing/edit/montage/strips/transitions/wipe.html#bpy-types-wipesequence"), + ("bpy.ops.armature.fill*", "animation/armatures/bones/editing/fill_between_joints.html#bpy-ops-armature-fill"), + ("bpy.ops.asset.tag_add*", "editors/asset_browser.html#bpy-ops-asset-tag-add"), + ("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"), + ("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"), + ("bpy.ops.file.pack_all*", "files/blend/packed_data.html#bpy-ops-file-pack-all"), + ("bpy.ops.file.previous*", "editors/file_browser.html#bpy-ops-file-previous"), + ("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"), + ("bpy.ops.image.project*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-ops-image-project"), + ("bpy.ops.image.replace*", "editors/image/editing.html#bpy-ops-image-replace"), + ("bpy.ops.image.save_as*", "editors/image/editing.html#bpy-ops-image-save-as"), + ("bpy.ops.marker.delete*", "animation/markers.html#bpy-ops-marker-delete"), + ("bpy.ops.marker.rename*", "animation/markers.html#bpy-ops-marker-rename"), + ("bpy.ops.marker.select*", "animation/markers.html#bpy-ops-marker-select"), + ("bpy.ops.material.copy*", "render/materials/assignment.html#bpy-ops-material-copy"), + ("bpy.ops.mesh.decimate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-decimate"), + ("bpy.ops.mesh.dissolve*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-dissolve"), + ("bpy.ops.mesh.rip_move*", "modeling/meshes/editing/vertex/rip_vertices.html#bpy-ops-mesh-rip-move"), + ("bpy.ops.mesh.separate*", "modeling/meshes/editing/mesh/separate.html#bpy-ops-mesh-separate"), + ("bpy.ops.mesh.solidify*", "modeling/meshes/editing/face/solidify_faces.html#bpy-ops-mesh-solidify"), + ("bpy.ops.nla.duplicate*", "editors/nla/editing.html#bpy-ops-nla-duplicate"), + ("bpy.ops.nla.move_down*", "editors/nla/editing.html#bpy-ops-nla-move-down"), + ("bpy.ops.object.*clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-clear"), + ("bpy.ops.object.delete*", "scene_layout/object/editing/delete.html#bpy-ops-object-delete"), + ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), + ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), + ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), + ("bpy.ops.sculpt.expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-expand"), + ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), + ("bpy.ops.wm.debug_menu*", "advanced/operators.html#bpy-ops-wm-debug-menu"), + ("bpy.ops.wm.obj_export*", "files/import_export/obj.html#bpy-ops-wm-obj-export"), + ("bpy.ops.wm.properties*", "files/data_blocks.html#bpy-ops-wm-properties"), + ("bpy.ops.wm.usd_export*", "files/import_export/usd.html#bpy-ops-wm-usd-export"), + ("bpy.types.addsequence*", "video_editing/edit/montage/strips/effects/add.html#bpy-types-addsequence"), + ("bpy.types.brush.cloth*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth"), + ("bpy.types.camera.show*", "render/cameras.html#bpy-types-camera-show"), + ("bpy.types.consoleline*", "editors/python_console.html#bpy-types-consoleline"), + ("bpy.types.curve.bevel*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel"), + ("bpy.types.mesh.remesh*", "modeling/meshes/retopology.html#bpy-types-mesh-remesh"), + ("bpy.types.meshstatvis*", "modeling/meshes/mesh_analysis.html#bpy-types-meshstatvis"), + ("bpy.types.nodesetting*", "interface/controls/nodes/parts.html#bpy-types-nodesetting"), + ("bpy.types.object.lock*", "scene_layout/object/properties/transforms.html#bpy-types-object-lock"), + ("bpy.types.object.show*", "scene_layout/object/properties/display.html#bpy-types-object-show"), + ("bpy.types.particlekey*", "physics/particles/emitter/physics/keyed.html#bpy-types-particlekey"), + ("bpy.types.posebone.ik*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik"), + ("bpy.types.preferences*", "editors/preferences/index.html#bpy-types-preferences"), + ("bpy.types.renderlayer*", "render/layers/passes.html#bpy-types-renderlayer"), + ("bpy.types.sculpt.lock*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-lock"), + ("bpy.types.shaderfxrim*", "grease_pencil/visual_effects/rim.html#bpy-types-shaderfxrim"), + ("bpy.types.spaceview3d*", "editors/3dview/index.html#bpy-types-spaceview3d"), + ("bpy.types.uipopupmenu*", "interface/controls/buttons/menus.html#bpy-types-uipopupmenu"), + ("bpy.types.vertexpaint*", "sculpt_paint/vertex_paint/index.html#bpy-types-vertexpaint"), + ("bpy.types.volumegrids*", "modeling/volumes/properties.html#bpy-types-volumegrids"), + ("bpy.types.woodtexture*", "render/materials/legacy_textures/types/wood.html#bpy-types-woodtexture"), + ("bpy.types.world.color*", "render/lights/world.html#bpy-types-world-color"), + ("bpy.ops.*.select_box*", "interface/selecting.html#bpy-ops-select-box"), + ("bpy.ops.curve.delete*", "modeling/curves/editing/curve.html#bpy-ops-curve-delete"), + ("bpy.ops.curve.reveal*", "modeling/curves/editing/curve.html#bpy-ops-curve-reveal"), + ("bpy.ops.curve.smooth*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth"), + ("bpy.ops.file.execute*", "editors/file_browser.html#bpy-ops-file-execute"), + ("bpy.ops.file.refresh*", "editors/file_browser.html#bpy-ops-file-refresh"), + ("bpy.ops.fluid.preset*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-ops-fluid-preset"), + ("bpy.ops.gpencil.copy*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-copy"), + ("bpy.ops.graph.delete*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-delete"), + ("bpy.ops.graph.mirror*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-mirror"), + ("bpy.ops.graph.reveal*", "editors/graph_editor/channels.html#bpy-ops-graph-reveal"), + ("bpy.ops.graph.sample*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sample"), + ("bpy.ops.graph.smooth*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-smooth"), + ("bpy.ops.graph.unbake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-unbake"), + ("bpy.ops.image.invert*", "editors/image/editing.html#bpy-ops-image-invert"), + ("bpy.ops.image.reload*", "editors/image/editing.html#bpy-ops-image-reload"), + ("bpy.ops.image.resize*", "editors/image/editing.html#bpy-ops-image-resize"), + ("bpy.ops.image.unpack*", "editors/image/editing.html#bpy-ops-image-unpack"), + ("bpy.ops.material.new*", "render/materials/assignment.html#bpy-ops-material-new"), + ("bpy.ops.object.align*", "scene_layout/object/editing/transform/align_objects.html#bpy-ops-object-align"), + ("bpy.ops.object.empty*", "modeling/empties.html#bpy-ops-object-empty"), + ("bpy.ops.object.quick*", "physics/introduction.html#bpy-ops-object-quick"), + ("bpy.ops.text.replace*", "editors/text_editor.html#bpy-ops-text-replace"), + ("bpy.ops.uv.mark_seam*", "modeling/meshes/uv/unwrapping/seams.html#bpy-ops-uv-mark-seam"), + ("bpy.ops.view3d.ruler*", "editors/3dview/toolbar/measure.html#bpy-ops-view3d-ruler"), + ("bpy.types.areaspaces*", "interface/window_system/areas.html#bpy-types-areaspaces"), + ("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"), + ("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"), + ("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"), + ("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"), + ("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"), + ("bpy.types.imagepaint*", "sculpt_paint/texture_paint/index.html#bpy-types-imagepaint"), + ("bpy.types.keymapitem*", "editors/preferences/keymap.html#bpy-types-keymapitem"), + ("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"), + ("bpy.types.maskparent*", "movie_clip/masking/sidebar.html#bpy-types-maskparent"), + ("bpy.types.maskspline*", "movie_clip/masking/sidebar.html#bpy-types-maskspline"), + ("bpy.types.motionpath*", "animation/motion_paths.html#bpy-types-motionpath"), + ("bpy.types.node.color*", "interface/controls/nodes/sidebar.html#bpy-types-node-color"), + ("bpy.types.node.label*", "interface/controls/nodes/sidebar.html#bpy-types-node-label"), + ("bpy.types.nodesocket*", "interface/controls/nodes/parts.html#bpy-types-nodesocket"), + ("bpy.types.paint.tile*", "sculpt_paint/texture_paint/tool_settings/tiling.html#bpy-types-paint-tile"), + ("bpy.types.pointcache*", "physics/baking.html#bpy-types-pointcache"), + ("bpy.types.pointlight*", "render/lights/light_object.html#bpy-types-pointlight"), + ("bpy.types.renderview*", "render/output/properties/stereoscopy/index.html#bpy-types-renderview"), + ("bpy.types.sceneeevee*", "render/eevee/index.html#bpy-types-sceneeevee"), + ("bpy.types.vectorfont*", "modeling/texts/index.html#bpy-types-vectorfont"), + ("bpy.ops.asset.clear*", "files/asset_libraries/introduction.html#bpy-ops-asset-clear"), + ("bpy.ops.clip.reload*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-reload"), + ("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"), + ("bpy.ops.file.cancel*", "editors/file_browser.html#bpy-ops-file-cancel"), + ("bpy.ops.file.parent*", "editors/file_browser.html#bpy-ops-file-parent"), + ("bpy.ops.graph.clean*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-clean"), + ("bpy.ops.graph.paste*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-paste"), + ("bpy.ops.marker.move*", "animation/markers.html#bpy-ops-marker-move"), + ("bpy.ops.mesh.bisect*", "modeling/meshes/editing/mesh/bisect.html#bpy-ops-mesh-bisect"), + ("bpy.ops.mesh.delete*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-delete"), + ("bpy.ops.nla.move_up*", "editors/nla/editing.html#bpy-ops-nla-move-up"), + ("bpy.ops.node.delete*", "interface/controls/nodes/editing.html#bpy-ops-node-delete"), + ("bpy.ops.object.bake*", "render/cycles/baking.html#bpy-ops-object-bake"), + ("bpy.ops.object.hook*", "modeling/meshes/editing/vertex/hooks.html#bpy-ops-object-hook"), + ("bpy.ops.object.join*", "scene_layout/object/editing/join.html#bpy-ops-object-join"), + ("bpy.ops.object.text*", "modeling/texts/index.html#bpy-ops-object-text"), + ("bpy.ops.preferences*", "editors/preferences/index.html#bpy-ops-preferences"), + ("bpy.ops.spreadsheet*", "editors/spreadsheet.html#bpy-ops-spreadsheet"), + ("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"), + ("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"), + ("bpy.ops.view3d.zoom*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom"), + ("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"), + ("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"), + ("bpy.types.blenddata*", "files/data_blocks.html#bpy-types-blenddata"), + ("bpy.types.bone.hide*", "animation/armatures/bones/properties/display.html#bpy-types-bone-hide"), + ("bpy.types.colorramp*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp"), + ("bpy.types.dopesheet*", "editors/dope_sheet/index.html#bpy-types-dopesheet"), + ("bpy.types.fmodifier*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifier"), + ("bpy.types.freestyle*", "render/freestyle/index.html#bpy-types-freestyle"), + ("bpy.types.masklayer*", "movie_clip/masking/sidebar.html#bpy-types-masklayer"), + ("bpy.types.movieclip*", "movie_clip/index.html#bpy-types-movieclip"), + ("bpy.types.node.name*", "interface/controls/nodes/sidebar.html#bpy-types-node-name"), + ("bpy.types.nodeframe*", "interface/controls/nodes/frame.html#bpy-types-nodeframe"), + ("bpy.types.nodegroup*", "interface/controls/nodes/groups.html#bpy-types-nodegroup"), + ("bpy.types.scene.muv*", "addons/uv/magic_uv.html#bpy-types-scene-muv"), + ("bpy.types.spotlight*", "render/lights/light_object.html#bpy-types-spotlight"), + ("bpy.types.textcurve*", "modeling/texts/index.html#bpy-types-textcurve"), + ("bpy.types.udimtiles*", "modeling/meshes/uv/workflows/udims.html#bpy-types-udimtiles"), + ("bpy.types.uipiemenu*", "interface/controls/buttons/menus.html#bpy-types-uipiemenu"), + ("bpy.types.uipopover*", "interface/controls/buttons/menus.html#bpy-types-uipopover"), + ("bpy.types.viewlayer*", "render/layers/introduction.html#bpy-types-viewlayer"), + ("bpy.ops.asset.mark*", "files/asset_libraries/introduction.html#bpy-ops-asset-mark"), + ("bpy.ops.collection*", "scene_layout/collections/collections.html#bpy-ops-collection"), + ("bpy.ops.constraint*", "animation/constraints/index.html#bpy-ops-constraint"), + ("bpy.ops.curve.draw*", "modeling/curves/tools/draw.html#bpy-ops-curve-draw"), + ("bpy.ops.curve.hide*", "modeling/curves/editing/curve.html#bpy-ops-curve-hide"), + ("bpy.ops.curve.spin*", "modeling/surfaces/editing/surface.html#bpy-ops-curve-spin"), + ("bpy.ops.graph.bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-bake"), + ("bpy.ops.graph.copy*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-copy"), + ("bpy.ops.graph.hide*", "editors/graph_editor/channels.html#bpy-ops-graph-hide"), + ("bpy.ops.graph.snap*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-snap"), + ("bpy.ops.image.flip*", "editors/image/editing.html#bpy-ops-image-flip"), + ("bpy.ops.image.open*", "editors/image/editing.html#bpy-ops-image-open"), + ("bpy.ops.image.pack*", "editors/image/editing.html#bpy-ops-image-pack"), + ("bpy.ops.image.save*", "editors/image/editing.html#bpy-ops-image-save"), + ("bpy.ops.image.tile*", "modeling/meshes/uv/workflows/udims.html#bpy-ops-image-tile"), + ("bpy.ops.marker.add*", "animation/markers.html#bpy-ops-marker-add"), + ("bpy.ops.mesh.bevel*", "modeling/meshes/editing/edge/bevel.html#bpy-ops-mesh-bevel"), + ("bpy.ops.mesh.inset*", "modeling/meshes/editing/face/inset_faces.html#bpy-ops-mesh-inset"), + ("bpy.ops.mesh.knife*", "modeling/meshes/tools/knife.html#bpy-ops-mesh-knife"), + ("bpy.ops.mesh.merge*", "modeling/meshes/editing/mesh/merge.html#bpy-ops-mesh-merge"), + ("bpy.ops.mesh.screw*", "modeling/meshes/editing/edge/screw.html#bpy-ops-mesh-screw"), + ("bpy.ops.mesh.split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-split"), + ("bpy.ops.nla.delete*", "editors/nla/editing.html#bpy-ops-nla-delete"), + ("bpy.ops.paint.mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-paint-mask"), + ("bpy.ops.pose.paste*", "animation/armatures/posing/editing/copy_paste.html#bpy-ops-pose-paste"), + ("bpy.ops.pose.relax*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-relax"), + ("bpy.ops.safe_areas*", "render/cameras.html#bpy-ops-safe-areas"), + ("bpy.types.aov.type*", "render/layers/passes.html#bpy-types-aov-type"), + ("bpy.types.armature*", "animation/armatures/index.html#bpy-types-armature"), + ("bpy.types.editbone*", "animation/armatures/bones/editing/index.html#bpy-types-editbone"), + ("bpy.types.facemaps*", "modeling/meshes/properties/object_data.html#bpy-types-facemaps"), + ("bpy.types.keyframe*", "animation/keyframes/index.html#bpy-types-keyframe"), + ("bpy.types.linesets*", "render/freestyle/view_layer/line_set.html#bpy-types-linesets"), + ("bpy.types.metaball*", "modeling/metas/index.html#bpy-types-metaball"), + ("bpy.types.modifier*", "modeling/modifiers/index.html#bpy-types-modifier"), + ("bpy.types.nlastrip*", "editors/nla/strips.html#bpy-types-nlastrip"), + ("bpy.types.nlatrack*", "editors/nla/tracks.html#bpy-types-nlatrack"), + ("bpy.types.nodelink*", "interface/controls/nodes/parts.html#bpy-types-nodelink"), + ("bpy.types.nodetree*", "interface/controls/nodes/parts.html#bpy-types-nodetree"), + ("bpy.types.particle*", "physics/particles/index.html#bpy-types-particle"), + ("bpy.types.sequence*", "video_editing/index.html#bpy-types-sequence"), + ("bpy.types.shaderfx*", "grease_pencil/visual_effects/index.html#bpy-types-shaderfx"), + ("bpy.types.shapekey*", "animation/shape_keys/index.html#bpy-types-shapekey"), + ("bpy.types.spacenla*", "editors/nla/index.html#bpy-types-spacenla"), + ("bpy.types.sunlight*", "render/lights/light_object.html#bpy-types-sunlight"), + ("bpy.ops.clip.open*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-open"), + ("bpy.ops.file.next*", "editors/file_browser.html#bpy-ops-file-next"), + ("bpy.ops.image.new*", "editors/image/editing.html#bpy-ops-image-new"), + ("bpy.ops.mesh.fill*", "modeling/meshes/editing/face/fill.html#bpy-ops-mesh-fill"), + ("bpy.ops.mesh.poke*", "modeling/meshes/editing/face/poke_faces.html#bpy-ops-mesh-poke"), + ("bpy.ops.mesh.spin*", "modeling/meshes/tools/spin.html#bpy-ops-mesh-spin"), + ("bpy.ops.nla.split*", "editors/nla/editing.html#bpy-ops-nla-split"), + ("bpy.ops.pose.copy*", "animation/armatures/posing/editing/copy_paste.html#bpy-ops-pose-copy"), + ("bpy.ops.pose.push*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-push"), + ("bpy.ops.rigidbody*", "physics/rigid_body/index.html#bpy-ops-rigidbody"), + ("bpy.ops.sequencer*", "video_editing/index.html#bpy-ops-sequencer"), + ("bpy.ops.text.find*", "editors/text_editor.html#bpy-ops-text-find"), + ("bpy.ops.transform*", "scene_layout/object/editing/transform/index.html#bpy-ops-transform"), + ("bpy.ops.uv.select*", "editors/uv/selecting.html#bpy-ops-uv-select"), + ("bpy.ops.uv.stitch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-stitch"), + ("bpy.ops.uv.unwrap*", "modeling/meshes/editing/uv.html#bpy-ops-uv-unwrap"), + ("bpy.ops.wm.append*", "files/linked_libraries/link_append.html#bpy-ops-wm-append"), + ("bpy.ops.wm.search*", "interface/controls/templates/operator_search.html#bpy-ops-wm-search"), + ("bpy.types.lattice*", "animation/lattice.html#bpy-types-lattice"), + ("bpy.types.library*", "files/linked_libraries/index.html#bpy-types-library"), + ("bpy.types.speaker*", "render/output/audio/speaker.html#bpy-types-speaker"), + ("bpy.types.textbox*", "modeling/texts/properties.html#bpy-types-textbox"), + ("bpy.types.texture*", "render/materials/legacy_textures/index.html#bpy-types-texture"), + ("bpy.ops.armature*", "animation/armatures/index.html#bpy-ops-armature"), + ("bpy.ops.geometry*", "modeling/index.html#bpy-ops-geometry"), + ("bpy.ops.material*", "render/materials/index.html#bpy-ops-material"), + ("bpy.ops.nla.bake*", "animation/actions.html#bpy-ops-nla-bake"), + ("bpy.ops.nla.snap*", "editors/nla/editing.html#bpy-ops-nla-snap"), + ("bpy.ops.nla.swap*", "editors/nla/editing.html#bpy-ops-nla-swap"), + ("bpy.ops.outliner*", "editors/outliner/index.html#bpy-ops-outliner"), + ("bpy.ops.particle*", "physics/particles/index.html#bpy-ops-particle"), + ("bpy.ops.uv.align*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align"), + ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv.html#bpy-ops-uv-reset"), + ("bpy.ops.wm.addon*", "editors/preferences/addons.html#bpy-ops-wm-addon"), + ("bpy.types.action*", "animation/actions.html#bpy-types-action"), + ("bpy.types.camera*", "render/cameras.html#bpy-types-camera"), + ("bpy.types.cycles*", "render/cycles/index.html#bpy-types-cycles"), + ("bpy.types.driver*", "animation/drivers/index.html#bpy-types-driver"), + ("bpy.types.fcurve*", "editors/graph_editor/fcurves/index.html#bpy-types-fcurve"), + ("bpy.types.header*", "interface/window_system/regions.html#bpy-types-header"), + ("bpy.types.object*", "scene_layout/object/index.html#bpy-types-object"), + ("bpy.types.region*", "interface/window_system/regions.html#bpy-types-region"), + ("bpy.types.render*", "render/index.html#bpy-types-render"), + ("bpy.types.screen*", "interface/index.html#bpy-types-screen"), + ("bpy.types.sculpt*", "sculpt_paint/sculpting/index.html#bpy-types-sculpt"), + ("bpy.types.shader*", "render/shader_nodes/shader/index.html#bpy-types-shader"), + ("bpy.types.spline*", "modeling/curves/properties/active_spline.html#bpy-types-spline"), + ("bpy.types.volume*", "modeling/volumes/index.html#bpy-types-volume"), + ("bpy.types.window*", "interface/index.html#bpy-types-window"), + ("bpy.ops.buttons*", "interface/controls/buttons/buttons.html#bpy-ops-buttons"), + ("bpy.ops.console*", "editors/python_console.html#bpy-ops-console"), + ("bpy.ops.ed.redo*", "interface/undo_redo.html#bpy-ops-ed-redo"), + ("bpy.ops.ed.undo*", "interface/undo_redo.html#bpy-ops-ed-undo"), + ("bpy.ops.gpencil*", "grease_pencil/index.html#bpy-ops-gpencil"), + ("bpy.ops.lattice*", "animation/lattice.html#bpy-ops-lattice"), + ("bpy.ops.poselib*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib"), + ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), + ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), + ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), + ("bpy.ops.uv.weld*", "modeling/meshes/uv/editing.html#bpy-ops-uv-weld"), + ("bpy.ops.wm.link*", "files/linked_libraries/link_append.html#bpy-ops-wm-link"), + ("bpy.ops.wm.tool*", "interface/tool_system.html#bpy-ops-wm-tool"), + ("bpy.types.addon*", "editors/preferences/addons.html#bpy-types-addon"), + ("bpy.types.brush*", "sculpt_paint/brush/brush.html#bpy-types-brush"), + ("bpy.types.curve*", "modeling/curves/index.html#bpy-types-curve"), + ("bpy.types.image*", "files/media/image_formats.html#bpy-types-image"), + ("bpy.types.itasc*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-itasc"), + ("bpy.types.nodes*", "interface/controls/nodes/index.html#bpy-types-nodes"), + ("bpy.types.paint*", "sculpt_paint/index.html#bpy-types-paint"), + ("bpy.types.panel*", "interface/window_system/tabs_panels.html#bpy-types-panel"), + ("bpy.types.scene*", "scene_layout/scene/index.html#bpy-types-scene"), + ("bpy.types.sound*", "render/output/audio/index.html#bpy-types-sound"), + ("bpy.types.space*", "editors/index.html#bpy-types-space"), + ("bpy.types.theme*", "editors/preferences/themes.html#bpy-types-theme"), + ("bpy.types.world*", "render/lights/world.html#bpy-types-world"), + ("bpy.ops.action*", "animation/actions.html#bpy-ops-action"), + ("bpy.ops.camera*", "render/cameras.html#bpy-ops-camera"), + ("bpy.ops.cycles*", "render/cycles/index.html#bpy-ops-cycles"), + ("bpy.ops.dpaint*", "physics/dynamic_paint/index.html#bpy-ops-dpaint"), + ("bpy.ops.export*", "files/import_export.html#bpy-ops-export"), + ("bpy.ops.import*", "files/import_export.html#bpy-ops-import"), + ("bpy.ops.marker*", "animation/markers.html#bpy-ops-marker"), + ("bpy.ops.object*", "scene_layout/object/index.html#bpy-ops-object"), + ("bpy.ops.render*", "render/index.html#bpy-ops-render"), + ("bpy.ops.script*", "advanced/scripting/index.html#bpy-ops-script"), + ("bpy.ops.sculpt*", "sculpt_paint/sculpting/index.html#bpy-ops-sculpt"), + ("bpy.ops.uv.muv*", "addons/uv/magic_uv.html#bpy-ops-uv-muv"), + ("bpy.ops.uv.pin*", "modeling/meshes/uv/editing.html#bpy-ops-uv-pin"), + ("bpy.ops.uv.rip*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip"), + ("bpy.ops.view3d*", "editors/3dview/index.html#bpy-ops-view3d"), + ("bpy.types.area*", "interface/window_system/areas.html#bpy-types-area"), + ("bpy.types.boid*", "physics/particles/emitter/physics/boids.html#bpy-types-boid"), + ("bpy.types.bone*", "animation/armatures/bones/index.html#bpy-types-bone"), + ("bpy.types.mask*", "movie_clip/masking/index.html#bpy-types-mask"), + ("bpy.types.menu*", "interface/controls/buttons/menus.html#bpy-types-menu"), + ("bpy.types.mesh*", "modeling/meshes/index.html#bpy-types-mesh"), + ("bpy.types.node*", "interface/controls/nodes/index.html#bpy-types-node"), + ("bpy.types.pose*", "animation/armatures/posing/index.html#bpy-types-pose"), + ("bpy.types.text*", "editors/text_editor.html#bpy-types-text"), + ("bpy.ops.brush*", "sculpt_paint/brush/brush.html#bpy-ops-brush"), + ("bpy.ops.cloth*", "physics/cloth/index.html#bpy-ops-cloth"), + ("bpy.ops.curve*", "modeling/curves/index.html#bpy-ops-curve"), + ("bpy.ops.graph*", "editors/graph_editor/index.html#bpy-ops-graph"), + ("bpy.ops.image*", "files/media/image_formats.html#bpy-ops-image"), + ("bpy.ops.mball*", "modeling/metas/index.html#bpy-ops-mball"), + ("bpy.ops.paint*", "sculpt_paint/index.html#bpy-ops-paint"), + ("bpy.ops.scene*", "scene_layout/scene/index.html#bpy-ops-scene"), + ("bpy.ops.sound*", "render/output/audio/index.html#bpy-ops-sound"), + ("bpy.types.aov*", "render/layers/passes.html#bpy-types-aov"), + ("bpy.types.key*", "animation/shape_keys/index.html#bpy-types-key"), + ("bpy.ops.anim*", "animation/index.html#bpy-ops-anim"), + ("bpy.ops.boid*", "physics/particles/emitter/physics/boids.html#bpy-ops-boid"), + ("bpy.ops.clip*", "movie_clip/index.html#bpy-ops-clip"), + ("bpy.ops.file*", "editors/file_browser.html#bpy-ops-file"), + ("bpy.ops.font*", "modeling/texts/index.html#bpy-ops-font"), + ("bpy.ops.mask*", "movie_clip/masking/index.html#bpy-ops-mask"), + ("bpy.ops.mesh*", "modeling/meshes/index.html#bpy-ops-mesh"), + ("bpy.ops.node*", "interface/controls/nodes/index.html#bpy-ops-node"), + ("bpy.ops.pose*", "animation/armatures/posing/index.html#bpy-ops-pose"), + ("bpy.ops.text*", "editors/text_editor.html#bpy-ops-text"), + ("bpy.ops.time*", "editors/timeline.html#bpy-ops-time"), + ("bpy.types.id*", "files/data_blocks.html#bpy-types-id"), + ("bpy.ops.nla*", "editors/nla/index.html#bpy-ops-nla"), + ("bpy.ops.ed*", "interface/undo_redo.html#bpy-ops-ed"), + ("bpy.ops.ui*", "interface/index.html#bpy-ops-ui"), + ("bpy.ops.wm*", "interface/index.html#bpy-ops-wm"), ) + +# autopep8: on diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 002b6e08290..a6842dc0005 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -204,6 +204,7 @@ def draw(layout, context, context_member, property_type, *, use_edit=True): # Add some spacing, so the right side of the buttons line up with layouts with decorators. operator_row.label(text="", icon='BLANK1') + class PropertyPanel: """ The subclass should have its own poll function diff --git a/release/scripts/presets/keyconfig/Blender.py b/release/scripts/presets/keyconfig/Blender.py index 7ce9a5650bd..2e77f233ca4 100644 --- a/release/scripts/presets/keyconfig/Blender.py +++ b/release/scripts/presets/keyconfig/Blender.py @@ -319,6 +319,7 @@ class Prefs(bpy.types.KeyConfigPreferences): col.label(text="File Browser") col.row().prop(self, "use_file_single_click") + blender_default = bpy.utils.execfile(os.path.join(DIRNAME, "keymap_data", "blender_default.py")) diff --git a/release/scripts/presets/keyconfig/Industry_Compatible.py b/release/scripts/presets/keyconfig/Industry_Compatible.py index 2a3eb2a0f9d..4e17555fef9 100644 --- a/release/scripts/presets/keyconfig/Industry_Compatible.py +++ b/release/scripts/presets/keyconfig/Industry_Compatible.py @@ -10,6 +10,7 @@ import bpy DIRNAME, FILENAME = os.path.split(__file__) IDNAME = os.path.splitext(FILENAME)[0] + def update_fn(_self, _context): load() @@ -33,5 +34,6 @@ def load(): keyconfig_init_from_data(kc, keyconfig_data) + if __name__ == "__main__": load() diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 6408873f13e..78620c41d1e 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -19,6 +19,7 @@ __all__ = ( # ------------------------------------------------------------------------------ # Configurable Parameters + class Params: __slots__ = ( "apple", @@ -604,18 +605,18 @@ def km_window(params): {"type": k, "value": 'PRESS', "shift": True}, {"properties": [("space_type", t)]}) for k, t in ( - ('F1', 'FILE_BROWSER'), - ('F2', 'CLIP_EDITOR'), - ('F3', 'NODE_EDITOR'), - ('F4', 'CONSOLE'), - ('F5', 'VIEW_3D'), - ('F6', 'GRAPH_EDITOR'), - ('F7', 'PROPERTIES'), - ('F8', 'SEQUENCE_EDITOR'), - ('F9', 'OUTLINER'), - ('F10', 'IMAGE_EDITOR'), - ('F11', 'TEXT_EDITOR'), - ('F12', 'DOPESHEET_EDITOR'), + ('F1', 'FILE_BROWSER'), + ('F2', 'CLIP_EDITOR'), + ('F3', 'NODE_EDITOR'), + ('F4', 'CONSOLE'), + ('F5', 'VIEW_3D'), + ('F6', 'GRAPH_EDITOR'), + ('F7', 'PROPERTIES'), + ('F8', 'SEQUENCE_EDITOR'), + ('F9', 'OUTLINER'), + ('F10', 'IMAGE_EDITOR'), + ('F11', 'TEXT_EDITOR'), + ('F12', 'DOPESHEET_EDITOR'), ) ), @@ -2959,6 +2960,7 @@ def km_sequencerpreview(params): ("sequencer.select_box", {"type": 'B', "value": 'PRESS'}, None), # View. + ("sequencer.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'HOME', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("sequencer.view_ghost_border", {"type": 'O', "value": 'PRESS'}, None), @@ -7168,7 +7170,7 @@ def km_3d_view_tool_edit_curve_pen(params): ("curve.pen", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True}, {"properties": [("insert_point", True), ("delete_point", True)]}), ("curve.pen", {"type": params.tool_mouse, "value": 'DOUBLE_CLICK'}, - {"properties": [("toggle_vector", True), ("cycle_handle_type", True),]}), + {"properties": [("toggle_vector", True), ("cycle_handle_type", True), ]}), ]}, ) @@ -7433,7 +7435,8 @@ def km_3d_view_tool_paint_gpencil_line(params): ("gpencil.primitive_line", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, {"properties": [("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7448,7 +7451,8 @@ def km_3d_view_tool_paint_gpencil_polyline(params): ("gpencil.primitive_polyline", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7465,7 +7469,8 @@ def km_3d_view_tool_paint_gpencil_box(params): ("gpencil.primitive_box", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, {"properties": [("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7482,7 +7487,8 @@ def km_3d_view_tool_paint_gpencil_circle(params): ("gpencil.primitive_circle", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, {"properties": [("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7499,7 +7505,8 @@ def km_3d_view_tool_paint_gpencil_arc(params): ("gpencil.primitive_curve", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, {"properties": [("type", 'ARC'), ("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7512,7 +7519,8 @@ def km_3d_view_tool_paint_gpencil_curve(params): ("gpencil.primitive_curve", params.tool_maybe_tweak_event, {"properties": [("type", 'CURVE'), ("wait_for_input", False)]}), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) @@ -7524,7 +7532,8 @@ def km_3d_view_tool_paint_gpencil_cutter(params): {"items": [ ("gpencil.stroke_cutter", {"type": params.tool_mouse, "value": 'PRESS'}, None), # Lasso select - ("gpencil.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), + ("gpencil.select_lasso", {"type": params.action_mouse, + "value": 'CLICK_DRAG', "ctrl": True, "alt": True}, None), ]}, ) diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 64039f200e9..7faa418d74e 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -67,12 +67,14 @@ def _template_items_context_menu(menu, key_args_primary): for kmi_args in (key_args_primary, {"type": 'APP', "value": 'PRESS'}) ] + def _template_items_context_panel(menu, key_args_primary): return [ op_panel(menu, kmi_args) for kmi_args in (key_args_primary, {"type": 'APP', "value": 'PRESS'}) ] + def _template_items_object_subdivision_set(): return [ ("object.subdivision_set", @@ -116,6 +118,7 @@ def _template_items_basic_tools(*, connected=False): op_tool_cycle("builtin.cursor", {"type": 'C', "value": 'PRESS'}), ] + def _template_items_tool_select(params, operator, *, extend): return [ (operator, {"type": 'LEFTMOUSE', "value": 'PRESS'}, @@ -436,7 +439,8 @@ def km_property_editor(params): ("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}), ("object.modifier_copy", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), # Grease pencil modifier panels - ("object.gpencil_modifier_remove", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("report", True)]}), + ("object.gpencil_modifier_remove", {"type": 'BACK_SPACE', + "value": 'PRESS'}, {"properties": [("report", True)]}), ("object.gpencil_modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}), ("object.gpencil_modifier_copy", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), # ShaderFX panels @@ -517,7 +521,8 @@ def km_outliner(params): ("outliner.show_one_level", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, {"properties": [("open", False)]}), ("outliner.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("outliner.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("outliner.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("outliner.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("outliner.keyingset_add_selected", {"type": 'K', "value": 'PRESS'}, None), ("outliner.keyingset_remove_selected", {"type": 'K', "value": 'PRESS', "alt": True}, None), @@ -577,7 +582,8 @@ def km_uv_editor(params): ("uv.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("uv.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("uv.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("uv.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("uv.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("uv.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("uv.hide", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("unselected", False)]}), @@ -621,6 +627,7 @@ def km_view3d_generic(_params): return keymap + # 3D View: main region. def km_view3d(params): items = [] @@ -722,7 +729,7 @@ def km_view3d(params): *((operator, {"type": 'LEFTMOUSE', "value": 'CLICK', **{m: True for m in mods}}, {"properties": [(c, True) for c in props]}, - ) for operator, props, mods in ( + ) for operator, props, mods in ( ("view3d.select", ("deselect_all",), ()), ("view3d.select", ("toggle",), ("shift",)), ("view3d.select", ("center", "object"), ("ctrl",)), @@ -768,7 +775,8 @@ def km_mask_editing(params): ("mask.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, {"properties": [("extend", False), ("deselect", False), ("toggle", True)]}), ("mask.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("mask.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("mask.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("mask.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("mask.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("mask.select_linked_pick", {"type": 'L', "value": 'PRESS'}, @@ -832,7 +840,8 @@ def km_markers(params): {"properties": [("extend", True), ("camera", True)]}), ("marker.select_box", {"type": 'Q', "value": 'PRESS'}, None), ("marker.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("marker.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("marker.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("marker.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("marker.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), ("marker.delete", {"type": 'DEL', "value": 'PRESS'}, None), @@ -895,18 +904,19 @@ def km_graph_editor(params): ("graph.select_leftright", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("mode", 'RIGHT'), ("extend", False)]}), ("graph.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("graph.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("graph.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("graph.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("graph.select_box", {"type": 'Q', "value": 'PRESS'}, {"properties": [("axis_range", False)]}), ("graph.select_box", {"type": 'Q', "value": 'PRESS', "alt": True}, {"properties": [("axis_range", True)]}), ("graph.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, - {"properties":[("tweak", True), ("axis_range", False), ("mode", 'SET')]}), + {"properties": [("tweak", True), ("axis_range", False), ("mode", 'SET')]}), ("graph.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True}, - {"properties":[("tweak", True), ("axis_range", False), ("mode", 'ADD')]}), + {"properties": [("tweak", True), ("axis_range", False), ("mode", 'ADD')]}), ("graph.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True}, - {"properties":[("tweak", True), ("axis_range", False), ("mode", 'SUB')]}), + {"properties": [("tweak", True), ("axis_range", False), ("mode", 'SUB')]}), ("graph.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("graph.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("graph.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), @@ -1121,7 +1131,8 @@ def km_node_editor(params): ("node.delete_reconnect", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, None), ("node.delete_reconnect", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None), ("node.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("node.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("node.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("node.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("node.select_linked_to", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True}, None), ("node.select_linked_from", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), @@ -1260,7 +1271,7 @@ def km_file_browser_main(params): {"properties": [("open", False), ("deselect_all", True)]}), ("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True}, {"properties": [("extend", True), ("open", False)]}), - ("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True,}, + ("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True, }, {"properties": [("extend", True), ("fill", True), ("open", False)]}), ("file.select", {"type": 'RIGHTMOUSE', "value": 'CLICK', "shift": True}, {"properties": [("extend", True), ("open", False)]}), @@ -1379,18 +1390,19 @@ def km_dopesheet(params): ("action.select_leftright", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("mode", 'RIGHT'), ("extend", False)]}), ("action.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("action.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("action.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("action.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("action.select_box", {"type": 'Q', "value": 'PRESS'}, {"properties": [("axis_range", False)]}), ("action.select_box", {"type": 'Q', "value": 'PRESS', "alt": True}, {"properties": [("axis_range", True)]}), ("action.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, - {"properties":[("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'SET')]}), + {"properties": [("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'SET')]}), ("action.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True}, - {"properties":[("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'ADD')]}), + {"properties": [("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'ADD')]}), ("action.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True}, - {"properties":[("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'SUB')]}), + {"properties": [("tweak", True), ("axis_range", False), ("wait_for_input", False), ("mode", 'SUB')]}), ("action.select_column", {"type": 'K', "value": 'PRESS'}, {"properties": [("mode", 'KEYS')]}), ("action.select_column", {"type": 'K', "value": 'PRESS', "ctrl": True}, @@ -1505,18 +1517,19 @@ def km_nla_editor(params): ("nla.select_leftright", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("mode", 'RIGHT'), ("extend", False)]}), ("nla.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("nla.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("nla.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("nla.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("nla.select_box", {"type": 'Q', "value": 'PRESS'}, {"properties": [("axis_range", False)]}), ("nla.select_box", {"type": 'Q', "value": 'PRESS', "alt": True}, {"properties": [("axis_range", True)]}), ("nla.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, - {"properties":[("tweak", True), ("mode", 'SET')]}), + {"properties": [("tweak", True), ("mode", 'SET')]}), ("nla.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True}, - {"properties":[("tweak", True), ("mode", 'ADD')]}), + {"properties": [("tweak", True), ("mode", 'ADD')]}), ("nla.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True}, - {"properties":[("tweak", True), ("mode", 'SUB')]}), + {"properties": [("tweak", True), ("mode", 'SUB')]}), ("nla.view_all", {"type": 'A', "value": 'PRESS'}, None), ("nla.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("nla.view_selected", {"type": 'F', "value": 'PRESS'}, None), @@ -1739,7 +1752,8 @@ def km_sequencer(params): ("wm.search_menu", {"type": 'TAB', "value": 'PRESS'}, None), *_template_items_animation(), ("sequencer.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("sequencer.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("sequencer.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("sequencer.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("sequencer.split", {"type": 'B', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'SOFT')]}), @@ -1816,11 +1830,11 @@ def km_sequencer(params): {"properties": [("extend", True)]}), ("sequencer.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "ctrl": True}, None), ("sequencer.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, - {"properties":[("tweak", True), ("mode", 'SET')]}), + {"properties": [("tweak", True), ("mode", 'SET')]}), ("sequencer.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True}, - {"properties":[("tweak", True), ("mode", 'ADD')]}), + {"properties": [("tweak", True), ("mode", 'ADD')]}), ("sequencer.select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True}, - {"properties":[("tweak", True), ("mode", 'SUB')]}), + {"properties": [("tweak", True), ("mode", 'SUB')]}), ("sequencer.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), ("sequencer.slip", {"type": 'R', "value": 'PRESS'}, None), ("wm.context_set_int", {"type": 'O', "value": 'PRESS'}, @@ -1852,6 +1866,7 @@ def km_sequencerpreview(params): ("wm.search_menu", {"type": 'TAB', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'A', "value": 'PRESS'}, None), ("sequencer.view_all_preview", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), + ("sequencer.view_selected", {"type": 'F', "value": 'PRESS'}, None), ("sequencer.view_ghost_border", {"type": 'O', "value": 'PRESS'}, None), ("sequencer.view_zoom_ratio", {"type": 'NUMPAD_1', "value": 'PRESS'}, {"properties": [("ratio", 1.0)]}), @@ -1873,7 +1888,7 @@ def km_sequencer_channels(params): # Rename. ("sequencer.rename_channel", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None), ("sequencer.rename_channel", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), - ]) + ]) return keymap @@ -2032,7 +2047,8 @@ def km_clip_editor(params): {"properties": [("extend", True)]}), ("clip.select_box", {"type": 'Q', "value": 'PRESS'}, None), ("clip.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("clip.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("clip.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("clip.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), op_menu("CLIP_MT_select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}), ("clip.add_marker_slide", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None), @@ -2146,6 +2162,7 @@ def km_clip_dopesheet_editor(_params): return keymap + def km_spreadsheet_generic(_params): items = [] keymap = ( @@ -2213,7 +2230,6 @@ def km_animation_channels(params): {"items": items}, ) - items.extend([ # Click select. ("anim.channels_click", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), @@ -2231,13 +2247,16 @@ def km_animation_channels(params): # Find (setting the name filter). ("anim.channels_select_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None), # Selection. - ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), - ("anim.channels_select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), + ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', + "ctrl": True}, {"properties": [("action", 'SELECT')]}), + ("anim.channels_select_all", {"type": 'A', "value": 'PRESS', + "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("anim.channels_select_all", {"type": 'I', "value": 'PRESS', + "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, None), - ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True,}, + ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True, }, {"properties": [("extend", True)]}), - ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True,}, + ("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True, }, {"properties": [("deselect", True)]}), # Delete. ("anim.channels_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, None), @@ -2300,7 +2319,8 @@ def _grease_pencil_selection(params): {"properties": [("extend", True), ("toggle", True)]}), # Select all ("gpencil.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("gpencil.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("gpencil.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("gpencil.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), # Select linked ("gpencil.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), @@ -2385,7 +2405,6 @@ def km_grease_pencil_stroke_edit_mode(params): op_tool_cycle("builtin.bend", {"type": 'B', "value": 'PRESS', "ctrl": True}), ]) - return keymap @@ -2764,7 +2783,8 @@ def km_grease_pencil_stroke_weight_mode(params): ("wm.radial_control", {"type": 'S', "value": 'PRESS'}, {"properties": [("data_path_primary", 'tool_settings.gpencil_weight_paint.brush.size')]}), # Context menu - *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_panel("VIEW3D_PT_gpencil_weight_context_menu", + {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) return keymap @@ -2813,6 +2833,7 @@ def km_grease_pencil_stroke_vertex_mode(params): return keymap + def km_grease_pencil_stroke_vertex_draw(params): items = [] keymap = ( @@ -2928,6 +2949,7 @@ def km_grease_pencil_stroke_vertex_replace(params): return keymap + def km_face_mask(params): items = [] keymap = ( @@ -2937,9 +2959,12 @@ def km_face_mask(params): ) items.extend([ - ("paint.face_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("paint.face_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), - ("paint.face_select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), + ("paint.face_select_all", {"type": 'A', "value": 'PRESS', + "ctrl": True}, {"properties": [("action", 'SELECT')]}), + ("paint.face_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("paint.face_select_all", {"type": 'I', "value": 'PRESS', + "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("paint.face_select_hide", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("unselected", False)]}), ("paint.face_select_hide", {"type": 'H', "value": 'PRESS', "shift": True}, @@ -2995,7 +3020,8 @@ def km_pose(params): ("pose.paste", {"type": 'V', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("flipped", True)]}), ("pose.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("pose.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("pose.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("pose.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("pose.select_parent", {"type": 'UP_ARROW', "value": 'PRESS', "ctrl": True}, None), ("pose.select_hierarchy", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, @@ -3030,7 +3056,6 @@ def km_pose(params): op_tool_cycle("builtin.measure", {"type": 'M', "value": 'PRESS'}), ]) - return keymap @@ -3044,9 +3069,10 @@ def km_object_mode(params): items.extend([ *_template_items_animation(), - #Selection + # Selection ("object.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("object.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("object.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("object.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("object.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("object.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), @@ -3148,10 +3174,10 @@ def km_curve(params): {"items": items}, ) - items.extend([ ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("curve.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("curve.select_row", {"type": 'R', "value": 'PRESS', "shift": True}, None), ("curve.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), @@ -3271,7 +3297,8 @@ def km_image_paint(params): ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.image_paint.brush.use_smooth_stroke')]}), op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), - *_template_items_context_panel("VIEW3D_PT_paint_texture_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), + *_template_items_context_panel("VIEW3D_PT_paint_texture_context_menu", + {"type": 'RIGHTMOUSE', "value": 'PRESS'}), # Tools ("paint.brush_select", {"type": 'D', "value": 'PRESS'}, {"properties": [("image_tool", 'DRAW')]}), @@ -3356,7 +3383,7 @@ def km_weight_paint(params): *_template_items_context_panel("VIEW3D_PT_paint_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), # Bone selection for combined weight paint + pose mode. ("view3d.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None), - # Tools + # Tools ("paint.brush_select", {"type": 'D', "value": 'PRESS'}, {"properties": [("weight_tool", 'DRAW')]}), ("paint.brush_select", {"type": 'B', "value": 'PRESS'}, @@ -3504,7 +3531,8 @@ def km_mesh(params): {"properties": [("use_fill", False)]}), ("mesh.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("mesh.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("mesh.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("mesh.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("mesh.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("mesh.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), @@ -3528,7 +3556,7 @@ def km_mesh(params): {"properties": [("data_path", 'tool_settings.use_proportional_edit')]}), # Menus. *_template_items_context_menu("VIEW3D_MT_edit_mesh_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), - #Tools + # Tools *_template_items_basic_tools(), op_tool_cycle("builtin.bevel", {"type": 'B', "value": 'PRESS', "ctrl": True}), op_tool_cycle("builtin.inset_faces", {"type": 'I', "value": 'PRESS'}), @@ -3562,7 +3590,8 @@ def km_armature(params): ("armature.parent_clear", {"type": 'P', "value": 'PRESS', "shift": True}, None), # Selection. ("armature.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("armature.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("armature.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("armature.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("armature.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, @@ -3610,7 +3639,6 @@ def km_metaball(params): {"items": items}, ) - items.extend([ ("mball.reveal_metaelems", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("mball.hide_metaelems", {"type": 'H', "value": 'PRESS', "ctrl": True}, @@ -3621,7 +3649,8 @@ def km_metaball(params): ("mball.delete_metaelems", {"type": 'DEL', "value": 'PRESS'}, None), ("mball.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), ("mball.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("mball.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("mball.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("mball.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("mball.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), *_template_items_context_menu("VIEW3D_MT_edit_metaball_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), @@ -3645,7 +3674,8 @@ def km_lattice(params): items.extend([ ("lattice.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("lattice.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("lattice.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("lattice.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("lattice.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("lattice.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), @@ -3653,7 +3683,7 @@ def km_lattice(params): *_template_items_context_menu("VIEW3D_MT_edit_lattice_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("wm.context_toggle", {"type": 'B', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_edit')]}), - # Tools + # Tools op_tool_cycle("builtin.select_box", {"type": 'Q', "value": 'PRESS'}), op_tool_cycle("builtin.move", {"type": 'W', "value": 'PRESS'}), op_tool_cycle("builtin.rotate", {"type": 'E', "value": 'PRESS'}), @@ -3676,7 +3706,8 @@ def km_particle(params): items.extend([ ("particle.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), - ("particle.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), + ("particle.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, + "shift": True}, {"properties": [("action", 'DESELECT')]}), ("particle.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("particle.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), ("particle.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), @@ -3793,7 +3824,6 @@ def km_font(params): *_template_items_context_menu("VIEW3D_MT_edit_font_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) - return keymap @@ -3806,35 +3836,35 @@ def km_object_non_modal(params): ) items.extend([ - ("object.mode_set",{"type": 'ONE', "value": 'PRESS'}, + ("object.mode_set", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("mode", 'PAINT_GPENCIL')]}), - ("object.mode_set",{"type": 'THREE', "value": 'PRESS'}, + ("object.mode_set", {"type": 'THREE', "value": 'PRESS'}, {"properties": [("mode", 'POSE')]}), - ("object.mode_set_with_submode",{"type": 'ONE', "value": 'PRESS'}, + ("object.mode_set_with_submode", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("mode", 'EDIT'), ("mesh_select_mode", {'VERT'})]}), - ("object.mode_set_with_submode",{"type": 'TWO', "value": 'PRESS'}, + ("object.mode_set_with_submode", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("mode", 'EDIT'), ("mesh_select_mode", {'EDGE'})]}), - ("object.mode_set_with_submode",{"type": 'THREE', "value": 'PRESS'}, + ("object.mode_set_with_submode", {"type": 'THREE', "value": 'PRESS'}, {"properties": [("mode", 'EDIT'), ("mesh_select_mode", {'FACE'})]}), - ("object.mode_set",{"type": 'ONE', "value": 'PRESS'}, + ("object.mode_set", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("mode", 'EDIT')]}), - ("object.mode_set",{"type": 'FOUR', "value": 'PRESS'}, + ("object.mode_set", {"type": 'FOUR', "value": 'PRESS'}, {"properties": [("mode", 'OBJECT')]}), - ("object.mode_set",{"type": 'FIVE', "value": 'PRESS'}, + ("object.mode_set", {"type": 'FIVE', "value": 'PRESS'}, {"properties": [("mode", 'SCULPT')]}), - ("object.mode_set",{"type": 'SIX', "value": 'PRESS'}, + ("object.mode_set", {"type": 'SIX', "value": 'PRESS'}, {"properties": [("mode", 'VERTEX_PAINT')]}), - ("object.mode_set",{"type": 'SEVEN', "value": 'PRESS'}, + ("object.mode_set", {"type": 'SEVEN', "value": 'PRESS'}, {"properties": [("mode", 'WEIGHT_PAINT')]}), - ("object.mode_set",{"type": 'EIGHT', "value": 'PRESS'}, + ("object.mode_set", {"type": 'EIGHT', "value": 'PRESS'}, {"properties": [("mode", 'TEXTURE_PAINT')]}), - ("object.mode_set",{"type": 'TWO', "value": 'PRESS'}, + ("object.mode_set", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("mode", 'EDIT_GPENCIL')]}), - ("object.mode_set",{"type": 'FIVE', "value": 'PRESS'}, + ("object.mode_set", {"type": 'FIVE', "value": 'PRESS'}, {"properties": [("mode", 'SCULPT_GPENCIL')]}), - ("object.mode_set",{"type": 'SIX', "value": 'PRESS'}, + ("object.mode_set", {"type": 'SIX', "value": 'PRESS'}, {"properties": [("mode", 'VERTEX_GPENCIL')]}), - ("object.mode_set",{"type": 'SEVEN', "value": 'PRESS'}, + ("object.mode_set", {"type": 'SEVEN', "value": 'PRESS'}, {"properties": [("mode", 'WEIGHT_GPENCIL')]}), ]) @@ -4052,7 +4082,7 @@ def km_generic_gizmo_maybe_drag(params): {"space_type": 'EMPTY', "region_type": 'WINDOW'}, {"items": _template_items_gizmo_tweak_value_drag() - }, + }, ) return keymap diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index bb2491d7720..58ccaffaf50 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -174,7 +174,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel): col = layout.column(align=True) col.label(text="This panel is a remainder of the old pose library,") - col.label(text="which was replaced by the Asset Browser.") + col.label(text="which was replaced by the Asset Browser") url = self.get_manual_url() col.operator("wm.url_open", text="More Info", icon='URL').url = url @@ -193,7 +193,7 @@ class DATA_PT_pose_library(ArmatureButtonsPanel, Panel): text="Convert to Pose Assets", icon='ASSET_MANAGER') else: col.label(text="Enable the Pose Library add-on to convert", icon='ERROR') - col.label(text="this legacy pose library to pose assets.", icon='BLANK1') + col.label(text="this legacy pose library to pose assets", icon='BLANK1') # Put the deprecated stuff in its own sub-layout. diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py index 9fdcd4c1faa..678972a677c 100644 --- a/release/scripts/startup/bl_ui/properties_data_volume.py +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -115,6 +115,12 @@ class DATA_PT_volume_render(DataButtonsPanel, Panel): col = layout.column(align=True) col.prop(render, "clipping") + col = layout.column(align=False) + col.prop(volume, "velocity_grid") + + col.prop(volume, "velocity_unit") + col.prop(volume, "velocity_scale") + class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): bl_label = "Viewport Display" diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 064a99034d3..9a116aa1717 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -432,7 +432,7 @@ class FalloffPanel(BrushPanel): row.operator("brush.curve_preset", icon='LINCURVE', text="").shape = 'LINE' row.operator("brush.curve_preset", icon='NOCURVE', text="").shape = 'MAX' - if mode in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT'} and brush.sculpt_tool != 'POSE': + if mode in {'SCULPT', 'PAINT_VERTEX', 'PAINT_WEIGHT', 'SCULPT_CURVES'} and brush.sculpt_tool != 'POSE': col.separator() row = col.row(align=True) row.use_property_split = True @@ -823,6 +823,11 @@ def brush_shared_settings(layout, context, brush, popover=False): size = True strength = True + # Sculpt Curves # + if mode == 'SCULPT_CURVES': + size = True + strength = True + ### Draw settings. ### ups = context.scene.tool_settings.unified_paint_settings @@ -920,6 +925,16 @@ def brush_settings_advanced(layout, context, brush, popover=False): col.prop(brush, "use_original_plane", text="Plane") layout.separator() + elif mode == 'SCULPT_CURVES': + if brush.curves_sculpt_tool == 'ADD': + layout.prop(brush.curves_sculpt_settings, "add_amount") + layout.prop(brush.curves_sculpt_settings, "curve_length") + layout.prop(brush.curves_sculpt_settings, "interpolate_length") + layout.prop(brush.curves_sculpt_settings, "interpolate_shape") + elif brush.curves_sculpt_tool == 'GROW_SHRINK': + layout.prop(brush.curves_sculpt_settings, "scale_uniform") + layout.prop(brush.curves_sculpt_settings, "minimum_length") + # 3D and 2D Texture Paint. elif mode in {'PAINT_TEXTURE', 'PAINT_2D'}: capabilities = brush.image_paint_capabilities diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 1b03da490b9..88f8658035b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -1485,6 +1485,27 @@ class PHYSICS_PT_viewport_display_advanced(PhysicButtonsPanel, Panel): note.label(icon='INFO', text="Range highlighting for flags is not available!") +class PHYSICS_PT_fluid_domain_render(PhysicButtonsPanel, Panel): + bl_label = "Render" + bl_parent_id = 'PHYSICS_PT_fluid' + bl_options = {'DEFAULT_CLOSED'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + + @classmethod + def poll(cls, context): + if not PhysicButtonsPanel.poll_gas_domain(context): + return False + + return (context.engine in cls.COMPAT_ENGINES) + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + + domain = context.fluid.domain_settings + layout.prop(domain, "velocity_scale") + + classes = ( FLUID_PT_presets, PHYSICS_PT_fluid, @@ -1513,6 +1534,7 @@ classes = ( PHYSICS_PT_viewport_display_color, PHYSICS_PT_viewport_display_debug, PHYSICS_PT_viewport_display_advanced, + PHYSICS_PT_fluid_domain_render, ) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index bbf9548a973..00ace072bda 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -429,9 +429,14 @@ class SEQUENCER_MT_view(Menu): layout.separator() + layout.operator_context = 'INVOKE_REGION_WIN' + if st.view_type == 'PREVIEW': + # See above (T32595) + layout.operator_context = 'INVOKE_REGION_PREVIEW' + layout.operator("sequencer.view_selected", text="Frame Selected") + if is_sequencer_view: layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("sequencer.view_selected", text="Frame Selected") layout.operator("sequencer.view_all") layout.operator("view2d.zoom_border", text="Zoom") diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index e00bd2edef9..5c6ca13776e 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -2950,13 +2950,13 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): _defs_sculpt.trim_lasso, ), _defs_sculpt.project_line, - _defs_sculpt.mask_by_color, None, _defs_sculpt.mesh_filter, _defs_sculpt.cloth_filter, _defs_sculpt.color_filter, None, _defs_sculpt.face_set_edit, + _defs_sculpt.mask_by_color, None, _defs_transform.translate, _defs_transform.rotate, diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index fc518e929d9..81ccdd82dd8 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -514,9 +514,9 @@ class _draw_tool_settings_context_mode: layout.prop(brush, "use_frontface") layout.prop(brush, "falloff_shape", expand=True) layout.prop(brush.curves_sculpt_settings, "add_amount") - layout.prop(tool_settings.curves_sculpt, "curve_length") - layout.prop(tool_settings.curves_sculpt, "interpolate_length") - layout.prop(tool_settings.curves_sculpt, "interpolate_shape") + layout.prop(brush.curves_sculpt_settings, "curve_length") + layout.prop(brush.curves_sculpt_settings, "interpolate_length") + layout.prop(brush.curves_sculpt_settings, "interpolate_shape") if brush.curves_sculpt_tool == 'GROW_SHRINK': layout.prop(brush, "direction", expand=True, text="") @@ -529,9 +529,6 @@ class _draw_tool_settings_context_mode: layout.prop(brush, "falloff_shape", expand=True) layout.prop(brush, "curve_preset") - if brush.curves_sculpt_tool == 'TEST1': - layout.prop(tool_settings.curves_sculpt, "distance") - class VIEW3D_HT_header(Header): bl_space_type = 'VIEW_3D' diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 10dfd182836..570d7c12e30 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -526,7 +526,10 @@ class SelectPaintSlotHelper: case 'COLOR_ATTRIBUTE': mesh = ob.data - layout.template_list( + + row = layout.row() + col = row.column() + col.template_list( "MESH_UL_color_attributes_selector", "color_attributes", mesh, @@ -536,6 +539,10 @@ class SelectPaintSlotHelper: rows=3, ) + col = row.column(align=True) + col.operator("geometry.color_attribute_add", icon='ADD', text="") + col.operator("geometry.color_attribute_remove", icon='REMOVE', text="") + if settings.missing_uvs: layout.separator() split = layout.split() diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index 737ea9350b3..42e4650365b 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -176,10 +176,10 @@ def geometry_input_node_items(context): yield NodeItem("ShaderNodeValue") yield NodeItem("FunctionNodeInputVector") yield NodeItemCustom(draw=lambda self, layout, context: layout.separator()) - if named_attribute_poll(context): - yield NodeItem("GeometryNodeInputNamedAttribute") yield NodeItem("GeometryNodeInputID") yield NodeItem("GeometryNodeInputIndex") + if named_attribute_poll(context): + yield NodeItem("GeometryNodeInputNamedAttribute") yield NodeItem("GeometryNodeInputNormal") yield NodeItem("GeometryNodeInputPosition") yield NodeItem("GeometryNodeInputRadius") @@ -627,8 +627,8 @@ geometry_node_categories = [ NodeItem("GeometryNodeAttributeDomainSize"), NodeItem("GeometryNodeAttributeStatistic"), NodeItem("GeometryNodeAttributeTransfer"), - NodeItem("GeometryNodeStoreNamedAttribute", poll=named_attribute_poll), NodeItem("GeometryNodeRemoveAttribute", poll=named_attribute_poll), + NodeItem("GeometryNodeStoreNamedAttribute", poll=named_attribute_poll), ]), GeometryNodeCategory("GEO_COLOR", "Color", items=[ NodeItem("ShaderNodeMixRGB"), diff --git a/release/scripts/templates_py/operator_file_export.py b/release/scripts/templates_py/operator_file_export.py index b4d0dc8b698..f1779593051 100644 --- a/release/scripts/templates_py/operator_file_export.py +++ b/release/scripts/templates_py/operator_file_export.py @@ -57,7 +57,8 @@ class ExportSomeData(Operator, ExportHelper): def menu_func_export(self, context): self.layout.operator(ExportSomeData.bl_idname, text="Text Export Operator") -# Register and add to the "file selector" menu (required to use F3 search "Text Export Operator" for quick access) + +# Register and add to the "file selector" menu (required to use F3 search "Text Export Operator" for quick access). def register(): bpy.utils.register_class(ExportSomeData) bpy.types.TOPBAR_MT_file_export.append(menu_func_export) diff --git a/release/scripts/templates_py/operator_file_import.py b/release/scripts/templates_py/operator_file_import.py index 83496fbe17b..d6f4780961a 100644 --- a/release/scripts/templates_py/operator_file_import.py +++ b/release/scripts/templates_py/operator_file_import.py @@ -56,11 +56,12 @@ class ImportSomeData(Operator, ImportHelper): return read_some_data(context, self.filepath, self.use_setting) -# Only needed if you want to add into a dynamic menu +# Only needed if you want to add into a dynamic menu. def menu_func_import(self, context): self.layout.operator(ImportSomeData.bl_idname, text="Text Import Operator") -# Register and add to the "file selector" menu (required to use F3 search "Text Import Operator" for quick access) + +# Register and add to the "file selector" menu (required to use F3 search "Text Import Operator" for quick access). def register(): bpy.utils.register_class(ImportSomeData) bpy.types.TOPBAR_MT_file_import.append(menu_func_import) diff --git a/release/scripts/templates_py/operator_mesh_add.py b/release/scripts/templates_py/operator_mesh_add.py index 5a6bed92c93..b4ee16ecdc7 100644 --- a/release/scripts/templates_py/operator_mesh_add.py +++ b/release/scripts/templates_py/operator_mesh_add.py @@ -97,7 +97,8 @@ class AddBox(bpy.types.Operator, AddObjectHelper): def menu_func(self, context): self.layout.operator(AddBox.bl_idname, icon='MESH_CUBE') -# Register and add to the "add mesh" menu (required to use F3 search "Add Box" for quick access) + +# Register and add to the "add mesh" menu (required to use F3 search "Add Box" for quick access). def register(): bpy.utils.register_class(AddBox) bpy.types.VIEW3D_MT_mesh_add.append(menu_func) diff --git a/release/scripts/templates_py/operator_mesh_uv.py b/release/scripts/templates_py/operator_mesh_uv.py index 2d4f5b17ba8..e94de433d1c 100644 --- a/release/scripts/templates_py/operator_mesh_uv.py +++ b/release/scripts/templates_py/operator_mesh_uv.py @@ -33,10 +33,12 @@ class UvOperator(bpy.types.Operator): main(context) return {'FINISHED'} + def menu_func(self, context): - self.layout.operator(UvOperator.bl_idname, text = "Simple UV Operator") + self.layout.operator(UvOperator.bl_idname, text="Simple UV Operator") + -# Register and add to the "UV" menu (required to also use F3 search "Simple UV Operator" for quick access) +# Register and add to the "UV" menu (required to also use F3 search "Simple UV Operator" for quick access). def register(): bpy.utils.register_class(UvOperator) bpy.types.IMAGE_MT_uvs.append(menu_func) diff --git a/release/scripts/templates_py/operator_modal.py b/release/scripts/templates_py/operator_modal.py index 41b01e22f78..c35e8826ec0 100644 --- a/release/scripts/templates_py/operator_modal.py +++ b/release/scripts/templates_py/operator_modal.py @@ -35,10 +35,12 @@ class ModalOperator(bpy.types.Operator): self.report({'WARNING'}, "No active object, could not finish") return {'CANCELLED'} + def menu_func(self, context): self.layout.operator(ModalOperator.bl_idname, text=ModalOperator.bl_label) -# Register and add to the "view" menu (required to also use F3 search "Simple Modal Operator" for quick access) + +# Register and add to the "view" menu (required to also use F3 search "Simple Modal Operator" for quick access). def register(): bpy.utils.register_class(ModalOperator) bpy.types.VIEW3D_MT_object.append(menu_func) diff --git a/release/scripts/templates_py/operator_modal_draw.py b/release/scripts/templates_py/operator_modal_draw.py index a3f46586cf5..20e888ad5f3 100644 --- a/release/scripts/templates_py/operator_modal_draw.py +++ b/release/scripts/templates_py/operator_modal_draw.py @@ -65,10 +65,12 @@ class ModalDrawOperator(bpy.types.Operator): self.report({'WARNING'}, "View3D not found, cannot run operator") return {'CANCELLED'} + def menu_func(self, context): - self.layout.operator(ModalDrawOperator.bl_idname, text = "Modal Draw Operator") + self.layout.operator(ModalDrawOperator.bl_idname, text="Modal Draw Operator") + -# Register and add to the "view" menu (required to also use F3 search "Modal Draw Operator" for quick access) +# Register and add to the "view" menu (required to also use F3 search "Modal Draw Operator" for quick access). def register(): bpy.utils.register_class(ModalDrawOperator) bpy.types.VIEW3D_MT_view.append(menu_func) diff --git a/release/scripts/templates_py/operator_modal_timer.py b/release/scripts/templates_py/operator_modal_timer.py index 19c003712ad..3e205010549 100644 --- a/release/scripts/templates_py/operator_modal_timer.py +++ b/release/scripts/templates_py/operator_modal_timer.py @@ -31,14 +31,17 @@ class ModalTimerOperator(bpy.types.Operator): wm = context.window_manager wm.event_timer_remove(self._timer) + def menu_func(self, context): self.layout.operator(ModalTimerOperator.bl_idname, text=ModalTimerOperator.bl_label) + def register(): bpy.utils.register_class(ModalTimerOperator) bpy.types.VIEW3D_MT_view.append(menu_func) -# Register and add to the "view" menu (required to also use F3 search "Modal Timer Operator" for quick access) + +# Register and add to the "view" menu (required to also use F3 search "Modal Timer Operator" for quick access). def unregister(): bpy.utils.unregister_class(ModalTimerOperator) bpy.types.VIEW3D_MT_view.remove(menu_func) diff --git a/release/scripts/templates_py/operator_modal_view3d.py b/release/scripts/templates_py/operator_modal_view3d.py index 5fd47731d0b..d0200bccc05 100644 --- a/release/scripts/templates_py/operator_modal_view3d.py +++ b/release/scripts/templates_py/operator_modal_view3d.py @@ -57,10 +57,12 @@ class ViewOperator(bpy.types.Operator): self.report({'WARNING'}, "Active space must be a View3d") return {'CANCELLED'} + def menu_func(self, context): - self.layout.operator(ViewOperator.bl_idname, text = "Simple View Modal Operator") + self.layout.operator(ViewOperator.bl_idname, text="Simple View Modal Operator") + -# Register and add to the "view" menu (required to also use F3 search "Simple View Modal Operator" for quick access) +# Register and add to the "view" menu (required to also use F3 search "Simple View Modal Operator" for quick access). def register(): bpy.utils.register_class(ViewOperator) bpy.types.VIEW3D_MT_view.append(menu_func) diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py index 022acc25e14..b2d8471d6b4 100644 --- a/release/scripts/templates_py/operator_modal_view3d_raycast.py +++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py @@ -95,10 +95,12 @@ class ViewOperatorRayCast(bpy.types.Operator): self.report({'WARNING'}, "Active space must be a View3d") return {'CANCELLED'} + def menu_func(self, context): self.layout.operator(ViewOperatorRayCast.bl_idname, text="Raycast View Modal Operator") -# Register and add to the "view" menu (required to also use F3 search "Raycast View Modal Operator" for quick access) + +# Register and add to the "view" menu (required to also use F3 search "Raycast View Modal Operator" for quick access). def register(): bpy.utils.register_class(ViewOperatorRayCast) bpy.types.VIEW3D_MT_view.append(menu_func) diff --git a/release/scripts/templates_py/operator_node.py b/release/scripts/templates_py/operator_node.py index b5ca491a0fe..83231a55c94 100644 --- a/release/scripts/templates_py/operator_node.py +++ b/release/scripts/templates_py/operator_node.py @@ -46,10 +46,12 @@ class NodeOperator(bpy.types.Operator): main(self, context) return {'FINISHED'} + def menu_func(self, context): self.layout.operator(NodeOperator.bl_idname, text=NodeOperator.bl_label) -# Register and add to the "Node" menu (required to also use F3 search "Simple Node Operator" for quick access) + +# Register and add to the "Node" menu (required to also use F3 search "Simple Node Operator" for quick access). def register(): bpy.utils.register_class(NodeOperator) bpy.types.NODE_MT_node.append(menu_func) diff --git a/release/scripts/templates_py/operator_simple.py b/release/scripts/templates_py/operator_simple.py index 9edb07996c0..0ac6084dfa6 100644 --- a/release/scripts/templates_py/operator_simple.py +++ b/release/scripts/templates_py/operator_simple.py @@ -19,10 +19,12 @@ class SimpleOperator(bpy.types.Operator): main(context) return {'FINISHED'} + def menu_func(self, context): self.layout.operator(SimpleOperator.bl_idname, text=SimpleOperator.bl_label) -# Register and add to the "object" menu (required to also use F3 search "Simple Object Operator" for quick access) + +# Register and add to the "object" menu (required to also use F3 search "Simple Object Operator" for quick access). def register(): bpy.utils.register_class(SimpleOperator) bpy.types.VIEW3D_MT_object.append(menu_func) diff --git a/release/scripts/templates_py/ui_tool_simple.py b/release/scripts/templates_py/ui_tool_simple.py index fa81b3b58a9..4d009444f2f 100644 --- a/release/scripts/templates_py/ui_tool_simple.py +++ b/release/scripts/templates_py/ui_tool_simple.py @@ -61,8 +61,8 @@ class MyWidgetTool(WorkSpaceTool): bl_label = "My Gizmo Tool" bl_description = "Short description" bl_icon = "ops.transform.translate" - bl_widget="VIEW3D_GGT_tool_generic_handle_free" - bl_widget_properties=[ + bl_widget = "VIEW3D_GGT_tool_generic_handle_free" + bl_widget_properties = [ ("radius", 75.0), ("backdrop_fill_alpha", 0.0), ] diff --git a/source/blender/blenkernel/BKE_attribute_math.hh b/source/blender/blenkernel/BKE_attribute_math.hh index 9efa64d1474..4482e13e1cf 100644 --- a/source/blender/blenkernel/BKE_attribute_math.hh +++ b/source/blender/blenkernel/BKE_attribute_math.hh @@ -5,6 +5,7 @@ #include "BLI_array.hh" #include "BLI_color.hh" #include "BLI_cpp_type.hh" +#include "BLI_math_color.hh" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" @@ -18,17 +19,23 @@ namespace blender::attribute_math { template<typename Func> inline void convert_to_static_type(const CPPType &cpp_type, const Func &func) { - cpp_type.to_static_type_tag<float, float2, float3, int, bool, int8_t, ColorGeometry4f>( - [&](auto type_tag) { - using T = typename decltype(type_tag)::type; - if constexpr (std::is_same_v<T, void>) { - /* It's expected that the given cpp type is one of the supported ones. */ - BLI_assert_unreachable(); - } - else { - func(T()); - } - }); + cpp_type.to_static_type_tag<float, + float2, + float3, + int, + bool, + int8_t, + ColorGeometry4f, + ColorGeometry4b>([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_same_v<T, void>) { + /* It's expected that the given cpp type is one of the supported ones. */ + BLI_assert_unreachable(); + } + else { + func(T()); + } + }); } template<typename Func> @@ -91,6 +98,22 @@ inline ColorGeometry4f mix3(const float3 &weights, return result; } +template<> +inline ColorGeometry4b mix3(const float3 &weights, + const ColorGeometry4b &v0, + const ColorGeometry4b &v1, + const ColorGeometry4b &v2) +{ + const float4 v0_f{&v0.r}; + const float4 v1_f{&v1.r}; + const float4 v2_f{&v2.r}; + const float4 mixed = v0_f * weights[0] + v1_f * weights[1] + v2_f * weights[2]; + return ColorGeometry4b{static_cast<uint8_t>(mixed[0]), + static_cast<uint8_t>(mixed[1]), + static_cast<uint8_t>(mixed[2]), + static_cast<uint8_t>(mixed[3])}; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -134,9 +157,13 @@ template<> inline float3 mix2(const float factor, const float3 &a, const float3 template<> inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b) { - ColorGeometry4f result; - interp_v4_v4v4(result, a, b, factor); - return result; + return math::interpolate(a, b, factor); +} + +template<> +inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b) +{ + return math::interpolate(a, b, factor); } /** \} */ @@ -278,19 +305,33 @@ class SimpleMixerWithAccumulationType { } }; -class ColorGeometryMixer { +class ColorGeometry4fMixer { private: MutableSpan<ColorGeometry4f> buffer_; ColorGeometry4f default_color_; Array<float> total_weights_; public: - ColorGeometryMixer(MutableSpan<ColorGeometry4f> buffer, - ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); + ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> buffer, + ColorGeometry4f default_color = ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f)); void mix_in(int64_t index, const ColorGeometry4f &color, float weight = 1.0f); void finalize(); }; +class ColorGeometry4bMixer { + private: + MutableSpan<ColorGeometry4b> buffer_; + ColorGeometry4b default_color_; + Array<float> total_weights_; + Array<float4> accumulation_buffer_; + + public: + ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color = ColorGeometry4b(0, 0, 0, 255)); + void mix_in(int64_t index, const ColorGeometry4b &color, float weight = 1.0f); + void finalize(); +}; + template<typename T> struct DefaultMixerStruct { /* Use void by default. This can be checked for in `if constexpr` statements. */ using type = void; @@ -307,7 +348,10 @@ template<> struct DefaultMixerStruct<float3> { template<> struct DefaultMixerStruct<ColorGeometry4f> { /* Use a special mixer for colors. ColorGeometry4f can't be added/multiplied, because this is not * something one should usually do with colors. */ - using type = ColorGeometryMixer; + using type = ColorGeometry4fMixer; +}; +template<> struct DefaultMixerStruct<ColorGeometry4b> { + using type = ColorGeometry4bMixer; }; template<> struct DefaultMixerStruct<int> { static int double_to_int(const double &value) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 282e2a40bd0..6e4d4d560f7 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -451,7 +451,7 @@ bool last_cylic_segment_is_vector(Span<int8_t> handle_types_left, Span<int8_t> h /** * Return true if the handle types at the index are free (#BEZIER_HANDLE_FREE) or vector - * (#BEZIER_HANDLE_VECTOR). In these cases, directional continuitity from the previous and next + * (#BEZIER_HANDLE_VECTOR). In these cases, directional continuities from the previous and next * evaluated segments is assumed not to be desired. */ bool point_is_sharp(Span<int8_t> handle_types_left, Span<int8_t> handle_types_right, int index); diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index 2070584a8a0..06feb07aef2 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -195,8 +195,8 @@ enum { G_DEBUG_XR = (1 << 19), /* XR/OpenXR messages */ G_DEBUG_XR_TIME = (1 << 20), /* XR/OpenXR timing messages */ - G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */ - G_DEBUG_WINTAB = (1 << 22), /* Debug Wintab. */ + G_DEBUG_GHOST = (1 << 21), /* Debug GHOST module. */ + G_DEBUG_WINTAB = (1 << 22), /* Debug Wintab. */ }; #define G_DEBUG_ALL \ diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index fff3b2a8f89..42d0e66cf49 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -414,6 +414,8 @@ int BKE_image_get_tile_from_pos(struct Image *ima, const float uv[2], float r_uv[2], float r_ofs[2]); +void BKE_image_get_tile_uv(const struct Image *ima, const int tile_number, float r_uv[2]); + /** * Return the tile_number for the closest UDIM tile. */ diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index 395fc5c7eba..e2b16a7681d 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -178,6 +178,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(int mode, int numverts_dst, bool dirty_nors_dst, struct Mesh *me_src, + struct Mesh *me_dst, MeshPairRemap *r_map); void BKE_mesh_remap_calc_edges_from_mesh(int mode, @@ -190,6 +191,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode, int numedges_dst, bool dirty_nors_dst, struct Mesh *me_src, + struct Mesh *me_dst, MeshPairRemap *r_map); void BKE_mesh_remap_calc_loops_from_mesh(int mode, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4ae37095411..f0488e84091 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -615,9 +615,6 @@ typedef struct SculptSession { union { struct { struct SculptVertexPaintGeomMap gmap; - - /* For non-airbrush painting to re-apply from the original (MLoop aligned). */ - unsigned int *previous_color; } vpaint; struct { @@ -734,6 +731,7 @@ enum { }; /* paint_canvas.cc */ + /** * Create a key that can be used to compare with previous ones to identify changes. * The resulting 'string' is owned by the caller. diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index bb918fcfdcb..978e52d8003 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -143,8 +143,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh, int cd_face_node_offset); void BKE_pbvh_build_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, + struct Mesh *mesh, struct Image *image, struct ImageUser *image_user); void BKE_pbvh_free(PBVH *pbvh); diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index 35eb340d0a1..fdfb5fa037e 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -21,7 +21,7 @@ namespace blender::bke::pbvh::pixels { struct TrianglePaintInput { int3 vert_indices; /** - * Delta barycentric coordinates between 2 neighbouring UV's in the U direction. + * Delta barycentric coordinates between 2 neighboring UV's in the U direction. * * Only the first two coordinates are stored. The third should be recalculated */ diff --git a/source/blender/blenkernel/BKE_type_conversions.hh b/source/blender/blenkernel/BKE_type_conversions.hh index 5152989d137..1cca172e188 100644 --- a/source/blender/blenkernel/BKE_type_conversions.hh +++ b/source/blender/blenkernel/BKE_type_conversions.hh @@ -2,6 +2,7 @@ #pragma once +#include "FN_field.hh" #include "FN_multi_function.hh" namespace blender::bke { @@ -59,8 +60,8 @@ class DataTypeConversions { void convert_to_initialized_n(GSpan from_span, GMutableSpan to_span) const; GVArray try_convert(GVArray varray, const CPPType &to_type) const; - GVMutableArray try_convert(GVMutableArray varray, const CPPType &to_type) const; + fn::GField try_convert(fn::GField field, const CPPType &to_type) const; }; const DataTypeConversions &get_implicit_type_conversions(); diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h index 77f01e7919d..bc578ef8b28 100644 --- a/source/blender/blenkernel/BKE_volume.h +++ b/source/blender/blenkernel/BKE_volume.h @@ -77,6 +77,11 @@ const VolumeGrid *BKE_volume_grid_active_get_for_read(const struct Volume *volum /* Tries to find a grid with the given name. Make sure that the volume has been loaded. */ const VolumeGrid *BKE_volume_grid_find_for_read(const struct Volume *volume, const char *name); +/* Tries to set the name of the velocity field. If no such grid exists with the given base name, + * this will try common post-fixes in order to detect velocity fields split into multiple grids. + * Return false if neither finding with the base name nor with the post-fixes succeeded. */ +bool BKE_volume_set_velocity_grid_by_name(struct Volume *volume, const char *base_name); + /* Grid * * By default only grid metadata is loaded, for access to the tree and voxels diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 33f0c331e46..8a0ad4b724b 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -734,7 +734,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, const bool use_deform, const bool need_mapping, const CustomData_MeshMasks *dataMask, - const int index, const bool use_cache, const bool allow_shared_mesh, /* return args */ @@ -848,12 +847,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, else { break; } - - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) { - md = nullptr; - break; - } } /* Result of all leading deforming modifiers is cached for @@ -1129,11 +1122,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform); - /* grab modifiers until index i */ - if ((index != -1) && (BLI_findindex(&ob->modifiers, md) >= index)) { - break; - } - if (sculpt_mode && md->type == eModifierType_Multires) { multires_applied = true; } @@ -1611,7 +1599,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph, const CustomData_MeshMasks *dataMask, const bool need_mapping) { -#if 0 /* XXX This is already taken care of in mesh_calc_modifiers()... */ +#if 0 /* XXX This is already taken care of in #mesh_calc_modifiers... */ if (need_mapping) { /* Also add the flag so that it is recorded in lastDataMask. */ dataMask->vmask |= CD_MASK_ORIGINDEX; @@ -1628,7 +1616,6 @@ static void mesh_build_data(struct Depsgraph *depsgraph, true, need_mapping, dataMask, - -1, true, true, &mesh_deform_eval, @@ -1745,13 +1732,13 @@ static void object_get_datamask(const Depsgraph *depsgraph, /* check if we need tfaces & mcols due to face select or texture paint */ if ((ob->mode & OB_MODE_TEXTURE_PAINT) || editing) { - r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + r_mask->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; r_mask->fmask |= CD_MASK_MTFACE; } /* check if we need mcols due to vertex paint or weightpaint */ if (ob->mode & OB_MODE_VERTEX_PAINT) { - r_mask->lmask |= CD_MASK_MLOOPCOL; + r_mask->lmask |= CD_MASK_PROP_BYTE_COLOR; } if (ob->mode & OB_MODE_WEIGHT_PAINT) { @@ -1882,7 +1869,7 @@ Mesh *mesh_create_eval_final(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, true, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, true, false, dataMask, false, false, nullptr, &result, nullptr); return result; } @@ -1893,7 +1880,7 @@ Mesh *mesh_create_eval_no_deform(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, false, false, dataMask, false, false, nullptr, &result, nullptr); return result; } @@ -1904,7 +1891,7 @@ Mesh *mesh_create_eval_no_deform_render(Depsgraph *depsgraph, { Mesh *result; mesh_calc_modifiers( - depsgraph, scene, ob, false, false, dataMask, -1, false, false, nullptr, &result, nullptr); + depsgraph, scene, ob, false, false, dataMask, false, false, nullptr, &result, nullptr); return result; } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 54fee079947..b886722676b 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1958,11 +1958,12 @@ static void nlaevalchan_assert_blendOrcombine_compatible(NlaEvalChannelSnapshot BLI_assert(lower_necs->length == blended_necs->length); } -/** Check each remap domain of blended values individually in case animator had a non-combine NLA +/** + * Check each remap domain of blended values individually in case animator had a non-combine NLA * strip with a subset of quaternion channels and remapping through any of them failed and thus * potentially has undefined values. * - * \returns true if case occured and handled. Returns false if case didn't occur. + * \returns true if case occurred and handled. Returns false if case didn't occur. */ static bool nlaevalchan_combine_quaternion_handle_undefined_blend_values( NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_or_lower_necs) @@ -1992,8 +1993,10 @@ static void nlaevalchan_copy_values(NlaEvalChannelSnapshot *dst, NlaEvalChannelS memcpy(dst->values, src->values, src->length * sizeof(float)); } -/** Copies from lower necs to blended necs if upper necs is NULL or has zero influence. - * \return true if copied. */ +/** + * Copies from lower necs to blended necs if upper necs is NULL or has zero influence. + * \return true if copied. + */ static bool nlaevalchan_blendOrcombine_try_copy_from_lower(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, @@ -2008,12 +2011,14 @@ static bool nlaevalchan_blendOrcombine_try_copy_from_lower(NlaEvalChannelSnapsho return true; } -/** Copies to lower necs from blended necs if upper necs is NULL or has zero influence. If +/** + * Copies to lower necs from blended necs if upper necs is NULL or has zero influence. If * successful, copies blended_necs remap domains to lower_necs. * * Does not check upper value blend domains. * - * \return true if copied. */ + * \return true if copied. + */ static bool nlaevalchan_blendOrcombine_try_copy_to_lower(NlaEvalChannelSnapshot *blended_necs, NlaEvalChannelSnapshot *upper_necs, const float upper_influence, @@ -2033,7 +2038,8 @@ static bool nlaevalchan_blendOrcombine_try_copy_to_lower(NlaEvalChannelSnapshot return true; } -/** Based on blendmode, blend lower necs with upper necs into blended necs. +/** + * Based on blendmode, blend lower necs with upper necs into blended necs. * * Each upper value's blend domain determines whether to blend or to copy directly * from lower. @@ -2133,7 +2139,6 @@ static void nlaevalchan_combine_quaternion(NlaEvalChannelSnapshot *lower_necs, * \param upper_blendmode: Enum value in eNlaStrip_Blend_Mode. * \param upper_influence: Value in range [0, 1]. * \param upper_necs: Never NULL. - * */ static void nlaevalchan_blendOrcombine(NlaEvalChannelSnapshot *lower_necs, NlaEvalChannelSnapshot *upper_necs, diff --git a/source/blender/blenkernel/intern/attribute.c b/source/blender/blenkernel/intern/attribute.c index 307868ce6d9..0cb0704ff80 100644 --- a/source/blender/blenkernel/intern/attribute.c +++ b/source/blender/blenkernel/intern/attribute.c @@ -311,6 +311,20 @@ AttributeDomain BKE_id_attribute_domain(const ID *id, const CustomDataLayer *lay int BKE_id_attribute_data_length(ID *id, CustomDataLayer *layer) { + /* When in mesh editmode, attributes point to bmesh customdata layers, the attribute data is + * empty since custom data is stored per element instead of a single array there (same es UVs + * etc.), see D11998. */ + switch (GS(id->name)) { + case ID_ME: { + Mesh *mesh = (Mesh *)id; + if (mesh->edit_mesh != NULL) { + return 0; + } + } + default: + break; + } + DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -622,10 +636,10 @@ CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name) layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER); } if (layer == NULL) { - layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_POINT); + layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_POINT); } if (layer == NULL) { - layer = BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_CORNER); + layer = BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER); } return layer; } diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 0ae9fa4356b..77c7857a528 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -70,11 +70,11 @@ static int attribute_data_type_complexity(const CustomDataType data_type) return 4; case CD_PROP_FLOAT3: return 5; - case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: return 6; + case CD_PROP_COLOR: + return 7; #if 0 /* These attribute types are not supported yet. */ - case CD_MLOOPCOL: - return 3; case CD_PROP_STRING: return 6; #endif diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index bfc4c8fcde0..8c021ed0e21 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -127,7 +127,7 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { static constexpr uint64_t supported_types_mask = CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | CD_MASK_PROP_COLOR | CD_MASK_PROP_BOOL | - CD_MASK_PROP_INT8; + CD_MASK_PROP_INT8 | CD_MASK_PROP_BYTE_COLOR; const AttributeDomain domain_; const CustomDataAccessInfo custom_data_access_; diff --git a/source/blender/blenkernel/intern/attribute_math.cc b/source/blender/blenkernel/intern/attribute_math.cc index df3cab474cd..c38df2a2969 100644 --- a/source/blender/blenkernel/intern/attribute_math.cc +++ b/source/blender/blenkernel/intern/attribute_math.cc @@ -4,8 +4,8 @@ namespace blender::attribute_math { -ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffer, - ColorGeometry4f default_color) +ColorGeometry4fMixer::ColorGeometry4fMixer(MutableSpan<ColorGeometry4f> output_buffer, + ColorGeometry4f default_color) : buffer_(output_buffer), default_color_(default_color), total_weights_(output_buffer.size(), 0.0f) @@ -13,9 +13,9 @@ ColorGeometryMixer::ColorGeometryMixer(MutableSpan<ColorGeometry4f> output_buffe buffer_.fill(ColorGeometry4f(0.0f, 0.0f, 0.0f, 0.0f)); } -void ColorGeometryMixer::mix_in(const int64_t index, - const ColorGeometry4f &color, - const float weight) +void ColorGeometry4fMixer::mix_in(const int64_t index, + const ColorGeometry4f &color, + const float weight) { BLI_assert(weight >= 0.0f); ColorGeometry4f &output_color = buffer_[index]; @@ -26,7 +26,7 @@ void ColorGeometryMixer::mix_in(const int64_t index, total_weights_[index] += weight; } -void ColorGeometryMixer::finalize() +void ColorGeometry4fMixer::finalize() { for (const int64_t i : buffer_.index_range()) { const float weight = total_weights_[i]; @@ -44,4 +44,43 @@ void ColorGeometryMixer::finalize() } } +ColorGeometry4bMixer::ColorGeometry4bMixer(MutableSpan<ColorGeometry4b> buffer, + ColorGeometry4b default_color) + : buffer_(buffer), + default_color_(default_color), + total_weights_(buffer.size(), 0.0f), + accumulation_buffer_(buffer.size(), float4(0, 0, 0, 0)) +{ +} + +void ColorGeometry4bMixer::mix_in(int64_t index, const ColorGeometry4b &color, float weight) +{ + BLI_assert(weight >= 0.0f); + float4 &accum_value = accumulation_buffer_[index]; + accum_value[0] += color.r * weight; + accum_value[1] += color.g * weight; + accum_value[2] += color.b * weight; + accum_value[3] += color.a * weight; + total_weights_[index] += weight; +} + +void ColorGeometry4bMixer::finalize() +{ + for (const int64_t i : buffer_.index_range()) { + const float weight = total_weights_[i]; + const float4 &accum_value = accumulation_buffer_[i]; + ColorGeometry4b &output_color = buffer_[i]; + if (weight > 0.0f) { + const float weight_inv = 1.0f / weight; + output_color.r = accum_value[0] * weight_inv; + output_color.g = accum_value[1] * weight_inv; + output_color.b = accum_value[2] * weight_inv; + output_color.a = accum_value[3] * weight_inv; + } + else { + output_color = default_color_; + } + } +} + } // namespace blender::attribute_math diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index b9cd9e1ee59..0593db34e20 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -1557,8 +1557,10 @@ void BKE_brush_init_curves_sculpt_settings(Brush *brush) if (brush->curves_sculpt_settings == NULL) { brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__); } - brush->curves_sculpt_settings->add_amount = 1; - brush->curves_sculpt_settings->minimum_length = 0.01f; + BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings; + settings->add_amount = 1; + settings->minimum_length = 0.01f; + settings->curve_length = 0.3f; } struct Brush *BKE_brush_first_search(struct Main *bmain, const eObjectMode ob_mode) diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index f7454a02de6..0d6a0c045a5 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -1171,6 +1171,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh) for (unsigned i = 0; i < mesh->totvert; i++, verts++) { copy_v3_v3(mvert[i].co, verts->xrest); } + BKE_mesh_normals_tag_dirty(new_mesh); return new_mesh; } @@ -1507,7 +1508,6 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) if (clmd->sim_parms->shapekey_rest && !(clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH)) { tmp_mesh = cloth_make_rest_mesh(clmd, mesh); - BKE_mesh_calc_normals(tmp_mesh); } EdgeSet *existing_vert_pairs = BLI_edgeset_new("cloth_sewing_edges_graph"); diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index bad70d4ccc6..4338883853d 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -113,9 +113,12 @@ static void curve_free_data(ID *id) BKE_curve_batch_cache_free(curve); BKE_nurbList_free(&curve->nurb); - BKE_curve_editfont_free(curve); - BKE_curve_editNurb_free(curve); + if (!curve->edit_data_from_original) { + BKE_curve_editfont_free(curve); + + BKE_curve_editNurb_free(curve); + } BKE_curveprofile_free(curve->bevel_profile); diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index c48d155f5ce..d7fd8f7a2b6 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -649,7 +649,6 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, offsets.vert.last(), offsets.edge.last(), 0, offsets.loop.last(), offsets.poly.last()); mesh->flag |= ME_AUTOSMOOTH; mesh->smoothresh = DEG2RADF(180.0f); - BKE_mesh_normals_tag_dirty(mesh); MutableSpan<MVert> verts(mesh->mvert, mesh->totvert); MutableSpan<MEdge> edges(mesh->medge, mesh->totedge); MutableSpan<MLoop> loops(mesh->mloop, mesh->totloop); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 6dd9460aaa9..22db90a06b0 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -765,7 +765,12 @@ static void layerFree_grid_paint_mask(void *data, int count, int UNUSED(size)) } } -/* --------- */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MLoopCol, #CD_PROP_BYTE_COLOR) + * \{ */ + static void layerCopyValue_mloopcol(const void *source, void *dest, const int mixmode, @@ -954,6 +959,12 @@ static int layerMaxNum_mloopcol() return MAX_MCOL; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Callbacks for (#MLoopUV, #CD_MLOOPUV) + * \{ */ + static void layerCopyValue_mloopuv(const void *source, void *dest, const int mixmode, @@ -1716,7 +1727,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { nullptr, nullptr, layerMaxNum_tface}, - /* 17: CD_MLOOPCOL */ + /* 17: CD_PROP_BYTE_COLOR */ {sizeof(MLoopCol), "MLoopCol", 1, @@ -2052,46 +2063,45 @@ const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { }; const CustomData_MeshMasks CD_MASK_MESH = { /* vmask */ (CD_MASK_MVERT | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | - CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | - CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | + CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /* vmask */ (CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_SHAPEKEY | CD_MASK_MVERT_SKIN | CD_MASK_PAINT_MASK | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_CREASE), /* emask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT), /* pmask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | + (CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */ }; const CustomData_MeshMasks CD_MASK_BMESH = { /* vmask */ (CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_SHAPEKEY | - CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | - CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), /* fmask */ 0, /* pmask */ (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ - (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | - CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | + CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { /* vmask */ (CD_MASK_MVERT | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | CD_MASK_BWEIGHT | CD_MASK_MVERT_SKIN | CD_MASK_ORCO | CD_MASK_CLOTH_ORCO | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_PAINT_MASK | - CD_MASK_PROP_ALL | CD_MASK_PROP_COLOR | CD_MASK_CREASE), + CD_MASK_PROP_ALL | CD_MASK_CREASE), /* emask */ (CD_MASK_MEDGE | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), @@ -2104,9 +2114,8 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL | CD_MASK_SCULPT_FACE_SETS), /* lmask */ (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPUV | - CD_MASK_MLOOPCOL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | - CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | - CD_MASK_PROP_ALL), + CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | + CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; static const LayerTypeInfo *layerType_getInfo(int type) @@ -3486,7 +3495,7 @@ void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int totloop) } else if (fdata->layers[i].type == CD_MCOL) { CustomData_add_layer_named( - ldata, CD_MLOOPCOL, CD_CALLOC, nullptr, totloop, fdata->layers[i].name); + ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, nullptr, totloop, fdata->layers[i].name); } else if (fdata->layers[i].type == CD_MDISPS) { CustomData_add_layer_named( @@ -3509,7 +3518,7 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *ldata, int total) CustomData_add_layer_named( fdata, CD_MTFACE, CD_CALLOC, nullptr, total, ldata->layers[i].name); } - if (ldata->layers[i].type == CD_MLOOPCOL) { + if (ldata->layers[i].type == CD_PROP_BYTE_COLOR) { CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, nullptr, total, ldata->layers[i].name); } else if (ldata->layers[i].type == CD_PREVIEW_MLOOPCOL) { @@ -3544,7 +3553,7 @@ bool CustomData_from_bmeshpoly_test(CustomData *fdata, CustomData *ldata, bool f if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) { return false; } - if (!LAYER_CMP(ldata, CD_MLOOPCOL, fdata, CD_MCOL)) { + if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) { return false; } if (!LAYER_CMP(ldata, CD_PREVIEW_MLOOPCOL, fdata, CD_PREVIEW_MCOL)) { @@ -3586,17 +3595,17 @@ void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *ldata) CustomData_set_layer_stencil(fdata, CD_MTFACE, act); } - if (CustomData_has_layer(ldata, CD_MLOOPCOL)) { - act = CustomData_get_active_layer(ldata, CD_MLOOPCOL); + if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) { + act = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_active(fdata, CD_MCOL, act); - act = CustomData_get_render_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_render_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_render(fdata, CD_MCOL, act); - act = CustomData_get_clone_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_clone(fdata, CD_MCOL, act); - act = CustomData_get_stencil_layer(ldata, CD_MLOOPCOL); + act = CustomData_get_stencil_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_stencil(fdata, CD_MCOL, act); } } @@ -3621,16 +3630,16 @@ void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, Custom if (CustomData_has_layer(fdata, CD_MCOL)) { act = CustomData_get_active_layer(fdata, CD_MCOL); - CustomData_set_layer_active(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_active(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_render_layer(fdata, CD_MCOL); - CustomData_set_layer_render(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_render(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_clone_layer(fdata, CD_MCOL); - CustomData_set_layer_clone(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_clone(ldata, CD_PROP_BYTE_COLOR, act); act = CustomData_get_stencil_layer(fdata, CD_MCOL); - CustomData_set_layer_stencil(ldata, CD_MLOOPCOL, act); + CustomData_set_layer_stencil(ldata, CD_PROP_BYTE_COLOR, act); } } @@ -5401,6 +5410,8 @@ const blender::CPPType *custom_data_type_to_cpp_type(const CustomDataType type) return &CPPType::get<bool>(); case CD_PROP_INT8: return &CPPType::get<int8_t>(); + case CD_PROP_BYTE_COLOR: + return &CPPType::get<ColorGeometry4b>(); default: return nullptr; } @@ -5430,6 +5441,9 @@ CustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) if (type.is<int8_t>()) { return CD_PROP_INT8; } + if (type.is<ColorGeometry4b>()) { + return CD_PROP_BYTE_COLOR; + } return static_cast<CustomDataType>(-1); } diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 2369ce88ebc..6a3f6a47f5e 100644 --- a/source/blender/blenkernel/intern/data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -217,7 +217,7 @@ int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type) return CD_FAKE_LNOR; case DT_TYPE_MLOOPCOL_VERT: case DT_TYPE_MLOOPCOL_LOOP: - return CD_MLOOPCOL; + return CD_PROP_BYTE_COLOR; case DT_TYPE_MPROPCOL_VERT: case DT_TYPE_MPROPCOL_LOOP: return CD_PROP_COLOR; @@ -1501,6 +1501,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, num_verts_dst, dirty_nors_dst, me_src, + me_dst, &geom_map[VDATA]); geom_map_init[VDATA] = true; } @@ -1579,6 +1580,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, num_edges_dst, dirty_nors_dst, me_src, + me_dst, &geom_map[EDATA]); geom_map_init[EDATA] = true; } diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 8c1161d6ff6..63aa03483b2 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -887,17 +887,11 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph, if (mti->type == eModifierTypeType_OnlyDeform) { int totvert; float(*vertex_coords)[3] = BKE_mesh_vert_coords_alloc(mesh, &totvert); - if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { - BKE_mesh_vertex_normals_ensure(mesh); - } mti->deformVerts(md, &mectx_deform, mesh, vertex_coords, totvert); BKE_mesh_vert_coords_apply(mesh, vertex_coords); MEM_freeN(vertex_coords); } else { - if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { - BKE_mesh_vertex_normals_ensure(mesh); - } Mesh *output_mesh = mti->modifyMesh(md, &mectx_apply, mesh); if (mesh != output_mesh) { geometry_set.replace_mesh(output_mesh); @@ -1472,10 +1466,12 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, const bool for_render) { BLI_assert(ELEM(ob->type, OB_SURF, OB_CURVES_LEGACY, OB_FONT)); - Curve &cow_curve = *(Curve *)ob->data; BKE_object_free_derived_caches(ob); - cow_curve.curve_eval = nullptr; + + /* It's important to retrieve this after calling #BKE_object_free_derived_caches, + * which may reset the object data pointer in some cases. */ + const Curve &original_curve = *static_cast<const Curve *>(ob->data); ob->runtime.curve_cache = MEM_cnew<CurveCache>(__func__); ListBase *dispbase = &ob->runtime.curve_cache->disp; @@ -1488,14 +1484,27 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, GeometrySet geometry = evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase); if (geometry.has_curves()) { - /* Assign the evaluated curve to the object's "data_eval". In addition to the curve_eval - * added to the curve here, it will also contain a copy of the original curve's data. This is - * essential, because it maintains the expected behavior for evaluated curve data from before - * the CurveEval data type was introduced, when an evaluated object's curve data was just a - * copy of the original curve and everything else ended up in #CurveCache. */ - CurveComponent &curve_component = geometry.get_component_for_write<CurveComponent>(); - cow_curve.curve_eval = curve_component.get_for_read(); - BKE_object_eval_assign_data(ob, &cow_curve.id, false); + /* Create a copy of the original curve and add necessary pointers to evaluated and edit mode + * data. This is needed for a few reasons: + * - Existing code from before curve evaluation was changed to use #GeometrySet expected to + * have a copy of the original curve data. (Any evaluated data was placed in + * #Object.runtime.curve_cache). + * - The result of modifier evaluation is not a #Curve data-block but a #Curves data-block, + * which can support constructive modifiers and geometry nodes. + * - The dependency graph has handling of edit mode pointers (see #update_edit_mode_pointers) + * but it doesn't seem to work in this case. + * + * Since the the plan is to replace this legacy curve object with the curves data-block + * (see T95355), this somewhat hacky inefficient solution is relatively temporary. + */ + Curve &cow_curve = *reinterpret_cast<Curve *>( + BKE_id_copy_ex(nullptr, &original_curve.id, nullptr, LIB_ID_COPY_LOCALIZE)); + cow_curve.curve_eval = geometry.get_curves_for_read(); + /* Copy edit mode pointers necessary for drawing to the duplicated curve. */ + cow_curve.editnurb = original_curve.editnurb; + cow_curve.editfont = original_curve.editfont; + cow_curve.edit_data_from_original = true; + BKE_object_eval_assign_data(ob, &cow_curve.id, true); } ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry)); diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index b85b2b3157c..22341f98375 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -336,7 +336,7 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { Mesh *me = ob->data; - return (CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name) != -1); + return (CustomData_get_named_layer_index(&me->ldata, CD_PROP_BYTE_COLOR, name) != -1); } if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { return (BKE_object_defgroup_name_index(ob, name) != -1); @@ -1664,7 +1664,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface const MLoop *mloop = mesh->mloop; const int totloop = mesh->totloop; const MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_MLOOPCOL, surface->init_layername); + &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); if (!col) { return; } @@ -1676,7 +1676,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_MLOOPCOL, surface->init_layername); + &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); if (!col) { return; } @@ -1899,7 +1899,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * pmd->type == MOD_DYNAMICPAINT_TYPE_CANVAS) { DynamicPaintSurface *surface; - bool update_normals = false; /* loop through surfaces */ for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { @@ -1941,20 +1940,28 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* paint layer */ MLoopCol *mloopcol = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, surface->output_name); + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name); /* if output layer is lost from a constructive modifier, re-add it */ if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) { - mloopcol = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name); + mloopcol = CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_CALLOC, + NULL, + totloop, + surface->output_name); } /* wet layer */ MLoopCol *mloopcol_wet = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, surface->output_name2); + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2); /* if output layer is lost from a constructive modifier, re-add it */ if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) { - mloopcol_wet = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name2); + mloopcol_wet = CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_CALLOC, + NULL, + totloop, + surface->output_name2); } data.ob = ob; @@ -2018,21 +2025,17 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * settings.use_threading = (sData->total_points > 1000); BLI_task_parallel_range( 0, sData->total_points, &data, dynamic_paint_apply_surface_wave_cb, &settings); - update_normals = true; + BKE_mesh_normals_tag_dirty(mesh); } /* displace */ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { dynamicPaint_applySurfaceDisplace(surface, result); - update_normals = true; + BKE_mesh_normals_tag_dirty(mesh); } } } } - - if (update_normals) { - BKE_mesh_normals_tag_dirty(result); - } } /* make a copy of mesh to use as brush data */ else if (pmd->brush && pmd->type == MOD_DYNAMICPAINT_TYPE_BRUSH) { diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 81e73b6cf2c..5de13fbdbed 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -3537,7 +3537,6 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje } BKE_mesh_calc_edges(result, false, false); - BKE_mesh_normals_tag_dirty(result); return result; } @@ -5071,6 +5070,9 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, tfds->openvdb_compression = fds->openvdb_compression; tfds->clipping = fds->clipping; tfds->openvdb_data_depth = fds->openvdb_data_depth; + + /* Render options. */ + tfds->velocity_scale = fds->velocity_scale; } else if (tfmd->flow) { FluidFlowSettings *tffs = tfmd->flow; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 47f7bb00b8f..fb39861d3e7 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -903,22 +903,6 @@ static void set_loop_uv(MLoopUV &uv, float2 co) copy_v2_v2(uv.uv, co); } -static ColorGeometry4f get_loop_color(const MLoopCol &col) -{ - ColorGeometry4b encoded_color = ColorGeometry4b(col.r, col.g, col.b, col.a); - ColorGeometry4f linear_color = encoded_color.decode(); - return linear_color; -} - -static void set_loop_color(MLoopCol &col, ColorGeometry4f linear_color) -{ - ColorGeometry4b encoded_color = linear_color.encode(); - col.r = encoded_color.r; - col.g = encoded_color.g; - col.b = encoded_color.b; - col.a = encoded_color.a; -} - static float get_crease(const MEdge &edge) { return edge.crease / 255.0f; @@ -1293,14 +1277,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_derived_read_attribute<MLoopUV, float2, get_loop_uv>, make_derived_write_attribute<MLoopUV, float2, get_loop_uv, set_loop_uv>); - static NamedLegacyCustomDataProvider vertex_colors( - ATTR_DOMAIN_CORNER, - CD_PROP_COLOR, - CD_MLOOPCOL, - corner_access, - make_derived_read_attribute<MLoopCol, ColorGeometry4f, get_loop_color>, - make_derived_write_attribute<MLoopCol, ColorGeometry4f, get_loop_color, set_loop_color>); - static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); @@ -1310,7 +1286,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() return ComponentAttributeProviders( {&position, &id, &material_index, &shade_smooth, &normal, &crease}, {&uvs, - &vertex_colors, &corner_custom_data, &vertex_groups, &point_custom_data, diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 53ec148fd2d..dfa820519a5 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -829,10 +829,7 @@ ImageTile *BKE_image_get_tile_from_iuser(Image *ima, const ImageUser *iuser) return BKE_image_get_tile(ima, image_get_tile_number_from_iuser(ima, iuser)); } -int BKE_image_get_tile_from_pos(struct Image *ima, - const float uv[2], - float r_uv[2], - float r_ofs[2]) +int BKE_image_get_tile_from_pos(Image *ima, const float uv[2], float r_uv[2], float r_ofs[2]) { float local_ofs[2]; if (r_ofs == nullptr) { @@ -860,6 +857,18 @@ int BKE_image_get_tile_from_pos(struct Image *ima, return tile_number; } +void BKE_image_get_tile_uv(const Image *ima, const int tile_number, float r_uv[2]) +{ + if (ima->source != IMA_SRC_TILED) { + zero_v2(r_uv); + } + else { + const int tile_index = tile_number - 1001; + r_uv[0] = static_cast<float>(tile_index % 10); + r_uv[1] = static_cast<float>(tile_index / 10); + } +} + int BKE_image_find_nearest_tile(const Image *image, const float co[2]) { const float co_floor[2] = {floorf(co[0]), floorf(co[1])}; @@ -868,17 +877,15 @@ int BKE_image_find_nearest_tile(const Image *image, const float co[2]) int tile_number_best = -1; LISTBASE_FOREACH (const ImageTile *, tile, &image->tiles) { - const int tile_index = tile->tile_number - 1001; - /* Coordinates of the current tile. */ - const float tile_index_co[2] = {static_cast<float>(tile_index % 10), - static_cast<float>(tile_index / 10)}; + float uv_offset[2]; + BKE_image_get_tile_uv(image, tile->tile_number, uv_offset); - if (equals_v2v2(co_floor, tile_index_co)) { + if (equals_v2v2(co_floor, uv_offset)) { return tile->tile_number; } /* Distance between co[2] and UDIM tile. */ - const float dist_sq = len_squared_v2v2(tile_index_co, co); + const float dist_sq = len_squared_v2v2(uv_offset, co); if (dist_sq < dist_best_sq) { dist_best_sq = dist_sq; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 4caaf314888..002b496393f 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -1943,6 +1943,8 @@ static void material_default_gpencil_init(Material *ma) static void material_default_surface_init(Material *ma) { + strcpy(ma->id.name, "MADefault Surface"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; @@ -1969,6 +1971,8 @@ static void material_default_surface_init(Material *ma) static void material_default_volume_init(Material *ma) { + strcpy(ma->id.name, "MADefault Volume"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; @@ -1992,6 +1996,8 @@ static void material_default_volume_init(Material *ma) static void material_default_holdout_init(Material *ma) { + strcpy(ma->id.name, "MADefault Holdout"); + bNodeTree *ntree = ntreeAddTree(NULL, "Shader Nodetree", ntreeType_Shader->idname); ma->nodetree = ntree; ma->use_nodes = true; diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 25d97d0bd3c..c13a2bc794a 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -463,7 +463,8 @@ static int customdata_compare( CustomDataLayer *l1, *l2; int layer_count1 = 0, layer_count2 = 0, j; const uint64_t cd_mask_non_generic = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MPOLY | - CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MDEFORMVERT; + CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR | + CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; for (int i = 0; i < c1->totlayer; i++) { @@ -581,7 +582,7 @@ static int customdata_compare( } break; } - case CD_MLOOPCOL: { + case CD_PROP_BYTE_COLOR: { MLoopCol *lp1 = (MLoopCol *)l1->data; MLoopCol *lp2 = (MLoopCol *)l2->data; int ltot = m1->totloop; @@ -768,7 +769,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) } else { const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE); const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL); @@ -786,7 +787,8 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) * some info to help troubleshoot what's going on. */ printf( "%s: warning! Tessellation uvs or vcol data got out of sync, " - "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != CD_MLOOPCOL: " + "had to reset!\n CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != " + "CD_PROP_BYTE_COLOR: " "%d\n", __func__, tottex_tessface, @@ -871,7 +873,7 @@ bool BKE_mesh_clear_facemap_customdata(struct Mesh *me) /** * This ensures grouped custom-data (e.g. #CD_MLOOPUV and #CD_MTFACE, or - * #CD_MLOOPCOL and #CD_MCOL) have the same relative active/render/clone/mask indices. + * #CD_PROP_BYTE_COLOR and #CD_MCOL) have the same relative active/render/clone/mask indices. * * NOTE(@campbellbarton): that for undo mesh data we want to skip 'ensure_tess_cd' call since * we don't want to store memory for #MFace data when its only used for older @@ -902,7 +904,7 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd) me->mpoly = (MPoly *)CustomData_get_layer(&me->pdata, CD_MPOLY); me->mloop = (MLoop *)CustomData_get_layer(&me->ldata, CD_MLOOP); - me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_MLOOPCOL); + me->mloopcol = (MLoopCol *)CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); me->mloopuv = (MLoopUV *)CustomData_get_layer(&me->ldata, CD_MLOOPUV); } @@ -1112,6 +1114,9 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src, mesh_ensure_cdlayers_primary(me_dst, do_tessface); BKE_mesh_update_customdata_pointers(me_dst, false); + /* Expect that normals aren't copied at all, since the destination mesh is new. */ + BLI_assert(BKE_mesh_vertex_normals_are_dirty(me_dst)); + return me_dst; } @@ -1688,6 +1693,7 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) mul_m3_v3(m3, *lnors); } } + BKE_mesh_normals_tag_dirty(me); } void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index eee1d3b9eec..3fcacb31b24 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -782,7 +782,6 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) } } - BKE_mesh_calc_normals(result); if (dbg_level > 0) { BKE_mesh_validate(result, true, true); } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index ff953ef5b46..a289d208684 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -120,9 +120,6 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me) } BKE_mesh_update_customdata_pointers(me, true); - - BKE_mesh_normals_tag_dirty(me); - BKE_mesh_calc_edges(me, true, false); } } @@ -514,7 +511,6 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase * } mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly); - BKE_mesh_normals_tag_dirty(mesh); if (totvert != 0) { memcpy(mesh->mvert, allvert, totvert * sizeof(MVert)); diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 6c5a5de31fc..ec2660a0145 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -661,7 +661,7 @@ static void bm_corners_to_loops_ex(ID *id, } for (int i = 0; i < numCol; i++) { - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_PROP_BYTE_COLOR, loopstart, i); MCol *mcol = (MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 2e634a14872..3a37c29c1d0 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -478,6 +478,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, const int numverts_dst, const bool UNUSED(dirty_nors_dst), Mesh *me_src, + Mesh *me_dst, MeshPairRemap *r_map) { const float full_weight = 1.0f; @@ -580,7 +581,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, MPoly *polys_src = me_src->mpoly; MLoop *loops_src = me_src->mloop; float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, NULL); - const float(*vert_normals_src)[3] = BKE_mesh_vertex_normals_ensure(me_src); + const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst); size_t tmp_buff_size = MREMAP_DEFAULT_BUFSIZE; float(*vcos)[3] = MEM_mallocN(sizeof(*vcos) * tmp_buff_size, __func__); @@ -592,7 +593,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, if (mode == MREMAP_MODE_VERT_POLYINTERP_VNORPROJ) { for (i = 0; i < numverts_dst; i++) { copy_v3_v3(tmp_co, verts_dst[i].co); - copy_v3_v3(tmp_no, vert_normals_src[i]); + copy_v3_v3(tmp_no, vert_normals_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -703,6 +704,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, const int numedges_dst, const bool UNUSED(dirty_nors_dst), Mesh *me_src, + Mesh *me_dst, MeshPairRemap *r_map) { const float full_weight = 1.0f; @@ -938,7 +940,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_EDGES, 2); - const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_src); + const float(*vert_normals_dst)[3] = BKE_mesh_vertex_normals_ensure(me_dst); for (i = 0; i < numedges_dst; i++) { /* For each dst edge, we sample some rays from it (interpolated from its vertices) diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 7be4a6f2f94..02c9f61957d 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -140,7 +140,6 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_calc_normals(mesh); MEM_freeN(qrd.out_faces); MEM_freeN(qrd.out_verts); @@ -257,7 +256,6 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/blenkernel/intern/mesh_tessellate.c b/source/blender/blenkernel/intern/mesh_tessellate.c index ae52e31cb9b..ea3cc043267 100644 --- a/source/blender/blenkernel/intern/mesh_tessellate.c +++ b/source/blender/blenkernel/intern/mesh_tessellate.c @@ -58,7 +58,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, * The issue is, unless having two different functions with nearly the same code, * there's not much ways to solve this. Better IMHO to live with it for now (sigh). */ const int numUV = CustomData_number_of_layers(ldata, CD_MLOOPUV); - const int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + const int numCol = CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR); const bool hasPCol = CustomData_has_layer(ldata, CD_PREVIEW_MLOOPCOL); const bool hasOrigSpace = CustomData_has_layer(ldata, CD_ORIGSPACE_MLOOP); const bool hasLoopNormal = CustomData_has_layer(ldata, CD_NORMAL); @@ -81,7 +81,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, for (i = 0; i < numCol; i++) { MCol(*mcol)[4] = CustomData_get_layer_n(fdata, CD_MCOL, i); - MLoopCol *mloopcol = CustomData_get_layer_n(ldata, CD_MLOOPCOL, i); + MLoopCol *mloopcol = CustomData_get_layer_n(ldata, CD_PROP_BYTE_COLOR, i); for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, mcol++) { for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) { diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 6af765d7de5..d16f7eaf588 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -1017,7 +1017,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, pdata, mask.pmask, totpoly, do_verbose, do_fixes, &is_change_p); const int tot_uvloop = CustomData_number_of_layers(ldata, CD_MLOOPUV); - const int tot_vcolloop = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + const int tot_vcolloop = CustomData_number_of_layers(ldata, CD_PROP_BYTE_COLOR); if (tot_uvloop > MAX_MTFACE) { PRINT_ERR( "\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, " diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index f4703b32582..e7ee8caf0eb 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -944,8 +944,10 @@ static void modwrap_dependsOnNormals(Mesh *me) break; } case ME_WRAPPER_TYPE_SUBD: + /* Not an expected case. */ + break; case ME_WRAPPER_TYPE_MDATA: - BKE_mesh_calc_normals(me); + /* Normals are calculated lazily. */ break; } } @@ -992,7 +994,7 @@ void BKE_modifier_deform_vertsEM(ModifierData *md, { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); if (me && mti->dependsOnNormals && mti->dependsOnNormals(md)) { - BKE_mesh_calc_normals(me); + modwrap_dependsOnNormals(me); } mti->deformVertsEM(md, ctx, em, me, vertexCos, numVerts); } diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index 65ba7b64d83..837b64affa8 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -156,7 +156,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape /* Vertices were moved around, need to update normals after all the vertices are updated * Probably this is possible to do in the loop above, but this is rather tricky because * we don't know all needed vertices' coordinates there yet. */ - BKE_mesh_calc_normals(base_mesh); + BKE_mesh_normals_tag_dirty(base_mesh); } void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context) diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 5ff1f6b950f..948064ad170 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1789,6 +1789,7 @@ void BKE_object_free_derived_caches(Object *ob) BKE_mesh_eval_delete((Mesh *)data_eval); } else { + BKE_libblock_free_data(data_eval, false); BKE_libblock_free_datablock(data_eval, 0); MEM_freeN(data_eval); } @@ -3564,19 +3565,19 @@ void BKE_object_apply_parent_inverse(struct Object *ob) * Use parent's world transform as the child's origin. * * Let: - * local = identity - * world = orthonormalized(parent) + * `local = identity` + * `world = orthonormalized(parent)` * * Then: - * world = parent @ parentinv @ local - * inv(parent) @ world = parentinv - * parentinv = inv(parent) @ world + * `world = parent @ parentinv @ local` + * `inv(parent) @ world = parentinv` + * `parentinv = inv(parent) @ world` * - * NOTE: If ob->obmat has shear, then this `parentinv` is insufficient because - * parent @ parentinv => shearless result + * NOTE: If `ob->obmat` has shear, then this `parentinv` is insufficient because + * `parent @ parentinv => shearless result` * * Thus, local will have shear which cannot be decomposed into TRS: - * local = inv(parent @ parentinv) @ world + * `local = inv(parent @ parentinv) @ world` * * This is currently not supported for consistency in the handling of shear during the other * parenting ops: Parent (Keep Transform), Clear [Parent] and Keep Transform. @@ -3591,11 +3592,11 @@ void BKE_object_apply_parent_inverse(struct Object *ob) /* Now, preserve `world` given the new `parentinv`. * - * world = parent @ parentinv @ local - * inv(parent) @ world = parentinv @ local - * inv(parentinv) @ inv(parent) @ world = local + * `world = parent @ parentinv @ local` + * `inv(parent) @ world = parentinv @ local` + * `inv(parentinv) @ inv(parent) @ world = local` * - * local = inv(parentinv) @ inv(parent) @ world + * `local = inv(parentinv) @ inv(parent) @ world` */ float ob_local[4][4]; copy_m4_m4(ob_local, ob->parentinv); @@ -3974,8 +3975,9 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const Object *ob, const Re } if (visibility_flag & OB_EMPTY_IMAGE_HIDE_NON_AXIS_ALIGNED) { - float3 proj; - project_plane_v3_v3v3(proj, ob->obmat[2], rv3d->viewinv[2]); + float3 proj, ob_z_axis; + normalize_v3_v3(ob_z_axis, ob->obmat[2]); + project_plane_v3_v3v3(proj, ob_z_axis, rv3d->viewinv[2]); const float proj_length_sq = len_squared_v3(proj); if (proj_length_sq > 1e-5f) { return false; diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index fbbd429f58a..f41d59c77ba 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -167,7 +167,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o #endif if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) { /* Always compute UVs, vertex colors as orcos for render. */ - cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + cddata_masks.lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; } makeDerivedMesh(depsgraph, scene, ob, &cddata_masks); /* was CD_MASK_BAREMESH */ diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 5fd7984ea90..0f523d87d9b 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -1101,7 +1101,6 @@ bool BKE_paint_ensure(ToolSettings *ts, struct Paint **r_paint) } else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) { CurvesSculpt *data = MEM_callocN(sizeof(*data), __func__); - data->curve_length = 0.3f; paint = &data->paint; } else if (*r_paint == &ts->imapaint.paint) { @@ -1341,8 +1340,6 @@ void BKE_sculptsession_free_vwpaint_data(struct SculptSession *ss) struct SculptVertexPaintGeomMap *gmap = NULL; if (ss->mode_type == OB_MODE_VERTEX_PAINT) { gmap = &ss->mode.vpaint.gmap; - - MEM_SAFE_FREE(ss->mode.vpaint.previous_color); } else if (ss->mode_type == OB_MODE_WEIGHT_PAINT) { gmap = &ss->mode.wpaint.gmap; @@ -1845,7 +1842,7 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object) { Mesh *orig_me = BKE_object_get_original_mesh(object); - int types[] = {CD_PROP_COLOR, CD_MLOOPCOL}; + int types[] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; bool has_color = false; for (int i = 0; i < ARRAY_SIZE(types); i++) { diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index e91f360ef22..1fb1570b3ff 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1267,7 +1267,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, Attribu { CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); - if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_MLOOPCOL)) { + if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) { *r_layer = NULL; *r_attr = ATTR_DOMAIN_NUM; return false; diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh.cc index d32a03186e3..be6e95426c2 100644 --- a/source/blender/blenkernel/intern/pbvh.cc +++ b/source/blender/blenkernel/intern/pbvh.cc @@ -50,7 +50,7 @@ inline void to_static_color_type(const CustomDataType type, const Func &func) case CD_PROP_COLOR: func(MPropCol()); break; - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: func(MLoopCol()); break; default: diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index 6a135c248ce..55d76938ad3 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -1240,7 +1240,7 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, EDGE_QUEUE_DISABLE(e); #endif - /* At the moment edges never get shorter (subdiv will make new edges) + /* At the moment edges never get shorter (subdivision will make new edges) * unlike collapse where edges can become longer. */ #if 0 if (len_squared_v3v3(v1->co, v2->co) <= eq_ctx->q->limit_len_squared) { diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index 77bd00da50a..b7a2b578a1c 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -267,6 +267,7 @@ bool pbvh_bmesh_node_nearest_to_ray(PBVHNode *node, void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode); /* pbvh_pixels.hh */ + void pbvh_pixels_free(PBVHNode *node); void pbvh_pixels_free_brush_test(PBVHNode *node); diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index d8dd2f4b382..5623cac44ac 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -22,12 +22,14 @@ namespace blender::bke::pbvh::pixels { -/** Durind debugging this check could be enabled. It will write to each image pixel that is covered - * by the pbvh. */ +/** + * During debugging this check could be enabled. + * It will write to each image pixel that is covered by the PBVH. + */ constexpr bool USE_WATERTIGHT_CHECK = false; /** - * Calculate the delta of two neighbour uv coordinates in the given image buffer. + * Calculate the delta of two neighbor UV coordinates in the given image buffer. */ static float2 calc_barycentric_delta(const float2 uvs[3], const float2 start_uv, @@ -273,11 +275,7 @@ static void apply_watertight_check(PBVH *pbvh, Image *image, ImageUser *image_us BKE_image_partial_update_mark_full_update(image); } -static void update_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, - struct Image *image, - struct ImageUser *image_user) +static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { Vector<PBVHNode *> nodes_to_update; @@ -285,14 +283,14 @@ static void update_pixels(PBVH *pbvh, return; } - MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(ldata, CD_MLOOPUV)); + MLoopUV *ldata_uv = static_cast<MLoopUV *>(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV)); if (ldata_uv == nullptr) { return; } for (PBVHNode *node : nodes_to_update) { NodeData *node_data = static_cast<NodeData *>(node->pixels.node_data); - init_triangles(pbvh, node, node_data, mloop); + init_triangles(pbvh, node, node_data, mesh->mloop); } EncodePixelsUserData user_data; @@ -375,13 +373,9 @@ void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &i extern "C" { using namespace blender::bke::pbvh::pixels; -void BKE_pbvh_build_pixels(PBVH *pbvh, - const struct MLoop *mloop, - struct CustomData *ldata, - struct Image *image, - struct ImageUser *image_user) +void BKE_pbvh_build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { - update_pixels(pbvh, mloop, ldata, image, image_user); + update_pixels(pbvh, mesh, image, image_user); } void pbvh_pixels_free(PBVHNode *node) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c index 83e4336e3b1..83427adcb43 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_mesh.c @@ -1155,7 +1155,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, * calculation. Since vertex normals are supposed to be a consistent cache, don't bother * calculating them here. The work may have been pointless anyway if the mesh is deformed or * changed afterwards. */ - BKE_mesh_normals_tag_dirty(result); + BLI_assert(BKE_mesh_vertex_normals_are_dirty(result) || BKE_mesh_poly_normals_are_dirty(result)); /* Free used memory. */ subdiv_mesh_context_free(&subdiv_context); return result; diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index e84ec5b3890..1c2665769db 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -2,6 +2,8 @@ #include "BKE_type_conversions.hh" +#include "DNA_meshdata_types.h" + #include "FN_multi_function_builder.hh" #include "BLI_color.hh" @@ -61,6 +63,10 @@ static ColorGeometry4f float_to_color(const float &a) { return ColorGeometry4f(a, a, a, 1.0f); } +static ColorGeometry4b float_to_byte_color(const float &a) +{ + return float_to_color(a).encode(); +} static float3 float2_to_float3(const float2 &a) { @@ -86,6 +92,10 @@ static ColorGeometry4f float2_to_color(const float2 &a) { return ColorGeometry4f(a.x, a.y, 0.0f, 1.0f); } +static ColorGeometry4b float2_to_byte_color(const float2 &a) +{ + return float2_to_color(a).encode(); +} static bool float3_to_bool(const float3 &a) { @@ -111,6 +121,10 @@ static ColorGeometry4f float3_to_color(const float3 &a) { return ColorGeometry4f(a.x, a.y, a.z, 1.0f); } +static ColorGeometry4b float3_to_byte_color(const float3 &a) +{ + return float3_to_color(a).encode(); +} static bool int_to_bool(const int32_t &a) { @@ -137,6 +151,10 @@ static ColorGeometry4f int_to_color(const int32_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int_to_byte_color(const int32_t &a) +{ + return int_to_color(a).encode(); +} static bool int8_to_bool(const int8_t &a) { @@ -162,6 +180,10 @@ static ColorGeometry4f int8_to_color(const int8_t &a) { return ColorGeometry4f((float)a, (float)a, (float)a, 1.0f); } +static ColorGeometry4b int8_to_byte_color(const int8_t &a) +{ + return int8_to_color(a).encode(); +} static float bool_to_float(const bool &a) { @@ -187,6 +209,10 @@ static ColorGeometry4f bool_to_color(const bool &a) { return (a) ? ColorGeometry4f(1.0f, 1.0f, 1.0f, 1.0f) : ColorGeometry4f(0.0f, 0.0f, 0.0f, 1.0f); } +static ColorGeometry4b bool_to_byte_color(const bool &a) +{ + return bool_to_color(a).encode(); +} static bool color_to_bool(const ColorGeometry4f &a) { @@ -212,6 +238,39 @@ static float3 color_to_float3(const ColorGeometry4f &a) { return float3(a.r, a.g, a.b); } +static ColorGeometry4b color_to_byte_color(const ColorGeometry4f &a) +{ + return a.encode(); +} + +static bool byte_color_to_bool(const ColorGeometry4b &a) +{ + return a.r > 0 || a.g > 0 || a.b > 0; +} +static float byte_color_to_float(const ColorGeometry4b &a) +{ + return color_to_float(a.decode()); +} +static int32_t byte_color_to_int(const ColorGeometry4b &a) +{ + return color_to_int(a.decode()); +} +static int8_t byte_color_to_int8(const ColorGeometry4b &a) +{ + return color_to_int8(a.decode()); +} +static float2 byte_color_to_float2(const ColorGeometry4b &a) +{ + return color_to_float2(a.decode()); +} +static float3 byte_color_to_float3(const ColorGeometry4b &a) +{ + return color_to_float3(a.decode()); +} +static ColorGeometry4f byte_color_to_color(const ColorGeometry4b &a) +{ + return a.decode(); +} static DataTypeConversions create_implicit_conversions() { @@ -223,6 +282,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float, bool, float_to_bool>(conversions); add_implicit_conversion<float, int8_t, float_to_int8>(conversions); add_implicit_conversion<float, ColorGeometry4f, float_to_color>(conversions); + add_implicit_conversion<float, ColorGeometry4b, float_to_byte_color>(conversions); add_implicit_conversion<float2, float3, float2_to_float3>(conversions); add_implicit_conversion<float2, float, float2_to_float>(conversions); @@ -230,6 +290,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float2, bool, float2_to_bool>(conversions); add_implicit_conversion<float2, int8_t, float2_to_int8>(conversions); add_implicit_conversion<float2, ColorGeometry4f, float2_to_color>(conversions); + add_implicit_conversion<float2, ColorGeometry4b, float2_to_byte_color>(conversions); add_implicit_conversion<float3, bool, float3_to_bool>(conversions); add_implicit_conversion<float3, int8_t, float3_to_int8>(conversions); @@ -237,6 +298,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<float3, int32_t, float3_to_int>(conversions); add_implicit_conversion<float3, float2, float3_to_float2>(conversions); add_implicit_conversion<float3, ColorGeometry4f, float3_to_color>(conversions); + add_implicit_conversion<float3, ColorGeometry4b, float3_to_byte_color>(conversions); add_implicit_conversion<int32_t, bool, int_to_bool>(conversions); add_implicit_conversion<int32_t, int8_t, int_to_int8>(conversions); @@ -244,6 +306,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int32_t, float2, int_to_float2>(conversions); add_implicit_conversion<int32_t, float3, int_to_float3>(conversions); add_implicit_conversion<int32_t, ColorGeometry4f, int_to_color>(conversions); + add_implicit_conversion<int32_t, ColorGeometry4b, int_to_byte_color>(conversions); add_implicit_conversion<int8_t, bool, int8_to_bool>(conversions); add_implicit_conversion<int8_t, int32_t, int8_to_int>(conversions); @@ -251,6 +314,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<int8_t, float2, int8_to_float2>(conversions); add_implicit_conversion<int8_t, float3, int8_to_float3>(conversions); add_implicit_conversion<int8_t, ColorGeometry4f, int8_to_color>(conversions); + add_implicit_conversion<int8_t, ColorGeometry4b, int8_to_byte_color>(conversions); add_implicit_conversion<bool, float, bool_to_float>(conversions); add_implicit_conversion<bool, int8_t, bool_to_int8>(conversions); @@ -258,6 +322,7 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<bool, float2, bool_to_float2>(conversions); add_implicit_conversion<bool, float3, bool_to_float3>(conversions); add_implicit_conversion<bool, ColorGeometry4f, bool_to_color>(conversions); + add_implicit_conversion<bool, ColorGeometry4b, bool_to_byte_color>(conversions); add_implicit_conversion<ColorGeometry4f, bool, color_to_bool>(conversions); add_implicit_conversion<ColorGeometry4f, int8_t, color_to_int8>(conversions); @@ -265,6 +330,15 @@ static DataTypeConversions create_implicit_conversions() add_implicit_conversion<ColorGeometry4f, int32_t, color_to_int>(conversions); add_implicit_conversion<ColorGeometry4f, float2, color_to_float2>(conversions); add_implicit_conversion<ColorGeometry4f, float3, color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4f, ColorGeometry4b, color_to_byte_color>(conversions); + + add_implicit_conversion<ColorGeometry4b, bool, byte_color_to_bool>(conversions); + add_implicit_conversion<ColorGeometry4b, int8_t, byte_color_to_int8>(conversions); + add_implicit_conversion<ColorGeometry4b, float, byte_color_to_float>(conversions); + add_implicit_conversion<ColorGeometry4b, int32_t, byte_color_to_int>(conversions); + add_implicit_conversion<ColorGeometry4b, float2, byte_color_to_float2>(conversions); + add_implicit_conversion<ColorGeometry4b, float3, byte_color_to_float3>(conversions); + add_implicit_conversion<ColorGeometry4b, ColorGeometry4f, byte_color_to_color>(conversions); return conversions; } @@ -411,4 +485,19 @@ GVMutableArray DataTypeConversions::try_convert(GVMutableArray varray, std::move(varray), to_type, *this); } +fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_type) const +{ + const CPPType &from_type = field.cpp_type(); + if (from_type == to_type) { + return field; + } + if (!this->is_convertible(from_type, to_type)) { + return {}; + } + const fn::MultiFunction &fn = + *bke::get_implicit_type_conversions().get_conversion_multi_function( + fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type)); + return {std::make_shared<fn::FieldOperation>(fn, Vector<fn::GField>{std::move(field)})}; +} + } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 0c131863edd..307466d7dc9 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -60,6 +60,7 @@ using blender::float3; using blender::float4x4; using blender::IndexRange; using blender::StringRef; +using blender::StringRefNull; #ifdef WITH_OPENVDB # include <atomic> @@ -517,6 +518,8 @@ static void volume_init_data(ID *id) MEMCPY_STRUCT_AFTER(volume, DNA_struct_default_get(Volume), id); BKE_volume_init_grids(volume); + + BLI_strncpy(volume->velocity_grid, "velocity", sizeof(volume->velocity_grid)); } static void volume_copy_data(Main *UNUSED(bmain), @@ -794,6 +797,57 @@ bool BKE_volume_is_loaded(const Volume *volume) #endif } +bool BKE_volume_set_velocity_grid_by_name(Volume *volume, const char *base_name) +{ + const StringRefNull ref_base_name = base_name; + + if (BKE_volume_grid_find_for_read(volume, base_name)) { + BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid)); + volume->runtime.velocity_x_grid[0] = '\0'; + volume->runtime.velocity_y_grid[0] = '\0'; + volume->runtime.velocity_z_grid[0] = '\0'; + return true; + } + + /* It could be that the velocity grid is split in multiple grids, try with known postfixes. */ + const StringRefNull postfixes[][3] = {{"x", "y", "z"}, {".x", ".y", ".z"}, {"_x", "_y", "_z"}}; + + for (const StringRefNull *postfix : postfixes) { + bool found = true; + for (int i = 0; i < 3; i++) { + std::string post_fixed_name = ref_base_name + postfix[i]; + if (!BKE_volume_grid_find_for_read(volume, post_fixed_name.c_str())) { + found = false; + break; + } + } + + if (!found) { + continue; + } + + /* Save the base name as well. */ + BLI_strncpy(volume->velocity_grid, base_name, sizeof(volume->velocity_grid)); + BLI_strncpy(volume->runtime.velocity_x_grid, + (ref_base_name + postfix[0]).c_str(), + sizeof(volume->runtime.velocity_x_grid)); + BLI_strncpy(volume->runtime.velocity_y_grid, + (ref_base_name + postfix[1]).c_str(), + sizeof(volume->runtime.velocity_y_grid)); + BLI_strncpy(volume->runtime.velocity_z_grid, + (ref_base_name + postfix[2]).c_str(), + sizeof(volume->runtime.velocity_z_grid)); + return true; + } + + /* Reset to avoid potential issues. */ + volume->velocity_grid[0] = '\0'; + volume->runtime.velocity_x_grid[0] = '\0'; + volume->runtime.velocity_y_grid[0] = '\0'; + volume->runtime.velocity_z_grid[0] = '\0'; + return false; +} + bool BKE_volume_load(const Volume *volume, const Main *bmain) { #ifdef WITH_OPENVDB @@ -857,6 +911,14 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) } } + /* Try to detect the velocity grid. */ + const char *common_velocity_names[] = {"velocity", "vel", "v"}; + for (const char *common_velocity_name : common_velocity_names) { + if (BKE_volume_set_velocity_grid_by_name(const_cast<Volume *>(volume), common_velocity_name)) { + break; + } + } + BLI_strncpy(grids.filepath, filepath, FILE_MAX); return grids.error_msg.empty(); diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 8544d6c9c77..ef75d3d2482 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -183,7 +183,6 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, {mesh->mloop, mesh->totloop}); BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh index 0754221eb65..98fd7d0f15d 100644 --- a/source/blender/blenlib/BLI_color.hh +++ b/source/blender/blenlib/BLI_color.hh @@ -345,5 +345,7 @@ BLI_color_convert_to_theme4b(const ColorSceneLinear4f<eAlpha::Straight> &scene_l using ColorGeometry4f = ColorSceneLinear4f<eAlpha::Premultiplied>; using ColorGeometry4b = ColorSceneLinearByteEncoded4b<eAlpha::Premultiplied>; +using ColorPaint4f = ColorSceneLinear4f<eAlpha::Straight>; +using ColorPaint4b = ColorSceneLinearByteEncoded4b<eAlpha::Straight>; } // namespace blender diff --git a/source/blender/blenlib/BLI_color_mix.hh b/source/blender/blenlib/BLI_color_mix.hh new file mode 100644 index 00000000000..4989ddc609e --- /dev/null +++ b/source/blender/blenlib/BLI_color_mix.hh @@ -0,0 +1,1051 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ + +/** \file + * \ingroup blenlib + * + * Contains color mixing utilities. + */ + +#include "BLI_color.hh" +#include "BLI_math_base.h" +#include "BLI_math_color.h" +#include "BLI_sys_types.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" + +#include <type_traits> + +namespace blender::color { + +struct ByteTraits { + using ValueType = uchar; + using BlendType = int; + + inline static const uchar range = 255; /* Zero-based maximum value. */ + inline static const float frange = 255.0f; /* Convenient floating-point version of range. */ + inline static const int cmpRange = 254; + inline static const int expandedRange = 256; /* One-based maximum value. */ + + inline static const int bytes = 1; + inline static const float unit = 255.0f; + + static inline BlendType divide_round(BlendType a, BlendType b) + { + return divide_round_i(a, b); + } + + static inline BlendType min(BlendType a, BlendType b) + { + return min_ii(a, b); + } + + static inline BlendType max(BlendType a, BlendType b) + { + return max_ii(a, b); + } + /* Discretizes in steps of 1.0 / range */ + static inline ValueType round(float f) + { + return round_fl_to_uchar(f); + } +}; + +struct FloatTraits { + using ValueType = float; + using BlendType = float; + + inline const static float range = 1.0f; + inline const static float frange = 1.0f; + inline const static float cmpRange = 0.9999f; + inline static const int expandedRange = 1.0f; + + inline const static float unit = 1.0f; + inline const static int bytes = 4; + + static inline BlendType divide_round(BlendType a, BlendType b) + { + return a / b; + } + + static inline BlendType min(BlendType a, BlendType b) + { + return min_ff(a, b); + } + + static inline BlendType max(BlendType a, BlendType b) + { + return min_ff(a, b); + } + + /* Discretizes in steps of 1.0 / range */ + static inline ValueType round(float f) + { + return f; + } +}; + +static float get_luminance(ColorPaint4f c) +{ + return IMB_colormanagement_get_luminance(&c.r); +} + +static int get_luminance(ColorPaint4b c) +{ + return IMB_colormanagement_get_luminance_byte(&c.r); +} + +#define EPS_SATURATION 0.0005f + +/* -------------------------------------------------------------------- */ +/** \name Color Blending Modes + * \{ */ + +template<typename Color, typename Traits> +static Color mix_blend(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Color col_mix(0, 0, 0, 0); + Blend mfac; + + if (fac == 0) { + return col_src; + } + + if (fac >= Traits::range) { + return col_dst; + } + + mfac = Traits::range - fac; + + cp_src = &col_src.r; + cp_dst = &col_dst.r; + cp_mix = &col_mix.r; + + /* Updated to use the rgb squared color model which blends nicer. */ + Blend r1 = cp_src[0] * cp_src[0]; + Blend g1 = cp_src[1] * cp_src[1]; + Blend b1 = cp_src[2] * cp_src[2]; + Blend a1 = cp_src[3] * cp_src[3]; + + Blend r2 = cp_dst[0] * cp_dst[0]; + Blend g2 = cp_dst[1] * cp_dst[1]; + Blend b2 = cp_dst[2] * cp_dst[2]; + Blend a2 = cp_dst[3] * cp_dst[3]; + + cp_mix[0] = Traits::round(sqrtf(Traits::divide_round((mfac * r1 + fac * r2), Traits::range))); + cp_mix[1] = Traits::round(sqrtf(Traits::divide_round((mfac * g1 + fac * g2), Traits::range))); + cp_mix[2] = Traits::round(sqrtf(Traits::divide_round((mfac * b1 + fac * b2), Traits::range))); + cp_mix[3] = Traits::round(sqrtf(Traits::divide_round((mfac * a1 + fac * a2), Traits::range))); + return Color(col_mix[0], col_mix[1], col_mix[2], col_mix[3]); + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_add(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + cp_src = (Value *)&col_src.r; + cp_dst = (Value *)&col_dst.r; + cp_mix = (Value *)&col_mix.r; + + temp = cp_src[0] + Traits::divide_round((fac * cp_dst[0]), Traits::range); + cp_mix[0] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[1] + Traits::divide_round((fac * cp_dst[1]), Traits::range); + cp_mix[1] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[2] + Traits::divide_round((fac * cp_dst[2]), Traits::range); + cp_mix[2] = (temp > Traits::cmpRange) ? Traits::range : temp; + temp = cp_src[3] + Traits::divide_round((fac * cp_dst[3]), Traits::range); + cp_mix[3] = (temp > Traits::cmpRange) ? Traits::range : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_sub(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend temp; + Color col_mix(0, 0, 0, 0); + + cp_src = (Value *)&col_src.r; + cp_dst = (Value *)&col_dst.r; + cp_mix = (Value *)&col_mix.r; + + temp = cp_src[0] - Traits::divide_round((fac * cp_dst[0]), Traits::range); + cp_mix[0] = (temp < 0) ? 0 : temp; + temp = cp_src[1] - Traits::divide_round((fac * cp_dst[1]), Traits::range); + cp_mix[1] = (temp < 0) ? 0 : temp; + temp = cp_src[2] - Traits::divide_round((fac * cp_dst[2]), Traits::range); + cp_mix[2] = (temp < 0) ? 0 : temp; + temp = cp_src[3] - Traits::divide_round((fac * cp_dst[3]), Traits::range); + cp_mix[3] = (temp < 0) ? 0 : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_mul(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* first mul, then blend the fac */ + cp_mix[0] = Traits::divide_round(mfac * cp_src[0] * Traits::range + fac * cp_dst[0] * cp_src[0], + Traits::range * Traits::range); + cp_mix[1] = Traits::divide_round(mfac * cp_src[1] * Traits::range + fac * cp_dst[1] * cp_src[1], + Traits::range * Traits::range); + cp_mix[2] = Traits::divide_round(mfac * cp_src[2] * Traits::range + fac * cp_dst[2] * cp_src[2], + Traits::range * Traits::range); + cp_mix[3] = Traits::divide_round(mfac * cp_src[3] * Traits::range + fac * cp_dst[3] * cp_src[3], + Traits::range * Traits::range); + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_lighten(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + if (fac >= Traits::range) { + return col_dst; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* See if we're lighter, if so mix, else don't do anything. + * if the paint color is darker then the original, then ignore */ + if (get_luminance(cp_src) > get_luminance(cp_dst)) { + return col_src; + } + + cp_mix[0] = Traits::divide_round(mfac * cp_src[0] + fac * cp_dst[0], Traits::range); + cp_mix[1] = Traits::divide_round(mfac * cp_src[1] + fac * cp_dst[1], Traits::range); + cp_mix[2] = Traits::divide_round(mfac * cp_src[2] + fac * cp_dst[2], Traits::range); + cp_mix[3] = Traits::divide_round(mfac * cp_src[3] + fac * cp_dst[3], Traits::range); + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_darken(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + if (fac >= Traits::range) { + return col_dst; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* See if we're darker, if so mix, else don't do anything. + * if the paint color is brighter then the original, then ignore */ + if (get_luminance(cp_src) < get_luminance(cp_dst)) { + return col_src; + } + + cp_mix[0] = Traits::divide_round((mfac * cp_src[0] + fac * cp_dst[0]), Traits::range); + cp_mix[1] = Traits::divide_round((mfac * cp_src[1] + fac * cp_dst[1]), Traits::range); + cp_mix[2] = Traits::divide_round((mfac * cp_src[2] + fac * cp_dst[2]), Traits::range); + cp_mix[3] = Traits::divide_round((mfac * cp_src[3] + fac * cp_dst[3]), Traits::range); + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_colordodge(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + Blend dodgefac = (Blend)((float)Traits::range * 0.885f); /* ~225/255 */ + + temp = (cp_dst[0] == Traits::range) ? + Traits::range : + Traits::min((cp_src[0] * dodgefac) / (Traits::range - cp_dst[0]), Traits::range); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / Traits::range; + temp = (cp_dst[1] == Traits::range) ? + Traits::range : + Traits::min((cp_src[1] * dodgefac) / (Traits::range - cp_dst[1]), Traits::range); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / Traits::range; + temp = (cp_dst[2] == Traits::range) ? + Traits::range : + Traits::min((cp_src[2] * dodgefac) / (Traits::range - cp_dst[2]), Traits::range); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / Traits::range; + temp = (cp_dst[3] == Traits::range) ? + Traits::range : + Traits::min((cp_src[3] * dodgefac) / (Traits::range - cp_dst[3]), Traits::range); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_difference(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + temp = abs(cp_src[0] - cp_dst[0]); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / Traits::range; + temp = abs(cp_src[1] - cp_dst[1]); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / Traits::range; + temp = abs(cp_src[2] - cp_dst[2]); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / Traits::range; + temp = abs(cp_src[3] - cp_dst[3]); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_screen(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + temp = Traits::max(Traits::range - (((Traits::range - cp_src[0]) * (Traits::range - cp_dst[0])) / + Traits::range), + 0); + cp_mix[0] = (mfac * cp_src[0] + temp * fac) / Traits::range; + temp = Traits::max(Traits::range - (((Traits::range - cp_src[1]) * (Traits::range - cp_dst[1])) / + Traits::range), + 0); + cp_mix[1] = (mfac * cp_src[1] + temp * fac) / Traits::range; + temp = Traits::max(Traits::range - (((Traits::range - cp_src[2]) * (Traits::range - cp_dst[2])) / + Traits::range), + 0); + cp_mix[2] = (mfac * cp_src[2] + temp * fac) / Traits::range; + temp = Traits::max(Traits::range - (((Traits::range - cp_src[3]) * (Traits::range - cp_dst[3])) / + Traits::range), + 0); + cp_mix[3] = (mfac * cp_src[3] + temp * fac) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_hardlight(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp_dst[i] > (Traits::range / 2)) { + temp = Traits::range - ((Traits::range - 2 * (cp_dst[i] - (Traits::range / 2))) * + (Traits::range - cp_src[i]) / Traits::range); + } + else { + temp = (2 * cp_dst[i] * cp_src[i]) / Traits::expandedRange; + } + cp_mix[i] = Traits::min((mfac * cp_src[i] + temp * fac) / Traits::range, Traits::range); + } + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_overlay(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + if (cp_src[i] > (Traits::range / 2)) { + temp = Traits::range - ((Traits::range - 2 * (cp_src[i] - (Traits::range / 2))) * + (Traits::range - cp_dst[i]) / Traits::range); + } + else { + temp = (2 * cp_dst[i] * cp_src[i]) / Traits::expandedRange; + } + cp_mix[i] = Traits::min((mfac * cp_src[i] + temp * fac) / Traits::range, Traits::range); + } + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_softlight(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + /* Use divide_round so we don't alter original byte equations. */ + const int add = Traits::divide_round(Traits::range, 4); + + for (int i = 0; i < 4; i++) { + if (cp_src[i] < (Traits::range / 2)) { + temp = ((2 * ((cp_dst[i] / 2) + add)) * cp_src[i]) / Traits::range; + } + else { + temp = Traits::range - (2 * (Traits::range - ((cp_dst[i] / 2) + add)) * + (Traits::range - cp_src[i]) / Traits::range); + } + cp_mix[i] = (temp * fac + cp_src[i] * mfac) / Traits::range; + } + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_exclusion(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac, temp; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + int i = 0; + + for (i = 0; i < 4; i++) { + temp = (Traits::range / 2) - + ((2 * (cp_src[i] - (Traits::range / 2)) * (cp_dst[i] - (Traits::range / 2))) / + Traits::range); + cp_mix[i] = (temp * fac + cp_src[i] * mfac) / Traits::range; + } + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_luminosity(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / Traits::frange, + cp_src[1] / Traits::frange, + cp_src[2] / Traits::frange, + &h1, + &s1, + &v1); + rgb_to_hsv(cp_dst[0] / Traits::frange, + cp_dst[1] / Traits::frange, + cp_dst[2] / Traits::frange, + &h2, + &s2, + &v2); + + v1 = v2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp_mix[0] = ((Blend)(r * Traits::frange) * fac + mfac * cp_src[0]) / Traits::range; + cp_mix[1] = ((Blend)(g * Traits::frange) * fac + mfac * cp_src[1]) / Traits::range; + cp_mix[2] = ((Blend)(b * Traits::frange) * fac + mfac * cp_src[2]) / Traits::range; + cp_mix[3] = ((Blend)(cp_dst[3]) * fac + mfac * cp_src[3]) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_saturation(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / Traits::frange, + cp_src[1] / Traits::frange, + cp_src[2] / Traits::frange, + &h1, + &s1, + &v1); + rgb_to_hsv(cp_dst[0] / Traits::frange, + cp_dst[1] / Traits::frange, + cp_dst[2] / Traits::frange, + &h2, + &s2, + &v2); + + if (s1 > EPS_SATURATION) { + s1 = s2; + } + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp_mix[0] = ((Blend)(r * Traits::frange) * fac + mfac * cp_src[0]) / Traits::range; + cp_mix[1] = ((Blend)(g * Traits::frange) * fac + mfac * cp_src[1]) / Traits::range; + cp_mix[2] = ((Blend)(b * Traits::frange) * fac + mfac * cp_src[2]) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_hue(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + rgb_to_hsv(cp_src[0] / Traits::frange, + cp_src[1] / Traits::frange, + cp_src[2] / Traits::frange, + &h1, + &s1, + &v1); + rgb_to_hsv(cp_dst[0] / Traits::frange, + cp_dst[1] / Traits::frange, + cp_dst[2] / Traits::frange, + &h2, + &s2, + &v2); + + h1 = h2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp_mix[0] = ((Blend)(r * Traits::frange) * fac + mfac * cp_src[0]) / Traits::range; + cp_mix[1] = ((Blend)(g * Traits::frange) * fac + mfac * cp_src[1]) / Traits::range; + cp_mix[2] = ((Blend)(b * Traits::frange) * fac + mfac * cp_src[2]) / Traits::range; + cp_mix[3] = ((Blend)(cp_dst[3]) * fac + mfac * cp_src[3]) / Traits::range; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_alpha_add(Color col_src, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_mix; + Blend temp; + Color col_mix = col_src; + + if (fac == 0) { + return col_src; + } + + cp_src = (Value *)&col_src; + cp_mix = (Value *)&col_mix; + + temp = cp_src[3] + fac; + cp_mix[3] = (temp > Traits::cmpRange) ? Traits::range : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_alpha_sub(Color col_src, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_mix; + Blend temp; + Color col_mix = col_src; + + if (fac == 0) { + return col_src; + } + + cp_src = (Value *)&col_src; + cp_mix = (Value *)&col_mix; + + temp = cp_src[3] - fac; + cp_mix[3] = temp < 0 ? 0 : temp; + + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_pinlight(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + const Blend cmp = Traits::range / 2; + + int i = 3; + Blend temp; + + while (i--) { + if (cp_dst[i] > cmp) { + temp = Traits::max(2 * (cp_dst[i] - cmp), cp_src[i]); + } + else { + temp = Traits::min(2 * cp_dst[i], cp_src[i]); + } + cp_mix[i] = (Value)((Traits::min(temp, Traits::range) * fac + cp_src[i] * mfac) / + Traits::range); + } + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_linearlight(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + const Blend cmp = Traits::range / 2; + + int i = 3; + while (i--) { + Blend temp; + + if (cp_dst[i] > cmp) { + temp = Traits::min(cp_src[i] + 2 * (cp_dst[i] - cmp), Traits::range); + } + else { + temp = Traits::max(cp_src[i] + 2 * cp_dst[i] - Traits::range, 0); + } + + cp_mix[i] = (Value)((temp * fac + cp_src[i] * mfac) / Traits::range); + } + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_vividlight(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + + const Blend cmp = Traits::range / 2; + + int i = 3; + + while (i--) { + Blend temp; + + if (cp_dst[i] == Traits::range) { + temp = (cp_src[i] == 0) ? cmp : Traits::range; + } + else if (cp_dst[i] == 0) { + temp = (cp_src[i] == Traits::range) ? cmp : 0; + } + else if (cp_dst[i] > cmp) { + temp = Traits::min(((cp_src[i]) * Traits::range) / (2 * (Traits::range - cp_dst[i])), + Traits::range); + } + else { + temp = Traits::max( + Traits::range - ((Traits::range - cp_src[i]) * Traits::range / (2 * cp_dst[i])), 0); + } + col_mix[i] = (Value)((temp * fac + cp_src[i] * mfac) / Traits::range); + } + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_color(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + float h1, s1, v1; + float h2, s2, v2; + float r, g, b; + + rgb_to_hsv(cp_src[0] / Traits::frange, + cp_src[1] / Traits::frange, + cp_src[2] / Traits::frange, + &h1, + &s1, + &v1); + rgb_to_hsv(cp_dst[0] / Traits::frange, + cp_dst[1] / Traits::frange, + cp_dst[2] / Traits::frange, + &h2, + &s2, + &v2); + + h1 = h2; + s1 = s2; + + hsv_to_rgb(h1, s1, v1, &r, &g, &b); + + cp_mix[0] = (Value)(((Blend)(r * Traits::frange) * fac + cp_src[0] * mfac) / Traits::range); + cp_mix[1] = (Value)(((Blend)(g * Traits::frange) * fac + cp_src[1] * mfac) / Traits::range); + cp_mix[2] = (Value)(((Blend)(b * Traits::frange) * fac + cp_src[2] * mfac) / Traits::range); + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_colorburn(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + int i = 3; + + while (i--) { + const Blend temp = + (cp_dst[i] == 0) ? + 0 : + Traits::max(Traits::range - ((Traits::range - cp_src[i]) * Traits::range) / cp_dst[i], + 0); + cp_mix[i] = (Value)((temp * fac + cp_src[i] * mfac) / Traits::range); + } + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +static Color mix_linearburn(Color col_src, Color col_dst, typename Traits::BlendType fac) +{ + using Value = typename Traits::ValueType; + using Blend = typename Traits::BlendType; + + Value *cp_src, *cp_dst, *cp_mix; + Blend mfac; + Color col_mix(0, 0, 0, 0); + + if (fac == 0) { + return col_src; + } + + mfac = Traits::range - fac; + + cp_src = (Value *)&col_src; + cp_dst = (Value *)&col_dst; + cp_mix = (Value *)&col_mix; + + int i = 3; + + while (i--) { + const Blend temp = Traits::max(cp_src[i] + cp_dst[i] - Traits::range, 0); + cp_mix[i] = (Value)((temp * fac + cp_src[i] * mfac) / Traits::range); + } + + col_mix.a = col_src.a; + return col_mix; +} + +template<typename Color, typename Traits> +BLI_INLINE Color BLI_mix_colors(const IMB_BlendMode tool, + const Color a, + const Color b, + const typename Traits::BlendType alpha) +{ + switch ((IMB_BlendMode)tool) { + case IMB_BLEND_MIX: + return mix_blend<Color, Traits>(a, b, alpha); + case IMB_BLEND_ADD: + return mix_add<Color, Traits>(a, b, alpha); + case IMB_BLEND_SUB: + return mix_sub<Color, Traits>(a, b, alpha); + case IMB_BLEND_MUL: + return mix_mul<Color, Traits>(a, b, alpha); + case IMB_BLEND_LIGHTEN: + return mix_lighten<Color, Traits>(a, b, alpha); + case IMB_BLEND_DARKEN: + return mix_darken<Color, Traits>(a, b, alpha); + case IMB_BLEND_COLORDODGE: + return mix_colordodge<Color, Traits>(a, b, alpha); + case IMB_BLEND_COLORBURN: + return mix_colorburn<Color, Traits>(a, b, alpha); + case IMB_BLEND_DIFFERENCE: + return mix_difference<Color, Traits>(a, b, alpha); + case IMB_BLEND_SCREEN: + return mix_screen<Color, Traits>(a, b, alpha); + case IMB_BLEND_HARDLIGHT: + return mix_hardlight<Color, Traits>(a, b, alpha); + case IMB_BLEND_OVERLAY: + return mix_overlay<Color, Traits>(a, b, alpha); + case IMB_BLEND_SOFTLIGHT: + return mix_softlight<Color, Traits>(a, b, alpha); + case IMB_BLEND_EXCLUSION: + return mix_exclusion<Color, Traits>(a, b, alpha); + case IMB_BLEND_LUMINOSITY: + return mix_luminosity<Color, Traits>(a, b, alpha); + case IMB_BLEND_SATURATION: + return mix_saturation<Color, Traits>(a, b, alpha); + case IMB_BLEND_HUE: + return mix_hue<Color, Traits>(a, b, alpha); + /* non-color */ + case IMB_BLEND_ERASE_ALPHA: + return mix_alpha_sub<Color, Traits>(a, alpha); + case IMB_BLEND_ADD_ALPHA: + return mix_alpha_add<Color, Traits>(a, alpha); + case IMB_BLEND_PINLIGHT: + return mix_pinlight<Color, Traits>(a, b, alpha); + case IMB_BLEND_LINEARLIGHT: + return mix_linearlight<Color, Traits>(a, b, alpha); + case IMB_BLEND_VIVIDLIGHT: + return mix_vividlight<Color, Traits>(a, b, alpha); + case IMB_BLEND_COLOR: + return mix_color<Color, Traits>(a, b, alpha); + default: + BLI_assert(0); + return Color(0, 0, 0, 0); + } +} +/** \} */ + +} // namespace blender::color diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index 4aed1caf796..2e756e912f9 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -854,14 +854,14 @@ template<typename T> inline GVArray::GVArray(const VArray<T> &varray) if (varray.may_have_ownership()) { *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); } - else if (varray.is_span()) { - Span<T> data = varray.get_internal_span(); - *this = GVArray::ForSpan(data); - } else if (varray.is_single()) { T value = varray.get_internal_single(); *this = GVArray::ForSingle(CPPType::get<T>(), varray.size(), &value); } + else if (varray.is_span()) { + Span<T> data = varray.get_internal_span(); + *this = GVArray::ForSpan(data); + } else { *this = GVArray::For<GVArrayImpl_For_VArray<T>>(varray); } @@ -880,15 +880,15 @@ template<typename T> inline VArray<T> GVArray::typed() const if (this->may_have_ownership()) { return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); } - if (this->is_span()) { - const Span<T> span = this->get_internal_span().typed<T>(); - return VArray<T>::ForSpan(span); - } if (this->is_single()) { T value; this->get_internal_single(&value); return VArray<T>::ForSingle(value, this->size()); } + if (this->is_span()) { + const Span<T> span = this->get_internal_span().typed<T>(); + return VArray<T>::ForSpan(span); + } return VArray<T>::template For<VArrayImpl_For_GVArray<T>>(*this); } diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 83f414f853a..81f5343056e 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -102,7 +102,10 @@ template<typename T, BLI_ENABLE_IF((is_math_float_type<T>))> inline T fract(cons return a - std::floor(a); } -template<typename T, typename FactorT, BLI_ENABLE_IF((is_math_float_type<FactorT>))> +template<typename T, + typename FactorT, + BLI_ENABLE_IF((std::is_arithmetic_v<T>)), + BLI_ENABLE_IF((is_math_float_type<FactorT>))> inline T interpolate(const T &a, const T &b, const FactorT &t) { return a * (1 - t) + b * t; diff --git a/source/blender/blenlib/BLI_math_color.hh b/source/blender/blenlib/BLI_math_color.hh index 5195cfb6238..b16053509cf 100644 --- a/source/blender/blenlib/BLI_math_color.hh +++ b/source/blender/blenlib/BLI_math_color.hh @@ -15,9 +15,22 @@ namespace blender::math { -inline ColorGeometry4f interpolate(const ColorGeometry4f &a, - const ColorGeometry4f &b, - const float t) +template<eAlpha Alpha> +inline ColorSceneLinear4f<Alpha> interpolate(const ColorSceneLinear4f<Alpha> &a, + const ColorSceneLinear4f<Alpha> &b, + const float t) +{ + return {math::interpolate(a.r, b.r, t), + math::interpolate(a.g, b.g, t), + math::interpolate(a.b, b.b, t), + math::interpolate(a.a, b.a, t)}; +} + +template<eAlpha Alpha> +inline ColorSceneLinearByteEncoded4b<Alpha> interpolate( + const ColorSceneLinearByteEncoded4b<Alpha> &a, + const ColorSceneLinearByteEncoded4b<Alpha> &b, + const float t) { return {math::interpolate(a.r, b.r, t), math::interpolate(a.g, b.g, t), diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index 0850864d86f..e36bbedee32 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -201,6 +201,14 @@ template<typename T, int Size> struct vec_base : public vec_struct_base<T, Size> } } + template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))> + explicit vec_base(const U *ptr) + { + for (int i = 0; i < Size; i++) { + (*this)[i] = ptr[i]; + } + } + vec_base(const T (*ptr)[Size]) : vec_base(static_cast<const T *>(ptr[0])) { } diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 27bb04f5796..453ca67b1e0 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -780,9 +780,6 @@ template<typename T> class VArrayCommon { Span<T> get_internal_span() const { BLI_assert(this->is_span()); - if (this->is_empty()) { - return {}; - } return impl_->get_internal_span(); } @@ -800,9 +797,6 @@ template<typename T> class VArrayCommon { T get_internal_single() const { BLI_assert(this->is_single()); - if (impl_->size() == 1) { - return impl_->get(0); - } return impl_->get_internal_single(); } diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index e8a3851e082..446a027b03b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -171,6 +171,7 @@ set(SRC BLI_boxpack_2d.h BLI_buffer.h BLI_color.hh + BLI_color_mix.hh BLI_compiler_attrs.h BLI_compiler_compat.h BLI_compiler_typecheck.h diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 26a0479f445..5ca6fe2efd0 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -301,56 +301,60 @@ static bool delete_soft(const wchar_t *path_16, const char **error_message) /* Deletes file or directory to recycling bin. The latter moves all contained files and * directories recursively to the recycling bin as well. */ IFileOperation *pfo; - IShellItem *pSI; + IShellItem *psi; HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - if (FAILED(hr)) { - *error_message = "Failed to initialize COM"; - goto error_1; - } - - hr = CoCreateInstance( - &CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, (void **)&pfo); - if (FAILED(hr)) { - *error_message = "Failed to create FileOperation instance"; - goto error_2; - } - - /* Flags for deletion: - * FOF_ALLOWUNDO: Enables moving file to recycling bin. - * FOF_SILENT: Don't show progress dialog box. - * FOF_WANTNUKEWARNING: Show dialog box if file can't be moved to recycling bin. */ - hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING); - - if (FAILED(hr)) { - *error_message = "Failed to set operation flags"; - goto error_2; - } - - hr = SHCreateItemFromParsingName(path_16, NULL, &IID_IShellItem, (void **)&pSI); - if (FAILED(hr)) { - *error_message = "Failed to parse path"; - goto error_2; - } - - hr = pfo->lpVtbl->DeleteItem(pfo, pSI, NULL); - if (FAILED(hr)) { - *error_message = "Failed to prepare delete operation"; - goto error_2; + if (SUCCEEDED(hr)) { + /* This is also the case when COM was previously initialized and CoInitializeEx returns + * S_FALSE, which is not an error. Both HRESULT values S_OK and S_FALSE indicate success. */ + + hr = CoCreateInstance( + &CLSID_FileOperation, NULL, CLSCTX_ALL, &IID_IFileOperation, (void **)&pfo); + + if (SUCCEEDED(hr)) { + /* Flags for deletion: + * FOF_ALLOWUNDO: Enables moving file to recycling bin. + * FOF_SILENT: Don't show progress dialog box. + * FOF_WANTNUKEWARNING: Show dialog box if file can't be moved to recycling bin. */ + hr = pfo->lpVtbl->SetOperationFlags(pfo, FOF_ALLOWUNDO | FOF_SILENT | FOF_WANTNUKEWARNING); + + if (SUCCEEDED(hr)) { + hr = SHCreateItemFromParsingName(path_16, NULL, &IID_IShellItem, (void **)&psi); + + if (SUCCEEDED(hr)) { + hr = pfo->lpVtbl->DeleteItem(pfo, psi, NULL); + + if (SUCCEEDED(hr)) { + hr = pfo->lpVtbl->PerformOperations(pfo); + + if (FAILED(hr)) { + *error_message = "Failed to prepare delete operation"; + } + } + else { + *error_message = "Failed to prepare delete operation"; + } + psi->lpVtbl->Release(psi); + } + else { + *error_message = "Failed to parse path"; + } + } + else { + *error_message = "Failed to set operation flags"; + } + pfo->lpVtbl->Release(pfo); + } + else { + *error_message = "Failed to create FileOperation instance"; + } + CoUninitialize(); } - - hr = pfo->lpVtbl->PerformOperations(pfo); - - if (FAILED(hr)) { - *error_message = "Failed to delete file or directory"; + else { + *error_message = "Failed to initialize COM"; } -error_2: - pfo->lpVtbl->Release(pfo); - CoUninitialize(); /* Has to be uninitialized when CoInitializeEx returns either S_OK or S_FALSE - */ -error_1: return FAILED(hr); } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index 655dc297c35..e4a93762da4 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -357,7 +357,7 @@ static void do_versions_mesh_mloopcol_swap_2_62_1(Mesh *me) for (a = 0; a < me->ldata.totlayer; a++) { layer = &me->ldata.layers[a]; - if (layer->type == CD_MLOOPCOL) { + if (layer->type == CD_PROP_BYTE_COLOR) { mloopcol = (MLoopCol *)layer->data; for (i = 0; i < me->totloop; i++, mloopcol++) { SWAP(uchar, mloopcol->r, mloopcol->b); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 0996b35c8ea..d992d426b9a 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1620,11 +1620,6 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) /* Deprecated, only kept for conversion. */ BKE_mesh_tessface_clear(me); - - /* Moved from do_versions because we need updated polygons for calculating normals. */ - if (!MAIN_VERSION_ATLEAST(bmain, 256, 6)) { - BKE_mesh_calc_normals(me); - } } } @@ -1931,7 +1926,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - /* Grease pencil multiframe falloff curve */ + /* Grease pencil multi-frame falloff curve. */ if (!DNA_struct_elem_find( fd->filesdna, "GP_Sculpt_Settings", "CurveMapping", "cur_falloff")) { for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c index ec60183218c..f0055fb73ac 100644 --- a/source/blender/blenloader/intern/versioning_300.c +++ b/source/blender/blenloader/intern/versioning_300.c @@ -2448,6 +2448,54 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + /* Rebuild active/render color attribute references. */ + if (!MAIN_VERSION_ATLEAST(bmain, 302, 6)) { + LISTBASE_FOREACH (Brush *, br, &bmain->brushes) { + /* buggy code in wm_toolsystem broke smear in old files, + reset to defaults */ + if (br->sculpt_tool == SCULPT_TOOL_SMEAR) { + br->alpha = 1.0f; + br->spacing = 5; + br->flag &= ~BRUSH_ALPHA_PRESSURE; + br->flag &= ~BRUSH_SPACE_ATTEN; + br->curve_preset = BRUSH_CURVE_SPHERE; + } + } + + LISTBASE_FOREACH (Mesh *, me, &bmain->meshes) { + for (int step = 0; step < 2; step++) { + CustomDataLayer *actlayer = NULL; + + int vact1, vact2; + + if (step) { + vact1 = CustomData_get_render_layer_index(&me->vdata, CD_PROP_COLOR); + vact2 = CustomData_get_render_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); + } + else { + vact1 = CustomData_get_active_layer_index(&me->vdata, CD_PROP_COLOR); + vact2 = CustomData_get_active_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); + } + + if (vact1 != -1) { + actlayer = me->vdata.layers + vact1; + } + else if (vact2 != -1) { + actlayer = me->ldata.layers + vact2; + } + + if (actlayer) { + if (step) { + BKE_id_attributes_render_color_set(&me->id, actlayer); + } + else { + BKE_id_attributes_active_color_set(&me->id, actlayer); + } + } + } + } + } + if (!MAIN_VERSION_ATLEAST(bmain, 302, 7)) { /* Generate 'system' liboverrides IDs. * NOTE: This is a fairly rough process, based on very basic heuristics. Should be enough for a @@ -2481,12 +2529,6 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) brush->curves_sculpt_settings = MEM_callocN(sizeof(BrushCurvesSculptSettings), __func__); brush->curves_sculpt_settings->add_amount = 1; } - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - if (scene->toolsettings && scene->toolsettings->curves_sculpt && - scene->toolsettings->curves_sculpt->curve_length == 0.0f) { - scene->toolsettings->curves_sculpt->curve_length = 0.3f; - } - } for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { @@ -2590,11 +2632,11 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) if (step) { vact1 = CustomData_get_render_layer_index(&me->vdata, CD_PROP_COLOR); - vact2 = CustomData_get_render_layer_index(&me->ldata, CD_MLOOPCOL); + vact2 = CustomData_get_render_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); } else { vact1 = CustomData_get_active_layer_index(&me->vdata, CD_PROP_COLOR); - vact2 = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL); + vact2 = CustomData_get_active_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); } if (vact1 != -1) { @@ -2689,5 +2731,15 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { + BrushCurvesSculptSettings *settings = brush->curves_sculpt_settings; + if (settings == NULL) { + continue; + } + if (settings->curve_length == 0.0f) { + settings->curve_length = 0.3f; + } + } } } diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index b9491a4913b..0246850123a 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -506,6 +506,17 @@ typedef bool (*BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_ #define BM_ELEM_CD_GET_INT(ele, offset) \ (BLI_assert(offset != -1), *((int *)((char *)(ele)->head.data + (offset)))) +#define BM_ELEM_CD_SET_BOOL(ele, offset, f) \ + { \ + CHECK_TYPE_NONCONST(ele); \ + BLI_assert(offset != -1); \ + *((bool *)((char *)(ele)->head.data + (offset))) = (f); \ + } \ + (void)0 + +#define BM_ELEM_CD_GET_BOOL(ele, offset) \ + (BLI_assert(offset != -1), *((bool *)((char *)(ele)->head.data + (offset)))) + #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) # define BM_ELEM_CD_GET_VOID_P(ele, offset) \ (BLI_assert(offset != -1), \ @@ -530,6 +541,64 @@ typedef bool (*BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_ #define BM_ELEM_CD_GET_FLOAT(ele, offset) \ (BLI_assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset)))) +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) + +# define BM_ELEM_CD_GET_FLOAT_P(ele, offset) \ + (BLI_assert(offset != -1), \ + _Generic(ele, \ + GENERIC_TYPE_ANY((float *)POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_NONCONST), \ + GENERIC_TYPE_ANY((const float *)POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_CONST))) + +# define BM_ELEM_CD_GET_FLOAT2_P(ele, offset) \ + (BLI_assert(offset != -1), \ + _Generic(ele, \ + GENERIC_TYPE_ANY((float(*)[2])POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_NONCONST), \ + GENERIC_TYPE_ANY((const float(*)[2])POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_CONST))) + +# define BM_ELEM_CD_GET_FLOAT3_P(ele, offset) \ + (BLI_assert(offset != -1), \ + _Generic(ele, \ + GENERIC_TYPE_ANY((float(*)[3])POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_NONCONST), \ + GENERIC_TYPE_ANY((const float(*)[3])POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_CONST))) + +#else + +# define BM_ELEM_CD_GET_FLOAT_P(ele, offset) \ + (BLI_assert(offset != -1), (float *)((char *)(ele)->head.data + (offset))) + +# define BM_ELEM_CD_GET_FLOAT2_P(ele, offset) \ + (BLI_assert(offset != -1), (float(*)[2])((char *)(ele)->head.data + (offset))) + +# define BM_ELEM_CD_GET_FLOAT3_P(ele, offset) \ + (BLI_assert(offset != -1), (float(*)[3])((char *)(ele)->head.data + (offset))) + +#endif + +#define BM_ELEM_CD_SET_FLOAT2(ele, offset, f) \ + { \ + CHECK_TYPE_NONCONST(ele); \ + BLI_assert(offset != -1); \ + ((float *)((char *)(ele)->head.data + (offset)))[0] = (f)[0]; \ + ((float *)((char *)(ele)->head.data + (offset)))[1] = (f)[1]; \ + } \ + (void)0 + +#define BM_ELEM_CD_SET_FLOAT3(ele, offset, f) \ + { \ + CHECK_TYPE_NONCONST(ele); \ + BLI_assert(offset != -1); \ + ((float *)((char *)(ele)->head.data + (offset)))[0] = (f)[0]; \ + ((float *)((char *)(ele)->head.data + (offset)))[1] = (f)[1]; \ + ((float *)((char *)(ele)->head.data + (offset)))[2] = (f)[2]; \ + } \ + (void)0 + #define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \ (BLI_assert(offset != -1), (uchar)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f)) diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 35614069f96..aa7f0f511ec 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -282,7 +282,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) delimit_data.cdata[delimit_data.cdata_len].cd_offset = -1; if (BMO_slot_bool_get(op->slots_in, "cmp_vcols") && bm_edge_delimit_cdata( - &bm->ldata, CD_MLOOPCOL, &delimit_data.cdata[delimit_data.cdata_len])) { + &bm->ldata, CD_PROP_BYTE_COLOR, &delimit_data.cdata[delimit_data.cdata_len])) { delimit_data.cdata_len += 1; } diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index be5521d45ab..8f32f878c58 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -675,7 +675,7 @@ static BMFace *bev_create_ngon(BMesh *bm, const int totv, BMFace **face_arr, BMFace *facerep, - BMEdge **edge_arr, + BMEdge **snap_edge_arr, int mat_nr, bool do_interp) { @@ -699,8 +699,8 @@ static BMFace *bev_create_ngon(BMesh *bm, } if (interp_f) { BMEdge *bme = NULL; - if (edge_arr) { - bme = edge_arr[i]; + if (snap_edge_arr) { + bme = snap_edge_arr[i]; } float save_co[3]; if (bme) { @@ -734,44 +734,6 @@ static BMFace *bev_create_ngon(BMesh *bm, return f; } -static BMFace *bev_create_quad(BMesh *bm, - BMVert *v1, - BMVert *v2, - BMVert *v3, - BMVert *v4, - BMFace *f1, - BMFace *f2, - BMFace *f3, - BMFace *f4, - int mat_nr) -{ - BMVert *varr[4] = {v1, v2, v3, v4}; - BMFace *farr[4] = {f1, f2, f3, f4}; - return bev_create_ngon(bm, varr, 4, farr, f1, NULL, mat_nr, true); -} - -static BMFace *bev_create_quad_ex(BMesh *bm, - BMVert *v1, - BMVert *v2, - BMVert *v3, - BMVert *v4, - BMFace *f1, - BMFace *f2, - BMFace *f3, - BMFace *f4, - BMEdge *e1, - BMEdge *e2, - BMEdge *e3, - BMEdge *e4, - BMFace *frep, - int mat_nr) -{ - BMVert *varr[4] = {v1, v2, v3, v4}; - BMFace *farr[4] = {f1, f2, f3, f4}; - BMEdge *earr[4] = {e1, e2, e3, e4}; - return bev_create_ngon(bm, varr, 4, farr, frep, earr, mat_nr, true); -} - /* Is Loop layer layer_index contiguous across shared vertex of l1 and l2? */ static bool contig_ldata_across_loops(BMesh *bm, BMLoop *l1, BMLoop *l2, int layer_index) { @@ -828,6 +790,25 @@ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f return true; } +/** + * In array face_component of total `totface` elements, swap values c1 and c2 + * wherever they occur. + */ +static void swap_face_components(int *face_component, int totface, int c1, int c2) +{ + if (c1 == c2) { + return; /* Nothing to do. */ + } + for (int f = 0; f < totface; f++) { + if (face_component[f] == c1) { + face_component[f] = c2; + } + else if (face_component[f] == c2) { + face_component[f] = c1; + } + } +} + /* * Set up the fields of bp->math_layer_info. * We always set has_math_layers to the correct value. @@ -836,6 +817,7 @@ static bool contig_ldata_across_edge(BMesh *bm, BMEdge *e, BMFace *f1, BMFace *f */ static void math_layer_info_init(BevelParams *bp, BMesh *bm) { + int f; bp->math_layer_info.has_math_layers = false; bp->math_layer_info.face_component = NULL; for (int i = 0; i < bm->ldata.totlayer; i++) { @@ -860,12 +842,12 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm) bool *in_stack = MEM_malloc_arrayN(totface, sizeof(bool), __func__); /* Set all component ids by DFS from faces with unassigned components. */ - for (int f = 0; f < totface; f++) { + for (f = 0; f < totface; f++) { face_component[f] = -1; in_stack[f] = false; } int current_component = -1; - for (int f = 0; f < totface; f++) { + for (f = 0; f < totface; f++) { if (face_component[f] == -1 && !in_stack[f]) { int stack_top = 0; current_component++; @@ -910,6 +892,44 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm) } MEM_freeN(stack); MEM_freeN(in_stack); + /* We can usually get more pleasing result if components 0 and 1 + * are the topmost and bottom-most (in z-coordinate) components, + * so adjust component indices to make that so. */ + if (current_component <= 0) { + return; /* Only one component, so no need to do this. */ + } + BMFace *top_face = NULL; + float top_face_z = -1e30f; + int top_face_component = -1; + BMFace *bot_face = NULL; + float bot_face_z = 1e30f; + int bot_face_component = -1; + for (f = 0; f < totface; f++) { + float cent[3]; + BMFace *bmf = BM_face_at_index(bm, f); + BM_face_calc_center_bounds(bmf, cent); + float fz = cent[2]; + if (fz > top_face_z) { + top_face_z = fz; + top_face = bmf; + top_face_component = face_component[f]; + } + if (fz < bot_face_z) { + bot_face_z = fz; + bot_face = bmf; + bot_face_component = face_component[f]; + } + } + BLI_assert(top_face != NULL && bot_face != NULL); + UNUSED_VARS_NDEBUG(top_face, bot_face); + swap_face_components(face_component, totface, face_component[0], top_face_component); + if (bot_face_component != top_face_component) { + if (bot_face_component == 0) { + /* It was swapped with old top_face_component. */ + bot_face_component = top_face_component; + } + swap_face_components(face_component, totface, face_component[1], bot_face_component); + } } /** @@ -3843,8 +3863,8 @@ static VMesh *new_adj_vmesh(MemArena *mem_arena, int count, int seg, BoundVert * * where ns2 = floor(nseg / 2). * But these overlap data from previous and next i: there are some forced equivalences. * Let's call these indices the canonical ones: we will just calculate data for these - * 0 <= j <= ns2, 0 <= k < ns2 (for odd ns2) - * 0 <= j < ns2, 0 <= k <= ns2 (for even ns2) + * 0 <= j <= ns2, 0 <= k <= ns2 (for odd ns) + * 0 <= j < ns2, 0 <= k <= ns2 (for even ns) * also (j=ns2, k=ns2) at i=0 (for even ns2) * This function returns the canonical one for any i, j, k in [0,n],[0,ns],[0,ns]. */ @@ -4799,46 +4819,85 @@ static BMEdge *find_closer_edge(float *co, BMEdge *e1, BMEdge *e2) return e2; } -/* Snap co to the closest edge of face f. Return the edge in *r_snap_e, - * the coordinates of snap point in r_ snap_co, - * and the distance squared to the snap point as function return */ -static float snap_face_dist_squared(float *co, BMFace *f, BMEdge **r_snap_e, float *r_snap_co) +/** + * Find which BoundVerts of \a bv are internal to face \a f. + * That is, when both the face and the point are projected to 2d, + * the point is on the boundary of or inside the projected face. + * There can only be up to three of then, since, including miters, + * that is the maximum number of BoundVerts that can be between two edges. + * Return the number of face-internal vertices found. + */ +static int find_face_internal_boundverts(const BevVert *bv, + const BMFace *f, + BoundVert *(r_internal[3])) { - BMEdge *beste = NULL; - float beste_d2 = 1e20f; - BMIter iter; - BMEdge *e; - BM_ITER_ELEM (e, &iter, f, BM_EDGES_OF_FACE) { - float closest[3]; - closest_to_line_segment_v3(closest, co, e->v1->co, e->v2->co); - float d2 = len_squared_v3v3(closest, co); - if (d2 < beste_d2) { - beste_d2 = d2; - beste = e; - copy_v3_v3(r_snap_co, closest); + if (f == NULL) { + return 0; + } + int n_internal = 0; + VMesh *vm = bv->vmesh; + BLI_assert(vm != NULL); + BoundVert *v = vm->boundstart; + do { + /* Possible speedup: do the matrix projection done by the following + * once, outside the loop, or even better, cache it if ever done + * in the course of Bevel. */ + if (BM_face_point_inside_test(f, v->nv.co)) { + r_internal[n_internal++] = v; + if (n_internal == 3) { + break; + } } + } while ((v = v->next) != vm->boundstart); + for (int i = n_internal; i < 3; i++) { + r_internal[i] = NULL; } - *r_snap_e = beste; - return beste_d2; + return n_internal; } -/* What would be the area of the polygon around bv if interpolated in face frep? +/** + * Find where the coordinates of the BndVerts in \a bv should snap to in face \a f. + * Face \a f should contain vertex `bv->v`. + * Project the snapped verts to 2d, then return the area of the resulting polygon. + * Usually one BndVert is inside the face, sometimes up to 3 (if there are miters), + * so don't snap those to an edge; all the rest snap to one of the edges of \a bmf + * incident on `bv->v`. */ -static float interp_poly_area(BevVert *bv, BMFace *frep) +static float projected_boundary_area(BevVert *bv, BMFace *f) { + BMEdge *e1, *e2; VMesh *vm = bv->vmesh; - + float(*proj_co)[2] = BLI_array_alloca(proj_co, vm->count); + float axis_mat[3][3]; + axis_dominant_v3_to_m3(axis_mat, f->no); + get_incident_edges(f, bv->v, &e1, &e2); + BLI_assert(e1 != NULL && e2 != NULL); BLI_assert(vm != NULL); - float(*uv_co)[3] = BLI_array_alloca(uv_co, vm->count); BoundVert *v = vm->boundstart; - int n = 0; + int i = 0; + BoundVert *unsnapped[3]; + find_face_internal_boundverts(bv, f, unsnapped); do { - BLI_assert(n < vm->count); - BMEdge *snape; - snap_face_dist_squared(v->nv.v->co, frep, &snape, uv_co[n]); - n++; + float *co = v->nv.v->co; + if (v == unsnapped[0] || v == unsnapped[1] || v == unsnapped[2]) { + mul_v2_m3v3(proj_co[i], axis_mat, co); + } + else { + float snap1[3], snap2[3]; + closest_to_line_segment_v3(snap1, co, e1->v1->co, e1->v2->co); + closest_to_line_segment_v3(snap2, co, e2->v1->co, e2->v2->co); + float d1_sq = len_squared_v3v3(snap1, co); + float d2_sq = len_squared_v3v3(snap2, co); + if (d1_sq <= d2_sq) { + mul_v2_m3v3(proj_co[i], axis_mat, snap1); + } + else { + mul_v2_m3v3(proj_co[i], axis_mat, snap2); + } + } + ++i; } while ((v = v->next) != vm->boundstart); - float area = fabsf(area_poly_v3(uv_co, n)); + float area = area_poly_v2(proj_co, vm->count); return area; } @@ -4851,7 +4910,8 @@ static float interp_poly_area(BevVert *bv, BMFace *frep) */ static bool is_bad_uv_poly(BevVert *bv, BMFace *frep) { - float area = interp_poly_area(bv, frep); + BLI_assert(bv->vmesh != NULL); + float area = projected_boundary_area(bv, frep); return area < BEVEL_EPSILON_BIG; } @@ -4876,6 +4936,8 @@ static BMFace *frep_for_center_poly(BevelParams *bp, BevVert *bv) bool consider_all_faces = bv->selcount == 1; /* Make an array that can hold maximum possible number of choices. */ BMFace **fchoices = BLI_array_alloca(fchoices, bv->edgecount); + /* For each choice, need to remember the unsnapped BoundVerts. */ + for (int i = 0; i < bv->edgecount; i++) { if (!bv->edges[i].is_bev && !consider_all_faces) { continue; @@ -4924,9 +4986,11 @@ static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_n int ns2 = vm->seg / 2; BMFace *frep; BMEdge *frep_e1, *frep_e2; + BoundVert *frep_unsnapped[3]; if (bv->any_seam) { frep = frep_for_center_poly(bp, bv); get_incident_edges(frep, bv->v, &frep_e1, &frep_e2); + find_face_internal_boundverts(bv, frep, frep_unsnapped); } else { frep = NULL; @@ -4938,8 +5002,13 @@ static void build_center_ngon(BevelParams *bp, BMesh *bm, BevVert *bv, int mat_n BLI_array_append(vv, mesh_vert(vm, i, ns2, ns2)->v); if (frep) { BLI_array_append(vf, frep); - BMEdge *frep_e = find_closer_edge(mesh_vert(vm, i, ns2, ns2)->v->co, frep_e1, frep_e2); - BLI_array_append(ve, v == vm->boundstart ? NULL : frep_e); + if (v == frep_unsnapped[0] || v == frep_unsnapped[1] || v == frep_unsnapped[2]) { + BLI_array_append(ve, NULL); + } + else { + BMEdge *frep_e = find_closer_edge(mesh_vert(vm, i, ns2, ns2)->v->co, frep_e1, frep_e2); + BLI_array_append(ve, frep_e); + } } else { BLI_array_append(vf, boundvert_rep_face(v, NULL)); @@ -5242,6 +5311,110 @@ static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv) return vm; } +static BMEdge *snap_edge_for_center_vmesh_vert(int i, + int n_bndv, + BMEdge *eprev, + BMEdge *enext, + BMFace **bndv_rep_faces, + BMFace *center_frep, + const bool *frep_beats_next) +{ + int previ = (i + n_bndv - 1) % n_bndv; + int nexti = (i + 1) % n_bndv; + + if (frep_beats_next[previ] && bndv_rep_faces[previ] == center_frep) { + return eprev; + } + if (!frep_beats_next[i] && bndv_rep_faces[nexti] == center_frep) { + return enext; + } + /* If n_bndv > 3 then we won't snap in the boundvert regions + * that are not directly adjacent to the center-winning boundvert. + * This is probably wrong, maybe getting UV positions outside the + * original area, but the alternative may be even worse. */ + return NULL; +} + +/** + * Fill the r_snap_edges array with the edges to snap to (or NUL, if no snapping) + * for the adj mesh face with lower left corner at (i, ring j, segment k). + * The indices of the four corners are (i,j,k), (i,j,k+1), (i,j+1,k+1), (i,j+1,k). + * The answer will be one of NULL (don't snap), eprev (the edge between + * boundvert i and boundvert i-1), or enext (the edge between boundvert i + * and boundvert i+1). + * When n is odd, the center column (seg ns2) is ambiguous as to whether it + * interpolates in the current boundvert's frep [= interpolation face] or the next one's. + * Similarly, when n is odd, the center row (ring ns2) is ambiguous as to + * whether it interpolates in the current boundvert's frep or the previous one's. + * Parameter frep_beats_next should have an array of size n_bndv of bools + * that say whether the tie should be broken in favor of the next boundvert's + * frep (if true) or the current one's. + * For vertices in the center polygon (when ns is odd), the snapping edge depends + * on where the boundvert is in relation to the boundvert that has the center face's frep, + * so the arguments bndv_rep_faces is an array of size n_bndv give the freps for each i, + * and center_frep is the frep for the center. + * + * Note: this function is for edge bevels only, at the moment. + */ +static void snap_edges_for_vmesh_vert(int i, + int j, + int k, + int ns, + int ns2, + int n_bndv, + BMEdge *eprev, + BMEdge *enext, + BMEdge *enextnext, + BMFace **bndv_rep_faces, + BMFace *center_frep, + const bool *frep_beats_next, + BMEdge *r_snap_edges[4]) +{ + BLI_assert(0 <= i && i < n_bndv && 0 <= j && j < ns2 && 0 <= k && k <= ns2); + for (int corner = 0; corner < 4; corner++) { + r_snap_edges[corner] = NULL; + if (ns % 2 == 0) { + continue; + } + int previ = (i + n_bndv - 1) % n_bndv; + /* Make jj and kk be the j and k indices for this corner. */ + int jj = corner < 2 ? j : j + 1; + int kk = (corner == 0 || corner == 3) ? k : k + 1; + if (jj < ns2 && kk < ns2) { + ; /* No snap. */ + } + else if (jj < ns2 && kk == ns2) { + /* On the left side of the center strip quads, but not on center poly. */ + if (!frep_beats_next[i]) { + r_snap_edges[corner] = enext; + } + } + else if (jj < ns2 && kk == ns2 + 1) { + /* On the right side of the center strip quads, but not on center poly. */ + if (frep_beats_next[i]) { + r_snap_edges[corner] = enext; + } + } + else if (jj == ns2 && kk < ns2) { + /* On the top of the top strip quads, but not on center poly. */ + if (frep_beats_next[previ]) { + r_snap_edges[corner] = eprev; + } + } + else if (jj == ns2 && kk == ns2) { + /* Center poly vert for boundvert i. */ + r_snap_edges[corner] = snap_edge_for_center_vmesh_vert( + i, n_bndv, eprev, enext, bndv_rep_faces, center_frep, frep_beats_next); + } + else if (jj == ns2 && kk == ns2 + 1) { + /* Center poly vert for boundvert i+1. */ + int nexti = (i + 1) % n_bndv; + r_snap_edges[corner] = snap_edge_for_center_vmesh_vert( + nexti, n_bndv, enext, enextnext, bndv_rep_faces, center_frep, frep_beats_next); + } + } +} + /** * Given that the boundary is built and the boundary #BMVert's have been made, * calculate the positions of the interior mesh points for the M_ADJ pattern, @@ -5295,17 +5468,62 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert } } vmesh_copy_equiv_verts(vm); - /* Make the polygons. */ + + /* Find and store the interpolation face for each BoundVert. */ + BMFace **bndv_rep_faces = BLI_array_alloca(bndv_rep_faces, n_bndv); BoundVert *bndv = vm->boundstart; do { int i = bndv->index; - BMFace *f = boundvert_rep_face(bndv, NULL); - BMFace *f2 = boundvert_rep_face(bndv->next, NULL); - BMFace *fchoices[2] = {f, f2}; - BMFace *fc = odd ? choose_rep_face(bp, fchoices, 2) : NULL; + bndv_rep_faces[i] = boundvert_rep_face(bndv, NULL); + } while ((bndv = bndv->next) != vm->boundstart); - EdgeHalf *e = (bp->affect_type == BEVEL_AFFECT_VERTICES) ? bndv->efirst : bndv->ebev; + /* If odd number of segments, need data to break interpolation ties. */ + BMVert **center_verts = NULL; + BMEdge **center_edge_snaps = NULL; + BMFace **center_face_interps = NULL; + bool *frep_beats_next = NULL; + BMFace *center_frep = NULL; + if (odd && bp->affect_type == BEVEL_AFFECT_EDGES) { + center_verts = BLI_array_alloca(center_verts, n_bndv); + center_edge_snaps = BLI_array_alloca(center_edge_snaps, n_bndv); + center_face_interps = BLI_array_alloca(center_face_interps, n_bndv); + frep_beats_next = BLI_array_alloca(frep_beats_next, n_bndv); + center_frep = frep_for_center_poly(bp, bv); + for (int i = 0; i < n_bndv; i++) { + center_edge_snaps[i] = NULL; + /* frep_beats_next[i] == true if frep for i is chosen over that for i + 1. */ + int inext = (i + 1) % n_bndv; + BMFace *fchoices[2] = {bndv_rep_faces[i], bndv_rep_faces[inext]}; + BMFace *fwinner = choose_rep_face(bp, fchoices, 2); + frep_beats_next[i] = fwinner == bndv_rep_faces[i]; + } + } + /* Make the polygons. */ + bndv = vm->boundstart; + do { + int i = bndv->index; + int inext = bndv->next->index; + BMFace *f = bndv_rep_faces[i]; + BMFace *f2 = bndv_rep_faces[inext]; + BMFace *fc = NULL; + if (odd && bp->affect_type == BEVEL_AFFECT_EDGES) { + fc = frep_beats_next[i] ? f : f2; + } + + EdgeHalf *e, *eprev, *enext; + if (bp->affect_type == BEVEL_AFFECT_VERTICES) { + e = bndv->efirst; + eprev = bndv->prev->efirst; + enext = bndv->next->efirst; + } + else { + e = bndv->ebev; + eprev = bndv->prev->ebev; + enext = bndv->next->ebev; + } BMEdge *bme = e ? e->e : NULL; + BMEdge *bmeprev = eprev ? eprev->e : NULL; + BMEdge *bmenext = enext ? enext->e : NULL; /* For odd ns, make polys with lower left corner at (i,j,k) for * j in [0, ns2-1], k in [0, ns2]. And then the center ngon. * For even ns, @@ -5315,77 +5533,84 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert */ for (int j = 0; j < ns2; j++) { for (int k = 0; k < ns2 + odd; k++) { + /* We will create a quad with these four corners. */ BMVert *bmv1 = mesh_vert(vm, i, j, k)->v; BMVert *bmv2 = mesh_vert(vm, i, j, k + 1)->v; BMVert *bmv3 = mesh_vert(vm, i, j + 1, k + 1)->v; BMVert *bmv4 = mesh_vert(vm, i, j + 1, k)->v; + BMVert *bmvs[4] = {bmv1, bmv2, bmv3, bmv4}; BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); - BMFace *r_f; + /* For each created quad, the UV's etc. will be interpolated + * in potentially a different face for each corner and may need + * to snap to a particular edge before interpolating. + * The fr and se arrays will be filled with the interpolation faces + * and snapping edges for the for corners in the order given + * in the bmvs array. + */ + BMFace *fr[4]; + BMEdge *se[4] = {NULL, NULL, NULL, NULL}; if (bp->affect_type == BEVEL_AFFECT_VERTICES) { + fr[0] = fr[1] = fr[2] = fr[3] = f2; if (j < k) { if (k == ns2 && j == ns2 - 1) { - r_f = bev_create_quad_ex(bm, - bmv1, - bmv2, - bmv3, - bmv4, - f2, - f2, - f2, - f2, - NULL, - NULL, - bndv->next->efirst->e, - bme, - f2, - mat_nr); - } - else { - r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); + se[2] = bndv->next->efirst->e; + se[3] = bme; } } - else if (j > k) { - r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, mat_nr); - } - else { /* j == k */ + else if (j == k) { /* Only one edge attached to v, since vertex only. */ - if (e->is_seam) { - r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f2, bme, NULL, bme, NULL, f2, mat_nr); - } - else { - r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f2, f2, f2, f, bme, NULL, bme, NULL, f2, mat_nr); + se[0] = se[2] = bme; + if (!e->is_seam) { + fr[3] = f; } } } else { /* Edge bevel. */ + fr[0] = fr[1] = fr[2] = fr[3] = f; if (odd) { + BMEdge *b1 = (eprev && eprev->is_seam) ? bmeprev : NULL; + BMEdge *b2 = (e && e->is_seam) ? bme : NULL; + BMEdge *b3 = (enext && enext->is_seam) ? bmenext : NULL; + snap_edges_for_vmesh_vert(i, + j, + k, + ns, + ns2, + n_bndv, + b1, + b2, + b3, + bndv_rep_faces, + center_frep, + frep_beats_next, + se); if (k == ns2) { - if (e && e->is_seam) { - r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, fc, fc, fc, fc, NULL, bme, bme, NULL, fc, mat_nr); + if (!e || e->is_seam) { + fr[0] = fr[1] = fr[2] = fr[3] = fc; } else { - r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f, f2, f2, f, NULL, bme, bme, NULL, fc, mat_nr); + fr[0] = fr[3] = f; + fr[1] = fr[2] = f2; + } + if (j == ns2 - 1) { + /* Use the 4th vertex of these faces as the ones used for the center polygon. */ + center_verts[i] = bmvs[3]; + center_edge_snaps[i] = se[3]; + center_face_interps[i] = bv->any_seam ? center_frep : f; } - } - else { - r_f = bev_create_quad(bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, mat_nr); } } - else { - BMEdge *bme1 = k == ns2 - 1 ? bme : NULL; - BMEdge *bme3 = NULL; + else { /* Edge bevel, Even number of segments. */ + if (k == ns2 - 1) { + se[1] = bme; + } if (j == ns2 - 1 && bndv->prev->ebev) { - bme3 = bndv->prev->ebev->e; + se[3] = bmeprev; } - BMEdge *bme2 = bme1 != NULL ? bme1 : bme3; - r_f = bev_create_quad_ex( - bm, bmv1, bmv2, bmv3, bmv4, f, f, f, f, NULL, bme1, bme2, bme3, f, mat_nr); + se[2] = se[1] != NULL ? se[1] : se[3]; } } + BMFace *r_f = bev_create_ngon(bm, bmvs, 4, fr, NULL, se, mat_nr, true); record_face_kind(bp, r_f, F_VERT); } } @@ -5413,7 +5638,18 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert /* Center ngon. */ if (odd) { - build_center_ngon(bp, bm, bv, mat_nr); + if (bp->affect_type == BEVEL_AFFECT_EDGES) { + BMFace *frep = NULL; + if (bv->any_seam) { + frep = frep_for_center_poly(bp, bv); + } + BMFace *cen_f = bev_create_ngon( + bm, center_verts, n_bndv, center_face_interps, frep, center_edge_snaps, mat_nr, true); + record_face_kind(bp, cen_f, F_VERT); + } + else { + build_center_ngon(bp, bm, bv, mat_nr); + } } } @@ -5425,7 +5661,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert * are two problems currently: * - Miter profiles don't have plane_no filled, so down direction is incorrect. * - Indexing profile points of miters with (i, 0, k) seems to return zero except for the first - * and last profile point. + * and last profile point. * TODO(Hans): Use repface / edge arrays for UV interpolation properly. */ static void bevel_build_cutoff(BevelParams *bp, BMesh *bm, BevVert *bv) @@ -5591,9 +5827,11 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) BMFace *repface; BMEdge *repface_e1, *repface_e2; + BoundVert *unsnapped[3]; if (bv->any_seam) { repface = frep_for_center_poly(bp, bv); get_incident_edges(repface, bv->v, &repface_e1, &repface_e2); + find_face_internal_boundverts(bv, repface, unsnapped); } else { repface = NULL; @@ -5607,8 +5845,13 @@ static BMFace *bevel_build_poly(BevelParams *bp, BMesh *bm, BevVert *bv) BLI_array_append(bmverts, bndv->nv.v); if (repface) { BLI_array_append(bmfaces, repface); - BMEdge *frep_e = find_closer_edge(bndv->nv.v->co, repface_e1, repface_e2); - BLI_array_append(bmedges, n > 0 ? frep_e : NULL); + if (bndv == unsnapped[0] || bndv == unsnapped[1] || bndv == unsnapped[2]) { + BLI_array_append(bmedges, NULL); + } + else { + BMEdge *frep_e = find_closer_edge(bndv->nv.v->co, repface_e1, repface_e2); + BLI_array_append(bmedges, frep_e); + } } else { BLI_array_append(bmfaces, boundvert_rep_face(bndv, NULL)); @@ -6359,10 +6602,10 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) sub_v3_v3v3(edge_dir, bv->v->co, v2->co); float z = fabsf(2.0f * sinf(angle_v3v3(vert_axis, edge_dir))); if (z < BEVEL_EPSILON) { - e->offset_l_spec = 0.01f * bv->offset; /* Undefined behavior, so tiny bevel. */ + e->offset_l_spec = 0.01f * bp->offset; /* Undefined behavior, so tiny bevel. */ } else { - e->offset_l_spec = bv->offset / z; + e->offset_l_spec = bp->offset / z; } break; } @@ -6371,10 +6614,10 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) sub_v3_v3v3(edge_dir, bv->v->co, v2->co); float z = fabsf(cosf(angle_v3v3(vert_axis, edge_dir))); if (z < BEVEL_EPSILON) { - e->offset_l_spec = 0.01f * bv->offset; /* Undefined behavior, so tiny bevel. */ + e->offset_l_spec = 0.01f * bp->offset; /* Undefined behavior, so tiny bevel. */ } else { - e->offset_l_spec = bv->offset / z; + e->offset_l_spec = bp->offset / z; } break; } @@ -6829,13 +7072,20 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) int odd = nseg % 2; int mid = nseg / 2; BMEdge *center_bme = NULL; + BMFace *fchoices[2] = {f1, f2}; + BMFace *f_choice = NULL; + int center_adj_k = -1; + if (odd & e1->is_seam) { + f_choice = choose_rep_face(bp, fchoices, 2); + if (nseg > 1) { + center_adj_k = f_choice == f1 ? mid + 2 : mid; + } + } for (int k = 1; k <= nseg; k++) { verts[3] = mesh_vert(vm1, i1, 0, k)->v; verts[2] = mesh_vert(vm2, i2, 0, nseg - k)->v; BMFace *r_f; if (odd && k == mid + 1) { - BMFace *fchoices[2] = {f1, f2}; - BMFace *f_choice = choose_rep_face(bp, fchoices, 2); if (e1->is_seam) { /* Straddles a seam: choose to interpolate in f_choice and snap the loops whose verts * are in the non-chosen face to bme for interpolation purposes. @@ -6856,6 +7106,25 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) r_f = bev_create_ngon(bm, verts, 4, faces, f_choice, NULL, mat_nr, true); } } + else if (odd && k == center_adj_k && e1->is_seam) { + /* The strip adjacent to the center one, in another UV island. + * Snap the edge near the seam to bme to match what happens in + * the bevel rings. + */ + BMEdge *edges[4]; + BMFace *f_interp; + if (k == mid) { + edges[0] = edges[1] = NULL; + edges[2] = edges[3] = bme; + f_interp = f1; + } + else { + edges[0] = edges[1] = bme; + edges[2] = edges[3] = NULL; + f_interp = f2; + } + r_f = bev_create_ngon(bm, verts, 4, NULL, f_interp, edges, mat_nr, true); + } else if (!odd && k == mid) { /* Left poly that touches an even center line on right. */ BMEdge *edges[4] = {NULL, NULL, bme, bme}; diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 6d3c203b076..8c54c923476 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -82,6 +82,7 @@ set(SRC intern/draw_cache_impl_volume.c intern/draw_color_management.cc intern/draw_common.c + intern/draw_curves.cc intern/draw_debug.c intern/draw_fluid.c intern/draw_hair.c @@ -98,6 +99,7 @@ set(SRC intern/draw_texture_pool.cc intern/draw_view.c intern/draw_view_data.cc + intern/draw_volume.cc intern/smaa_textures.c engines/basic/basic_engine.c engines/basic/basic_shader.c @@ -194,6 +196,7 @@ set(SRC intern/draw_color_management.h intern/draw_common.h intern/draw_common_shader_shared.h + intern/draw_curves_private.h intern/draw_debug.h intern/draw_hair_private.h intern/draw_instance_data.h diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 81edee17c76..47e8f234a01 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -353,8 +353,6 @@ static void eevee_draw_scene(void *vedata) EEVEE_renderpasses_draw_debug(vedata); - EEVEE_volumes_free_smoke_textures(); - stl->g_data->view_updated = false; DRW_view_set_active(NULL); @@ -574,7 +572,6 @@ static void eevee_render_to_image(void *vedata, } } - EEVEE_volumes_free_smoke_textures(); EEVEE_motion_blur_data_free(&ved->stl->effects->motion_blur); if (RE_engine_test_break(engine)) { diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index 2e1b92de068..4f562dd9804 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -965,7 +965,7 @@ static void eevee_lightbake_cache_create(EEVEE_Data *vedata, EEVEE_LightBake *lb txl->color = NULL; DRW_render_instance_buffer_finish(); - DRW_hair_update(); + DRW_curves_update(); } static void eevee_lightbake_copy_irradiance(EEVEE_LightBake *lbake, LightCache *lcache) @@ -1463,9 +1463,6 @@ void EEVEE_lightbake_job(void *custom_data, short *stop, short *do_update, float } eevee_lightbake_delete_resources(lbake); - - /* Free GPU smoke textures and the smoke domain list correctly: See also T73921. */ - EEVEE_volumes_free_smoke_textures(); } void EEVEE_lightbake_update_world_quick(EEVEE_ViewLayerData *sldata, diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index e3342508a14..2e0937dbe49 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -440,9 +440,9 @@ void EEVEE_motion_blur_cache_finish(EEVEE_Data *vedata) DRW_render_instance_buffer_finish(); /* Need to be called after #DRW_render_instance_buffer_finish() */ - /* Also we weed to have a correct FBO bound for #DRW_hair_update. */ + /* Also we weed to have a correct FBO bound for #DRW_curves_update. */ GPU_framebuffer_bind(vedata->fbl->main_fb); - DRW_hair_update(); + DRW_curves_update(); DRW_cache_restart(); } diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 9f97dacf9fe..ee336326166 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -1558,7 +1558,6 @@ void EEVEE_volumes_compute(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_volumes_resolve(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); void EEVEE_volumes_output_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, uint tot_samples); void EEVEE_volumes_output_accumulate(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata); -void EEVEE_volumes_free_smoke_textures(void); void EEVEE_volumes_free(void); /* eevee_effects.c */ diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 47e2b95f367..bef19c589c2 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -538,9 +538,9 @@ void EEVEE_render_draw(EEVEE_Data *vedata, RenderEngine *engine, RenderLayer *rl DRW_render_instance_buffer_finish(); /* Need to be called after DRW_render_instance_buffer_finish() */ - /* Also we weed to have a correct FBO bound for DRW_hair_update */ + /* Also we weed to have a correct FBO bound for DRW_curves_update */ GPU_framebuffer_bind(fbl->main_fb); - DRW_hair_update(); + DRW_curves_update(); /* Sort transparents before the loop. */ DRW_pass_sort_shgroup_z(psl->transparent_pass); diff --git a/source/blender/draw/engines/eevee/eevee_shaders.c b/source/blender/draw/engines/eevee/eevee_shaders.c index 4e4a2a9eb8e..85cc7f65126 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.c +++ b/source/blender/draw/engines/eevee/eevee_shaders.c @@ -1487,6 +1487,10 @@ struct GPUMaterial *EEVEE_material_get( GPUMaterial *mat = eevee_material_get_ex(scene, ma, wo, options, deferred); int status = GPU_material_status(mat); + /* Return null material and bypass drawing for volume shaders. */ + if ((options & VAR_MAT_VOLUME) && status != GPU_MAT_SUCCESS) { + return NULL; + } switch (status) { case GPU_MAT_SUCCESS: break; diff --git a/source/blender/draw/engines/eevee/eevee_shaders_extra.cc b/source/blender/draw/engines/eevee/eevee_shaders_extra.cc index bb1a0b0abe4..05577944140 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders_extra.cc +++ b/source/blender/draw/engines/eevee/eevee_shaders_extra.cc @@ -81,7 +81,7 @@ void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, const bool do_fragment_attrib_load = is_background || is_volume; if (is_hair && !info.vertex_out_interfaces_.is_empty()) { - /** Hair attributes comme from sampler buffer. Transfer attributes to sampler. */ + /** Hair attributes come from sampler buffer. Transfer attributes to sampler. */ for (auto &input : info.vertex_inputs_) { info.sampler(0, ImageType::FLOAT_BUFFER, input.name, Frequency::BATCH); } @@ -97,12 +97,26 @@ void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, } attr_load << "};\n"; attr_load << iface.name << " " << iface.instance_name << ";\n"; - /* Global vars just to make code valid. Only Orco is supported. */ - for (const ShaderCreateInfo::VertIn &in : info.vertex_inputs_) { - attr_load << in.type << " " << in.name << ";\n"; + if (!is_volume) { + /* Global vars just to make code valid. Only Orco is supported. */ + for (const ShaderCreateInfo::VertIn &in : info.vertex_inputs_) { + attr_load << in.type << " " << in.name << ";\n"; + } } info.vertex_out_interfaces_.clear(); } + if (is_volume) { + /** Volume grid attributes come from 3D textures. Transfer attributes to samplers. */ + for (auto &input : info.vertex_inputs_) { + info.sampler(0, ImageType::FLOAT_3D, input.name, Frequency::BATCH); + } + info.additional_info("draw_volume_infos"); + /* Do not add twice. */ + if (!GPU_material_flag_get(gpumat, GPU_MATFLAG_OBJECT_INFO)) { + info.additional_info("draw_object_infos"); + } + info.vertex_inputs_.clear(); + } if (!is_volume) { info.define("EEVEE_GENERATED_INTERFACE"); @@ -137,7 +151,7 @@ void eevee_shader_material_create_info_amend(GPUMaterial *gpumat, } frag_gen << "Closure nodetree_exec()\n"; frag_gen << "{\n"; - if (GPU_material_is_volume_shader(gpumat)) { + if (is_volume) { frag_gen << ((codegen.volume) ? codegen.volume : "return CLOSURE_DEFAULT;\n"); } else { diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 6a0c9fb36df..b8bef61f8b1 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -43,35 +43,8 @@ static struct { GPUTexture *dummy_scatter; GPUTexture *dummy_transmit; - - /* List of all fluid simulation / smoke domains rendered within this frame. */ - ListBase smoke_domains; } e_data = {NULL}; /* Engine data */ -static void eevee_create_textures_volumes(void) -{ - const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - e_data.dummy_zero = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, zero); - - const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - e_data.dummy_one = DRW_texture_create_3d(1, 1, 1, GPU_RGBA8, DRW_TEX_WRAP, one); - - const float flame = 0.0f; - e_data.dummy_flame = DRW_texture_create_3d(1, 1, 1, GPU_R8, DRW_TEX_WRAP, &flame); -} - -static GPUTexture *eevee_volume_default_texture(eGPUVolumeDefaultValue default_value) -{ - switch (default_value) { - case GPU_VOLUME_DEFAULT_0: - return e_data.dummy_zero; - case GPU_VOLUME_DEFAULT_1: - return e_data.dummy_one; - } - - return e_data.dummy_zero; -} - void EEVEE_volumes_set_jitter(EEVEE_ViewLayerData *sldata, uint current_sample) { EEVEE_CommonUniformBuffer *common_data = &sldata->common_data; @@ -227,11 +200,6 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) Scene *scene = draw_ctx->scene; DRWShadingGroup *grp = NULL; - /* Textures */ - if (!e_data.dummy_zero) { - eevee_create_textures_volumes(); - } - /* Quick breakdown of the Volumetric rendering: * * The rendering is separated in 4 stages: @@ -268,7 +236,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) !LOOK_DEV_STUDIO_LIGHT_ENABLED(draw_ctx->v3d)) { struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, NULL, wo, VAR_MAT_VOLUME); - if (GPU_material_has_volume_output(mat)) { + if (mat && GPU_material_has_volume_output(mat)) { grp = DRW_shgroup_material_create(mat, psl->volumetric_world_ps); } @@ -283,11 +251,7 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); /* Fix principle volumetric not working with world materials. */ - ListBase gpu_grids = GPU_material_volume_grids(mat); - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, &gpu_grids) { - DRW_shgroup_uniform_texture( - grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); - } + grp = DRW_shgroup_volume_create_sub(NULL, NULL, grp, mat); DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]); @@ -299,187 +263,17 @@ void EEVEE_volumes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) /* If no world or volume material is present just clear the buffer with this drawcall */ grp = DRW_shgroup_create(EEVEE_shaders_volumes_clear_sh_get(), psl->volumetric_world_ps); DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); + DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); + DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); + DRW_shgroup_uniform_block(grp, "shadow_block", sldata->shadow_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); DRW_shgroup_call_procedural_triangles(grp, NULL, common_data->vol_tex_size[2]); } } -static bool eevee_volume_object_grids_init(Object *ob, ListBase *gpu_grids, DRWShadingGroup *grp) -{ - Volume *volume = ob->data; - BKE_volume_load(volume, G.main); - - /* Test if we need to use multiple transforms. */ - DRWVolumeGrid *first_drw_grid = NULL; - bool multiple_transforms = true; - - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { - const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, gpu_grid->name); - DRWVolumeGrid *drw_grid = (volume_grid) ? - DRW_volume_batch_cache_get_grid(volume, volume_grid) : - NULL; - - if (drw_grid) { - if (first_drw_grid == NULL) { - first_drw_grid = drw_grid; - } - else if (drw_grid && - !equals_m4m4(drw_grid->object_to_texture, first_drw_grid->object_to_texture)) { - multiple_transforms = true; - break; - } - } - } - - /* Bail out of no grids to render. */ - if (first_drw_grid == NULL) { - return false; - } - - /* Set transform matrix for the volume as a whole. This one is also used for - * clipping so must map the entire bounding box to 0..1. */ - float bounds_to_object[4][4]; - - if (multiple_transforms) { - /* For multiple grids with different transform, we first transform from object space - * to bounds, then for each individual grid from bounds to texture. */ - const BoundBox *bb = BKE_volume_boundbox_get(ob); - float bb_size[3]; - sub_v3_v3v3(bb_size, bb->vec[6], bb->vec[0]); - size_to_mat4(bounds_to_object, bb_size); - copy_v3_v3(bounds_to_object[3], bb->vec[0]); - - invert_m4_m4(first_drw_grid->object_to_bounds, bounds_to_object); - DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", first_drw_grid->object_to_bounds); - } - else { - /* All grid transforms are equal, we can transform to texture space immediately. */ - DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", first_drw_grid->object_to_texture); - } - - /* Don't use orco transform here, only matrix. */ - DRW_shgroup_uniform_vec3_copy(grp, "volumeOrcoLoc", (float[3]){0.5f, 0.5f, 0.5f}); - DRW_shgroup_uniform_vec3_copy(grp, "volumeOrcoSize", (float[3]){0.5f, 0.5f, 0.5f}); - - /* Set density scale. */ - const float density_scale = BKE_volume_density_scale(volume, ob->obmat); - DRW_shgroup_uniform_float_copy(grp, "volumeDensityScale", density_scale); - - /* Bind volume grid textures. */ - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { - const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, gpu_grid->name); - DRWVolumeGrid *drw_grid = (volume_grid) ? - DRW_volume_batch_cache_get_grid(volume, volume_grid) : - NULL; - - /* Handle 3 cases here: - * - Grid exists and texture was loaded -> use texture. - * - Grid exists but has zero size or failed to load -> use zero. - * - Grid does not exist -> use default value. */ - GPUTexture *grid_tex = (drw_grid) ? drw_grid->texture : - (volume_grid) ? e_data.dummy_zero : - eevee_volume_default_texture(gpu_grid->default_value); - - DRW_shgroup_uniform_texture(grp, gpu_grid->sampler_name, grid_tex); - - if (drw_grid && multiple_transforms) { - /* Specify per-volume transform matrix that is applied after the - * transform from object to bounds. */ - mul_m4_m4m4(drw_grid->bounds_to_texture, drw_grid->object_to_texture, bounds_to_object); - DRW_shgroup_uniform_mat4(grp, gpu_grid->transform_name, drw_grid->bounds_to_texture); - } - } - - return true; -} - -static bool eevee_volume_object_mesh_init(Scene *scene, - Object *ob, - ListBase *gpu_grids, - DRWShadingGroup *grp) -{ - static const float white[3] = {1.0f, 1.0f, 1.0f}; - ModifierData *md = NULL; - - /* Smoke Simulation */ - if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) && - (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) && - ((FluidModifierData *)md)->domain != NULL) { - FluidModifierData *fmd = (FluidModifierData *)md; - FluidDomainSettings *fds = fmd->domain; - - /* Don't try to show liquid domains here. */ - if (!fds->fluid || !(fds->type == FLUID_DOMAIN_TYPE_GAS)) { - return false; - } - - /* Don't show smoke before simulation starts, this could be made an option in the future. */ - /* (sebbas): Always show smoke for manta */ -#if 0 - const DRWContextState *draw_ctx = DRW_context_state_get(); - const bool show_smoke = ((int)DEG_get_ctime(draw_ctx->depsgraph) >= - *fds->point_cache[0]->startframe); -#endif - - if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS) /* && show_smoke */) { - DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE); - BLI_addtail(&e_data.smoke_domains, BLI_genericNodeN(fmd)); - } - - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { - if (STREQ(gpu_grid->name, "density")) { - DRW_shgroup_uniform_texture_ref( - grp, gpu_grid->sampler_name, fds->tex_density ? &fds->tex_density : &e_data.dummy_one); - } - else if (STREQ(gpu_grid->name, "color")) { - DRW_shgroup_uniform_texture_ref( - grp, gpu_grid->sampler_name, fds->tex_color ? &fds->tex_color : &e_data.dummy_one); - } - else if (STR_ELEM(gpu_grid->name, "flame", "temperature")) { - DRW_shgroup_uniform_texture_ref( - grp, gpu_grid->sampler_name, fds->tex_flame ? &fds->tex_flame : &e_data.dummy_flame); - } - else { - DRW_shgroup_uniform_texture( - grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); - } - } - - /* Constant Volume color. */ - bool use_constant_color = ((fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) == 0 && - (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET) != 0); - - DRW_shgroup_uniform_vec3( - grp, "volumeColor", (use_constant_color) ? fds->active_color : white, 1); - - /* Output is such that 0..1 maps to 0..1000K */ - DRW_shgroup_uniform_vec2(grp, "volumeTemperature", &fds->flame_ignition, 1); - } - else { - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, gpu_grid, gpu_grids) { - DRW_shgroup_uniform_texture( - grp, gpu_grid->sampler_name, eevee_volume_default_texture(gpu_grid->default_value)); - } - } - - /* Transform for mesh volumes. */ - static const float unit_mat[4][4] = {{1.0f, 0.0f, 0.0f, 0.0f}, - {0.0f, 1.0f, 0.0f, 0.0f}, - {0.0f, 0.0f, 1.0f, 0.0f}, - {0.0f, 0.0f, 0.0f, 1.0f}}; - float *texco_loc, *texco_size; - BKE_mesh_texspace_get_reference((struct Mesh *)ob->data, NULL, &texco_loc, &texco_size); - - DRW_shgroup_uniform_mat4(grp, "volumeObjectToTexture", unit_mat); - DRW_shgroup_uniform_vec3(grp, "volumeOrcoLoc", texco_loc, 1); - DRW_shgroup_uniform_vec3(grp, "volumeOrcoSize", texco_size, 1); - - return true; -} - void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, Scene *scene, @@ -506,15 +300,22 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, int mat_options = VAR_MAT_VOLUME | VAR_MAT_MESH; struct GPUMaterial *mat = EEVEE_material_get(vedata, scene, ma, NULL, mat_options); - eGPUMaterialStatus status = GPU_material_status(mat); /* If shader failed to compile or is currently compiling. */ - if (status != GPU_MAT_SUCCESS) { + if (mat == NULL) { return; } + /* TODO(fclem): Reuse main shading group to avoid shading binding cost just like for surface + * shaders. */ DRWShadingGroup *grp = DRW_shgroup_material_create(mat, vedata->psl->volumetric_objects_ps); + grp = DRW_shgroup_volume_create_sub(scene, ob, grp, mat); + + if (grp == NULL) { + return; + } + /* TODO(fclem): remove those "unnecessary" UBOs */ DRW_shgroup_uniform_block(grp, "planar_block", sldata->planar_ubo); DRW_shgroup_uniform_block(grp, "probe_block", sldata->probe_ubo); @@ -522,22 +323,7 @@ void EEVEE_volumes_cache_object_add(EEVEE_ViewLayerData *sldata, DRW_shgroup_uniform_block(grp, "light_block", sldata->light_ubo); DRW_shgroup_uniform_block(grp, "grid_block", sldata->grid_ubo); DRW_shgroup_uniform_block(grp, "renderpass_block", sldata->renderpass_ubo.combined); - DRW_shgroup_uniform_block(grp, "common_block", sldata->common_ubo); - - ListBase gpu_grids = GPU_material_volume_grids(mat); - - if (ob->type == OB_VOLUME) { - if (!eevee_volume_object_grids_init(ob, &gpu_grids, grp)) { - return; - } - } - else { - if (!eevee_volume_object_mesh_init(scene, ob, &gpu_grids, grp)) { - return; - } - } - /* TODO: Reduce to number of slices intersecting. */ /* TODO: Preemptive culling. */ DRW_shgroup_call_procedural_triangles(grp, ob, sldata->common_data.vol_tex_size[2]); @@ -753,16 +539,6 @@ void EEVEE_volumes_resolve(EEVEE_ViewLayerData *UNUSED(sldata), EEVEE_Data *veda } } -void EEVEE_volumes_free_smoke_textures(void) -{ - /* Free Smoke Textures after rendering */ - LISTBASE_FOREACH (LinkData *, link, &e_data.smoke_domains) { - FluidModifierData *fmd = (FluidModifierData *)link->data; - DRW_smoke_free(fmd); - } - BLI_freelistN(&e_data.smoke_domains); -} - void EEVEE_volumes_free(void) { DRW_TEXTURE_FREE_SAFE(e_data.dummy_scatter); diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index 0e8e8dd9d01..ab0f4d6bec8 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -144,3 +144,13 @@ vec3 attr_load_uv(vec3 attr) return attr; } #endif + +/* Passthrough. */ +float attr_load_temperature_post(float attr) +{ + return attr; +} +vec4 attr_load_color_post(vec4 attr) +{ + return attr; +} diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl index 9ad7a4fdbc1..79ec3807d0b 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -179,3 +179,13 @@ vec3 attr_load_uv(vec3 attr) { return vec3(0); } + +/* Passthrough. */ +float attr_load_temperature_post(float attr) +{ + return attr; +} +vec4 attr_load_color_post(vec4 attr) +{ + return attr; +} diff --git a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl index 6c6b810422b..49c18832f72 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl @@ -157,3 +157,13 @@ vec3 attr_load_uv(vec3 attr) return attr; } #endif + +/* Passthrough. */ +float attr_load_temperature_post(float attr) +{ + return attr; +} +vec4 attr_load_color_post(vec4 attr) +{ + return attr; +} diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl index e0a79872928..914261d7f59 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_frag.glsl @@ -4,17 +4,13 @@ /* Based on Frosbite Unified Volumetric. * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */ -#ifdef MESH_SHADER -uniform vec3 volumeOrcoLoc; -uniform vec3 volumeOrcoSize; -uniform mat4 volumeObjectToTexture; -uniform float volumeDensityScale = 1.0; -#endif +/* Store volumetric properties into the froxel textures. */ flat in int slice; /* Warning: these are not attributes, these are global vars. */ vec3 worldPosition = vec3(0.0); +vec3 objectPosition = vec3(0.0); vec3 viewPosition = vec3(0.0); vec3 viewNormal = vec3(0.0); vec3 volumeOrco = vec3(0.0); @@ -24,9 +20,9 @@ layout(location = 1) out vec4 volumeExtinction; layout(location = 2) out vec4 volumeEmissive; layout(location = 3) out vec4 volumePhase; -/* Store volumetric properties into the froxel textures. */ +int attr_id; -#ifdef MESH_SHADER +#ifndef CLEAR GlobalData init_globals(void) { GlobalData surf; @@ -80,10 +76,8 @@ void main() viewPosition = get_view_space_from_depth(ndc_cell.xy, ndc_cell.z); worldPosition = point_view_to_world(viewPosition); #ifdef MESH_SHADER - volumeOrco = point_world_to_object(worldPosition); - /* TODO: redundant transform */ - volumeOrco = (volumeOrco - volumeOrcoLoc + volumeOrcoSize) / (volumeOrcoSize * 2.0); - volumeOrco = (volumeObjectToTexture * vec4(volumeOrco, 1.0)).xyz; + objectPosition = point_world_to_object(worldPosition); + volumeOrco = OrcoTexCoFactors[0].xyz + objectPosition * OrcoTexCoFactors[1].xyz; if (any(lessThan(volumeOrco, vec3(0.0))) || any(greaterThan(volumeOrco, vec3(1.0)))) { /* Note: Discard is not an explicit return in Metal prior to versions 2.3. @@ -100,15 +94,13 @@ void main() volumeEmissive = vec4(0.0, 0.0, 0.0, 1.0); volumePhase = vec4(0.0, 0.0, 0.0, 0.0); #else -# ifdef MESH_SHADER g_data = init_globals(); attrib_load(); -# endif Closure cl = nodetree_exec(); # ifdef MESH_SHADER - cl.scatter *= volumeDensityScale; - cl.absorption *= volumeDensityScale; - cl.emission *= volumeDensityScale; + cl.scatter *= drw_volume.density_scale; + cl.absorption *= drw_volume.density_scale; + cl.emission *= drw_volume.density_scale; # endif volumeScattering = vec4(cl.scatter, 1.0); @@ -124,35 +116,72 @@ void main() #endif } -vec3 attr_load_orco(vec4 orco) +vec3 grid_coordinates() +{ + vec3 co = volumeOrco; +#ifdef MESH_SHADER + /* Optional per-grid transform. */ + if (drw_volume.grids_xform[attr_id][3][3] != 0.0) { + co = (drw_volume.grids_xform[attr_id] * vec4(objectPosition, 1.0)).xyz; + } +#endif + attr_id += 1; + return co; +} + +vec3 attr_load_orco(sampler3D orco) { + attr_id += 1; return volumeOrco; } -vec4 attr_load_tangent(vec4 tangent) +vec4 attr_load_tangent(sampler3D tangent) { + attr_id += 1; return vec4(0); } -vec4 attr_load_vec4(vec4 attr) +vec4 attr_load_vec4(sampler3D tex) { - return vec4(0); + return texture(tex, grid_coordinates()); } -vec3 attr_load_vec3(vec3 attr) +vec3 attr_load_vec3(sampler3D tex) { - return vec3(0); + return texture(tex, grid_coordinates()).rgb; } -vec2 attr_load_vec2(vec2 attr) +vec2 attr_load_vec2(sampler3D tex) { - return vec2(0); + return texture(tex, grid_coordinates()).rg; } -float attr_load_float(float attr) +float attr_load_float(sampler3D tex) { - return 0.0; + return texture(tex, grid_coordinates()).r; } -vec4 attr_load_color(vec4 attr) +vec4 attr_load_color(sampler3D tex) { - return vec4(0); + return texture(tex, grid_coordinates()); } -vec3 attr_load_uv(vec3 attr) +vec3 attr_load_uv(sampler3D attr) { + attr_id += 1; return vec3(0); } + +/* TODO(@fclem): These implementation details should concern the DRWManager and not be a fix on + * the engine side. But as of now, the engines are reponsible for loading the attributes. */ +float attr_load_temperature_post(float attr) +{ +#ifdef MESH_SHADER + /* Bring the into standard range without having to modify the grid values */ + attr = (attr > 0.01) ? (attr * drw_volume.temperature_mul + drw_volume.temperature_bias) : 0.0; +#endif + return attr; +} +vec4 attr_load_color_post(vec4 attr) +{ +#ifdef MESH_SHADER + /* Density is premultiplied for interpolation, divide it out here. */ + attr.rgb *= safe_rcp(attr.a); + attr.rgb *= drw_volume.color_mul.rgb; + attr.a = 1.0; +#endif + return attr; +} diff --git a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl index 26b60c992e1..527bbd18896 100644 --- a/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/volumetric_integration_frag.glsl @@ -11,10 +11,8 @@ uniform sampler3D volumeScattering; /* Result of the scatter step */ uniform sampler3D volumeExtinction; #ifdef USE_VOLUME_OPTI -uniform layout(r11f_g11f_b10f) -writeonly restrict image3D finalScattering_img; -uniform layout(r11f_g11f_b10f) -writeonly restrict image3D finalTransmittance_img; +uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalScattering_img; +uniform layout(r11f_g11f_b10f) writeonly restrict image3D finalTransmittance_img; vec3 finalScattering; vec3 finalTransmittance; diff --git a/source/blender/draw/engines/overlay/overlay_extra.c b/source/blender/draw/engines/overlay/overlay_extra.c index abcca5525c7..5d8ba06e181 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.c +++ b/source/blender/draw/engines/overlay/overlay_extra.c @@ -1474,23 +1474,6 @@ static void OVERLAY_volume_extra(OVERLAY_ExtraCallBuffers *cb, } if (draw_velocity || show_gridlines) { - BLI_addtail(&data->stl->pd->smoke_domains, BLI_genericNodeN(fmd)); - } -} - -static void OVERLAY_volume_free_smoke_textures(OVERLAY_Data *data) -{ - /* Free Smoke Textures after rendering */ - /* XXX This is a waste of processing and GPU bandwidth if nothing - * is updated. But the problem is since Textures are stored in the - * modifier we don't want them to take precious VRAM if the - * modifier is not used for display. We should share them for - * all viewport in a redraw at least. */ - LinkData *link; - while ((link = BLI_pophead(&data->stl->pd->smoke_domains))) { - FluidModifierData *fmd = (FluidModifierData *)link->data; - DRW_smoke_free_velocity(fmd); - MEM_freeN(link); } } @@ -1624,8 +1607,6 @@ void OVERLAY_extra_draw(OVERLAY_Data *vedata) void OVERLAY_extra_in_front_draw(OVERLAY_Data *vedata) { DRW_draw_pass(vedata->psl->extra_ps[1]); - - OVERLAY_volume_free_smoke_textures(vedata); } void OVERLAY_extra_centers_draw(OVERLAY_Data *vedata) diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h index 71b6c9424e6..4c933e08a57 100644 --- a/source/blender/draw/engines/overlay/overlay_private.h +++ b/source/blender/draw/engines/overlay/overlay_private.h @@ -304,7 +304,6 @@ typedef struct OVERLAY_PrivateData { DRWView *view_edit_curves_points; /** TODO: get rid of this. */ - ListBase smoke_domains; ListBase bg_movie_clips; /** Two instances for in_front option and without. */ diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh index 5d098d61dbf..698c7d1a8b7 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_volume_info.hh @@ -55,7 +55,6 @@ GPU_SHADER_CREATE_INFO(workbench_volume_coba) GPU_SHADER_CREATE_INFO(workbench_volume_no_coba) .sampler(4, ImageType::FLOAT_3D, "shadowTexture") - .sampler(5, ImageType::UINT_2D, "transferTexture") .push_constant(Type::VEC3, "activeColor"); /** \} */ diff --git a/source/blender/draw/engines/workbench/workbench_data.c b/source/blender/draw/engines/workbench/workbench_data.c index f4e042933d1..f7f156e5297 100644 --- a/source/blender/draw/engines/workbench/workbench_data.c +++ b/source/blender/draw/engines/workbench/workbench_data.c @@ -163,7 +163,6 @@ void workbench_private_data_init(WORKBENCH_PrivateData *wpd) wpd->taa_sample_len = workbench_antialiasing_sample_count_get(wpd); wpd->volumes_do = false; - BLI_listbase_clear(&wpd->smoke_domains); /* FIXME: This reproduce old behavior when workbench was separated in 2 engines. * But this is a workaround for a missing update tagging. */ diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 566fd30096d..fb20bde2f65 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -271,6 +271,18 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd, BKE_pbvh_is_drawing_set(ob->sculpt->pbvh, is_sculpt_pbvh); } + bool has_color = false; + + if (me) { + const CustomData *cd_vdata = workbench_mesh_get_vert_custom_data(me); + const CustomData *cd_ldata = workbench_mesh_get_loop_custom_data(me); + + has_color = (CustomData_has_layer(cd_vdata, CD_PROP_COLOR) || + CustomData_has_layer(cd_vdata, CD_PROP_BYTE_COLOR) || + CustomData_has_layer(cd_ldata, CD_PROP_COLOR) || + CustomData_has_layer(cd_ldata, CD_PROP_BYTE_COLOR)); + } + if (color_type == V3D_SHADING_TEXTURE_COLOR) { if (ob->dt < OB_TEXTURE) { color_type = V3D_SHADING_MATERIAL_COLOR; @@ -285,14 +297,6 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd, color_type = V3D_SHADING_OBJECT_COLOR; } else { - const CustomData *cd_vdata = workbench_mesh_get_vert_custom_data(me); - const CustomData *cd_ldata = workbench_mesh_get_loop_custom_data(me); - - bool has_color = (CustomData_has_layer(cd_vdata, CD_PROP_COLOR) || - CustomData_has_layer(cd_vdata, CD_MLOOPCOL) || - CustomData_has_layer(cd_ldata, CD_PROP_COLOR) || - CustomData_has_layer(cd_ldata, CD_MLOOPCOL)); - if (!has_color) { color_type = V3D_SHADING_OBJECT_COLOR; } @@ -314,7 +318,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd, *r_texpaint_mode = true; } } - else if (is_vertpaint_mode && me && CustomData_has_layer(ldata, CD_MLOOPCOL)) { + else if (is_vertpaint_mode && me && has_color) { color_type = V3D_SHADING_VERTEX_COLOR; } } @@ -613,10 +617,8 @@ static void workbench_draw_scene(void *ved) workbench_draw_finish(vedata); } -void workbench_draw_finish(void *ved) +void workbench_draw_finish(void *UNUSED(ved)) { - WORKBENCH_Data *vedata = ved; - workbench_volume_draw_finish(vedata); /* Reset default view. */ DRW_view_set_active(NULL); } diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 727b771ee08..492bce1e571 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -324,10 +324,6 @@ typedef struct WORKBENCH_PrivateData { /** Index of current material inside the material chunk. Only for material coloring mode. */ int material_index; - /* Volumes */ - /** List of smoke domain textures to free after drawing. */ - ListBase smoke_domains; - /* Depth of Field */ /** Depth of field temp buffers. */ struct GPUTexture *dof_blur_tx; @@ -533,7 +529,6 @@ void workbench_volume_cache_populate(WORKBENCH_Data *vedata, struct ModifierData *md, eV3DShadingColorType color_type); void workbench_volume_draw_pass(WORKBENCH_Data *vedata); -void workbench_volume_draw_finish(WORKBENCH_Data *vedata); /* workbench_engine.c */ diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index 72de3fe298a..1279682e899 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -170,9 +170,9 @@ void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer DRW_render_instance_buffer_finish(); - /* Also we weed to have a correct FBO bound for #DRW_hair_update */ + /* Also we weed to have a correct FBO bound for #DRW_curves_update */ GPU_framebuffer_bind(dfbl->default_fb); - DRW_hair_update(); + DRW_curves_update(); GPU_framebuffer_bind(dfbl->default_fb); GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f); diff --git a/source/blender/draw/engines/workbench/workbench_volume.c b/source/blender/draw/engines/workbench/workbench_volume.c index c6f40c5d6bb..2c902e9b627 100644 --- a/source/blender/draw/engines/workbench/workbench_volume.c +++ b/source/blender/draw/engines/workbench/workbench_volume.c @@ -178,8 +178,6 @@ static void workbench_volume_modifier_cache_populate(WORKBENCH_Data *vedata, else { DRW_shgroup_call(grp, DRW_cache_cube_get(), ob); } - - BLI_addtail(&wpd->smoke_domains, BLI_genericNodeN(fmd)); } static void workbench_volume_material_color(WORKBENCH_PrivateData *wpd, @@ -334,20 +332,3 @@ void workbench_volume_draw_pass(WORKBENCH_Data *vedata) DRW_draw_pass(psl->volume_ps); } } - -void workbench_volume_draw_finish(WORKBENCH_Data *vedata) -{ - WORKBENCH_PrivateData *wpd = vedata->stl->wpd; - - /* Free Smoke Textures after rendering */ - /* XXX This is a waste of processing and GPU bandwidth if nothing - * is updated. But the problem is since Textures are stored in the - * modifier we don't want them to take precious VRAM if the - * modifier is not used for display. We should share them for - * all viewport in a redraw at least. */ - LISTBASE_FOREACH (LinkData *, link, &wpd->smoke_domains) { - FluidModifierData *fmd = (FluidModifierData *)link->data; - DRW_smoke_free(fmd); - } - BLI_freelistN(&wpd->smoke_domains); -} diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index ed94c485b32..d7e752a43f4 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -53,6 +53,8 @@ * */ +#include "DRW_render.h" + #include "MEM_guardedalloc.h" #include "draw_texture_pool.h" @@ -61,6 +63,7 @@ #include "BLI_span.hh" #include "BLI_utildefines.h" #include "BLI_utility_mixins.hh" +#include "BLI_vector.hh" #include "GPU_framebuffer.h" #include "GPU_storage_buffer.h" diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index b084a5e5945..f2742f3bcc7 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -29,9 +29,11 @@ #include "GPU_material.h" #include "GPU_texture.h" +#include "DRW_render.h" + #include "draw_cache_impl.h" /* own include */ #include "draw_cache_inline.h" -#include "draw_hair_private.h" /* own include */ +#include "draw_curves_private.h" /* own include */ using blender::float3; using blender::IndexRange; @@ -41,7 +43,7 @@ using blender::Span; /* Curves GPUBatch Cache */ struct CurvesBatchCache { - ParticleHairCache hair; + CurvesEvalCache curves_cache; GPUBatch *edit_points; @@ -70,6 +72,28 @@ static void curves_batch_cache_init(Curves &curves) cache->is_dirty = false; } +static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) +{ + /* TODO: more granular update tagging. */ + GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); + GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); + DRW_TEXTURE_FREE_SAFE(curves_cache.point_tex); + DRW_TEXTURE_FREE_SAFE(curves_cache.length_tex); + + GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); + GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); + DRW_TEXTURE_FREE_SAFE(curves_cache.strand_tex); + DRW_TEXTURE_FREE_SAFE(curves_cache.strand_seg_tex); + + for (int i = 0; i < MAX_HAIR_SUBDIV; i++) { + GPU_VERTBUF_DISCARD_SAFE(curves_cache.final[i].proc_buf); + DRW_TEXTURE_FREE_SAFE(curves_cache.final[i].proc_tex); + for (int j = 0; j < MAX_THICKRES; j++) { + GPU_BATCH_DISCARD_SAFE(curves_cache.final[i].proc_hairs[j]); + } + } +} + static void curves_batch_cache_clear(Curves &curves) { CurvesBatchCache *cache = static_cast<CurvesBatchCache *>(curves.batch_cache); @@ -77,7 +101,8 @@ static void curves_batch_cache_clear(Curves &curves) return; } - particle_batch_cache_clear_hair(&cache->hair); + curves_batch_cache_clear_data(cache->curves_cache); + GPU_BATCH_DISCARD_SAFE(cache->edit_points); } @@ -116,10 +141,9 @@ void DRW_curves_batch_cache_free(Curves *curves) MEM_SAFE_FREE(curves->batch_cache); } -static void ensure_seg_pt_count(const Curves &curves, ParticleHairCache &curves_cache) +static void ensure_seg_pt_count(const Curves &curves, CurvesEvalCache &curves_cache) { - if ((curves_cache.pos != nullptr && curves_cache.indices != nullptr) || - (curves_cache.proc_point_buf != nullptr)) { + if (curves_cache.proc_point_buf != nullptr) { return; } @@ -169,7 +193,7 @@ static void curves_batch_cache_fill_segments_proc_pos(const Curves &curves_id, } static void curves_batch_cache_ensure_procedural_pos(Curves &curves, - ParticleHairCache &cache, + CurvesEvalCache &cache, GPUMaterial *gpu_material) { if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { @@ -229,7 +253,7 @@ static void curves_batch_cache_fill_strands_data(const Curves &curves_id, } static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves, - ParticleHairCache &cache) + CurvesEvalCache &cache) { GPUVertBufRaw data_step, seg_step; @@ -259,7 +283,7 @@ static void curves_batch_cache_ensure_procedural_strand_data(Curves &curves, cache.proc_strand_seg_buf); } -static void curves_batch_cache_ensure_procedural_final_points(ParticleHairCache &cache, int subdiv) +static void curves_batch_cache_ensure_procedural_final_points(CurvesEvalCache &cache, int subdiv) { /* Same format as point_tex. */ GPUVertFormat format = {0}; @@ -296,7 +320,7 @@ static void curves_batch_cache_fill_segments_indices(const Curves &curves, } static void curves_batch_cache_ensure_procedural_indices(Curves &curves, - ParticleHairCache &cache, + CurvesEvalCache &cache, const int thickness_res, const int subdiv) { @@ -330,7 +354,7 @@ static void curves_batch_cache_ensure_procedural_indices(Curves &curves, } bool curves_ensure_procedural_data(Object *object, - ParticleHairCache **r_hair_cache, + CurvesEvalCache **r_hair_cache, GPUMaterial *gpu_material, const int subdiv, const int thickness_res) @@ -339,30 +363,31 @@ bool curves_ensure_procedural_data(Object *object, Curves &curves = *static_cast<Curves *>(object->data); CurvesBatchCache &cache = curves_batch_cache_get(curves); - *r_hair_cache = &cache.hair; + *r_hair_cache = &cache.curves_cache; const int steps = 3; /* TODO: don't hard-code? */ (*r_hair_cache)->final[subdiv].strands_res = 1 << (steps + subdiv); /* Refreshed on combing and simulation. */ if ((*r_hair_cache)->proc_point_buf == nullptr) { - ensure_seg_pt_count(curves, cache.hair); - curves_batch_cache_ensure_procedural_pos(curves, cache.hair, gpu_material); + ensure_seg_pt_count(curves, cache.curves_cache); + curves_batch_cache_ensure_procedural_pos(curves, cache.curves_cache, gpu_material); need_ft_update = true; } /* Refreshed if active layer or custom data changes. */ if ((*r_hair_cache)->strand_tex == nullptr) { - curves_batch_cache_ensure_procedural_strand_data(curves, cache.hair); + curves_batch_cache_ensure_procedural_strand_data(curves, cache.curves_cache); } /* Refreshed only on subdiv count change. */ if ((*r_hair_cache)->final[subdiv].proc_buf == nullptr) { - curves_batch_cache_ensure_procedural_final_points(cache.hair, subdiv); + curves_batch_cache_ensure_procedural_final_points(cache.curves_cache, subdiv); need_ft_update = true; } if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] == nullptr) { - curves_batch_cache_ensure_procedural_indices(curves, cache.hair, thickness_res, subdiv); + curves_batch_cache_ensure_procedural_indices( + curves, cache.curves_cache, thickness_res, subdiv); } return need_ft_update; @@ -385,10 +410,10 @@ void DRW_curves_batch_cache_create_requested(const Object *ob) CurvesBatchCache &cache = curves_batch_cache_get(*curves); if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache.edit_points, &cache.hair.proc_point_buf); + DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); } - if (DRW_vbo_requested(cache.hair.proc_point_buf)) { - curves_batch_cache_ensure_procedural_pos(*curves, cache.hair, nullptr); + if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { + curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); } } diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index c4fa60ef51d..e4aec17eb69 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -518,15 +518,17 @@ static uint mesh_cd_calc_gpu_layers_vcol_used(const Mesh *me_query, domain = ATTR_DOMAIN_POINT; layer_i = CustomData_get_named_layer_index(cd_vdata, CD_PROP_COLOR, name); - layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_vdata, CD_MLOOPCOL, name) : - layer_i; + layer_i = layer_i == -1 ? + CustomData_get_named_layer_index(cd_vdata, CD_PROP_BYTE_COLOR, name) : + layer_i; if (layer_i == -1) { domain = ATTR_DOMAIN_CORNER; layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_PROP_COLOR, name) : layer_i; - layer_i = layer_i == -1 ? CustomData_get_named_layer_index(cd_ldata, CD_MLOOPCOL, name) : - layer_i; + layer_i = layer_i == -1 ? + CustomData_get_named_layer_index(cd_ldata, CD_PROP_BYTE_COLOR, name) : + layer_i; } /* Note: this is not the same as the layer_i below. */ @@ -610,17 +612,17 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, } if (layer == -1) { - layer = CustomData_get_named_layer(cd_vdata, CD_MLOOPCOL, name); + layer = CustomData_get_named_layer(cd_vdata, CD_PROP_BYTE_COLOR, name); if (layer != -1) { - type = CD_MLOOPCOL; + type = CD_PROP_BYTE_COLOR; domain = ATTR_DOMAIN_POINT; } } if (layer == -1) { - layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPCOL, name); + layer = CustomData_get_named_layer(cd_ldata, CD_PROP_BYTE_COLOR, name); if (layer != -1) { - type = CD_MLOOPCOL; + type = CD_PROP_BYTE_COLOR; domain = ATTR_DOMAIN_CORNER; } } @@ -700,11 +702,11 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, } /* Note: attr->type will always be CD_PROP_COLOR even for - * CD_MLOOPCOL layers, see node_shader_gpu_vertex_color in + * CD_PROP_BYTE_COLOR layers, see node_shader_gpu_vertex_color in * node_shader_vertex_color.cc. */ case CD_MCOL: - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: case CD_PROP_COLOR: { int vcol_bit = mesh_cd_calc_gpu_layers_vcol_used(&me_query, cd_vdata, cd_ldata, name); diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index c6b56723818..0f1ab967ca5 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -164,7 +164,7 @@ static void particle_batch_cache_clear_point(ParticlePointCache *point_cache) GPU_VERTBUF_DISCARD_SAFE(point_cache->pos); } -void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache) +static void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache) { /* TODO: more granular update tagging. */ GPU_VERTBUF_DISCARD_SAFE(hair_cache->proc_point_buf); @@ -822,10 +822,11 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); render_uv = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { - cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); - render_col = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { + cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, + CD_PROP_BYTE_COLOR); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); + render_col = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); } } @@ -891,7 +892,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR, i); GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); int n = 0; @@ -1162,9 +1163,9 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { - num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { + num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); + active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); } } @@ -1195,7 +1196,8 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, for (int i = 0; i < num_col_layers; i++) { char uuid[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); + const char *name = CustomData_get_layer_name( + &psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR, i); GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); BLI_snprintf(uuid, sizeof(uuid), "c%s", attr_safe_name); diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index d302140d9ac..779ac43178c 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -21,6 +21,8 @@ struct Object; struct ParticleSystem; struct RegionView3D; struct ViewLayer; +struct Scene; +struct DRWData; /* Keep in sync with globalsBlock in shaders */ BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16) @@ -54,16 +56,12 @@ struct DRWShadingGroup *DRW_shgroup_hair_create_sub(struct Object *object, struct DRWShadingGroup *shgrp, struct GPUMaterial *gpu_material); -struct DRWShadingGroup *DRW_shgroup_curves_create_sub(struct Object *object, - struct DRWShadingGroup *shgrp, - struct GPUMaterial *gpu_material); /** * \note Only valid after #DRW_hair_update(). */ struct GPUVertBuf *DRW_hair_pos_buffer_get(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md); -struct GPUVertBuf *DRW_curves_pos_buffer_get(struct Object *object); void DRW_hair_duplimat_get(struct Object *object, struct ParticleSystem *psys, struct ModifierData *md, @@ -73,6 +71,37 @@ void DRW_hair_init(void); void DRW_hair_update(void); void DRW_hair_free(void); +/* draw_curves.cc */ + +/** + * \note Only valid after #DRW_curves_update(). + */ +struct GPUVertBuf *DRW_curves_pos_buffer_get(struct Object *object); + +struct DRWShadingGroup *DRW_shgroup_curves_create_sub(struct Object *object, + struct DRWShadingGroup *shgrp, + struct GPUMaterial *gpu_material); + +void DRW_curves_init(void); +void DRW_curves_update(void); +void DRW_curves_free(void); + +/* draw_volume.cc */ + +/** + * Add attributes bindings of volume grids to an existing shading group. + * No draw call is added so the caller can decide how to use the data. + * \return nullptr if there is something to draw. + */ +struct DRWShadingGroup *DRW_shgroup_volume_create_sub(struct Scene *scene, + struct Object *ob, + struct DRWShadingGroup *shgrp, + struct GPUMaterial *gpu_material); + +void DRW_volume_init(struct DRWData *drw_data); +void DRW_volume_ubos_pool_free(void *pool); +void DRW_volume_free(void); + /* draw_fluid.c */ /* Fluid simulation. */ @@ -83,7 +112,9 @@ void DRW_fluid_ensure_flags(struct FluidModifierData *fmd); void DRW_fluid_ensure_range_field(struct FluidModifierData *fmd); void DRW_smoke_free(struct FluidModifierData *fmd); -void DRW_smoke_free_velocity(struct FluidModifierData *fmd); + +void DRW_smoke_init(struct DRWData *drw_data); +void DRW_smoke_exit(struct DRWData *drw_data); /* draw_common.c */ diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc new file mode 100644 index 00000000000..88118361115 --- /dev/null +++ b/source/blender/draw/intern/draw_curves.cc @@ -0,0 +1,325 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2017 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup draw + * + * \brief Contains procedural GPU hair drawing methods. + */ + +#include "BLI_string_utils.h" +#include "BLI_utildefines.h" + +#include "DNA_customdata_types.h" + +#include "GPU_batch.h" +#include "GPU_capabilities.h" +#include "GPU_compute.h" +#include "GPU_material.h" +#include "GPU_shader.h" +#include "GPU_texture.h" +#include "GPU_vertex_buffer.h" + +#include "DRW_render.h" + +#include "draw_hair_private.h" +#include "draw_shader.h" + +#ifndef __APPLE__ +# define USE_TRANSFORM_FEEDBACK +# define USE_COMPUTE_SHADERS +#endif + +BLI_INLINE eParticleRefineShaderType drw_curves_shader_type_get() +{ +#ifdef USE_COMPUTE_SHADERS + if (GPU_compute_shader_support() && GPU_shader_storage_buffer_objects_support()) { + return PART_REFINE_SHADER_COMPUTE; + } +#endif +#ifdef USE_TRANSFORM_FEEDBACK + return PART_REFINE_SHADER_TRANSFORM_FEEDBACK; +#endif + return PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND; +} + +#ifndef USE_TRANSFORM_FEEDBACK +struct CurvesEvalCall { + struct CurvesEvalCall *next; + GPUVertBuf *vbo; + DRWShadingGroup *shgrp; + uint vert_len; +}; + +static CurvesEvalCall *g_tf_calls = nullptr; +static int g_tf_id_offset; +static int g_tf_target_width; +static int g_tf_target_height; +#endif + +static GPUVertBuf *g_dummy_vbo = nullptr; +static GPUTexture *g_dummy_texture = nullptr; +static DRWPass *g_tf_pass; /* XXX can be a problem with multiple DRWManager in the future */ + +static GPUShader *curves_eval_shader_get(CurvesEvalShader type) +{ + return DRW_shader_curves_refine_get(type, drw_curves_shader_type_get()); +} + +void DRW_curves_init(void) +{ + /* Initialize legacy hair too, to avoid verbosity in callers. */ + DRW_hair_init(); + +#if defined(USE_TRANSFORM_FEEDBACK) || defined(USE_COMPUTE_SHADERS) + g_tf_pass = DRW_pass_create("Update Curves Pass", (DRWState)0); +#else + g_tf_pass = DRW_pass_create("Update Curves Pass", DRW_STATE_WRITE_COLOR); +#endif + + if (g_dummy_vbo == nullptr) { + /* initialize vertex format */ + GPUVertFormat format = {0}; + uint dummy_id = GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + + g_dummy_vbo = GPU_vertbuf_create_with_format(&format); + + const float vert[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + GPU_vertbuf_data_alloc(g_dummy_vbo, 1); + GPU_vertbuf_attr_fill(g_dummy_vbo, dummy_id, vert); + /* Create vbo immediately to bind to texture buffer. */ + GPU_vertbuf_use(g_dummy_vbo); + + g_dummy_texture = GPU_texture_create_from_vertbuf("hair_dummy_attr", g_dummy_vbo); + } +} + +static void drw_curves_cache_shgrp_attach_resources(DRWShadingGroup *shgrp, + CurvesEvalCache *cache, + const int subdiv) +{ + DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", cache->point_tex); + DRW_shgroup_uniform_texture(shgrp, "hairStrandBuffer", cache->strand_tex); + DRW_shgroup_uniform_texture(shgrp, "hairStrandSegBuffer", cache->strand_seg_tex); + DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &cache->final[subdiv].strands_res, 1); +} + +static void drw_curves_cache_update_compute(CurvesEvalCache *cache, const int subdiv) +{ + const int strands_len = cache->strands_len; + const int final_points_len = cache->final[subdiv].strands_res * strands_len; + if (final_points_len > 0) { + GPUShader *shader = curves_eval_shader_get(CURVES_EVAL_CATMULL_ROM); + DRWShadingGroup *shgrp = DRW_shgroup_create(shader, g_tf_pass); + drw_curves_cache_shgrp_attach_resources(shgrp, cache, subdiv); + DRW_shgroup_vertex_buffer(shgrp, "posTime", cache->final[subdiv].proc_buf); + + const int max_strands_per_call = GPU_max_work_group_count(0); + int strands_start = 0; + while (strands_start < strands_len) { + int batch_strands_len = MIN2(strands_len - strands_start, max_strands_per_call); + DRWShadingGroup *subgroup = DRW_shgroup_create_sub(shgrp); + DRW_shgroup_uniform_int_copy(subgroup, "hairStrandOffset", strands_start); + DRW_shgroup_call_compute(subgroup, batch_strands_len, cache->final[subdiv].strands_res, 1); + strands_start += batch_strands_len; + } + } +} + +static void drw_curves_cache_update_transform_feedback(CurvesEvalCache *cache, const int subdiv) +{ + const int final_points_len = cache->final[subdiv].strands_res * cache->strands_len; + if (final_points_len > 0) { + GPUShader *tf_shader = curves_eval_shader_get(CURVES_EVAL_CATMULL_ROM); + +#ifdef USE_TRANSFORM_FEEDBACK + DRWShadingGroup *tf_shgrp = DRW_shgroup_transform_feedback_create( + tf_shader, g_tf_pass, cache->final[subdiv].proc_buf); +#else + DRWShadingGroup *tf_shgrp = DRW_shgroup_create(tf_shader, g_tf_pass); + + CurvesEvalCall *pr_call = MEM_new<CurvesEvalCall>(__func__); + pr_call->next = g_tf_calls; + pr_call->vbo = cache->final[subdiv].proc_buf; + pr_call->shgrp = tf_shgrp; + pr_call->vert_len = final_points_len; + g_tf_calls = pr_call; + DRW_shgroup_uniform_int(tf_shgrp, "targetHeight", &g_tf_target_height, 1); + DRW_shgroup_uniform_int(tf_shgrp, "targetWidth", &g_tf_target_width, 1); + DRW_shgroup_uniform_int(tf_shgrp, "idOffset", &g_tf_id_offset, 1); +#endif + + drw_curves_cache_shgrp_attach_resources(tf_shgrp, cache, subdiv); + DRW_shgroup_call_procedural_points(tf_shgrp, nullptr, final_points_len); + } +} + +static CurvesEvalCache *drw_curves_cache_get(Object *object, + GPUMaterial *gpu_material, + int subdiv, + int thickness_res) +{ + CurvesEvalCache *cache; + bool update = curves_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res); + + if (update) { + if (drw_curves_shader_type_get() == PART_REFINE_SHADER_COMPUTE) { + drw_curves_cache_update_compute(cache, subdiv); + } + else { + drw_curves_cache_update_transform_feedback(cache, subdiv); + } + } + return cache; +} + +GPUVertBuf *DRW_curves_pos_buffer_get(Object *object) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + + int subdiv = scene->r.hair_subdiv; + int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2; + + CurvesEvalCache *cache = drw_curves_cache_get(object, nullptr, subdiv, thickness_res); + + return cache->final[subdiv].proc_buf; +} + +DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, + DRWShadingGroup *shgrp_parent, + GPUMaterial *gpu_material) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + Scene *scene = draw_ctx->scene; + + int subdiv = scene->r.hair_subdiv; + int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2; + + CurvesEvalCache *curves_cache = drw_curves_cache_get( + object, gpu_material, subdiv, thickness_res); + + DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent); + + /* Fix issue with certain driver not drawing anything if there is no texture bound to + * "ac", "au", "u" or "c". */ + DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture); + DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture); + DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture); + DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture); + + /* TODO: Generalize radius implementation for curves data type. */ + float hair_rad_shape = 1.0f; + float hair_rad_root = 0.005f; + float hair_rad_tip = 0.0f; + bool hair_close_tip = true; + + DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", curves_cache->final[subdiv].proc_tex); + if (curves_cache->length_tex) { + DRW_shgroup_uniform_texture(shgrp, "hairLen", curves_cache->length_tex); + } + DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &curves_cache->final[subdiv].strands_res, 1); + DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res); + DRW_shgroup_uniform_float_copy(shgrp, "hairRadShape", hair_rad_shape); + DRW_shgroup_uniform_mat4_copy(shgrp, "hairDupliMatrix", object->obmat); + DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", hair_rad_root); + DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip); + DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); + /* TODO(fclem): Until we have a better way to cull the curves and render with orco, bypass + * culling test. */ + GPUBatch *geom = curves_cache->final[subdiv].proc_hairs[thickness_res - 1]; + DRW_shgroup_call_no_cull(shgrp, geom, object); + + return shgrp; +} + +void DRW_curves_update() +{ + /* Update legacy hair too, to avoid verbosity in callers. */ + DRW_hair_update(); + +#ifndef USE_TRANSFORM_FEEDBACK + /** + * Workaround to transform feedback not working on mac. + * On some system it crashes (see T58489) and on some other it renders garbage (see T60171). + * + * So instead of using transform feedback we render to a texture, + * read back the result to system memory and re-upload as VBO data. + * It is really not ideal performance wise, but it is the simplest + * and the most local workaround that still uses the power of the GPU. + */ + + if (g_tf_calls == nullptr) { + return; + } + + /* Search ideal buffer size. */ + uint max_size = 0; + for (CurvesEvalCall *pr_call = g_tf_calls; pr_call; pr_call = pr_call->next) { + max_size = max_ii(max_size, pr_call->vert_len); + } + + /* Create target Texture / Frame-buffer */ + /* Don't use max size as it can be really heavy and fail. + * Do chunks of maximum 2048 * 2048 hair points. */ + int width = 2048; + int height = min_ii(width, 1 + max_size / width); + GPUTexture *tex = DRW_texture_pool_query_2d( + width, height, GPU_RGBA32F, (DrawEngineType *)DRW_curves_update); + g_tf_target_height = height; + g_tf_target_width = width; + + GPUFrameBuffer *fb = nullptr; + GPU_framebuffer_ensure_config(&fb, + { + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(tex), + }); + + float *data = static_cast<float *>( + MEM_mallocN(sizeof(float[4]) * width * height, "tf fallback buffer")); + + GPU_framebuffer_bind(fb); + while (g_tf_calls != nullptr) { + CurvesEvalCall *pr_call = g_tf_calls; + g_tf_calls = g_tf_calls->next; + + g_tf_id_offset = 0; + while (pr_call->vert_len > 0) { + int max_read_px_len = min_ii(width * height, pr_call->vert_len); + + DRW_draw_pass_subset(g_tf_pass, pr_call->shgrp, pr_call->shgrp); + /* Read back result to main memory. */ + GPU_framebuffer_read_color(fb, 0, 0, width, height, 4, 0, GPU_DATA_FLOAT, data); + /* Upload back to VBO. */ + GPU_vertbuf_use(pr_call->vbo); + GPU_vertbuf_update_sub(pr_call->vbo, + sizeof(float[4]) * g_tf_id_offset, + sizeof(float[4]) * max_read_px_len, + data); + + g_tf_id_offset += max_read_px_len; + pr_call->vert_len -= max_read_px_len; + } + + MEM_freeN(pr_call); + } + + MEM_freeN(data); + GPU_framebuffer_free(fb); +#else + /* Just render the pass when using compute shaders or transform feedback. */ + DRW_draw_pass(g_tf_pass); + if (drw_curves_shader_type_get() == PART_REFINE_SHADER_COMPUTE) { + GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); + } +#endif +} + +void DRW_curves_free() +{ + DRW_hair_free(); + + GPU_VERTBUF_DISCARD_SAFE(g_dummy_vbo); + DRW_TEXTURE_FREE_SAFE(g_dummy_texture); +} diff --git a/source/blender/draw/intern/draw_curves_private.h b/source/blender/draw/intern/draw_curves_private.h new file mode 100644 index 00000000000..76d5f15319d --- /dev/null +++ b/source/blender/draw/intern/draw_curves_private.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2017 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup draw + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_THICKRES 2 /* see eHairType */ +#define MAX_HAIR_SUBDIV 4 /* see hair_subdiv rna */ + +typedef enum CurvesEvalShader { + CURVES_EVAL_CATMULL_ROM = 0, + CURVES_EVAL_BEZIER = 1, +} CurvesEvalShader; +#define CURVES_EVAL_SHADER_NUM 3 + +struct GPUVertBuf; +struct GPUIndexBuf; +struct GPUBatch; +struct GPUTexture; + +typedef struct CurvesEvalFinalCache { + /* Output of the subdivision stage: vertex buffer sized to subdiv level. */ + GPUVertBuf *proc_buf; + GPUTexture *proc_tex; + + /* Just contains a huge index buffer used to draw the final curves. */ + GPUBatch *proc_hairs[MAX_THICKRES]; + + /* Points per curve, at least 2. */ + int strands_res; +} CurvesEvalFinalCache; + +/* Curves procedural display: Evaluation is done on the GPU. */ +typedef struct CurvesEvalCache { + /* Input control points */ + GPUVertBuf *proc_point_buf; + GPUTexture *point_tex; + + /** Info of control points strands (segment count and base index) */ + GPUVertBuf *proc_strand_buf; + GPUTexture *strand_tex; + + /* Curve length data. */ + GPUVertBuf *proc_length_buf; + GPUTexture *length_tex; + + GPUVertBuf *proc_strand_seg_buf; + GPUTexture *strand_seg_tex; + + CurvesEvalFinalCache final[MAX_HAIR_SUBDIV]; + + int strands_len; + int elems_len; + int point_len; +} CurvesEvalCache; + +/** + * Ensure all textures and buffers needed for GPU accelerated drawing. + */ +bool curves_ensure_procedural_data(struct Object *object, + struct CurvesEvalCache **r_hair_cache, + struct GPUMaterial *gpu_material, + int subdiv, + int thickness_res); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c index 667bd24dddb..d3d4bbf505e 100644 --- a/source/blender/draw/intern/draw_fluid.c +++ b/source/blender/draw/intern/draw_fluid.c @@ -9,6 +9,7 @@ #include <string.h> +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -21,6 +22,8 @@ #include "GPU_texture.h" +#include "draw_manager.h" + #include "draw_common.h" /* Own include. */ #ifdef WITH_FLUID @@ -419,46 +422,6 @@ static bool get_smoke_velocity_field(FluidDomainSettings *fds, /** \name Public API * \{ */ -void DRW_smoke_free(FluidModifierData *fmd) -{ - if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { - if (fmd->domain->tex_density) { - GPU_texture_free(fmd->domain->tex_density); - fmd->domain->tex_density = NULL; - } - - if (fmd->domain->tex_color) { - GPU_texture_free(fmd->domain->tex_color); - fmd->domain->tex_color = NULL; - } - - if (fmd->domain->tex_shadow) { - GPU_texture_free(fmd->domain->tex_shadow); - fmd->domain->tex_shadow = NULL; - } - - if (fmd->domain->tex_flame) { - GPU_texture_free(fmd->domain->tex_flame); - fmd->domain->tex_flame = NULL; - } - - if (fmd->domain->tex_flame_coba) { - GPU_texture_free(fmd->domain->tex_flame_coba); - fmd->domain->tex_flame_coba = NULL; - } - - if (fmd->domain->tex_coba) { - GPU_texture_free(fmd->domain->tex_coba); - fmd->domain->tex_coba = NULL; - } - - if (fmd->domain->tex_field) { - GPU_texture_free(fmd->domain->tex_field); - fmd->domain->tex_field = NULL; - } - } -} - void DRW_smoke_ensure_coba_field(FluidModifierData *fmd) { #ifndef WITH_FLUID @@ -469,6 +432,7 @@ void DRW_smoke_ensure_coba_field(FluidModifierData *fmd) if (!fds->tex_field) { fds->tex_field = create_field_texture(fds, false); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_field)); } if (!fds->tex_coba && !ELEM(fds->coba_field, FLUID_DOMAIN_FIELD_PHI, @@ -478,6 +442,7 @@ void DRW_smoke_ensure_coba_field(FluidModifierData *fmd) FLUID_DOMAIN_FIELD_FLAGS, FLUID_DOMAIN_FIELD_PRESSURE)) { fds->tex_coba = create_transfer_function(TFUNC_COLOR_RAMP, fds->coba); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_coba)); } } #endif @@ -493,19 +458,24 @@ void DRW_smoke_ensure(FluidModifierData *fmd, int highres) if (!fds->tex_density) { fds->tex_density = create_density_texture(fds, highres); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_density)); } if (!fds->tex_color) { fds->tex_color = create_color_texture(fds, highres); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_color)); } if (!fds->tex_flame) { fds->tex_flame = create_flame_texture(fds, highres); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flame)); } if (!fds->tex_flame_coba && fds->tex_flame) { fds->tex_flame_coba = create_transfer_function(TFUNC_FLAME_SPECTRUM, NULL); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flame_coba)); } if (!fds->tex_shadow) { fds->tex_shadow = create_volume_texture( fds->res, GPU_R8, GPU_DATA_FLOAT, manta_smoke_get_shadow(fds->fluid)); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_shadow)); } } #endif /* WITH_FLUID */ @@ -536,6 +506,9 @@ void DRW_smoke_ensure_velocity(FluidModifierData *fmd) "vely", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_y); fds->tex_velocity_z = GPU_texture_create_3d( "velz", UNPACK3(fds->res), 1, GPU_R16F, GPU_DATA_FLOAT, vel_z); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_x)); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_y)); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_velocity_z)); } } #endif /* WITH_FLUID */ @@ -551,6 +524,7 @@ void DRW_fluid_ensure_flags(FluidModifierData *fmd) if (!fds->tex_flags) { fds->tex_flags = create_volume_texture( fds->res, GPU_R8UI, GPU_DATA_INT, manta_smoke_get_flags(fds->fluid)); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_flags)); swizzle_texture_channel_single(fds->tex_flags); } @@ -568,42 +542,29 @@ void DRW_fluid_ensure_range_field(FluidModifierData *fmd) if (!fds->tex_range_field) { fds->tex_range_field = create_field_texture(fds, true); + BLI_addtail(&DST.vmempool->smoke_textures, BLI_genericNodeN(&fds->tex_range_field)); } } #endif /* WITH_FLUID */ } -void DRW_smoke_free_velocity(FluidModifierData *fmd) +void DRW_smoke_init(DRWData *drw_data) { - /* TODO: Unify with the other #GPU_free_smoke. */ - - if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { - if (fmd->domain->tex_velocity_x) { - GPU_texture_free(fmd->domain->tex_velocity_x); - } - - if (fmd->domain->tex_velocity_y) { - GPU_texture_free(fmd->domain->tex_velocity_y); - } - - if (fmd->domain->tex_velocity_z) { - GPU_texture_free(fmd->domain->tex_velocity_z); - } - - if (fmd->domain->tex_flags) { - GPU_texture_free(fmd->domain->tex_flags); - } - - if (fmd->domain->tex_range_field) { - GPU_texture_free(fmd->domain->tex_range_field); - } + BLI_listbase_clear(&drw_data->smoke_textures); +} - fmd->domain->tex_velocity_x = NULL; - fmd->domain->tex_velocity_y = NULL; - fmd->domain->tex_velocity_z = NULL; - fmd->domain->tex_flags = NULL; - fmd->domain->tex_range_field = NULL; +void DRW_smoke_exit(DRWData *drw_data) +{ + /* Free Smoke Textures after rendering */ + /* XXX This is a waste of processing and GPU bandwidth if nothing + * is updated. But the problem is since Textures are stored in the + * modifier we don't want them to take precious VRAM if the + * modifier is not used for display. We should share them for + * all viewport in a redraw at least. */ + LISTBASE_FOREACH (LinkData *, link, &drw_data->smoke_textures) { + GPU_TEXTURE_FREE_SAFE(*(GPUTexture **)link->data); } + BLI_freelistN(&drw_data->smoke_textures); } /** \} */ diff --git a/source/blender/draw/intern/draw_hair.c b/source/blender/draw/intern/draw_hair.c index aac6f7e58c5..8351452769d 100644 --- a/source/blender/draw/intern/draw_hair.c +++ b/source/blender/draw/intern/draw_hair.c @@ -179,25 +179,6 @@ static ParticleHairCache *drw_hair_particle_cache_get(Object *object, return cache; } -static ParticleHairCache *drw_curves_cache_get(Object *object, - GPUMaterial *gpu_material, - int subdiv, - int thickness_res) -{ - ParticleHairCache *cache; - bool update = curves_ensure_procedural_data(object, &cache, gpu_material, subdiv, thickness_res); - - if (update) { - if (drw_hair_shader_type_get() == PART_REFINE_SHADER_COMPUTE) { - drw_hair_particle_cache_update_compute(cache, subdiv); - } - else { - drw_hair_particle_cache_update_transform_feedback(cache, subdiv); - } - } - return cache; -} - GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, ModifierData *md) { const DRWContextState *draw_ctx = DRW_context_state_get(); @@ -212,19 +193,6 @@ GPUVertBuf *DRW_hair_pos_buffer_get(Object *object, ParticleSystem *psys, Modifi return cache->final[subdiv].proc_buf; } -GPUVertBuf *DRW_curves_pos_buffer_get(Object *object) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - - int subdiv = scene->r.hair_subdiv; - int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2; - - ParticleHairCache *cache = drw_curves_cache_get(object, NULL, subdiv, thickness_res); - - return cache->final[subdiv].proc_buf; -} - void DRW_hair_duplimat_get(Object *object, ParticleSystem *UNUSED(psys), ModifierData *UNUSED(md), @@ -323,71 +291,6 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, return shgrp; } -DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, - DRWShadingGroup *shgrp_parent, - GPUMaterial *gpu_material) -{ - const DRWContextState *draw_ctx = DRW_context_state_get(); - Scene *scene = draw_ctx->scene; - - int subdiv = scene->r.hair_subdiv; - int thickness_res = (scene->r.hair_type == SCE_HAIR_SHAPE_STRAND) ? 1 : 2; - - ParticleHairCache *curves_cache = drw_curves_cache_get( - object, gpu_material, subdiv, thickness_res); - - DRWShadingGroup *shgrp = DRW_shgroup_create_sub(shgrp_parent); - - /* TODO: optimize this. Only bind the ones GPUMaterial needs. */ - for (int i = 0; i < curves_cache->num_uv_layers; i++) { - for (int n = 0; n < MAX_LAYER_NAME_CT && curves_cache->uv_layer_names[i][n][0] != '\0'; n++) { - DRW_shgroup_uniform_texture( - shgrp, curves_cache->uv_layer_names[i][n], curves_cache->uv_tex[i]); - } - } - for (int i = 0; i < curves_cache->num_col_layers; i++) { - for (int n = 0; n < MAX_LAYER_NAME_CT && curves_cache->col_layer_names[i][n][0] != '\0'; n++) { - DRW_shgroup_uniform_texture( - shgrp, curves_cache->col_layer_names[i][n], curves_cache->col_tex[i]); - } - } - - /* Fix issue with certain driver not drawing anything if there is no texture bound to - * "ac", "au", "u" or "c". */ - if (curves_cache->num_uv_layers == 0) { - DRW_shgroup_uniform_texture(shgrp, "u", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "au", g_dummy_texture); - } - if (curves_cache->num_col_layers == 0) { - DRW_shgroup_uniform_texture(shgrp, "c", g_dummy_texture); - DRW_shgroup_uniform_texture(shgrp, "ac", g_dummy_texture); - } - - /* TODO: Generalize radius implementation for curves data type. */ - float hair_rad_shape = 1.0f; - float hair_rad_root = 0.005f; - float hair_rad_tip = 0.0f; - bool hair_close_tip = true; - - DRW_shgroup_uniform_texture(shgrp, "hairPointBuffer", curves_cache->final[subdiv].proc_tex); - if (curves_cache->length_tex) { - DRW_shgroup_uniform_texture(shgrp, "hairLen", curves_cache->length_tex); - } - DRW_shgroup_uniform_int(shgrp, "hairStrandsRes", &curves_cache->final[subdiv].strands_res, 1); - DRW_shgroup_uniform_int_copy(shgrp, "hairThicknessRes", thickness_res); - DRW_shgroup_uniform_float_copy(shgrp, "hairRadShape", hair_rad_shape); - DRW_shgroup_uniform_mat4_copy(shgrp, "hairDupliMatrix", object->obmat); - DRW_shgroup_uniform_float_copy(shgrp, "hairRadRoot", hair_rad_root); - DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip); - DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); - /* TODO(fclem): Until we have a better way to cull the curves and render with orco, bypass - * culling test. */ - GPUBatch *geom = curves_cache->final[subdiv].proc_hairs[thickness_res - 1]; - DRW_shgroup_call_no_cull(shgrp, geom, object); - - return shgrp; -} - void DRW_hair_update(void) { #ifndef USE_TRANSFORM_FEEDBACK diff --git a/source/blender/draw/intern/draw_hair_private.h b/source/blender/draw/intern/draw_hair_private.h index 58e8609106b..5d84c8863f2 100644 --- a/source/blender/draw/intern/draw_hair_private.h +++ b/source/blender/draw/intern/draw_hair_private.h @@ -75,8 +75,6 @@ typedef struct ParticleHairCache { int point_len; } ParticleHairCache; -void particle_batch_cache_clear_hair(struct ParticleHairCache *hair_cache); - /** * Ensure all textures and buffers needed for GPU accelerated drawing. */ @@ -88,15 +86,6 @@ bool particles_ensure_procedural_data(struct Object *object, int subdiv, int thickness_res); -/** - * Ensure all textures and buffers needed for GPU accelerated drawing. - */ -bool curves_ensure_procedural_data(struct Object *object, - struct ParticleHairCache **r_hair_cache, - struct GPUMaterial *gpu_material, - int subdiv, - int thickness_res); - #ifdef __cplusplus } #endif diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 88d05fcd928..adf9d4a13df 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -478,6 +478,7 @@ void DRW_viewport_data_free(DRWData *drw_data) MEM_freeN(drw_data->matrices_ubo); MEM_freeN(drw_data->obinfos_ubo); } + DRW_volume_ubos_pool_free(drw_data->volume_grids_ubos); MEM_freeN(drw_data); } @@ -1649,7 +1650,9 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, DRW_globals_update(); drw_debug_init(); - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); /* No frame-buffer allowed before drawing. */ BLI_assert(GPU_framebuffer_active_get() == GPU_framebuffer_back_get()); @@ -1704,7 +1707,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, GPU_framebuffer_bind(DST.default_framebuffer); GPU_framebuffer_clear_depth_stencil(DST.default_framebuffer, 1.0f, 0xFF); - DRW_hair_update(); + DRW_curves_update(); DRW_draw_callbacks_pre_scene(); @@ -1715,6 +1718,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, GPU_flush(); } + DRW_smoke_exit(DST.vmempool); + DRW_stats_reset(); DRW_draw_callbacks_post_scene(); @@ -1999,6 +2004,8 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) GPU_framebuffer_restore(); + DRW_smoke_exit(DST.vmempool); + drw_manager_exit(&DST); /* Reset state after drawing */ @@ -2015,7 +2022,9 @@ void DRW_render_object_iter( void (*callback)(void *vedata, Object *ob, RenderEngine *engine, struct Depsgraph *depsgraph)) { const DRWContextState *draw_ctx = DRW_context_state_get(); - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); drw_task_graph_init(); const int object_type_exclude_viewport = draw_ctx->v3d ? @@ -2070,7 +2079,9 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type, drw_manager_init(&DST, NULL, NULL); - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); ViewportEngineData *data = DRW_view_data_engine_data_get_ensure(DST.view_data_active, draw_engine_type); @@ -2079,6 +2090,8 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type, callback(data, user_data); DST.buffer_finish_called = false; + DRW_smoke_exit(DST.vmempool); + GPU_framebuffer_restore(); /* The use of custom pipeline in other thread using the same @@ -2095,11 +2108,15 @@ void DRW_custom_pipeline(DrawEngineType *draw_engine_type, void DRW_cache_restart(void) { + DRW_smoke_exit(DST.vmempool); + drw_manager_init(&DST, DST.viewport, (int[2]){UNPACK2(DST.size)}); DST.buffer_finish_called = false; - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); } void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, @@ -2416,7 +2433,9 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, /* Init engines */ drw_engines_init(); - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); { drw_engines_cache_init(); @@ -2493,7 +2512,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, DRW_state_reset(); DRW_draw_callbacks_pre_scene(); - DRW_hair_update(); + DRW_curves_update(); /* Only 1-2 passes. */ while (true) { @@ -2511,6 +2530,8 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, } } + DRW_smoke_exit(DST.vmempool); + DRW_state_reset(); drw_engines_disable(); @@ -2586,7 +2607,9 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph, /* Init engines */ drw_engines_init(); - DRW_hair_init(); + DRW_curves_init(); + DRW_volume_init(DST.vmempool); + DRW_smoke_init(DST.vmempool); { drw_engines_cache_init(); @@ -2619,10 +2642,12 @@ static void drw_draw_depth_loop_impl(struct Depsgraph *depsgraph, /* Start Drawing */ DRW_state_reset(); - DRW_hair_update(); + DRW_curves_update(); drw_engines_draw_scene(); + DRW_smoke_exit(DST.vmempool); + DRW_state_reset(); /* TODO: Reading depth for operators should be done here. */ @@ -3008,7 +3033,8 @@ void DRW_engines_free(void) GPU_FRAMEBUFFER_FREE_SAFE(g_select_buffer.framebuffer_depth_only); DRW_shaders_free(); - DRW_hair_free(); + DRW_curves_free(); + DRW_volume_free(); DRW_shape_cache_free(); DRW_stats_free(); DRW_globals_free(); diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 832897b7040..8812f112014 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -527,6 +527,10 @@ typedef struct DRWData { struct GPUUniformBuf **obinfos_ubo; struct GHash *obattrs_ubo_pool; uint ubo_len; + /** Per draw-call volume object data. */ + void *volume_grids_ubos; /* VolumeUniformBufPool */ + /** List of smoke textures to free after drawing. */ + ListBase smoke_textures; /** Texture pool to reuse temp texture across engines. */ /* TODO(@fclem): The pool could be shared even between view-ports. */ struct DRWTexturePool *texture_pool; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 39f083aaf96..b5432da0957 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -15,6 +15,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_pbvh.h" +#include "BKE_volume.h" #include "DNA_curve_types.h" #include "DNA_mesh_types.h" @@ -555,10 +556,19 @@ void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup, static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4]) { ID *ob_data = (ob) ? ob->data : NULL; + float loc[3], size[3]; float *texcoloc = NULL; float *texcosize = NULL; if (ob_data != NULL) { switch (GS(ob_data->name)) { + case ID_VO: { + BoundBox *bbox = BKE_volume_boundbox_get(ob); + mid_v3_v3v3(loc, bbox->vec[0], bbox->vec[6]); + sub_v3_v3v3(size, bbox->vec[0], bbox->vec[6]); + texcoloc = loc; + texcosize = size; + break; + } case ID_ME: BKE_mesh_texspace_get_reference((Mesh *)ob_data, NULL, &texcoloc, &texcosize); break; diff --git a/source/blender/draw/intern/draw_shader.c b/source/blender/draw/intern/draw_shader.c index 53da300c106..487a09d313d 100644 --- a/source/blender/draw/intern/draw_shader.c +++ b/source/blender/draw/intern/draw_shader.c @@ -92,6 +92,30 @@ GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement, return e_data.hair_refine_sh[refinement]; } +GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type, eParticleRefineShaderType sh_type) +{ + /* TODO: Implement curves evaluation types (Bezier and Catmull Rom). */ + if (e_data.hair_refine_sh[type] == NULL) { + GPUShader *sh = NULL; + switch (sh_type) { + case PART_REFINE_SHADER_COMPUTE: + sh = hair_refine_shader_compute_create(type); + break; + case PART_REFINE_SHADER_TRANSFORM_FEEDBACK: + sh = hair_refine_shader_transform_feedback_create(type); + break; + case PART_REFINE_SHADER_TRANSFORM_FEEDBACK_WORKAROUND: + sh = hair_refine_shader_transform_feedback_workaround_create(type); + break; + default: + BLI_assert_msg(0, "Incorrect shader type"); + } + e_data.hair_refine_sh[type] = sh; + } + + return e_data.hair_refine_sh[type]; +} + /** \} */ void DRW_shaders_free(void) diff --git a/source/blender/draw/intern/draw_shader.h b/source/blender/draw/intern/draw_shader.h index 65b9cafc1d9..650e78c9362 100644 --- a/source/blender/draw/intern/draw_shader.h +++ b/source/blender/draw/intern/draw_shader.h @@ -7,6 +7,7 @@ #pragma once +#include "draw_curves_private.h" #include "draw_hair_private.h" #ifdef __cplusplus @@ -25,6 +26,10 @@ typedef enum eParticleRefineShaderType { struct GPUShader *DRW_shader_hair_refine_get(ParticleRefineShader refinement, eParticleRefineShaderType sh_type); + +struct GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type, + eParticleRefineShaderType sh_type); + void DRW_shaders_free(void); #ifdef __cplusplus diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 58875c0496a..db128fffde7 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -6,12 +6,16 @@ typedef struct ViewInfos ViewInfos; typedef struct ObjectMatrices ObjectMatrices; typedef struct ObjectInfos ObjectInfos; +typedef struct VolumeInfos VolumeInfos; #endif #define DRW_SHADER_SHARED_H #define DRW_RESOURCE_CHUNK_LEN 512 +/* Define the maximum number of grid we allow in a volume UBO. */ +#define DRW_GRID_PER_VOLUME_MAX 16 + struct ViewInfos { /* View matrices */ float4x4 persmat; @@ -63,6 +67,18 @@ struct ObjectInfos { }; BLI_STATIC_ASSERT_ALIGN(ViewInfos, 16) +struct VolumeInfos { + /* Object to grid-space. */ + float4x4 grids_xform[DRW_GRID_PER_VOLUME_MAX]; + /* NOTE: vec4 for alignment. Only float3 needed. */ + float4 color_mul; + float density_scale; + float temperature_mul; + float temperature_bias; + float _pad; +}; +BLI_STATIC_ASSERT_ALIGN(VolumeInfos, 16) + #define OrcoTexCoFactors (drw_infos[resource_id].drw_OrcoTexCoFactors) #define ObjectInfo (drw_infos[resource_id].drw_Infos) #define ObjectColor (drw_infos[resource_id].drw_ObjectColor) diff --git a/source/blender/draw/intern/draw_volume.cc b/source/blender/draw/intern/draw_volume.cc new file mode 100644 index 00000000000..8d9a6f486e2 --- /dev/null +++ b/source/blender/draw/intern/draw_volume.cc @@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup draw + * + * \brief Contains Volume object GPU attributes configuration. + */ + +#include "DRW_gpu_wrapper.hh" +#include "DRW_render.h" + +#include "DNA_fluid_types.h" +#include "DNA_volume_types.h" + +#include "BKE_fluid.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_volume.h" +#include "BKE_volume_render.h" + +#include "GPU_material.h" + +#include "draw_common.h" +#include "draw_manager.h" + +using namespace blender; +using namespace blender::draw; +using VolumeInfosBuf = blender::draw::UniformBuffer<VolumeInfos>; + +static struct { + GPUTexture *dummy_zero; + GPUTexture *dummy_one; + float dummy_grid_mat[4][4]; +} g_data = {}; + +struct VolumeUniformBufPool { + Vector<VolumeInfosBuf *> ubos; + uint used = 0; + + ~VolumeUniformBufPool() + { + for (VolumeInfosBuf *ubo : ubos) { + delete ubo; + } + } + + void reset() + { + used = 0; + } + + VolumeInfosBuf *alloc() + { + if (used >= ubos.size()) { + VolumeInfosBuf *buf = new VolumeInfosBuf(); + ubos.append(buf); + return buf; + } + return ubos[used++]; + } +}; + +void DRW_volume_ubos_pool_free(void *pool) +{ + delete reinterpret_cast<VolumeUniformBufPool *>(pool); +} + +static void drw_volume_globals_init() +{ + const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float one[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + g_data.dummy_zero = GPU_texture_create_3d( + "dummy_zero", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, zero); + g_data.dummy_one = GPU_texture_create_3d( + "dummy_one", 1, 1, 1, 1, GPU_RGBA8, GPU_DATA_FLOAT, one); + GPU_texture_wrap_mode(g_data.dummy_zero, true, true); + GPU_texture_wrap_mode(g_data.dummy_one, true, true); + + memset(g_data.dummy_grid_mat, 0, sizeof(g_data.dummy_grid_mat)); +} + +void DRW_volume_free(void) +{ + GPU_TEXTURE_FREE_SAFE(g_data.dummy_zero); + GPU_TEXTURE_FREE_SAFE(g_data.dummy_one); +} + +static GPUTexture *grid_default_texture(eGPUDefaultValue default_value) +{ + switch (default_value) { + case GPU_DEFAULT_0: + return g_data.dummy_zero; + case GPU_DEFAULT_1: + return g_data.dummy_one; + } + return g_data.dummy_zero; +} + +void DRW_volume_init(DRWData *drw_data) +{ + if (drw_data->volume_grids_ubos == nullptr) { + drw_data->volume_grids_ubos = new VolumeUniformBufPool(); + } + VolumeUniformBufPool *pool = (VolumeUniformBufPool *)drw_data->volume_grids_ubos; + pool->reset(); + + if (g_data.dummy_one == nullptr) { + drw_volume_globals_init(); + } +} + +static DRWShadingGroup *drw_volume_object_grids_init(Object *ob, + ListBase *attrs, + DRWShadingGroup *grp) +{ + VolumeUniformBufPool *pool = (VolumeUniformBufPool *)DST.vmempool->volume_grids_ubos; + VolumeInfosBuf &volume_infos = *pool->alloc(); + + Volume *volume = (Volume *)ob->data; + BKE_volume_load(volume, G.main); + + grp = DRW_shgroup_create_sub(grp); + + volume_infos.density_scale = BKE_volume_density_scale(volume, ob->obmat); + volume_infos.color_mul = float4(1.0f); + volume_infos.temperature_mul = 1.0f; + volume_infos.temperature_bias = 0.0f; + + /* Bind volume grid textures. */ + int grid_id = 0; + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, attrs) { + const VolumeGrid *volume_grid = BKE_volume_grid_find_for_read(volume, attr->name); + const DRWVolumeGrid *drw_grid = (volume_grid) ? + DRW_volume_batch_cache_get_grid(volume, volume_grid) : + nullptr; + + /* Handle 3 cases here: + * - Grid exists and texture was loaded -> use texture. + * - Grid exists but has zero size or failed to load -> use zero. + * - Grid does not exist -> use default value. */ + const GPUTexture *grid_tex = (drw_grid) ? drw_grid->texture : + (volume_grid) ? g_data.dummy_zero : + grid_default_texture(attr->default_value); + DRW_shgroup_uniform_texture(grp, attr->input_name, grid_tex); + + copy_m4_m4(volume_infos.grids_xform[grid_id++].ptr(), drw_grid->object_to_texture); + } + + volume_infos.push_update(); + + DRW_shgroup_uniform_block(grp, "drw_volume", volume_infos); + + return grp; +} + +static DRWShadingGroup *drw_volume_object_mesh_init(Scene *scene, + Object *ob, + ListBase *attrs, + DRWShadingGroup *grp) +{ + VolumeUniformBufPool *pool = (VolumeUniformBufPool *)DST.vmempool->volume_grids_ubos; + VolumeInfosBuf &volume_infos = *pool->alloc(); + + ModifierData *md = nullptr; + + volume_infos.density_scale = 1.0f; + volume_infos.color_mul = float4(1.0f); + volume_infos.temperature_mul = 1.0f; + volume_infos.temperature_bias = 0.0f; + + /* Smoke Simulation */ + if ((md = BKE_modifiers_findby_type(ob, eModifierType_Fluid)) && + (BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) && + ((FluidModifierData *)md)->domain != nullptr) { + FluidModifierData *fmd = (FluidModifierData *)md; + FluidDomainSettings *fds = fmd->domain; + + /* Don't try to show liquid domains here. */ + if (!fds->fluid || !(fds->type == FLUID_DOMAIN_TYPE_GAS)) { + return nullptr; + } + + if (fds->fluid && (fds->type == FLUID_DOMAIN_TYPE_GAS)) { + DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE); + } + + grp = DRW_shgroup_create_sub(grp); + + int grid_id = 0; + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, attrs) { + if (STREQ(attr->name, "density")) { + DRW_shgroup_uniform_texture_ref( + grp, attr->input_name, fds->tex_density ? &fds->tex_density : &g_data.dummy_one); + } + else if (STREQ(attr->name, "color")) { + DRW_shgroup_uniform_texture_ref( + grp, attr->input_name, fds->tex_color ? &fds->tex_color : &g_data.dummy_one); + } + else if (STR_ELEM(attr->name, "flame", "temperature")) { + DRW_shgroup_uniform_texture_ref( + grp, attr->input_name, fds->tex_flame ? &fds->tex_flame : &g_data.dummy_zero); + } + else { + DRW_shgroup_uniform_texture( + grp, attr->input_name, grid_default_texture(attr->default_value)); + } + copy_m4_m4(volume_infos.grids_xform[grid_id++].ptr(), g_data.dummy_grid_mat); + } + + bool use_constant_color = ((fds->active_fields & FLUID_DOMAIN_ACTIVE_COLORS) == 0 && + (fds->active_fields & FLUID_DOMAIN_ACTIVE_COLOR_SET) != 0); + if (use_constant_color) { + volume_infos.color_mul = float4(UNPACK3(fds->active_color), 1.0f); + } + + /* Output is such that 0..1 maps to 0..1000K */ + volume_infos.temperature_mul = fds->flame_max_temp - fds->flame_ignition; + volume_infos.temperature_bias = fds->flame_ignition; + } + else { + grp = DRW_shgroup_create_sub(grp); + + int grid_id = 0; + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, attrs) { + DRW_shgroup_uniform_texture( + grp, attr->input_name, grid_default_texture(attr->default_value)); + copy_m4_m4(volume_infos.grids_xform[grid_id++].ptr(), g_data.dummy_grid_mat); + } + } + + volume_infos.push_update(); + + DRW_shgroup_uniform_block(grp, "drw_volume", volume_infos); + + return grp; +} + +static DRWShadingGroup *drw_volume_world_grids_init(ListBase *attrs, DRWShadingGroup *grp) +{ + /* Bind default volume grid textures. */ + LISTBASE_FOREACH (GPUMaterialAttribute *, attr, attrs) { + DRW_shgroup_uniform_texture(grp, attr->input_name, grid_default_texture(attr->default_value)); + } + return grp; +} + +DRWShadingGroup *DRW_shgroup_volume_create_sub(Scene *scene, + Object *ob, + DRWShadingGroup *shgrp, + GPUMaterial *gpu_material) +{ + ListBase attrs = GPU_material_attributes(gpu_material); + + if (ob == nullptr) { + return drw_volume_world_grids_init(&attrs, shgrp); + } + if (ob->type == OB_VOLUME) { + return drw_volume_object_grids_init(ob, &attrs, shgrp); + } + return drw_volume_object_mesh_init(scene, ob, &attrs, shgrp); +} diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc index d52226a4c90..4cb68cad66c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_vcol.cc @@ -173,7 +173,7 @@ static void extract_vcol_init(const MeshRenderData *mr, } BMIter iter; - const bool is_byte = ref.layer->type == CD_MLOOPCOL; + const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR; const bool is_point = ref.domain == ATTR_DOMAIN_POINT; BMFace *f; @@ -318,7 +318,7 @@ static void extract_vcol_init_subdiv(const DRWSubdivCache *subdiv_cache, BMIter iter; BMFace *f; int cd_ofs = cdata->layers[layer_i].offset; - const bool is_byte = ref.layer->type == CD_MLOOPCOL; + const bool is_byte = ref.layer->type == CD_PROP_BYTE_COLOR; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { BMLoop *l_iter = f->l_first; diff --git a/source/blender/draw/intern/shaders/common_attribute_lib.glsl b/source/blender/draw/intern/shaders/common_attribute_lib.glsl index 99db2929a13..30239a84c0c 100644 --- a/source/blender/draw/intern/shaders/common_attribute_lib.glsl +++ b/source/blender/draw/intern/shaders/common_attribute_lib.glsl @@ -19,3 +19,15 @@ vec4 attr_load_vec4(samplerBuffer attr); vec3 attr_load_vec3(samplerBuffer attr); vec2 attr_load_vec2(samplerBuffer attr); float attr_load_float(samplerBuffer attr); + +vec3 attr_load_orco(sampler3D orco); +vec4 attr_load_tangent(sampler3D tangent); +vec3 attr_load_uv(sampler3D attr); +vec4 attr_load_color(sampler3D tex); +vec4 attr_load_vec4(sampler3D tex); +vec3 attr_load_vec3(sampler3D tex); +vec2 attr_load_vec2(sampler3D tex); +float attr_load_float(sampler3D tex); + +float attr_load_temperature_post(float attr); +vec4 attr_load_color_post(vec4 attr); diff --git a/source/blender/draw/intern/shaders/draw_object_infos_info.hh b/source/blender/draw/intern/shaders/draw_object_infos_info.hh index 392b016fc3b..c74a043ec97 100644 --- a/source/blender/draw/intern/shaders/draw_object_infos_info.hh +++ b/source/blender/draw/intern/shaders/draw_object_infos_info.hh @@ -6,3 +6,7 @@ GPU_SHADER_CREATE_INFO(draw_object_infos) .typedef_source("draw_shader_shared.h") .define("OBINFO_LIB") .uniform_buf(1, "ObjectInfos", "drw_infos[DRW_RESOURCE_CHUNK_LEN]", Frequency::BATCH); + +GPU_SHADER_CREATE_INFO(draw_volume_infos) + .typedef_source("draw_shader_shared.h") + .uniform_buf(2, "VolumeInfos", "drw_volume", Frequency::BATCH); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 5b742ddf272..14a3b958ea6 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1126,17 +1126,17 @@ static void get_keyframe_values_create_reports(ReportList *reports, for (int i = 0; i < count; i++) { const bool cur_index_evaluated = ELEM(index, i, -1) || force_all; if (!cur_index_evaluated) { - /* values[i] was never intended to be remapped. */ + /* `values[i]` was never intended to be remapped. */ continue; } if (BLI_BITMAP_TEST_BOOL(successful_remaps, i)) { - /* values[i] succesfully remapped. */ + /* `values[i]` successfully remapped. */ continue; } total_failed++; - /* Report that values[i] were intended to be remapped but failed remapping process. */ + /* Report that `values[i]` were intended to be remapped but failed remapping process. */ BLI_dynstr_appendf(ds_failed_indices, "%d, ", i); } diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 467b8efa622..452f1df86fb 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -241,7 +241,6 @@ enum class ConvertAttributeMode { Generic, UVMap, VertexGroup, - VertexColor, }; static bool geometry_attribute_convert_poll(bContext *C) @@ -288,7 +287,7 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) const CustomDataType dst_type = static_cast<CustomDataType>( RNA_enum_get(op->ptr, "data_type")); - if (ELEM(dst_type, CD_PROP_STRING, CD_MLOOPCOL)) { + if (ELEM(dst_type, CD_PROP_STRING)) { BKE_report(op->reports, RPT_ERROR, "Cannot convert to the selected type"); return OPERATOR_CANCELLED; } @@ -314,20 +313,6 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) &mesh->ldata, CD_MLOOPUV, CD_ASSIGN, dst_uvs, mesh->totloop, name.c_str()); break; } - case ConvertAttributeMode::VertexColor: { - MLoopCol *dst_colors = static_cast<MLoopCol *>( - MEM_calloc_arrayN(mesh->totloop, sizeof(MLoopCol), __func__)); - VArray<ColorGeometry4f> src_varray = mesh_component.attribute_get_for_read<ColorGeometry4f>( - name, ATTR_DOMAIN_CORNER, ColorGeometry4f{0.0f, 0.0f, 0.0f, 1.0f}); - for (const int i : IndexRange(mesh->totloop)) { - ColorGeometry4b encoded_color = src_varray[i].encode(); - copy_v4_v4_uchar(&dst_colors[i].r, &encoded_color.r); - } - mesh_component.attribute_try_delete(name); - CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPCOL, CD_ASSIGN, dst_colors, mesh->totloop, name.c_str()); - break; - } case ConvertAttributeMode::VertexGroup: { Array<float> src_weights(mesh->totvert); VArray<float> src_varray = mesh_component.attribute_get_for_read<float>( @@ -385,7 +370,7 @@ void GEOMETRY_OT_color_attribute_add(wmOperatorType *ot) {0, nullptr, 0, nullptr, nullptr}}; static EnumPropertyItem types[3] = {{CD_PROP_COLOR, "COLOR", 0, "Color", ""}, - {CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", ""}, + {CD_PROP_BYTE_COLOR, "BYTE_COLOR", 0, "Byte Color", ""}, {0, nullptr, 0, nullptr, nullptr}}; prop = RNA_def_enum(ot->srna, @@ -415,9 +400,9 @@ static int geometry_color_attribute_set_render_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "name", name); CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT); - layer = !layer ? BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_POINT) : layer; + layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_POINT) : layer; layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER) : layer; - layer = !layer ? BKE_id_attribute_find(id, name, CD_MLOOPCOL, ATTR_DOMAIN_CORNER) : layer; + layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER) : layer; if (layer) { BKE_id_attributes_render_color_set(id, layer); @@ -550,7 +535,6 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) {int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""}, {int(ConvertAttributeMode::UVMap), "UV_MAP", 0, "UV Map", ""}, {int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""}, - {int(ConvertAttributeMode::VertexColor), "VERTEX_COLOR", 0, "Color Attribute", ""}, {0, nullptr, 0, nullptr, nullptr}, }; diff --git a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c index e4cb6d149f5..54aa5d16941 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/cage2d_gizmo.c @@ -99,7 +99,7 @@ static void cage2d_draw_box_corners(const rctf *r, const float color[3], const float line_width) { - /* Note(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */ + /* NOTE(Metal): Prefer using 3D coordinates with 3D shader, even if rendering 2D gizmo's. */ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_POLYLINE_UNIFORM_COLOR); @@ -442,7 +442,7 @@ static void imm_draw_point_aspect_2d( uint pos, float x, float y, float rad_x, float rad_y, bool solid) { if (solid) { - /* Note(Metal/AMD): Small Triangle-list primitives more optimal for GPU HW than Trianglestrip. + /* NOTE(Metal/AMD): Small Triangle-list primitives more optimal for GPU HW than Triangle-strip. */ immBegin(GPU_PRIM_TRIS, 6); immVertex2f(pos, x - rad_x, y - rad_y); @@ -455,7 +455,7 @@ static void imm_draw_point_aspect_2d( immEnd(); } else { - /* Note(Metal/AMD): Small Line-list primitives more optimal for GPU HW than Linestrip. */ + /* NOTE(Metal/AMD): Small Line-list primitives more optimal for GPU HW than Line-strip. */ immBegin(GPU_PRIM_LINES, 8); immVertex2f(pos, x - rad_x, y - rad_y); immVertex2f(pos, x - rad_x, y + rad_y); @@ -479,7 +479,7 @@ static void cage2d_draw_circle_wire(const rctf *r, const int draw_options, const float line_width) { - /* Note(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's. + /* NOTE(Metal): Prefer using 3D coordinates with 3D shader input, even if rendering 2D gizmo's. */ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); @@ -491,7 +491,7 @@ static void cage2d_draw_circle_wire(const rctf *r, immUniform2fv("viewportSize", &viewport[2]); immUniform1f("lineWidth", line_width * U.pixelsize); - /* Small 'lines' primitives more efficient for hardware processing than linestrip. */ + /* Small 'lines' primitives more efficient for hardware processing than line-strip. */ immBegin(GPU_PRIM_LINES, 8); immVertex3f(pos, r->xmin, r->ymin, 0.0f); immVertex3f(pos, r->xmax, r->ymin, 0.0f); diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 93a4a784674..7c7f532f087 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1313,7 +1313,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* Calc geometry data. */ BKE_gpencil_stroke_geometry_update(gpd, gps); - /* In Multiframe mode, duplicate the stroke in other frames. */ + /* In multi-frame mode, duplicate the stroke in other frames. */ if (GPENCIL_MULTIEDIT_SESSIONS_ON(p->gpd)) { const bool tail = (ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK); BKE_gpencil_stroke_copy_to_keyframes(gpd, gpl, p->gpf, gps, tail); diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h index fd4a28240fa..c69698f3f73 100644 --- a/source/blender/editors/include/ED_space_api.h +++ b/source/blender/editors/include/ED_space_api.h @@ -18,7 +18,7 @@ struct bContext; void ED_spacetypes_init(void); void ED_spacemacros_init(void); -/* the pluginnable API for export to editors */ +/* The plugin-able API for export to editors. */ /* -------------------------------------------------------------------- */ /** \name Calls for registering default spaces diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a5e2e9353bf..4e6437e043a 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -13,6 +13,7 @@ #include "DNA_brush_types.h" #include "DNA_cachefile_types.h" +#include "DNA_collection_types.h" #include "DNA_constraint_types.h" #include "DNA_curveprofile_types.h" #include "DNA_gpencil_modifier_types.h" @@ -588,6 +589,234 @@ void UI_context_active_but_prop_get_templateID(bContext *C, } } +static void template_id_liboverride_hierarchy_collection_root_find_recursive( + Collection *collection, + const int parent_level, + Collection **r_collection_parent_best, + int *r_parent_level_best) +{ + if (!ID_IS_LINKED(collection) && !ID_IS_OVERRIDE_LIBRARY_REAL(collection)) { + return; + } + if (ID_IS_OVERRIDABLE_LIBRARY(collection) || ID_IS_OVERRIDE_LIBRARY_REAL(collection)) { + if (parent_level > *r_parent_level_best) { + *r_parent_level_best = parent_level; + *r_collection_parent_best = collection; + } + } + for (CollectionParent *iter = collection->parents.first; iter != NULL; iter = iter->next) { + if (iter->collection->id.lib != collection->id.lib && ID_IS_LINKED(iter->collection)) { + continue; + } + template_id_liboverride_hierarchy_collection_root_find_recursive( + iter->collection, parent_level + 1, r_collection_parent_best, r_parent_level_best); + } +} + +static void template_id_liboverride_hierarchy_collections_tag_recursive( + Collection *root_collection, ID *target_id, const bool do_parents) +{ + root_collection->id.tag |= LIB_TAG_DOIT; + + /* Tag all local parents of the root collection, so that usages of the root collection and other + * linked ones can be replaced by the local overrides in those parents too. */ + if (do_parents) { + for (CollectionParent *iter = root_collection->parents.first; iter != NULL; + iter = iter->next) { + if (ID_IS_LINKED(iter->collection)) { + continue; + } + iter->collection->id.tag |= LIB_TAG_DOIT; + } + } + + for (CollectionChild *iter = root_collection->children.first; iter != NULL; iter = iter->next) { + if (iter->collection->id.lib != root_collection->id.lib && ID_IS_LINKED(root_collection)) { + continue; + } + if (ID_IS_LINKED(iter->collection) && iter->collection->id.lib != target_id->lib) { + continue; + } + if (GS(target_id->name) == ID_OB && + !BKE_collection_has_object_recursive(iter->collection, (Object *)target_id)) { + continue; + } + if (GS(target_id->name) == ID_GR && + !BKE_collection_has_collection(iter->collection, (Collection *)target_id)) { + continue; + } + template_id_liboverride_hierarchy_collections_tag_recursive( + iter->collection, target_id, false); + } +} + +static void template_id_liboverride_hierarchy_create(bContext *C, + Main *bmain, + TemplateID *template_ui, + PointerRNA *idptr, + const char **r_undo_push_label) +{ + ID *id = idptr->data; + ID *owner_id = template_ui->ptr.owner_id; + + /* Attempt to perform a hierarchy override, based on contextual data available. + * NOTE: do not attempt to perform such hierarchy override at all cost, if there is not enough + * context, better to abort than create random overrides all over the place. */ + if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id)) { + return; + } + + Object *object_active = CTX_data_active_object(C); + if (object_active == NULL && GS(owner_id->name) == ID_OB) { + object_active = (Object *)owner_id; + } + if (object_active != NULL) { + if (ID_IS_LINKED(object_active)) { + if (object_active->id.lib != id->lib || + !ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(object_active)) { + /* The active object is from a different library than the overridden ID, or otherwise + * cannot be used in hierarchy. */ + object_active = NULL; + } + } + else if (!ID_IS_OVERRIDE_LIBRARY_REAL(object_active)) { + /* Fully local object cannot be used in override hierarchy either. */ + object_active = NULL; + } + } + + Collection *collection_active = CTX_data_collection(C); + if (collection_active == NULL && GS(owner_id->name) == ID_GR) { + collection_active = (Collection *)owner_id; + } + if (collection_active != NULL) { + if (ID_IS_LINKED(collection_active)) { + if (collection_active->id.lib != id->lib || + !ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(collection_active)) { + /* The active collection is from a different library than the overridden ID, or otherwise + * cannot be used in hierarchy. */ + collection_active = NULL; + } + else { + int parent_level_best = -1; + Collection *collection_parent_best = NULL; + template_id_liboverride_hierarchy_collection_root_find_recursive( + collection_active, 0, &collection_parent_best, &parent_level_best); + collection_active = collection_parent_best; + } + } + else if (!ID_IS_OVERRIDE_LIBRARY_REAL(collection_active)) { + /* Fully local collection cannot be used in override hierarchy either. */ + collection_active = NULL; + } + } + if (collection_active == NULL && object_active != NULL && + (ID_IS_LINKED(object_active) || ID_IS_OVERRIDE_LIBRARY_REAL(object_active))) { + /* If we failed to find a valid 'active' collection so far for our override hierarchy, but do + * have a valid 'active' object, try to find a collection from that object. */ + LISTBASE_FOREACH (Collection *, collection_iter, &bmain->collections) { + if (!(ID_IS_LINKED(collection_iter) || ID_IS_OVERRIDE_LIBRARY_REAL(collection_iter))) { + continue; + } + if (!BKE_collection_has_object_recursive(collection_iter, object_active)) { + continue; + } + int parent_level_best = -1; + Collection *collection_parent_best = NULL; + template_id_liboverride_hierarchy_collection_root_find_recursive( + collection_iter, 0, &collection_parent_best, &parent_level_best); + collection_active = collection_parent_best; + break; + } + } + + ID *id_override = NULL; + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + switch (GS(id->name)) { + case ID_GR: + if (collection_active != NULL && + BKE_collection_has_collection(collection_active, (Collection *)id)) { + template_id_liboverride_hierarchy_collections_tag_recursive(collection_active, id, true); + if (object_active != NULL) { + object_active->id.tag |= LIB_TAG_DOIT; + } + BKE_lib_override_library_create( + bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + } + else if (object_active != NULL && !ID_IS_LINKED(object_active) && + &object_active->instance_collection->id == id) { + object_active->id.tag |= LIB_TAG_DOIT; + BKE_lib_override_library_create(bmain, + scene, + view_layer, + id->lib, + id, + &object_active->id, + &object_active->id, + &id_override); + } + break; + case ID_OB: + if (collection_active != NULL && + BKE_collection_has_object_recursive(collection_active, (Object *)id)) { + template_id_liboverride_hierarchy_collections_tag_recursive(collection_active, id, true); + if (object_active != NULL) { + object_active->id.tag |= LIB_TAG_DOIT; + } + BKE_lib_override_library_create( + bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + } + break; + case ID_ME: + case ID_CU_LEGACY: + case ID_MB: + case ID_LT: + case ID_LA: + case ID_CA: + case ID_SPK: + case ID_AR: + case ID_GD: + case ID_CV: + case ID_PT: + case ID_VO: + if (object_active != NULL && object_active->data == id) { + if (collection_active != NULL && + BKE_collection_has_object_recursive(collection_active, object_active)) { + template_id_liboverride_hierarchy_collections_tag_recursive(collection_active, id, true); + if (object_active != NULL) { + object_active->id.tag |= LIB_TAG_DOIT; + } + BKE_lib_override_library_create( + bmain, scene, view_layer, NULL, id, &collection_active->id, NULL, &id_override); + } + else { + object_active->id.tag |= LIB_TAG_DOIT; + BKE_lib_override_library_create( + bmain, scene, view_layer, NULL, id, &object_active->id, NULL, &id_override); + } + } + break; + case ID_MA: + case ID_TE: + case ID_IM: + break; + case ID_WO: + break; + case ID_PA: + break; + default: + break; + } + if (id_override != NULL) { + id_override->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_SYSTEM_DEFINED; + *r_undo_push_label = "Make Library Override Hierarchy"; + + WM_event_add_notifier(C, NC_WINDOW, NULL); + DEG_relations_tag_update(bmain); + } +} + static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) { TemplateID *template_ui = (TemplateID *)arg_litem; @@ -637,33 +866,8 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event) if (id) { Main *bmain = CTX_data_main(C); if (CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) { - if (ID_IS_OVERRIDABLE_LIBRARY(id)) { - /* Only remap that specific ID usage to overriding local data-block. */ - ID *override_id = BKE_lib_override_library_create_from_id(bmain, id, false); - if (override_id != NULL) { - BKE_main_id_newptr_and_tag_clear(bmain); - - if (GS(override_id->name) == ID_OB) { - Scene *scene = CTX_data_scene(C); - if (!BKE_collection_has_object_recursive(scene->master_collection, - (Object *)override_id)) { - BKE_collection_object_add_from( - bmain, scene, (Object *)id, (Object *)override_id); - } - } - - /* Assign new pointer, takes care of updates/notifiers */ - RNA_id_pointer_create(override_id, &idptr); - /* Insert into override hierarchy if possible. */ - ID *owner_id = template_ui->ptr.owner_id; - if (owner_id != NULL && ID_IS_OVERRIDE_LIBRARY_REAL(owner_id)) { - override_id->override_library->hierarchy_root = - owner_id->override_library->hierarchy_root; - owner_id->override_library->flag &= ~IDOVERRIDE_LIBRARY_FLAG_NO_HIERARCHY; - } - } - undo_push_label = "Make Library Override"; - } + template_id_liboverride_hierarchy_create( + C, bmain, template_ui, &idptr, &undo_push_label); } else { if (BKE_lib_id_make_local(bmain, id, 0)) { @@ -1006,6 +1210,7 @@ static void template_ID(const bContext *C, } if (ID_IS_LINKED(id)) { + const bool disabled = !BKE_idtype_idcode_is_localizable(GS(id->name)); if (id->tag & LIB_TAG_INDIRECT) { but = uiDefIconBut(block, UI_BTYPE_BUT, @@ -1020,12 +1225,10 @@ static void template_ID(const bContext *C, 0, 0, 0, - TIP_("Indirect library data-block, cannot change")); - UI_but_flag_enable(but, UI_BUT_DISABLED); + TIP_("Indirect library data-block, cannot be made local, " + "Shift + Click to create a library override hierarchy")); } else { - const bool disabled = (!BKE_idtype_idcode_is_localizable(GS(id->name)) || - (idfrom && idfrom->lib)); but = uiDefIconBut(block, UI_BTYPE_BUT, 0, @@ -1041,13 +1244,13 @@ static void template_ID(const bContext *C, 0, TIP_("Direct linked library data-block, click to make local, " "Shift + Click to create a library override")); - if (disabled) { - UI_but_flag_enable(but, UI_BUT_DISABLED); - } - else { - UI_but_funcN_set( - but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL)); - } + } + if (disabled) { + UI_but_flag_enable(but, UI_BUT_DISABLED); + } + else { + UI_but_funcN_set( + but, template_id_cb, MEM_dupallocN(template_ui), POINTER_FROM_INT(UI_ID_LOCAL)); } } else if (ID_IS_OVERRIDE_LIBRARY(id)) { diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c index beed4abd52b..3345d422bd1 100644 --- a/source/blender/editors/io/io_obj.c +++ b/source/blender/editors/io/io_obj.c @@ -438,7 +438,7 @@ void WM_OT_obj_import(struct wmOperatorType *ot) 0.0f, 1000.0f, "Clamp Bounding Box", - "Resize the objects to keep bounding box under this value. Value 0 diables clamping", + "Resize the objects to keep bounding box under this value. Value 0 disables clamping", 0.0f, 1000.0f); RNA_def_enum(ot->srna, diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index e3c3f1c38a0..0bd054e1b89 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -319,7 +319,7 @@ static int select_exec(bContext *C, wmOperator *op) ED_mask_view_lock_state_restore_no_jump(C, &lock_state); - return OPERATOR_FINISHED; + return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; } MaskSplinePointUW *uw; @@ -361,14 +361,14 @@ static int select_exec(bContext *C, wmOperator *op) ED_mask_view_lock_state_restore_no_jump(C, &lock_state); - return OPERATOR_FINISHED; + return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; } if (deselect_all) { /* For clip editor tracks, leave deselect all to clip editor. */ if (!ED_clip_can_select(C)) { ED_mask_deselect_all(C); ED_mask_view_lock_state_restore_no_jump(C, &lock_state); - return OPERATOR_FINISHED; + return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; } } @@ -386,7 +386,9 @@ static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event) RNA_float_set_array(op->ptr, "location", co); - return select_exec(C, op); + const int retval = select_exec(C, op); + + return WM_operator_flag_only_pass_through_on_press(retval, event); } void MASK_OT_select(wmOperatorType *ot) diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index d3fc83eedd7..7634ce6af9e 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -230,8 +230,6 @@ static int geometry_extract_apply(bContext *C, } } - BKE_mesh_calc_normals(new_ob->data); - WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob); BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL); DEG_relations_tag_update(bmain); @@ -551,7 +549,6 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) CustomData_free_layers(&new_ob_mesh->vdata, CD_PAINT_MASK, new_ob_mesh->totvert); BKE_mesh_nomain_to_mesh(new_ob_mesh, new_ob->data, new_ob, &CD_MASK_MESH, true); - BKE_mesh_calc_normals(new_ob->data); BKE_mesh_copy_parameters_for_eval(new_ob->data, mesh); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, new_ob); BKE_mesh_batch_cache_dirty_tag(new_ob->data, BKE_MESH_BATCH_DIRTY_ALL); @@ -561,7 +558,6 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) } BKE_mesh_nomain_to_mesh(new_mesh, ob->data, ob, &CD_MASK_MESH, true); - BKE_mesh_calc_normals(ob->data); if (ob->mode == OB_MODE_SCULPT) { SculptSession *ss = ob->sculpt; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 7feb04b3672..c3d5f33705c 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -937,7 +937,7 @@ bool EDBM_uv_check(BMEditMesh *em) bool EDBM_vert_color_check(BMEditMesh *em) { /* some of these checks could be a touch overkill */ - return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL); + return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_PROP_BYTE_COLOR); } /** \} */ diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 6f5c9d410c7..d11f0b490c1 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -109,7 +109,7 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) int layer_index, tot, n; char htype = BM_FACE; - if (ELEM(type, CD_MLOOPCOL, CD_MLOOPUV)) { + if (ELEM(type, CD_PROP_BYTE_COLOR, CD_MLOOPUV)) { htype = BM_LOOP; } else if (ELEM(type, CD_PROP_COLOR)) { @@ -379,25 +379,25 @@ int ED_mesh_color_add( if (me->edit_mesh) { em = me->edit_mesh; - layernum = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL); + layernum = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_BYTE_COLOR); if (layernum >= MAX_MCOL) { BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i vertex color layers", MAX_MCOL); return -1; } - /* CD_MLOOPCOL */ - BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPCOL, name); + /* CD_PROP_BYTE_COLOR */ + BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_BYTE_COLOR, name); /* copy data from active vertex color layer */ if (layernum && do_init) { - const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPCOL); - BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPCOL, layernum_dst, layernum); + const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_BYTE_COLOR); + BM_data_layer_copy(em->bm, &em->bm->ldata, CD_PROP_BYTE_COLOR, layernum_dst, layernum); } if (active_set || layernum == 0) { - CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPCOL, layernum); + CustomData_set_layer_active(&em->bm->ldata, CD_PROP_BYTE_COLOR, layernum); } } else { - layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); if (layernum >= MAX_MCOL) { BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i vertex color layers", MAX_MCOL); return -1; @@ -405,14 +405,15 @@ int ED_mesh_color_add( if (me->mloopcol && do_init) { CustomData_add_layer_named( - &me->ldata, CD_MLOOPCOL, CD_DUPLICATE, me->mloopcol, me->totloop, name); + &me->ldata, CD_PROP_BYTE_COLOR, CD_DUPLICATE, me->mloopcol, me->totloop, name); } else { - CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name); + CustomData_add_layer_named( + &me->ldata, CD_PROP_BYTE_COLOR, CD_DEFAULT, NULL, me->totloop, name); } if (active_set || layernum == 0) { - CustomData_set_layer_active(&me->ldata, CD_MLOOPCOL, layernum); + CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, layernum); } BKE_mesh_update_customdata_pointers(me, true); @@ -427,18 +428,20 @@ int ED_mesh_color_add( bool ED_mesh_color_ensure(struct Mesh *me, const char *name) { BLI_assert(me->edit_mesh == NULL); + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - if (!me->mloopcol && me->totloop) { - CustomData_add_layer_named(&me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, name); - int layer_i = CustomData_get_layer_index(&me->ldata, CD_MLOOPCOL); + if (!layer) { + CustomData_add_layer_named( + &me->ldata, CD_PROP_BYTE_COLOR, CD_DEFAULT, NULL, me->totloop, name); + layer = me->ldata.layers + CustomData_get_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); - BKE_id_attributes_active_color_set(&me->id, me->ldata.layers + layer_i); + BKE_id_attributes_active_color_set(&me->id, layer); BKE_mesh_update_customdata_pointers(me, true); } DEG_id_tag_update(&me->id, 0); - return (me->mloopcol != NULL); + return (layer != NULL); } bool ED_mesh_color_remove_index(Mesh *me, const int n) @@ -447,7 +450,7 @@ bool ED_mesh_color_remove_index(Mesh *me, const int n) CustomDataLayer *cdl; int index; - index = CustomData_get_layer_index_n(ldata, CD_MLOOPCOL, n); + index = CustomData_get_layer_index_n(ldata, CD_PROP_BYTE_COLOR, n); cdl = (index == -1) ? NULL : &ldata->layers[index]; if (!cdl) { @@ -463,7 +466,7 @@ bool ED_mesh_color_remove_index(Mesh *me, const int n) bool ED_mesh_color_remove_active(Mesh *me) { CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_active_layer(ldata, CD_MLOOPCOL); + const int n = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); if (n != -1) { return ED_mesh_color_remove_index(me, n); } @@ -472,7 +475,7 @@ bool ED_mesh_color_remove_active(Mesh *me) bool ED_mesh_color_remove_named(Mesh *me, const char *name) { CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_named_layer(ldata, CD_MLOOPCOL, name); + const int n = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, name); if (n != -1) { return ED_mesh_color_remove_index(me, n); } @@ -715,7 +718,7 @@ static bool vertex_color_remove_poll(bContext *C) Object *ob = ED_object_context(C); Mesh *me = ob->data; CustomData *ldata = GET_CD_DATA(me, ldata); - const int active = CustomData_get_active_layer(ldata, CD_MLOOPCOL); + const int active = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); if (active != -1) { return true; } @@ -1092,7 +1095,8 @@ void ED_mesh_update(Mesh *mesh, bContext *C, bool calc_edges, bool calc_edges_lo /* Default state is not to have tessface's so make sure this is the case. */ BKE_mesh_tessface_clear(mesh); - BKE_mesh_calc_normals(mesh); + /* Tag lazily calculated data as dirty. */ + BKE_mesh_normals_tag_dirty(mesh); DEG_id_tag_update(&mesh->id, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, mesh); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index d57471b658c..9575fde68f0 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -681,8 +681,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) /* tessface data removed above, no need to update */ BKE_mesh_update_customdata_pointers(me, false); - /* update normals in case objects with non-uniform scale are joined */ - BKE_mesh_calc_normals(me); + /* Tag normals dirty because vertex positions could be changed from the original. */ + BKE_mesh_normals_tag_dirty(me); /* old material array */ for (a = 1; a <= ob->totcol; a++) { diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index b3c5879b4d0..508d452bfe4 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -1638,7 +1638,7 @@ struct CollectionAddInfo { ushort local_view_bits; /* The transform that should be applied to the collection, determined through operator properties * if set (e.g. to place the collection under the cursor), otherwise through context (e.g. 3D - * cursor location). */ + * cursor location). */ float loc[3], rot[3]; }; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index d469efbd0a1..1483c24ac70 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -172,28 +172,35 @@ static bool multiresbake_check(bContext *C, wmOperator *op) ok = false; } else { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; - if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - ok = false; - } - else { - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { - ok = false; - } + if (!ibuf) { + BKE_report( + op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); - if (ibuf->rect_float && !(ELEM(ibuf->channels, 0, 4))) { ok = false; } - - if (!ok) { - BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); + else { + if (ibuf->rect == NULL && ibuf->rect_float == NULL) { + ok = false; + } + + if (ibuf->rect_float && !(ELEM(ibuf->channels, 0, 4))) { + ok = false; + } + + if (!ok) { + BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); + } } - } - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_release_ibuf(ima, ibuf, NULL); + } } } } @@ -274,21 +281,27 @@ static void clear_single_image(Image *image, ClearFlag flag) const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f}; if ((image->id.tag & LIB_TAG_DOIT) == 0) { - ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); + LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; - if (flag == CLEAR_TANGENT_NORMAL) { - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); - } - else if (flag == CLEAR_DISPLACEMENT) { - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); - } - else { - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - } + ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, NULL); - image->id.tag |= LIB_TAG_DOIT; + if (flag == CLEAR_TANGENT_NORMAL) { + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); + } + else if (flag == CLEAR_DISPLACEMENT) { + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); + } + else { + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); + } + + image->id.tag |= LIB_TAG_DOIT; - BKE_image_release_ibuf(image, ibuf, NULL); + BKE_image_release_ibuf(image, ibuf, NULL); + } } } diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index 3060a1ecf62..a7379d7e492 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -19,6 +19,7 @@ #include "BLI_fileops.h" #include "BLI_listbase.h" #include "BLI_path_util.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_global.h" @@ -165,6 +166,7 @@ static void bake_update_image(ScrArea *area, Image *image) } static bool write_internal_bake_pixels(Image *image, + const int image_tile_number, BakePixel pixel_array[], float *buffer, const int width, @@ -174,7 +176,8 @@ static bool write_internal_bake_pixels(Image *image, const bool is_clear, const bool is_noncolor, Mesh const *mesh_eval, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { ImBuf *ibuf; void *lock; @@ -182,7 +185,10 @@ static bool write_internal_bake_pixels(Image *image, char *mask_buffer = NULL; const size_t pixels_num = (size_t)width * (size_t)height; - ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = image_tile_number; + ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); if (!ibuf) { return false; @@ -270,7 +276,7 @@ static bool write_internal_bake_pixels(Image *image, /* margins */ if (margin > 0) { - RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer); + RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset); } ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; @@ -303,10 +309,8 @@ static void bake_targets_refresh(BakeTargets *targets) if (ima) { BKE_image_partial_update_mark_full_update(ima); - LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { - BKE_image_free_gputextures(ima); - DEG_id_tag_update(&ima->id, 0); - } + BKE_image_free_gputextures(ima); + DEG_id_tag_update(&ima->id, 0); } } } @@ -321,7 +325,8 @@ static bool write_external_bake_pixels(const char *filepath, ImageFormatData *im_format, const bool is_noncolor, Mesh const *mesh_eval, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { ImBuf *ibuf = NULL; bool ok = false; @@ -378,7 +383,7 @@ static bool write_external_bake_pixels(const char *filepath, mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask"); RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); - RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer); + RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset); if (mask_buffer) { MEM_freeN(mask_buffer); @@ -443,7 +448,7 @@ static bool bake_object_check(ViewLayer *view_layer, if (target == R_BAKE_TARGET_VERTEX_COLORS) { MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR); const bool mcol_valid = (mcol != NULL); - MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL); + MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); if (mloopcol == NULL && !mcol_valid) { BKE_reportf(reports, RPT_ERROR, @@ -467,7 +472,6 @@ static bool bake_object_check(ViewLayer *view_layer, ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree); if (image) { - ImBuf *ibuf; if (node) { if (BKE_node_is_connected_to_output(ntree, node)) { @@ -482,21 +486,27 @@ static bool bake_object_check(ViewLayer *view_layer, } } - void *lock; - ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); + LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; - if (ibuf) { - BKE_image_release_ibuf(image, ibuf, lock); - } - else { - BKE_reportf(reports, - RPT_ERROR, - "Uninitialized image \"%s\" from object \"%s\"", - image->id.name + 2, - ob->id.name + 2); + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock); + + if (ibuf) { + BKE_image_release_ibuf(image, ibuf, lock); + } + else { + BKE_reportf(reports, + RPT_ERROR, + "Uninitialized image \"%s\" from object \"%s\"", + image->id.name + 2, + ob->id.name + 2); - BKE_image_release_ibuf(image, ibuf, lock); - return false; + BKE_image_release_ibuf(image, ibuf, lock); + return false; + } } } else { @@ -687,36 +697,35 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, } } - /* Over-allocate in case there is more materials than images. */ + /* Allocate material mapping. */ targets->materials_num = materials_num; - targets->images = MEM_callocN(sizeof(BakeImage) * targets->materials_num, "BakeTargets.images"); - targets->material_to_image = MEM_callocN(sizeof(int) * targets->materials_num, + targets->material_to_image = MEM_callocN(sizeof(Image *) * targets->materials_num, "BakeTargets.material_to_image"); /* Error handling and tag (in case multiple materials share the same image). */ BKE_main_id_tag_idcode(bkr->main, ID_IM, LIB_TAG_DOIT, false); + targets->images = NULL; + for (int i = 0; i < materials_num; i++) { Image *image; ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); - /* Some materials have no image, we just ignore those cases. */ - if (image == NULL) { - targets->material_to_image[i] = -1; - } - else if (image->id.tag & LIB_TAG_DOIT) { - for (int j = 0; j < i; j++) { - if (targets->images[j].image == image) { - targets->material_to_image[i] = j; - break; - } + targets->material_to_image[i] = image; + + /* Some materials have no image, we just ignore those cases. + * Also setup each image only once. */ + if (image && !(image->id.tag & LIB_TAG_DOIT)) { + LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { + /* Add bake image. */ + targets->images = MEM_recallocN(targets->images, + sizeof(BakeImage) * (targets->images_num + 1)); + targets->images[targets->images_num].image = image; + targets->images[targets->images_num].tile_number = tile->tile_number; + targets->images_num++; } - } - else { - targets->material_to_image[i] = targets->images_num; - targets->images[targets->images_num].image = image; + image->id.tag |= LIB_TAG_DOIT; - targets->images_num++; } } @@ -735,13 +744,19 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr, /* Saving to image datablocks. */ for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; + + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = bk_image->tile_number; + void *lock; - ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, NULL, &lock); + ImBuf *ibuf = BKE_image_acquire_ibuf(bk_image->image, &iuser, &lock); if (ibuf) { bk_image->width = ibuf->x; bk_image->height = ibuf->y; bk_image->offset = targets->pixels_num; + BKE_image_get_tile_uv(bk_image->image, bk_image->tile_number, bk_image->uv_offset); targets->pixels_num += (size_t)ibuf->x * (size_t)ibuf->y; } @@ -768,6 +783,7 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr, for (int i = 0; i < targets->images_num; i++) { BakeImage *bk_image = &targets->images[i]; const bool ok = write_internal_bake_pixels(bk_image->image, + bk_image->tile_number, pixel_array + bk_image->offset, targets->result + bk_image->offset * targets->channels_num, @@ -778,7 +794,8 @@ static bool bake_targets_output_internal(const BakeAPIRender *bkr, bkr->is_clear, targets->is_noncolor, mesh_eval, - bkr->uv_layer); + bkr->uv_layer, + bk_image->uv_offset); /* might be read by UI to set active image for display */ bake_update_image(bkr->area, bk_image->image); @@ -815,7 +832,6 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr, bk_image->width = bkr->width; bk_image->height = bkr->height; bk_image->offset = targets->pixels_num; - bk_image->image = NULL; targets->pixels_num += (size_t)bkr->width * (size_t)bkr->height; @@ -827,7 +843,7 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr, if (!bkr->is_split_materials) { /* saving a single image */ for (int i = 0; i < targets->materials_num; i++) { - targets->material_to_image[i] = 0; + targets->material_to_image[i] = targets->images[0].image; } } @@ -865,25 +881,26 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr, } if (bkr->is_split_materials) { - if (bk_image->image) { - BLI_path_suffix(name, FILE_MAX, bk_image->image->id.name + 2, "_"); + if (ob_eval->mat[i]) { + BLI_path_suffix(name, FILE_MAX, ob_eval->mat[i]->id.name + 2, "_"); + } + else if (mesh_eval->mat[i]) { + BLI_path_suffix(name, FILE_MAX, mesh_eval->mat[i]->id.name + 2, "_"); } else { - if (ob_eval->mat[i]) { - BLI_path_suffix(name, FILE_MAX, ob_eval->mat[i]->id.name + 2, "_"); - } - else if (mesh_eval->mat[i]) { - BLI_path_suffix(name, FILE_MAX, mesh_eval->mat[i]->id.name + 2, "_"); - } - else { - /* if everything else fails, use the material index */ - char tmp[5]; - sprintf(tmp, "%d", i % 1000); - BLI_path_suffix(name, FILE_MAX, tmp, "_"); - } + /* if everything else fails, use the material index */ + char tmp[5]; + sprintf(tmp, "%d", i % 1000); + BLI_path_suffix(name, FILE_MAX, tmp, "_"); } } + if (bk_image->tile_number) { + char tmp[FILE_MAX]; + SNPRINTF(tmp, "%d", bk_image->tile_number); + BLI_path_suffix(name, FILE_MAX, tmp, "_"); + } + /* save it externally */ const bool ok = write_external_bake_pixels(name, pixel_array + bk_image->offset, @@ -896,7 +913,8 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr, &bake->im_format, targets->is_noncolor, mesh_eval, - bkr->uv_layer); + bkr->uv_layer, + bk_image->uv_offset); if (!ok) { BKE_reportf(reports, RPT_ERROR, "Problem saving baked map in \"%s\"", name); @@ -927,7 +945,7 @@ static bool bake_targets_init_vertex_colors(BakeTargets *targets, Object *ob, Re Mesh *me = ob->data; MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR); const bool mcol_valid = (mcol != NULL); - MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL); + MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); if (mloopcol == NULL && !mcol_valid) { BKE_report(reports, RPT_ERROR, "No vertex colors layer found to bake to"); return false; @@ -1081,7 +1099,7 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) Mesh *me = ob->data; MPropCol *mcol = CustomData_get_layer(&me->vdata, CD_PROP_COLOR); const bool mcol_valid = (mcol != NULL); - MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL); + MLoopCol *mloopcol = CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR); const int channels_num = targets->channels_num; const float *result = targets->result; diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 23d2327fe72..dfe858e5bd9 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -89,7 +89,7 @@ static void dt_add_vcol_layers(CustomData *cdata, EnumPropertyItem **r_item, int *r_totitem) { - int types[2] = {CD_PROP_COLOR, CD_MLOOPCOL}; + int types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; for (int i = 0; i < 2; i++) { CustomDataType type = types[i]; @@ -196,14 +196,14 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C, cddata_masks.vmask |= CD_MASK_PROP_COLOR; } if (data_type & (DT_TYPE_MLOOPCOL_VERT)) { - cddata_masks.vmask |= CD_MASK_MLOOPCOL; + cddata_masks.vmask |= CD_MASK_PROP_BYTE_COLOR; } if (data_type & (DT_TYPE_MPROPCOL_LOOP)) { cddata_masks.lmask |= CD_MASK_PROP_COLOR; } if (data_type & (DT_TYPE_MLOOPCOL_LOOP)) { - cddata_masks.lmask |= CD_MASK_MLOOPCOL; + cddata_masks.lmask |= CD_MASK_PROP_BYTE_COLOR; } Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index f7543c97903..8b2dbd4a865 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -855,7 +855,7 @@ bool ED_object_modifier_apply(Main *bmain, Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); ModifierData *md_eval = (ob_eval) ? BKE_modifiers_findby_name(ob_eval, md->name) : md; - /* allow apply of a not-realtime modifier, by first re-enabling realtime. */ + /* Allow apply of a non-real-time modifier, by first re-enabling real-time. */ int prev_mode = md_eval->mode; md_eval->mode |= eModifierMode_Realtime; diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index 966df0668ca..ba2efa6e517 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -40,6 +40,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_shrinkwrap.h" +#include "BKE_unit.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -282,7 +283,7 @@ static void voxel_size_parallel_lines_draw(uint pos3d, immEnd(); } -static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) +static void voxel_size_edit_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) { VoxelSizeEditCustomData *cd = static_cast<VoxelSizeEditCustomData *>(arg); @@ -338,8 +339,15 @@ static void voxel_size_edit_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), short fstyle_points = fstyle->points; char str[VOXEL_SIZE_EDIT_MAX_STR_LEN]; short strdrawlen = 0; - - BLI_snprintf(str, VOXEL_SIZE_EDIT_MAX_STR_LEN, "%.4f", cd->voxel_size); + Scene *scene = CTX_data_scene(C); + UnitSettings *unit = &scene->unit; + BKE_unit_value_as_string(str, + VOXEL_SIZE_EDIT_MAX_STR_LEN, + (double)(cd->voxel_size * unit->scale_length), + 4, + B_UNIT_LENGTH, + unit, + true); strdrawlen = BLI_strlen_utf8(str); immUnbindProgram(); @@ -885,9 +893,6 @@ static void quadriflow_start_job(void *customdata, short *stop, short *do_update BKE_mesh_nomain_to_mesh(new_mesh, mesh, ob, &CD_MASK_MESH, true); if (qj->smooth_normals) { - if (qj->use_mesh_symmetry) { - BKE_mesh_calc_normals(static_cast<Mesh *>(ob->data)); - } BKE_mesh_smooth_flag_set(static_cast<Mesh *>(ob->data), true); } diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index 976fe683f95..da3df159c33 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -884,9 +884,6 @@ static int apply_objects_internal(bContext *C, /* adjust data */ BKE_mesh_transform(me, mat, true); - - /* If normal layers exist, they are now dirty. */ - BKE_mesh_normals_tag_dirty(me); } else if (ob->type == OB_ARMATURE) { bArmature *arm = static_cast<bArmature *>(ob->data); @@ -1173,6 +1170,12 @@ void OBJECT_OT_transform_apply(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Apply Parent Inverse Operator + * \{ */ + static int object_parent_inverse_apply_exec(bContext *C, wmOperator *UNUSED(op)) { CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { @@ -1194,7 +1197,7 @@ void OBJECT_OT_parent_inverse_apply(wmOperatorType *ot) { /* identifiers */ ot->name = "Apply Parent Inverse"; - ot->description = "Apply the object's parent inverse to the its data"; + ot->description = "Apply the object's parent inverse to its data"; ot->idname = "OBJECT_OT_parent_inverse_apply"; /* api callbacks */ diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index abdae5c44f9..08eed52f440 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -48,7 +48,7 @@ set(SRC paint_ops.c paint_stroke.c paint_utils.c - paint_vertex.c + paint_vertex.cc paint_vertex_color_ops.c paint_vertex_color_utils.c paint_vertex_proj.c diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index 5f262384945..0d399419ad8 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -96,6 +96,7 @@ struct AddOperationExecutor { CurvesSculpt *curves_sculpt_ = nullptr; Brush *brush_ = nullptr; + BrushCurvesSculptSettings *brush_settings_ = nullptr; float brush_radius_re_; float2 brush_pos_re_; @@ -162,17 +163,18 @@ struct AddOperationExecutor { curves_sculpt_ = scene_->toolsettings->curves_sculpt; brush_ = BKE_paint_brush(&curves_sculpt_->paint); + brush_settings_ = brush_->curves_sculpt_settings; brush_radius_re_ = BKE_brush_size_get(scene_, brush_); brush_pos_re_ = stroke_extension.mouse_position; use_front_face_ = brush_->flag & BRUSH_FRONTFACE; const eBrushFalloffShape falloff_shape = static_cast<eBrushFalloffShape>( brush_->falloff_shape); - add_amount_ = std::max(0, brush_->curves_sculpt_settings->add_amount); - interpolate_length_ = curves_sculpt_->flag & CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH; - interpolate_shape_ = curves_sculpt_->flag & CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE; + add_amount_ = std::max(0, brush_settings_->add_amount); + interpolate_length_ = brush_settings_->flag & BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH; + interpolate_shape_ = brush_settings_->flag & BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE; use_interpolation_ = interpolate_length_ || interpolate_shape_; - new_curve_length_ = curves_sculpt_->curve_length; + new_curve_length_ = brush_settings_->curve_length; tot_old_curves_ = curves_->curves_num(); tot_old_points_ = curves_->points_num(); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 6a47f90d4ac..232d632aa3f 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -136,6 +136,9 @@ struct CombOperationExecutor { curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); + if (curves_->curves_num() == 0) { + return; + } brush_pos_prev_re_ = self_->brush_pos_last_re_; brush_pos_re_ = stroke_extension.mouse_position; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 7cc5e524c30..6228a643a76 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -311,6 +311,9 @@ struct CurvesEffectOperationExecutor { curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); + if (curves_->curves_num() == 0) { + return; + } CurvesSculpt &curves_sculpt = *scene_->toolsettings->curves_sculpt; brush_ = BKE_paint_brush(&curves_sculpt.paint); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index b367c5bb6ec..6d930d35f04 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -116,6 +116,9 @@ struct SnakeHookOperatorExecutor { curves_id_ = static_cast<Curves *>(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); + if (curves_->curves_num() == 0) { + return; + } brush_pos_prev_re_ = self.last_mouse_position_re_; brush_pos_re_ = stroke_extension.mouse_position; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index f784ebe4b4f..187f793eefe 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -133,7 +133,7 @@ void PAINT_OT_weight_gradient(struct wmOperatorType *ot); void PAINT_OT_vertex_paint_toggle(struct wmOperatorType *ot); void PAINT_OT_vertex_paint(struct wmOperatorType *ot); -unsigned int vpaint_get_current_col(struct Scene *scene, struct VPaint *vp, bool secondary); +unsigned int vpaint_get_current_color(struct Scene *scene, struct VPaint *vp, bool secondary); /* paint_vertex_color_utils.c */ diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 5929aa75b45..3ca686e9351 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -950,7 +950,6 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; Mesh *trim_mesh = trim_operation->mesh; - BKE_mesh_calc_normals(trim_mesh); const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(trim_mesh); BMesh *bm; @@ -1288,7 +1287,6 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) }), sculpt_mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); BKE_mesh_nomain_to_mesh( result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true); } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.cc index 33b92c22d3f..8b62dd33961 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -13,11 +13,14 @@ #include "MEM_guardedalloc.h" #include "BLI_array_utils.h" +#include "BLI_color.hh" +#include "BLI_color_mix.hh" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rect.h" #include "BLI_string.h" #include "BLI_task.h" +#include "BLI_task.hh" #include "DNA_brush_types.h" #include "DNA_mesh_types.h" @@ -26,6 +29,7 @@ #include "DNA_scene_types.h" #include "RNA_access.h" +#include "RNA_prototypes.h" #include "BKE_attribute.h" #include "BKE_brush.h" @@ -66,14 +70,53 @@ #include "paint_intern.h" /* own include */ #include "sculpt_intern.h" +using blender::IndexRange; +using namespace blender; +using namespace blender::color; + /* -------------------------------------------------------------------- */ /** \name Internal Utilities * \{ */ +static uint color2uint(ColorPaint4b c) +{ + return *(reinterpret_cast<uint *>(&c)); +} + +static bool isZero(ColorPaint4f c) +{ + return c.r == 0.0f && c.g == 0.0f && c.b == 0.0f && c.a == 0.0f; +} + +static bool isZero(ColorPaint4b c) +{ + return c.r == 0 && c.g == 0 && c.b == 0 && c.a == 0; +} + +template<typename Color = ColorPaint4f> static ColorPaint4f toFloat(const Color &c) +{ + if constexpr (std::is_same_v<Color, ColorPaint4b>) { + return c.decode(); + } + else { + return c; + } +} + +template<typename Color = ColorPaint4f> static Color fromFloat(const ColorPaint4f &c) +{ + if constexpr (std::is_same_v<Color, ColorPaint4b>) { + return c.encode(); + } + else { + return c; + } +} + /* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */ -struct VPaintAverageAccum { - uint len; - uint value[3]; +template<typename BlendType> struct VPaintAverageAccum { + BlendType len; + BlendType value[3]; }; struct WPaintAverageAccum { @@ -93,7 +136,27 @@ struct NormalAnglePrecalc { float angle_range; }; -static void view_angle_limits_init(struct NormalAnglePrecalc *a, float angle, bool do_mask_normal) +/* Returns number of elements. */ +static int get_vcol_elements(Mesh *me, size_t *r_elem_size) +{ + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + + if (r_elem_size) { + *r_elem_size = layer->type == CD_PROP_COLOR ? sizeof(float) * 4ULL : 4ULL; + } + + switch (domain) { + case ATTR_DOMAIN_POINT: + return me->totvert; + case ATTR_DOMAIN_CORNER: + return me->totloop; + default: + return 0; + } +} + +static void view_angle_limits_init(NormalAnglePrecalc *a, float angle, bool do_mask_normal) { angle = RAD2DEGF(angle); a->do_mask_normal = do_mask_normal; @@ -117,7 +180,7 @@ static void view_angle_limits_init(struct NormalAnglePrecalc *a, float angle, bo a->angle_inner__cos = cosf(a->angle_inner); } -static float view_angle_limits_apply_falloff(const struct NormalAnglePrecalc *a, +static float view_angle_limits_apply_falloff(const NormalAnglePrecalc *a, float angle_cos, float *mask_p) { @@ -169,10 +232,10 @@ static bool vertex_paint_use_fast_update_check(Object *ob) { const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob); - if (me_eval != NULL) { + if (me_eval != nullptr) { Mesh *me = BKE_mesh_from_object(ob); if (me && me->mloopcol) { - return (me->mloopcol == CustomData_get_layer(&me_eval->ldata, CD_MLOOPCOL)); + return (me->mloopcol == CustomData_get_layer(&me_eval->ldata, CD_PROP_BYTE_COLOR)); } } @@ -196,9 +259,8 @@ bool vertex_paint_mode_poll(bContext *C) } CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)ob->data); - AttributeDomain domain = BKE_id_attribute_domain((ID *)ob->data, layer); - return layer && layer->type == CD_MLOOPCOL && domain == ATTR_DOMAIN_CORNER; + return layer != nullptr; } static bool vertex_paint_poll_ex(bContext *C, bool check_tool) @@ -239,8 +301,8 @@ static bool weight_paint_poll_ex(bContext *C, bool check_tool) Object *ob = CTX_data_active_object(C); ScrArea *area; - if ((ob != NULL) && (ob->mode & OB_MODE_WEIGHT_PAINT) && - (BKE_paint_brush(&CTX_data_tool_settings(C)->wpaint->paint) != NULL) && + if ((ob != nullptr) && (ob->mode & OB_MODE_WEIGHT_PAINT) && + (BKE_paint_brush(&CTX_data_tool_settings(C)->wpaint->paint) != nullptr) && (area = CTX_wm_area(C)) && (area->spacetype == SPACE_VIEW3D)) { ARegion *region = CTX_wm_region(C); if (ELEM(region->regiontype, RGN_TYPE_WINDOW, RGN_TYPE_HUD)) { @@ -262,41 +324,54 @@ bool weight_paint_poll_ignore_tool(bContext *C) return weight_paint_poll_ex(C, false); } -uint vpaint_get_current_col(Scene *scene, VPaint *vp, bool secondary) +template<typename Color, typename Traits, AttributeDomain domain> +static Color vpaint_get_current_col(Scene *scene, VPaint *vp, bool secondary) { Brush *brush = BKE_paint_brush(&vp->paint); - uchar col[4]; - rgb_float_to_uchar(col, - secondary ? BKE_brush_secondary_color_get(scene, brush) : - BKE_brush_color_get(scene, brush)); - col[3] = 255; /* alpha isn't used, could even be removed to speedup paint a little */ - return *(uint *)col; + float color[4]; + const float *brush_color = secondary ? BKE_brush_secondary_color_get(scene, brush) : + BKE_brush_color_get(scene, brush); + copy_v3_v3(color, brush_color); + color[3] = 1.0f; /* alpha isn't used, could even be removed to speedup paint a little */ + + return fromFloat<Color>(ColorPaint4f(color)); +} + +uint vpaint_get_current_color(Scene *scene, VPaint *vp, bool secondary) +{ + ColorPaint4b col = vpaint_get_current_col<ColorPaint4b, ByteTraits, ATTR_DOMAIN_CORNER>( + scene, vp, secondary); + + return color2uint(col); } /* wpaint has 'wpaint_blend' */ -static uint vpaint_blend(const VPaint *vp, - uint color_curr, - uint color_orig, - uint color_paint, - const int alpha_i, - /* pre scaled from [0-1] --> [0-255] */ - const int brush_alpha_value_i) +template<typename Color, typename Traits> +static Color vpaint_blend(const VPaint *vp, + Color color_curr, + Color color_orig, + Color color_paint, + const typename Traits::ValueType alpha, + const typename Traits::BlendType brush_alpha_value) { + using Value = typename Traits::ValueType; + const Brush *brush = vp->paint.brush; - const IMB_BlendMode blend = brush->blend; + const IMB_BlendMode blend = (IMB_BlendMode)brush->blend; - uint color_blend = ED_vpaint_blend_tool(blend, color_curr, color_paint, alpha_i); + Color color_blend = BLI_mix_colors<Color, Traits>(blend, color_curr, color_paint, alpha); /* If no accumulate, clip color adding with `color_orig` & `color_test`. */ if (!brush_use_accumulate(vp)) { - uint color_test, a; - char *cp, *ct, *co; + uint a; + Color color_test; + Value *cp, *ct, *co; - color_test = ED_vpaint_blend_tool(blend, color_orig, color_paint, brush_alpha_value_i); + color_test = BLI_mix_colors<Color, Traits>(blend, color_orig, color_paint, brush_alpha_value); - cp = (char *)&color_blend; - ct = (char *)&color_test; - co = (char *)&color_orig; + cp = (Value *)&color_blend; + ct = (Value *)&color_test; + co = (Value *)&color_orig; for (a = 0; a < 4; a++) { if (ct[a] < co[a]) { @@ -320,36 +395,15 @@ static uint vpaint_blend(const VPaint *vp, if ((brush->flag & BRUSH_LOCK_ALPHA) && !ELEM(blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA)) { - char *cp, *cc; - cp = (char *)&color_blend; - cc = (char *)&color_curr; + Value *cp, *cc; + cp = (Value *)&color_blend; + cc = (Value *)&color_curr; cp[3] = cc[3]; } return color_blend; } -static void tex_color_alpha(VPaint *vp, const ViewContext *vc, const float co[3], float r_rgba[4]) -{ - const Brush *brush = BKE_paint_brush(&vp->paint); - BLI_assert(brush->mtex.tex != NULL); - if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) { - BKE_brush_sample_tex_3d(vc->scene, brush, co, r_rgba, 0, NULL); - } - else { - float co_ss[2]; /* screenspace */ - if (ED_view3d_project_float_object( - vc->region, co, co_ss, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == - V3D_PROJ_RET_OK) { - const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */ - BKE_brush_sample_tex_3d(vc->scene, brush, co_ss_3d, r_rgba, 0, NULL); - } - else { - zero_v4(r_rgba); - } - } -} - /* vpaint has 'vpaint_blend' */ static float wpaint_blend(const VPaint *wp, float weight, @@ -359,7 +413,7 @@ static float wpaint_blend(const VPaint *wp, const short do_flip) { const Brush *brush = wp->paint.brush; - IMB_BlendMode blend = brush->blend; + IMB_BlendMode blend = (IMB_BlendMode)brush->blend; if (do_flip) { switch (blend) { @@ -390,6 +444,32 @@ static float wpaint_blend(const VPaint *wp, return weight; } +static void paint_and_tex_color_alpha_intern(VPaint *vp, + const ViewContext *vc, + const float co[3], + float r_rgba[4]) +{ + const Brush *brush = BKE_paint_brush(&vp->paint); + BLI_assert(brush->mtex.tex != nullptr); + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) { + BKE_brush_sample_tex_3d(vc->scene, brush, co, r_rgba, 0, nullptr); + } + else { + float co_ss[2]; /* screenspace */ + if (ED_view3d_project_float_object( + vc->region, + co, + co_ss, + (eV3DProjTest)(V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR)) == V3D_PROJ_RET_OK) { + const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */ + BKE_brush_sample_tex_3d(vc->scene, brush, co_ss_3d, r_rgba, 0, nullptr); + } + else { + zero_v4(r_rgba); + } + } +} + static float wpaint_clamp_monotonic(float oldval, float curval, float newval) { if (newval < oldval) { @@ -488,7 +568,7 @@ static bool do_weight_paint_normalize_all_locked(MDeformVert *dvert, uint i, tot = 0; MDeformWeight *dw; - if (lock_flags == NULL) { + if (lock_flags == nullptr) { do_weight_paint_normalize_all(dvert, defbase_tot, vgroup_validmap); return true; } @@ -703,7 +783,7 @@ struct WeightPaintGroupData { * this _could_ be made a part of the operators 'WPaintData' struct, or at * least a member, but for now keep its own struct, initialized on every * paint stroke update - campbell */ -typedef struct WeightPaintInfo { +struct WeightPaintInfo { int defbase_tot; @@ -711,7 +791,7 @@ typedef struct WeightPaintInfo { int defbase_tot_sel; int defbase_tot_unsel; - struct WeightPaintGroupData active, mirror; + WeightPaintGroupData active, mirror; /* boolean array for locked bones, * length of defbase_tot */ @@ -734,7 +814,7 @@ typedef struct WeightPaintInfo { bool is_normalized; float brush_alpha_value; /* result of BKE_brush_alpha_get() */ -} WeightPaintInfo; +}; static void do_weight_paint_vertex_single( /* vars which remain the same for every vert */ @@ -746,7 +826,7 @@ static void do_weight_paint_vertex_single( float alpha, float paintweight) { - Mesh *me = ob->data; + Mesh *me = (Mesh *)ob->data; MDeformVert *dv = &me->dvert[index]; bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; @@ -763,7 +843,7 @@ static void do_weight_paint_vertex_single( /* Check if we should mirror vertex groups (X-axis). */ if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) { - index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology); + index_mirr = mesh_get_x_mirror_vert(ob, nullptr, index, topology); vgroup_mirr = wpi->mirror.index; /* another possible error - mirror group _and_ active group are the same (which is fine), @@ -801,7 +881,7 @@ static void do_weight_paint_vertex_single( dw = BKE_defvert_ensure_index(dv, wpi->active.index); } - if (dw == NULL) { + if (dw == nullptr) { return; } @@ -811,9 +891,9 @@ static void do_weight_paint_vertex_single( if (wp->flag & VP_FLAG_VGROUP_RESTRICT) { dw_mirr = BKE_defvert_find_index(dv_mirr, vgroup_mirr); - if (dw_mirr == NULL) { + if (dw_mirr == nullptr) { index_mirr = vgroup_mirr = -1; - dv_mirr = NULL; + dv_mirr = nullptr; } } else { @@ -834,8 +914,8 @@ static void do_weight_paint_vertex_single( } } else { - dv_mirr = NULL; - dw_mirr = NULL; + dv_mirr = nullptr; + dw_mirr = nullptr; } weight_cur = dw->weight; @@ -959,13 +1039,13 @@ static void do_weight_paint_vertex_multi( float alpha, float paintweight) { - Mesh *me = ob->data; + Mesh *me = (Mesh *)ob->data; MDeformVert *dv = &me->dvert[index]; bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; /* mirror vars */ int index_mirr = -1; - MDeformVert *dv_mirr = NULL; + MDeformVert *dv_mirr = nullptr; /* weights */ float curw, curw_real, oldw, neww, change, curw_mirr, change_mirr; @@ -973,7 +1053,7 @@ static void do_weight_paint_vertex_multi( /* Check if we should mirror vertex groups (X-axis). */ if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) { - index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology); + index_mirr = mesh_get_x_mirror_vert(ob, nullptr, index, topology); if (!ELEM(index_mirr, -1, index)) { dv_mirr = &me->dvert[index_mirr]; @@ -1033,13 +1113,13 @@ static void do_weight_paint_vertex_multi( /* verify for all groups that 0 < result <= 1 */ multipaint_clamp_change(dv, wpi->defbase_tot, wpi->defbase_sel, &change); - if (dv_mirr != NULL) { + if (dv_mirr != nullptr) { curw_mirr = BKE_defvert_multipaint_collective_weight( dv_mirr, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->is_normalized); if (curw_mirr == 0.0f) { /* can't mirror into a zero weight vertex */ - dv_mirr = NULL; + dv_mirr = nullptr; } else { /* mirror is changed to achieve the same collective weight value */ @@ -1062,7 +1142,7 @@ static void do_weight_paint_vertex_multi( /* apply validated change to vertex and mirror */ multipaint_apply_change(dv, wpi->defbase_tot, change, wpi->defbase_sel); - if (dv_mirr != NULL) { + if (dv_mirr != nullptr) { multipaint_apply_change(dv_mirr, wpi->defbase_tot, change_mirr, wpi->defbase_sel); } @@ -1071,7 +1151,7 @@ static void do_weight_paint_vertex_multi( do_weight_paint_normalize_all_locked_try_active( dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->active.lock); - if (dv_mirr != NULL) { + if (dv_mirr != nullptr) { do_weight_paint_normalize_all_locked_try_active( dv_mirr, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->active.lock); } @@ -1105,21 +1185,46 @@ static void vertex_paint_init_session(Depsgraph *depsgraph, /* Create persistent sculpt mode data */ BKE_sculpt_toolsettings_data_ensure(scene); - BLI_assert(ob->sculpt == NULL); - ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); + BLI_assert(ob->sculpt == nullptr); + ob->sculpt = (SculptSession *)MEM_callocN(sizeof(SculptSession), "sculpt session"); ob->sculpt->mode_type = object_mode; - BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false); + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); } -static void vertex_paint_init_stroke(Depsgraph *depsgraph, Object *ob) +static void vertex_paint_init_stroke(Scene *scene, Depsgraph *depsgraph, Object *ob) { - BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false); + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); + ToolSettings *ts = scene->toolsettings; + SculptSession *ss = ob->sculpt; + + /* Ensure ss->cache is allocated. It will mostly be initialized in + * vwpaint_update_cache_invariants and vwpaint_update_cache_variants. + */ + if (!ss->cache) { + ss->cache = (StrokeCache *)MEM_callocN(sizeof(StrokeCache), "stroke cache"); + } + + /* Allocate scratch array for previous colors if needed. */ + if (!brush_use_accumulate(ts->vpaint)) { + if (!ob->sculpt->cache->prev_colors_vpaint) { + Mesh *me = BKE_object_get_original_mesh(ob); + size_t elem_size; + int elem_num; + + elem_num = get_vcol_elements(me, &elem_size); + + ob->sculpt->cache->prev_colors_vpaint = (uint *)MEM_callocN(elem_num * elem_size, __func__); + } + } + else { + MEM_SAFE_FREE(ob->sculpt->cache->prev_colors_vpaint); + } } static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) { /* Create maps */ - struct SculptVertexPaintGeomMap *gmap = NULL; + SculptVertexPaintGeomMap *gmap = nullptr; if (ob->mode == OB_MODE_VERTEX_PAINT) { gmap = &ob->sculpt->mode.vpaint.gmap; BLI_assert(ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT); @@ -1129,18 +1234,18 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) BLI_assert(ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT); } else { - ob->sculpt->mode_type = 0; + ob->sculpt->mode_type = (eObjectMode)0; BLI_assert(0); return; } - Mesh *me = ob->data; + Mesh *me = (Mesh *)ob->data; - if (gmap->vert_to_loop == NULL) { - gmap->vert_map_mem = NULL; - gmap->vert_to_loop = NULL; - gmap->poly_map_mem = NULL; - gmap->vert_to_poly = NULL; + if (gmap->vert_to_loop == nullptr) { + gmap->vert_map_mem = nullptr; + gmap->vert_to_loop = nullptr; + gmap->poly_map_mem = nullptr; + gmap->vert_to_poly = nullptr; BKE_mesh_vert_loop_map_create(&gmap->vert_to_loop, &gmap->vert_map_mem, me->mpoly, @@ -1158,24 +1263,15 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } /* Create average brush arrays */ - if (ob->mode == OB_MODE_VERTEX_PAINT) { - if (!brush_use_accumulate(ts->vpaint)) { - if (ob->sculpt->mode.vpaint.previous_color == NULL) { - ob->sculpt->mode.vpaint.previous_color = MEM_callocN(me->totloop * sizeof(uint), __func__); - } - } - else { - MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color); - } - } - else if (ob->mode == OB_MODE_WEIGHT_PAINT) { + if (ob->mode == OB_MODE_WEIGHT_PAINT) { if (!brush_use_accumulate(ts->wpaint)) { - if (ob->sculpt->mode.wpaint.alpha_weight == NULL) { - ob->sculpt->mode.wpaint.alpha_weight = MEM_callocN(me->totvert * sizeof(float), __func__); + if (ob->sculpt->mode.wpaint.alpha_weight == nullptr) { + ob->sculpt->mode.wpaint.alpha_weight = (float *)MEM_callocN(me->totvert * sizeof(float), + __func__); } - if (ob->sculpt->mode.wpaint.dvert_prev == NULL) { - ob->sculpt->mode.wpaint.dvert_prev = MEM_callocN(me->totvert * sizeof(MDeformVert), - __func__); + if (ob->sculpt->mode.wpaint.dvert_prev == nullptr) { + ob->sculpt->mode.wpaint.dvert_prev = (MDeformVert *)MEM_callocN( + me->totvert * sizeof(MDeformVert), __func__); MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev; for (int i = 0; i < me->totvert; i++, dv++) { /* Use to show this isn't initialized, never apply to the mesh data. */ @@ -1185,10 +1281,10 @@ static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob) } else { MEM_SAFE_FREE(ob->sculpt->mode.wpaint.alpha_weight); - if (ob->sculpt->mode.wpaint.dvert_prev != NULL) { + if (ob->sculpt->mode.wpaint.dvert_prev != nullptr) { BKE_defvert_array_free_elems(ob->sculpt->mode.wpaint.dvert_prev, me->totvert); MEM_freeN(ob->sculpt->mode.wpaint.dvert_prev); - ob->sculpt->mode.wpaint.dvert_prev = NULL; + ob->sculpt->mode.wpaint.dvert_prev = nullptr; } } } @@ -1213,7 +1309,7 @@ static void ed_vwpaintmode_enter_generic( if (mode_flag == OB_MODE_VERTEX_PAINT) { const ePaintMode paint_mode = PAINT_MODE_VERTEX; - ED_mesh_color_ensure(me, NULL); + ED_mesh_color_ensure(me, nullptr); BKE_paint_ensure(scene->toolsettings, (Paint **)&scene->toolsettings->vpaint); Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode); @@ -1240,7 +1336,7 @@ static void ed_vwpaintmode_enter_generic( if (ob->sculpt) { if (ob->sculpt->cache) { SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } BKE_sculptsession_free(ob); } @@ -1255,7 +1351,7 @@ void ED_object_vpaintmode_enter_ex(Main *bmain, Depsgraph *depsgraph, Scene *sce { ed_vwpaintmode_enter_generic(bmain, depsgraph, scene, ob, OB_MODE_VERTEX_PAINT); } -void ED_object_vpaintmode_enter(struct bContext *C, Depsgraph *depsgraph) +void ED_object_vpaintmode_enter(bContext *C, Depsgraph *depsgraph) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -1267,7 +1363,7 @@ void ED_object_wpaintmode_enter_ex(Main *bmain, Depsgraph *depsgraph, Scene *sce { ed_vwpaintmode_enter_generic(bmain, depsgraph, scene, ob, OB_MODE_WEIGHT_PAINT); } -void ED_object_wpaintmode_enter(struct bContext *C, Depsgraph *depsgraph) +void ED_object_wpaintmode_enter(bContext *C, Depsgraph *depsgraph) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); @@ -1309,7 +1405,7 @@ static void ed_vwpaintmode_exit_generic(Object *ob, const eObjectMode mode_flag) /* If the cache is not released by a cancel or a done, free it now. */ if (ob->sculpt && ob->sculpt->cache) { SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } BKE_sculptsession_free(ob); @@ -1332,7 +1428,7 @@ void ED_object_vpaintmode_exit_ex(Object *ob) { ed_vwpaintmode_exit_generic(ob, OB_MODE_VERTEX_PAINT); } -void ED_object_vpaintmode_exit(struct bContext *C) +void ED_object_vpaintmode_exit(bContext *C) { Object *ob = CTX_data_active_object(C); ED_object_vpaintmode_exit_ex(ob); @@ -1342,7 +1438,7 @@ void ED_object_wpaintmode_exit_ex(Object *ob) { ed_vwpaintmode_exit_generic(ob, OB_MODE_WEIGHT_PAINT); } -void ED_object_wpaintmode_exit(struct bContext *C) +void ED_object_wpaintmode_exit(bContext *C) { Object *ob = CTX_data_active_object(C); ED_object_wpaintmode_exit_ex(ob); @@ -1368,7 +1464,7 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) ToolSettings *ts = scene->toolsettings; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, ob, (eObjectMode)mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } @@ -1409,10 +1505,10 @@ static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op) static bool paint_mode_toggle_poll_test(bContext *C) { Object *ob = CTX_data_active_object(C); - if (ob == NULL || ob->type != OB_MESH) { + if (ob == nullptr || ob->type != OB_MESH) { return false; } - if (!ob->data || ID_IS_LINKED(ob->data) || ID_IS_OVERRIDE_LIBRARY(ob->data)) { + if (!ob->data || ID_IS_LINKED(ob->data)) { return false; } return true; @@ -1442,9 +1538,9 @@ void PAINT_OT_weight_paint_toggle(wmOperatorType *ot) struct WPaintData { ViewContext vc; - struct NormalAnglePrecalc normal_angle_precalc; + NormalAnglePrecalc normal_angle_precalc; - struct WeightPaintGroupData active, mirror; + WeightPaintGroupData active, mirror; /* variables for auto normalize */ const bool *vgroup_validmap; /* stores if vgroups tie to deforming bones or not */ @@ -1507,7 +1603,7 @@ static void vwpaint_update_cache_invariants( StrokeCache *cache; Scene *scene = CTX_data_scene(C); UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings; - ViewContext *vc = paint_stroke_view_context(op->customdata); + ViewContext *vc = paint_stroke_view_context((PaintStroke *)op->customdata); Object *ob = CTX_data_active_object(C); float mat[3][3]; float view_dir[3] = {0.0f, 0.0f, 1.0f}; @@ -1515,7 +1611,7 @@ static void vwpaint_update_cache_invariants( /* VW paint needs to allocate stroke cache before update is called. */ if (!ss->cache) { - cache = MEM_callocN(sizeof(StrokeCache), "stroke cache"); + cache = (StrokeCache *)MEM_callocN(sizeof(StrokeCache), "stroke cache"); ss->cache = cache; } else { @@ -1551,7 +1647,7 @@ static void vwpaint_update_cache_invariants( /* Truly temporary data that isn't stored in properties */ cache->vc = vc; cache->brush = brush; - cache->first_time = 1; + cache->first_time = true; /* cache projection matrix */ ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat); @@ -1618,12 +1714,12 @@ static void vwpaint_update_cache_variants(bContext *C, VPaint *vp, Object *ob, P static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2]) { Scene *scene = CTX_data_scene(C); - struct PaintStroke *stroke = op->customdata; + PaintStroke *stroke = (PaintStroke *)op->customdata; ToolSettings *ts = scene->toolsettings; Object *ob = CTX_data_active_object(C); Mesh *me = BKE_mesh_from_object(ob); - struct WPaintData *wpd; - struct WPaintVGroupIndex vgroup_index; + WPaintData *wpd; + WPaintVGroupIndex vgroup_index; int defbase_tot, defbase_tot_sel; bool *defbase_sel; SculptSession *ss = ob->sculpt; @@ -1638,13 +1734,13 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo /* check if we are attempting to paint onto a locked vertex group, * and other options disallow it from doing anything useful */ bDeformGroup *dg; - dg = BLI_findlink(&me->vertex_group_names, vgroup_index.active); + dg = (bDeformGroup *)BLI_findlink(&me->vertex_group_names, vgroup_index.active); if (dg->flag & DG_LOCK_WEIGHT) { BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); return false; } if (vgroup_index.mirror != -1) { - dg = BLI_findlink(&me->vertex_group_names, vgroup_index.mirror); + dg = (bDeformGroup *)BLI_findlink(&me->vertex_group_names, vgroup_index.mirror); if (dg->flag & DG_LOCK_WEIGHT) { BKE_report(op->reports, RPT_WARNING, "Mirror group is locked, aborting"); return false; @@ -1667,7 +1763,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo for (i = 0; i < defbase_tot; i++) { if (defbase_sel[i]) { - dg = BLI_findlink(&me->vertex_group_names, i); + dg = (bDeformGroup *)BLI_findlink(&me->vertex_group_names, i); if (dg->flag & DG_LOCK_WEIGHT) { BKE_report(op->reports, RPT_WARNING, "Multipaint group is locked, aborting"); MEM_freeN(defbase_sel); @@ -1679,7 +1775,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo /* ALLOCATIONS! no return after this line */ /* make mode data storage */ - wpd = MEM_callocN(sizeof(struct WPaintData), "WPaintData"); + wpd = (WPaintData *)MEM_callocN(sizeof(WPaintData), "WPaintData"); paint_stroke_set_mode_data(stroke, wpd); ED_view3d_viewcontext_init(C, &wpd->vc, depsgraph); view_angle_limits_init(&wpd->normal_angle_precalc, @@ -1712,10 +1808,10 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo } if (wpd->do_lock_relative || (ts->auto_normalize && wpd->lock_flags && !wpd->do_multipaint)) { - bool *unlocked = MEM_dupallocN(wpd->vgroup_validmap); + bool *unlocked = (bool *)MEM_dupallocN(wpd->vgroup_validmap); if (wpd->lock_flags) { - bool *locked = MEM_mallocN(sizeof(bool) * wpd->defbase_tot, __func__); + bool *locked = (bool *)MEM_mallocN(sizeof(bool) * wpd->defbase_tot, __func__); BKE_object_defgroup_split_locked_validmap( wpd->defbase_tot, wpd->lock_flags, wpd->vgroup_validmap, locked, unlocked); wpd->vgroup_locked = locked; @@ -1726,7 +1822,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo if (wpd->do_multipaint && ts->auto_normalize) { bool *tmpflags; - tmpflags = MEM_mallocN(sizeof(bool) * defbase_tot, __func__); + tmpflags = (bool *)MEM_mallocN(sizeof(bool) * defbase_tot, __func__); if (wpd->lock_flags) { BLI_array_binary_or(tmpflags, wpd->defbase_sel, wpd->lock_flags, wpd->defbase_tot); } @@ -1738,27 +1834,27 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo else if (ts->auto_normalize) { bool *tmpflags; - tmpflags = wpd->lock_flags ? MEM_dupallocN(wpd->lock_flags) : - MEM_callocN(sizeof(bool) * defbase_tot, __func__); + tmpflags = wpd->lock_flags ? (bool *)MEM_dupallocN(wpd->lock_flags) : + (bool *)MEM_callocN(sizeof(bool) * defbase_tot, __func__); tmpflags[wpd->active.index] = true; wpd->active.lock = tmpflags; - tmpflags = wpd->lock_flags ? MEM_dupallocN(wpd->lock_flags) : - MEM_callocN(sizeof(bool) * defbase_tot, __func__); + tmpflags = wpd->lock_flags ? (bool *)MEM_dupallocN(wpd->lock_flags) : + (bool *)MEM_callocN(sizeof(bool) * defbase_tot, __func__); tmpflags[(wpd->mirror.index != -1) ? wpd->mirror.index : wpd->active.index] = true; wpd->mirror.lock = tmpflags; } /* If not previously created, create vertex/weight paint mode session data */ - vertex_paint_init_stroke(depsgraph, ob); + vertex_paint_init_stroke(scene, depsgraph, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); if (ELEM(vp->paint.brush->weightpaint_tool, WPAINT_TOOL_SMEAR, WPAINT_TOOL_BLUR)) { - wpd->precomputed_weight = MEM_mallocN(sizeof(float) * me->totvert, __func__); + wpd->precomputed_weight = (float *)MEM_mallocN(sizeof(float) * me->totvert, __func__); } - if (ob->sculpt->mode.wpaint.dvert_prev != NULL) { + if (ob->sculpt->mode.wpaint.dvert_prev != nullptr) { MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev; for (int i = 0; i < me->totvert; i++, dv++) { /* Use to show this isn't initialized, never apply to the mesh data. */ @@ -1807,27 +1903,26 @@ static void do_wpaint_precompute_weight_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; const MDeformVert *dv = &data->me->dvert[n]; data->wpd->precomputed_weight[n] = wpaint_get_active_weight(dv, data->wpi); } static void precompute_weight_values( - bContext *C, Object *ob, Brush *brush, struct WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me) + bContext *C, Object *ob, Brush *brush, WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me) { if (wpd->precomputed_weight_ready && !brush_use_accumulate_ex(brush, ob->mode)) { return; } /* threaded loop over vertices */ - SculptThreadedTaskData data = { - .C = C, - .ob = ob, - .wpd = wpd, - .wpi = wpi, - .me = me, - }; + SculptThreadedTaskData data; + data.C = C; + data.ob = ob; + data.wpd = wpd; + data.wpi = wpi; + data.me = me; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -1840,11 +1935,11 @@ static void do_wpaint_brush_blur_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; SculptSession *ss = data->ob->sculpt; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap; + const SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap; const Brush *brush = data->brush; const StrokeCache *cache = ss->cache; @@ -1931,11 +2026,11 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; SculptSession *ss = data->ob->sculpt; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap; + const SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap; const Brush *brush = data->brush; const Scene *scene = CTX_data_scene(data->C); @@ -2041,7 +2136,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; SculptSession *ss = data->ob->sculpt; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); @@ -2112,7 +2207,7 @@ static void do_wpaint_brush_draw_task_cb_ex(void *__restrict userdata, static void do_wpaint_brush_calc_average_weight_cb_ex( void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = (SculptThreadedTaskData *)userdata; SculptSession *ss = data->ob->sculpt; StrokeCache *cache = ss->cache; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); @@ -2122,7 +2217,7 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - struct WPaintAverageAccum *accum = (struct WPaintAverageAccum *)data->custom_data + n; + WPaintAverageAccum *accum = (WPaintAverageAccum *)data->custom_data + n; accum->len = 0; accum->value = 0.0; @@ -2143,7 +2238,6 @@ static void do_wpaint_brush_calc_average_weight_cb_ex( BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) { const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; - // const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; const char v_flag = data->me->mvert[v_index].flag; /* If the vertex is selected. */ @@ -2162,7 +2256,8 @@ static void calculate_average_weight(SculptThreadedTaskData *data, PBVHNode **UNUSED(nodes), int totnode) { - struct WPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__); + WPaintAverageAccum *accum = (WPaintAverageAccum *)MEM_mallocN(sizeof(*accum) * totnode, + __func__); data->custom_data = accum; TaskParallelSettings settings; @@ -2187,7 +2282,7 @@ static void wpaint_paint_leaves(bContext *C, Object *ob, Sculpt *sd, VPaint *vp, - struct WPaintData *wpd, + WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me, PBVHNode **nodes, @@ -2197,17 +2292,16 @@ static void wpaint_paint_leaves(bContext *C, const Brush *brush = ob->sculpt->cache->brush; /* threaded loop over nodes */ - SculptThreadedTaskData data = { - .C = C, - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .vp = vp, - .wpd = wpd, - .wpi = wpi, - .me = me, - }; + SculptThreadedTaskData data = {nullptr}; + data.C = C; + data.sd = sd; + data.ob = ob; + data.brush = brush; + data.nodes = nodes; + data.vp = vp; + data.wpd = wpd; + data.wpi = wpi; + data.me = me; /* Use this so average can modify its weight without touching the brush. */ data.strength = BKE_brush_weight_get(scene, brush); @@ -2239,16 +2333,16 @@ static PBVHNode **vwpaint_pbvh_gather_generic( { SculptSession *ss = ob->sculpt; const bool use_normal = vwpaint_use_normal(wp); - PBVHNode **nodes = NULL; + PBVHNode **nodes = nullptr; /* Build a list of all nodes that are potentially within the brush's area of influence */ if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = ss->cache->radius_squared, - .original = true, - }; + SculptSearchSphereData data = {nullptr}; + data.ss = ss; + data.sd = sd; + data.radius_squared = ss->cache->radius_squared; + data.original = true; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); if (use_normal) { SCULPT_pbvh_calc_area_normal( @@ -2259,16 +2353,16 @@ static PBVHNode **vwpaint_pbvh_gather_generic( } } else { - struct DistRayAABB_Precalc dist_ray_to_aabb_precalc; + DistRayAABB_Precalc dist_ray_to_aabb_precalc; dist_squared_ray_to_aabb_v3_precalc( &dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal); - SculptSearchCircleData data = { - .ss = ss, - .sd = sd, - .radius_squared = ss->cache->radius_squared, - .original = true, - .dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc, - }; + SculptSearchCircleData data = {nullptr}; + data.ss = ss; + data.sd = sd; + data.radius_squared = ss->cache->radius_squared; + data.original = true; + data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode); if (use_normal) { copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal); @@ -2284,7 +2378,7 @@ static void wpaint_do_paint(bContext *C, Object *ob, VPaint *wp, Sculpt *sd, - struct WPaintData *wpd, + WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me, Brush *brush, @@ -2311,7 +2405,7 @@ static void wpaint_do_radial_symmetry(bContext *C, Object *ob, VPaint *wp, Sculpt *sd, - struct WPaintData *wpd, + WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me, Brush *brush, @@ -2327,10 +2421,10 @@ static void wpaint_do_radial_symmetry(bContext *C, /* near duplicate of: sculpt.c's, * 'do_symmetrical_brush_actions' and 'vpaint_do_symmetrical_brush_actions'. */ static void wpaint_do_symmetrical_brush_actions( - bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi) + bContext *C, Object *ob, VPaint *wp, Sculpt *sd, WPaintData *wpd, WeightPaintInfo *wpi) { Brush *brush = BKE_paint_brush(&wp->paint); - Mesh *me = ob->data; + Mesh *me = (Mesh *)ob->data; SculptSession *ss = ob->sculpt; StrokeCache *cache = ss->cache; const char symm = SCULPT_mesh_symmetry_xyz_get(ob); @@ -2380,14 +2474,14 @@ static void wpaint_do_symmetrical_brush_actions( static void wpaint_stroke_update_step(bContext *C, wmOperator *UNUSED(op), - struct PaintStroke *stroke, + PaintStroke *stroke, PointerRNA *itemptr) { Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); VPaint *wp = ts->wpaint; Brush *brush = BKE_paint_brush(&wp->paint); - struct WPaintData *wpd = paint_stroke_mode_data(stroke); + WPaintData *wpd = (WPaintData *)paint_stroke_mode_data(stroke); ViewContext *vc; Object *ob = CTX_data_active_object(C); @@ -2400,11 +2494,11 @@ static void wpaint_stroke_update_step(bContext *C, const float brush_alpha_value = BKE_brush_alpha_get(scene, brush); - /* intentionally don't initialize as NULL, make sure we initialize all members below */ + /* intentionally don't initialize as nullptr, make sure we initialize all members below */ WeightPaintInfo wpi; /* cannot paint if there is no stroke data */ - if (wpd == NULL) { + if (wpd == nullptr) { /* XXX: force a redraw here, since even though we can't paint, * at least view won't freeze until stroke ends */ ED_region_tag_redraw(CTX_wm_region(C)); @@ -2434,7 +2528,7 @@ static void wpaint_stroke_update_step(bContext *C, wpi.vgroup_unlocked = wpd->vgroup_unlocked; wpi.do_flip = RNA_boolean_get(itemptr, "pen_flip") || ss->cache->invert; wpi.do_multipaint = wpd->do_multipaint; - wpi.do_auto_normalize = ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL) && + wpi.do_auto_normalize = ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != nullptr) && (wpi.do_multipaint || wpi.vgroup_validmap[wpi.active.index])); wpi.do_lock_relative = wpd->do_lock_relative; wpi.is_normalized = wpi.do_auto_normalize || wpi.do_lock_relative; @@ -2442,7 +2536,7 @@ static void wpaint_stroke_update_step(bContext *C, /* *** done setting up WeightPaintInfo *** */ if (wpd->precomputed_weight) { - precompute_weight_values(C, ob, brush, wpd, &wpi, ob->data); + precompute_weight_values(C, ob, brush, wpd, &wpi, (Mesh *)ob->data); } wpaint_do_symmetrical_brush_actions(C, ob, wp, sd, wpd, &wpi); @@ -2455,9 +2549,9 @@ static void wpaint_stroke_update_step(bContext *C, mul_v3_m4v3(loc_world, ob->obmat, ss->cache->true_location); paint_last_stroke_update(scene, loc_world); - BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag((Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL); - DEG_id_tag_update(ob->data, 0); + DEG_id_tag_update((ID *)ob->data, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); swap_m4m4(wpd->vc.rv3d->persmat, mat); @@ -2483,10 +2577,10 @@ static void wpaint_stroke_update_step(bContext *C, ED_region_tag_redraw_partial(vc->region, &r, true); } -static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) +static void wpaint_stroke_done(const bContext *C, PaintStroke *stroke) { Object *ob = CTX_data_active_object(C); - struct WPaintData *wpd = paint_stroke_mode_data(stroke); + WPaintData *wpd = (WPaintData *)paint_stroke_mode_data(stroke); if (wpd) { if (wpd->defbase_sel) { @@ -2530,7 +2624,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) ParticleSystem *psys; int i; - for (psys = ob->particlesystem.first; psys; psys = psys->next) { + for (psys = (ParticleSystem *)ob->particlesystem.first; psys; psys = psys->next) { for (i = 0; i < PSYS_TOT_VG; i++) { if (psys->vgroup[i] == BKE_object_defgroup_active_index_get(ob)) { psys->recalc |= ID_RECALC_PSYS_RESET; @@ -2540,12 +2634,12 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) } } - DEG_id_tag_update(ob->data, 0); + DEG_id_tag_update((ID *)ob->data, 0); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -2557,12 +2651,12 @@ static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event) SCULPT_stroke_get_location, wpaint_stroke_test_start, wpaint_stroke_update_step, - NULL, + nullptr, wpaint_stroke_done, event->type); if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) { - paint_stroke_free(C, op, op->customdata); + paint_stroke_free(C, op, (PaintStroke *)op->customdata); return OPERATOR_FINISHED; } /* add modal handler */ @@ -2581,12 +2675,12 @@ static int wpaint_exec(bContext *C, wmOperator *op) SCULPT_stroke_get_location, wpaint_stroke_test_start, wpaint_stroke_update_step, - NULL, + nullptr, wpaint_stroke_done, 0); /* frees op->customdata */ - paint_stroke_exec(C, op, op->customdata); + paint_stroke_exec(C, op, (PaintStroke *)op->customdata); return OPERATOR_FINISHED; } @@ -2596,15 +2690,15 @@ static void wpaint_cancel(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob->sculpt->cache) { SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } - paint_stroke_cancel(C, op, op->customdata); + paint_stroke_cancel(C, op, (PaintStroke *)op->customdata); } static int wpaint_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); + return paint_stroke_modal(C, op, event, (PaintStroke **)&op->customdata); } void PAINT_OT_weight_paint(wmOperatorType *ot) @@ -2647,7 +2741,7 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) ToolSettings *ts = scene->toolsettings; if (!is_mode_set) { - if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) { + if (!ED_object_mode_compat_set(C, ob, (eObjectMode)mode_flag, op->reports)) { return OPERATOR_CANCELLED; } } @@ -2667,13 +2761,12 @@ static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op) BKE_paint_toolslots_brush_validate(bmain, &ts->vpaint->paint); } - BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag((Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL); /* update modifier stack for mapping requirements */ DEG_id_tag_update(&me->id, 0); WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene); - WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode); WM_toolsystem_update_from_context_view3d(C); @@ -2720,14 +2813,20 @@ void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot) * - revise whether op->customdata should be added in object, in set_vpaint. */ -struct VPaintData { +struct VPaintDataBase { ViewContext vc; - struct NormalAnglePrecalc normal_angle_precalc; + AttributeDomain domain; + CustomDataType type; +}; + +template<typename Color, typename Traits, AttributeDomain domain> +struct VPaintData : public VPaintDataBase { + NormalAnglePrecalc normal_angle_precalc; - uint paintcol; + Color paintcol; struct VertProjHandle *vp_handle; - struct CoNo *vertexcosnos; + CoNo *vertexcosnos; /** * Modify #Mesh.mloopcol directly, since the derived mesh is drawing from this @@ -2743,44 +2842,43 @@ struct VPaintData { /* Special storage for smear brush, avoid feedback loop - update each step. */ struct { - uint *color_prev; - uint *color_curr; + void *color_prev; + void *color_curr; } smear; }; -static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2]) +template<typename Color, typename Traits, AttributeDomain domain> +static void *vpaint_init_vpaint(bContext *C, + wmOperator *op, + Scene *scene, + Depsgraph *depsgraph, + VPaint *vp, + Object *ob, + Mesh *me, + const Brush *brush) { - Scene *scene = CTX_data_scene(C); - ToolSettings *ts = scene->toolsettings; - struct PaintStroke *stroke = op->customdata; - VPaint *vp = ts->vpaint; - Brush *brush = BKE_paint_brush(&vp->paint); - struct VPaintData *vpd; - Object *ob = CTX_data_active_object(C); - Mesh *me; - SculptSession *ss = ob->sculpt; - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + VPaintData<Color, Traits, domain> *vpd; - /* context checks could be a poll() */ - me = BKE_mesh_from_object(ob); - if (me == NULL || me->totpoly == 0) { - return false; - } + size_t elem_size; + int elem_num = get_vcol_elements(me, &elem_size); + /* make mode data storage */ + vpd = MEM_new<VPaintData<Color, Traits, domain>>("VPaintData"); - ED_mesh_color_ensure(me, NULL); - if (me->mloopcol == NULL) { - return false; + if constexpr (std::is_same_v<Color, ColorPaint4f>) { + vpd->type = CD_PROP_COLOR; + } + else { + vpd->type = CD_PROP_BYTE_COLOR; } - /* make mode data storage */ - vpd = MEM_callocN(sizeof(*vpd), "VPaintData"); - paint_stroke_set_mode_data(stroke, vpd); + vpd->domain = domain; + ED_view3d_viewcontext_init(C, &vpd->vc, depsgraph); view_angle_limits_init(&vpd->normal_angle_precalc, vp->paint.brush->falloff_angle, (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0); - vpd->paintcol = vpaint_get_current_col( + vpd->paintcol = vpaint_get_current_col<Color, Traits, domain>( scene, vp, (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT)); vpd->is_texbrush = !(brush->vertexpaint_tool == VPAINT_TOOL_BLUR) && brush->mtex.tex; @@ -2789,22 +2887,23 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f * if not we can skip face map trickiness */ if (vertex_paint_use_fast_update_check(ob)) { vpd->use_fast_update = true; - // printf("Fast update!\n"); } else { vpd->use_fast_update = false; - // printf("No fast update!\n"); } /* to keep tracked of modified loops for shared vertex color blending */ if (brush->vertexpaint_tool == VPAINT_TOOL_BLUR) { - vpd->mlooptag = MEM_mallocN(sizeof(bool) * me->totloop, "VPaintData mlooptag"); + vpd->mlooptag = (bool *)MEM_mallocN(sizeof(bool) * elem_num, "VPaintData mlooptag"); } if (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) { - vpd->smear.color_prev = MEM_mallocN(sizeof(uint) * me->totloop, __func__); - memcpy(vpd->smear.color_prev, me->mloopcol, sizeof(uint) * me->totloop); - vpd->smear.color_curr = MEM_dupallocN(vpd->smear.color_prev); + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + + vpd->smear.color_prev = MEM_malloc_arrayN(elem_num, elem_size, __func__); + memcpy(vpd->smear.color_prev, layer->data, elem_size * elem_num); + + vpd->smear.color_curr = (uint *)MEM_dupallocN(vpd->smear.color_prev); } /* Create projection handle */ @@ -2814,516 +2913,845 @@ static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const f ob->sculpt->building_vp_handle = false; } + return static_cast<void *>(vpd); +} + +static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2]) +{ + Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; + PaintStroke *stroke = (PaintStroke *)op->customdata; + VPaint *vp = ts->vpaint; + Brush *brush = BKE_paint_brush(&vp->paint); + Object *ob = CTX_data_active_object(C); + Mesh *me; + SculptSession *ss = ob->sculpt; + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + + /* context checks could be a poll() */ + me = BKE_mesh_from_object(ob); + if (me == nullptr || me->totpoly == 0) { + return false; + } + + ED_mesh_color_ensure(me, nullptr); + + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + if (!layer) { + return false; + } + + AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + void *vpd = nullptr; + + if (domain == ATTR_DOMAIN_POINT) { + if (layer->type == CD_PROP_COLOR) { + vpd = vpaint_init_vpaint<ColorPaint4f, FloatTraits, ATTR_DOMAIN_POINT>( + C, op, scene, depsgraph, vp, ob, me, brush); + } + else if (layer->type == CD_PROP_BYTE_COLOR) { + vpd = vpaint_init_vpaint<ColorPaint4b, ByteTraits, ATTR_DOMAIN_POINT>( + C, op, scene, depsgraph, vp, ob, me, brush); + } + } + else if (domain == ATTR_DOMAIN_CORNER) { + if (layer->type == CD_PROP_COLOR) { + vpd = vpaint_init_vpaint<ColorPaint4f, FloatTraits, ATTR_DOMAIN_CORNER>( + C, op, scene, depsgraph, vp, ob, me, brush); + } + else if (layer->type == CD_PROP_BYTE_COLOR) { + vpd = vpaint_init_vpaint<ColorPaint4b, ByteTraits, ATTR_DOMAIN_CORNER>( + C, op, scene, depsgraph, vp, ob, me, brush); + } + } + + BLI_assert(vpd != nullptr); + + paint_stroke_set_mode_data(stroke, vpd); + /* If not previously created, create vertex/weight paint mode session data */ - vertex_paint_init_stroke(depsgraph, ob); + vertex_paint_init_stroke(scene, depsgraph, ob); vwpaint_update_cache_invariants(C, vp, ss, op, mouse); vertex_paint_init_session_data(ts, ob); - if (ob->sculpt->mode.vpaint.previous_color != NULL) { - memset(ob->sculpt->mode.vpaint.previous_color, 0, sizeof(uint) * me->totloop); - } - return true; } -static void do_vpaint_brush_calc_average_color_cb_ex(void *__restrict userdata, - const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) +template<class Color = ColorPaint4b, typename Traits = ByteTraits> +static void do_vpaint_brush_blur_loops(bContext *C, + Sculpt *UNUSED(sd), + VPaint *vp, + VPaintData<Color, Traits, ATTR_DOMAIN_CORNER> *vpd, + Object *ob, + Mesh *me, + PBVHNode **nodes, + int totnode, + Color *lcol) { - SculptThreadedTaskData *data = userdata; - SculptSession *ss = data->ob->sculpt; - const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); - const bool has_grids = (pbvh_type == PBVH_GRIDS); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + using Blend = typename Traits::BlendType; - StrokeCache *cache = ss->cache; - uint *lcol = data->lcol; - char *col; - const bool use_vert_sel = (data->me->editflag & - (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + SculptSession *ss = ob->sculpt; - struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n; - accum->len = 0; - memset(accum->value, 0, sizeof(accum->value)); + const Brush *brush = ob->sculpt->cache->brush; + const Scene *scene = CTX_data_scene(C); + + Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint); + + blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + for (int n : range) { + const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); + const bool has_grids = (pbvh_type == PBVH_GRIDS); + + const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + const StrokeCache *cache = ss->cache; + float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; + get_brush_alpha_data( + scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + const bool use_normal = vwpaint_use_normal(vp); + const bool use_vert_sel = (me->editflag & + (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, brush->falloff_shape); + const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( + ss, brush->falloff_shape); + + /* For each vertex */ + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + /* Test to see if the vertex coordinates are within the spherical brush region. */ + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + /* For grid based pbvh, take the vert whose loop corresponds to the current grid. + * Otherwise, take the current vert. */ + const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + vd.vert_indices[vd.i]; + const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; + const MVert *mv = &me->mvert[v_index]; + + /* If the vertex is selected for painting. */ + if (!use_vert_sel || mv->flag & SELECT) { + float brush_strength = cache->bstrength; + const float angle_cos = (use_normal && vd.no) ? + dot_v3v3(sculpt_normal_frontface, vd.no) : + 1.0f; + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || + view_angle_limits_apply_falloff( + &vpd->normal_angle_precalc, angle_cos, &brush_strength))) { + const float brush_fade = BKE_brush_curve_strength( + brush, sqrtf(test.dist), cache->radius); - SculptBrushTest test; - SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( - ss, &test, data->brush->falloff_shape); + /* Get the average poly color */ + Color color_final(0, 0, 0, 0); - /* For each vertex */ - PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - /* Test to see if the vertex coordinates are within the spherical brush region. */ - if (sculpt_brush_test_sq_fn(&test, vd.co)) { - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; - if (BKE_brush_curve_strength(data->brush, 0.0, cache->radius) > 0.0) { - /* If the vertex is selected for painting. */ - const MVert *mv = &data->me->mvert[v_index]; - if (!use_vert_sel || mv->flag & SELECT) { - accum->len += gmap->vert_to_loop[v_index].count; - /* if a vertex is within the brush region, then add its color to the blend. */ - for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) { - const int l_index = gmap->vert_to_loop[v_index].indices[j]; - col = (char *)(&lcol[l_index]); - /* Color is squared to compensate the sqrt color encoding. */ - accum->value[0] += col[0] * col[0]; - accum->value[1] += col[1] * col[1]; - accum->value[2] += col[2] * col[2]; + int total_hit_loops = 0; + Blend blend[4] = {0}; + + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + int p_index = gmap->vert_to_poly[v_index].indices[j]; + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + total_hit_loops += mp->totloop; + for (int k = 0; k < mp->totloop; k++) { + const uint l_index = mp->loopstart + k; + Color *col = lcol + l_index; + + /* Color is squared to compensate the sqrt color encoding. */ + blend[0] += (Blend)col->r * (Blend)col->r; + blend[1] += (Blend)col->g * (Blend)col->g; + blend[2] += (Blend)col->b * (Blend)col->b; + blend[3] += (Blend)col->a * (Blend)col->a; + } + } + } + + if (total_hit_loops != 0) { + /* Use rgb^2 color averaging. */ + Color *col = &color_final; + + color_final.r = Traits::round( + sqrtf(Traits::divide_round(blend[0], total_hit_loops))); + color_final.g = Traits::round( + sqrtf(Traits::divide_round(blend[1], total_hit_loops))); + color_final.b = Traits::round( + sqrtf(Traits::divide_round(blend[2], total_hit_loops))); + color_final.a = Traits::round( + sqrtf(Traits::divide_round(blend[3], total_hit_loops))); + + /* For each poly owning this vert, + * paint each loop belonging to this vert. */ + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + const int p_index = gmap->vert_to_poly[v_index].indices[j]; + const int l_index = gmap->vert_to_loop[v_index].indices[j]; + BLI_assert(me->mloop[l_index].v == v_index); + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ + + if (previous_color != nullptr) { + /* Get the previous loop color */ + if (isZero(previous_color[l_index])) { + previous_color[l_index] = lcol[l_index]; + } + color_orig = previous_color[l_index]; + } + const float final_alpha = Traits::range * brush_fade * brush_strength * + brush_alpha_pressure * grid_alpha; + /* Mix the new color with the original + * based on the brush strength and the curve. */ + lcol[l_index] = vpaint_blend<Color, Traits>(vp, + lcol[l_index], + color_orig, + *col, + final_alpha, + Traits::range * brush_strength); + } + } + } + } } } } - } - } - BKE_pbvh_vertex_iter_end; + BKE_pbvh_vertex_iter_end; + }; + }); } -static float tex_color_alpha_ubyte(SculptThreadedTaskData *data, - const float v_co[3], - uint *r_color) +template<class Color = ColorPaint4b, typename Traits = ByteTraits> +static void do_vpaint_brush_blur_verts(bContext *C, + Sculpt *UNUSED(sd), + VPaint *vp, + VPaintData<Color, Traits, ATTR_DOMAIN_POINT> *vpd, + Object *ob, + Mesh *me, + PBVHNode **nodes, + int totnode, + Color *lcol) { - float rgba[4]; - float rgba_br[3]; - tex_color_alpha(data->vp, &data->vpd->vc, v_co, rgba); - rgb_uchar_to_float(rgba_br, (const uchar *)&data->vpd->paintcol); - mul_v3_v3(rgba_br, rgba); - rgb_float_to_uchar((uchar *)r_color, rgba_br); - return rgba[3]; -} + using Blend = typename Traits::BlendType; -static void do_vpaint_brush_draw_task_cb_ex(void *__restrict userdata, - const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) -{ - SculptThreadedTaskData *data = userdata; - SculptSession *ss = data->ob->sculpt; - const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); - const bool has_grids = (pbvh_type == PBVH_GRIDS); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + SculptSession *ss = ob->sculpt; - const Brush *brush = data->brush; - const StrokeCache *cache = ss->cache; - uint *lcol = data->lcol; - const Scene *scene = CTX_data_scene(data->C); - float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; - get_brush_alpha_data( - scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); - const bool use_normal = vwpaint_use_normal(data->vp); - const bool use_vert_sel = (data->me->editflag & - (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; - const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + const Brush *brush = ob->sculpt->cache->brush; + const Scene *scene = CTX_data_scene(C); + + Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint); + + blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + for (int n : range) { + const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); + const bool has_grids = (pbvh_type == PBVH_GRIDS); + + const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + const StrokeCache *cache = ss->cache; + float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; + get_brush_alpha_data( + scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + const bool use_normal = vwpaint_use_normal(vp); + const bool use_vert_sel = (me->editflag & + (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, brush->falloff_shape); + const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( + ss, brush->falloff_shape); + + /* For each vertex */ + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + /* Test to see if the vertex coordinates are within the spherical brush region. */ + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + /* For grid based pbvh, take the vert whose loop corresponds to the current grid. + * Otherwise, take the current vert. */ + const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + vd.vert_indices[vd.i]; + const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; + const MVert *mv = &me->mvert[v_index]; + + /* If the vertex is selected for painting. */ + if (!use_vert_sel || mv->flag & SELECT) { + float brush_strength = cache->bstrength; + const float angle_cos = (use_normal && vd.no) ? + dot_v3v3(sculpt_normal_frontface, vd.no) : + 1.0f; + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || + view_angle_limits_apply_falloff( + &vpd->normal_angle_precalc, angle_cos, &brush_strength))) { + const float brush_fade = BKE_brush_curve_strength( + brush, sqrtf(test.dist), cache->radius); - SculptBrushTest test; - SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( - ss, &test, data->brush->falloff_shape); - const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( - ss, data->brush->falloff_shape); + /* Get the average poly color */ + Color color_final(0, 0, 0, 0); - /* For each vertex */ - PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - /* Test to see if the vertex coordinates are within the spherical brush region. */ - if (sculpt_brush_test_sq_fn(&test, vd.co)) { - /* NOTE: Grids are 1:1 with corners (aka loops). - * For grid based pbvh, take the vert whose loop corresponds to the current grid. - * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; - const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv = &data->me->mvert[v_index]; + int total_hit_loops = 0; + Blend blend[4] = {0}; - /* If the vertex is selected for painting. */ - if (!use_vert_sel || mv->flag & SELECT) { - /* Calc the dot prod. between ray norm on surf and current vert - * (ie splash prevention factor), and only paint front facing verts. */ - float brush_strength = cache->bstrength; - const float angle_cos = (use_normal && vd.no) ? dot_v3v3(sculpt_normal_frontface, vd.no) : - 1.0f; - if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || - view_angle_limits_apply_falloff( - &data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { - const float brush_fade = BKE_brush_curve_strength( - brush, sqrtf(test.dist), cache->radius); - uint color_final = data->vpd->paintcol; - - /* If we're painting with a texture, sample the texture color and alpha. */ - float tex_alpha = 1.0; - if (data->vpd->is_texbrush) { - /* NOTE: we may want to paint alpha as vertex color alpha. */ - tex_alpha = tex_color_alpha_ubyte( - data, data->vpd->vertexcosnos[v_index].co, &color_final); - } - /* For each poly owning this vert, paint each loop belonging to this vert. */ - for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { - const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(data->me->mloop[l_index].v == v_index); - const MPoly *mp = &data->me->mpoly[p_index]; - if (!use_face_sel || mp->flag & ME_FACE_SEL) { - uint color_orig = 0; /* unused when array is NULL */ - if (ss->mode.vpaint.previous_color != NULL) { - /* Get the previous loop color */ - if (ss->mode.vpaint.previous_color[l_index] == 0) { - ss->mode.vpaint.previous_color[l_index] = lcol[l_index]; + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + int p_index = gmap->vert_to_poly[v_index].indices[j]; + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + total_hit_loops += mp->totloop; + for (int k = 0; k < mp->totloop; k++) { + const uint l_index = mp->loopstart + k; + const uint v_index = me->mloop[l_index].v; + + Color *col = lcol + v_index; + + /* Color is squared to compensate the sqrt color encoding. */ + blend[0] += (Blend)col->r * (Blend)col->r; + blend[1] += (Blend)col->g * (Blend)col->g; + blend[2] += (Blend)col->b * (Blend)col->b; + blend[3] += (Blend)col->a * (Blend)col->a; + } + } + } + + if (total_hit_loops != 0) { + /* Use rgb^2 color averaging. */ + Color *col = &color_final; + + color_final.r = Traits::round( + sqrtf(Traits::divide_round(blend[0], total_hit_loops))); + color_final.g = Traits::round( + sqrtf(Traits::divide_round(blend[1], total_hit_loops))); + color_final.b = Traits::round( + sqrtf(Traits::divide_round(blend[2], total_hit_loops))); + color_final.a = Traits::round( + sqrtf(Traits::divide_round(blend[3], total_hit_loops))); + + /* For each poly owning this vert, + * paint each loop belonging to this vert. */ + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + const int p_index = gmap->vert_to_poly[v_index].indices[j]; + + BLI_assert(me->mloop[gmap->vert_to_loop[v_index].indices[j]].v == v_index); + + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ + + if (previous_color != nullptr) { + /* Get the previous loop color */ + if (isZero(previous_color[v_index])) { + previous_color[v_index] = lcol[v_index]; + } + color_orig = previous_color[v_index]; + } + const float final_alpha = Traits::range * brush_fade * brush_strength * + brush_alpha_pressure * grid_alpha; + /* Mix the new color with the original + * based on the brush strength and the curve. */ + lcol[v_index] = vpaint_blend<Color, Traits>(vp, + lcol[v_index], + color_orig, + *col, + final_alpha, + Traits::range * brush_strength); + } } - color_orig = ss->mode.vpaint.previous_color[l_index]; } - const float final_alpha = 255 * brush_fade * brush_strength * tex_alpha * - brush_alpha_pressure * grid_alpha; - - /* Mix the new color with the original based on final_alpha. */ - lcol[l_index] = vpaint_blend(data->vp, - lcol[l_index], - color_orig, - color_final, - final_alpha, - 255 * brush_strength); } } } } - } - } - BKE_pbvh_vertex_iter_end; + BKE_pbvh_vertex_iter_end; + }; + }); } -static void do_vpaint_brush_blur_task_cb_ex(void *__restrict userdata, - const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) +template<typename Color = ColorPaint4b, typename Traits, AttributeDomain domain> +static void do_vpaint_brush_smear(bContext *C, + Sculpt *UNUSED(sd), + VPaint *vp, + VPaintData<Color, Traits, domain> *vpd, + Object *ob, + Mesh *me, + PBVHNode **nodes, + int totnode, + Color *lcol) { - SculptThreadedTaskData *data = userdata; - SculptSession *ss = data->ob->sculpt; + SculptSession *ss = ob->sculpt; + + const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + const StrokeCache *cache = ss->cache; const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); const bool has_grids = (pbvh_type == PBVH_GRIDS); - Scene *scene = CTX_data_scene(data->C); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; - const Brush *brush = data->brush; - const StrokeCache *cache = ss->cache; - uint *lcol = data->lcol; - float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; - get_brush_alpha_data( - scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); - const bool use_normal = vwpaint_use_normal(data->vp); - const bool use_vert_sel = (data->me->editflag & - (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; - const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + const Brush *brush = ob->sculpt->cache->brush; + const Scene *scene = CTX_data_scene(C); + Color *color_curr = static_cast<Color *>(vpd->smear.color_curr); + Color *color_prev_smear = static_cast<Color *>(vpd->smear.color_prev); + Color *color_prev = reinterpret_cast<Color *>(ss->cache->prev_colors_vpaint); + + blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + for (int n : range) { + float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; + + get_brush_alpha_data( + scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + float brush_dir[3]; + const bool use_normal = vwpaint_use_normal(vp); + const bool use_vert_sel = (me->editflag & + (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + + sub_v3_v3v3(brush_dir, cache->location, cache->last_location); + project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal); + + if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) { + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, brush->falloff_shape); + const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( + ss, brush->falloff_shape); + + /* For each vertex */ + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + /* Test to see if the vertex coordinates are within the spherical brush region. */ + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + /* For grid based pbvh, take the vert whose loop corresponds to the current grid. + * Otherwise, take the current vert. */ + const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + vd.vert_indices[vd.i]; + const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; + const MVert *mv_curr = &me->mvert[v_index]; + + /* if the vertex is selected for painting. */ + if (!use_vert_sel || mv_curr->flag & SELECT) { + /* Calc the dot prod. between ray norm on surf and current vert + * (ie splash prevention factor), and only paint front facing verts. */ + float brush_strength = cache->bstrength; + const float angle_cos = (use_normal && vd.no) ? + dot_v3v3(sculpt_normal_frontface, vd.no) : + 1.0f; + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || + view_angle_limits_apply_falloff( + &vpd->normal_angle_precalc, angle_cos, &brush_strength))) { + const float brush_fade = BKE_brush_curve_strength( + brush, sqrtf(test.dist), cache->radius); + + bool do_color = false; + /* Minimum dot product between brush direction and current + * to neighbor direction is 0.0, meaning orthogonal. */ + float stroke_dot_max = 0.0f; + + /* Get the color of the loop in the opposite + * direction of the brush movement */ + Color color_final(0, 0, 0, 0); + + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + const int p_index = gmap->vert_to_poly[v_index].indices[j]; + const int l_index = gmap->vert_to_loop[v_index].indices[j]; + BLI_assert(me->mloop[l_index].v == v_index); + UNUSED_VARS_NDEBUG(l_index); + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + const MLoop *ml_other = &me->mloop[mp->loopstart]; + for (int k = 0; k < mp->totloop; k++, ml_other++) { + const uint v_other_index = ml_other->v; + if (v_other_index != v_index) { + const MVert *mv_other = &me->mvert[v_other_index]; + + /* Get the direction from the + * selected vert to the neighbor. */ + float other_dir[3]; + sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co); + project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal); + + normalize_v3(other_dir); + + const float stroke_dot = dot_v3v3(other_dir, brush_dir); + int elem_index; + + if constexpr (domain == ATTR_DOMAIN_POINT) { + elem_index = ml_other->v; + } + else { + elem_index = mp->loopstart + k; + } + + if (stroke_dot > stroke_dot_max) { + stroke_dot_max = stroke_dot; + color_final = color_prev_smear[elem_index]; + do_color = true; + } + } + } + } + } - SculptBrushTest test; - SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( - ss, &test, data->brush->falloff_shape); - const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( - ss, data->brush->falloff_shape); + if (do_color) { + const float final_alpha = Traits::range * brush_fade * brush_strength * + brush_alpha_pressure * grid_alpha; - /* For each vertex */ - PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - /* Test to see if the vertex coordinates are within the spherical brush region. */ - if (sculpt_brush_test_sq_fn(&test, vd.co)) { - /* For grid based pbvh, take the vert whose loop corresponds to the current grid. - * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; - const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv = &data->me->mvert[v_index]; + /* For each poly owning this vert, + * paint each loop belonging to this vert. */ + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + const int p_index = gmap->vert_to_poly[v_index].indices[j]; + const int l_index = gmap->vert_to_loop[v_index].indices[j]; - /* If the vertex is selected for painting. */ - if (!use_vert_sel || mv->flag & SELECT) { - float brush_strength = cache->bstrength; - const float angle_cos = (use_normal && vd.no) ? dot_v3v3(sculpt_normal_frontface, vd.no) : - 1.0f; - if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || - view_angle_limits_apply_falloff( - &data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { - const float brush_fade = BKE_brush_curve_strength( - brush, sqrtf(test.dist), cache->radius); + int elem_index; + if constexpr (domain == ATTR_DOMAIN_POINT) { + elem_index = v_index; + } + else { + elem_index = l_index; + } - /* Get the average poly color */ - uint color_final = 0; - int total_hit_loops = 0; - uint blend[4] = {0}; - for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { - int p_index = gmap->vert_to_poly[v_index].indices[j]; - const MPoly *mp = &data->me->mpoly[p_index]; - if (!use_face_sel || mp->flag & ME_FACE_SEL) { - total_hit_loops += mp->totloop; - for (int k = 0; k < mp->totloop; k++) { - const uint l_index = mp->loopstart + k; - const char *col = (const char *)(&lcol[l_index]); - /* Color is squared to compensate the sqrt color encoding. */ - blend[0] += (uint)col[0] * (uint)col[0]; - blend[1] += (uint)col[1] * (uint)col[1]; - blend[2] += (uint)col[2] * (uint)col[2]; - blend[3] += (uint)col[3] * (uint)col[3]; + BLI_assert(me->mloop[l_index].v == v_index); + + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + /* Get the previous element color */ + Color color_orig(0, 0, 0, 0); /* unused when array is nullptr */ + + if (color_prev != nullptr) { + /* Get the previous element color */ + if (isZero(color_prev[elem_index])) { + color_prev[elem_index] = lcol[elem_index]; + } + color_orig = color_prev[elem_index]; + } + /* Mix the new color with the original + * based on the brush strength and the curve. */ + lcol[elem_index] = vpaint_blend<Color, Traits>(vp, + lcol[elem_index], + color_orig, + color_final, + final_alpha, + Traits::range * + brush_strength); + + color_curr[elem_index] = lcol[elem_index]; + } + } + } } } } - if (total_hit_loops != 0) { - /* Use rgb^2 color averaging. */ - char *col = (char *)(&color_final); - col[0] = round_fl_to_uchar(sqrtf(divide_round_i(blend[0], total_hit_loops))); - col[1] = round_fl_to_uchar(sqrtf(divide_round_i(blend[1], total_hit_loops))); - col[2] = round_fl_to_uchar(sqrtf(divide_round_i(blend[2], total_hit_loops))); - col[3] = round_fl_to_uchar(sqrtf(divide_round_i(blend[3], total_hit_loops))); - - /* For each poly owning this vert, - * paint each loop belonging to this vert. */ - for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { - const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(data->me->mloop[l_index].v == v_index); - const MPoly *mp = &data->me->mpoly[p_index]; - if (!use_face_sel || mp->flag & ME_FACE_SEL) { - uint color_orig = 0; /* unused when array is NULL */ - if (ss->mode.vpaint.previous_color != NULL) { - /* Get the previous loop color */ - if (ss->mode.vpaint.previous_color[l_index] == 0) { - ss->mode.vpaint.previous_color[l_index] = lcol[l_index]; - } - color_orig = ss->mode.vpaint.previous_color[l_index]; + } + BKE_pbvh_vertex_iter_end; + } + } + }); +} + +template<typename Color, typename Traits, AttributeDomain domain> +static void calculate_average_color(VPaintData<Color, Traits, domain> *vpd, + Object *ob, + Mesh *me, + const Brush *brush, + Color *lcol, + PBVHNode **nodes, + int totnode) +{ + using Blend = typename Traits::BlendType; + + VPaintAverageAccum<Blend> *accum = (VPaintAverageAccum<Blend> *)MEM_mallocN( + sizeof(*accum) * totnode, __func__); + blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + for (int n : range) { + SculptSession *ss = ob->sculpt; + const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); + const bool has_grids = (pbvh_type == PBVH_GRIDS); + const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + + StrokeCache *cache = ss->cache; + const bool use_vert_sel = (me->editflag & + (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + + VPaintAverageAccum<Blend> *accum2 = accum + n; + accum2->len = 0; + memset(accum2->value, 0, sizeof(accum2->value)); + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, brush->falloff_shape); + + /* For each vertex */ + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + /* Test to see if the vertex coordinates are within the spherical brush region. */ + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + vd.vert_indices[vd.i]; + if (BKE_brush_curve_strength(brush, 0.0, cache->radius) > 0.0) { + /* If the vertex is selected for painting. */ + const MVert *mv = &me->mvert[v_index]; + if (!use_vert_sel || mv->flag & SELECT) { + accum2->len += gmap->vert_to_loop[v_index].count; + /* if a vertex is within the brush region, then add its color to the blend. */ + for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) { + int elem_index; + + if constexpr (domain == ATTR_DOMAIN_CORNER) { + elem_index = gmap->vert_to_loop[v_index].indices[j]; + } + else { + elem_index = v_index; } - const float final_alpha = 255 * brush_fade * brush_strength * - brush_alpha_pressure * grid_alpha; - /* Mix the new color with the original - * based on the brush strength and the curve. */ - lcol[l_index] = vpaint_blend(data->vp, - lcol[l_index], - color_orig, - *((uint *)col), - final_alpha, - 255 * brush_strength); + + Color *col = lcol + elem_index; + + /* Color is squared to compensate the sqrt color encoding. */ + accum2->value[0] += col->r * col->r; + accum2->value[1] += col->g * col->g; + accum2->value[2] += col->b * col->b; } } } } } + BKE_pbvh_vertex_iter_end; } + }); + + Blend accum_len = 0; + Blend accum_value[3] = {0}; + Color blend(0, 0, 0, 0); + + for (int i = 0; i < totnode; i++) { + accum_len += accum[i].len; + accum_value[0] += accum[i].value[0]; + accum_value[1] += accum[i].value[1]; + accum_value[2] += accum[i].value[2]; + } + if (accum_len != 0) { + blend.r = Traits::round(sqrtf(Traits::divide_round(accum_value[0], accum_len))); + blend.g = Traits::round(sqrtf(Traits::divide_round(accum_value[1], accum_len))); + blend.b = Traits::round(sqrtf(Traits::divide_round(accum_value[2], accum_len))); + blend.a = Traits::range; + + vpd->paintcol = blend; } - BKE_pbvh_vertex_iter_end; } -static void do_vpaint_brush_smear_task_cb_ex(void *__restrict userdata, - const int n, - const TaskParallelTLS *__restrict UNUSED(tls)) +template<typename Color, typename Traits, AttributeDomain domain> +static float paint_and_tex_color_alpha(VPaint *vp, + VPaintData<Color, Traits, domain> *vpd, + const float v_co[3], + Color *r_color) { - SculptThreadedTaskData *data = userdata; - SculptSession *ss = data->ob->sculpt; - const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); - const bool has_grids = (pbvh_type == PBVH_GRIDS); - - Scene *scene = CTX_data_scene(data->C); - const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; - const Brush *brush = data->brush; - const StrokeCache *cache = ss->cache; - uint *lcol = data->lcol; - float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; - get_brush_alpha_data( - scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); - float brush_dir[3]; - const bool use_normal = vwpaint_use_normal(data->vp); - const bool use_vert_sel = (data->me->editflag & - (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; - const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + ColorPaint4f rgba; + ColorPaint4f rgba_br = toFloat(*r_color); - sub_v3_v3v3(brush_dir, cache->location, cache->last_location); - project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal); + paint_and_tex_color_alpha_intern(vp, &vpd->vc, v_co, &rgba.r); - if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) { + rgb_uchar_to_float(&rgba_br.r, (const uchar *)&vpd->paintcol); + mul_v3_v3(rgba_br, rgba); - SculptBrushTest test; - SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( - ss, &test, data->brush->falloff_shape); - const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( - ss, data->brush->falloff_shape); + *r_color = fromFloat<Color>(rgba_br); + return rgba[3]; +} - /* For each vertex */ - PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - /* Test to see if the vertex coordinates are within the spherical brush region. */ - if (sculpt_brush_test_sq_fn(&test, vd.co)) { - /* For grid based pbvh, take the vert whose loop corresponds to the current grid. - * Otherwise, take the current vert. */ - const int v_index = has_grids ? data->me->mloop[vd.grid_indices[vd.g]].v : - vd.vert_indices[vd.i]; - const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv_curr = &data->me->mvert[v_index]; +template<typename Color, typename Traits, AttributeDomain domain> +static void vpaint_do_draw(bContext *C, + Sculpt *UNUSED(sd), + VPaint *vp, + VPaintData<Color, Traits, domain> *vpd, + Object *ob, + Mesh *me, + PBVHNode **nodes, + int totnode, + Color *lcol) +{ + SculptSession *ss = ob->sculpt; + const PBVHType pbvh_type = BKE_pbvh_type(ss->pbvh); - /* if the vertex is selected for painting. */ - if (!use_vert_sel || mv_curr->flag & SELECT) { - /* Calc the dot prod. between ray norm on surf and current vert - * (ie splash prevention factor), and only paint front facing verts. */ - float brush_strength = cache->bstrength; - const float angle_cos = (use_normal && vd.no) ? - dot_v3v3(sculpt_normal_frontface, vd.no) : - 1.0f; - if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && - ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || - view_angle_limits_apply_falloff( - &data->vpd->normal_angle_precalc, angle_cos, &brush_strength))) { - const float brush_fade = BKE_brush_curve_strength( - brush, sqrtf(test.dist), cache->radius); + const Brush *brush = ob->sculpt->cache->brush; + const Scene *scene = CTX_data_scene(C); + + Color *previous_color = static_cast<Color *>(ss->cache->prev_colors_vpaint); + + blender::threading::parallel_for(IndexRange(totnode), 1LL, [&](IndexRange range) { + for (int n : range) { + const bool has_grids = (pbvh_type == PBVH_GRIDS); + const SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap; + + const StrokeCache *cache = ss->cache; + float brush_size_pressure, brush_alpha_value, brush_alpha_pressure; + get_brush_alpha_data( + scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure); + const bool use_normal = vwpaint_use_normal(vp); + const bool use_vert_sel = (me->editflag & + (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, brush->falloff_shape); + const float *sculpt_normal_frontface = SCULPT_brush_frontface_normal_from_falloff_shape( + ss, brush->falloff_shape); + + Color paintcol = vpd->paintcol; + + /* For each vertex */ + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { + /* Test to see if the vertex coordinates are within the spherical brush region. */ + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + /* NOTE: Grids are 1:1 with corners (aka loops). + * For grid based pbvh, take the vert whose loop corresponds to the current grid. + * Otherwise, take the current vert. */ + const int v_index = has_grids ? me->mloop[vd.grid_indices[vd.g]].v : + vd.vert_indices[vd.i]; + const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; + const MVert *mv = &me->mvert[v_index]; + + /* If the vertex is selected for painting. */ + if (!use_vert_sel || mv->flag & SELECT) { + /* Calc the dot prod. between ray norm on surf and current vert + * (ie splash prevention factor), and only paint front facing verts. */ + float brush_strength = cache->bstrength; + const float angle_cos = (use_normal && vd.no) ? + dot_v3v3(sculpt_normal_frontface, vd.no) : + 1.0f; + if (((brush->flag & BRUSH_FRONTFACE) == 0 || (angle_cos > 0.0f)) && + ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 || + view_angle_limits_apply_falloff( + &vpd->normal_angle_precalc, angle_cos, &brush_strength))) { + const float brush_fade = BKE_brush_curve_strength( + brush, sqrtf(test.dist), cache->radius); - bool do_color = false; - /* Minimum dot product between brush direction and current - * to neighbor direction is 0.0, meaning orthogonal. */ - float stroke_dot_max = 0.0f; + Color color_final = paintcol; - /* Get the color of the loop in the opposite - * direction of the brush movement */ - uint color_final = 0; - for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { - const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(data->me->mloop[l_index].v == v_index); - UNUSED_VARS_NDEBUG(l_index); - const MPoly *mp = &data->me->mpoly[p_index]; - if (!use_face_sel || mp->flag & ME_FACE_SEL) { - const MLoop *ml_other = &data->me->mloop[mp->loopstart]; - for (int k = 0; k < mp->totloop; k++, ml_other++) { - const uint v_other_index = ml_other->v; - if (v_other_index != v_index) { - const MVert *mv_other = &data->me->mvert[v_other_index]; - - /* Get the direction from the - * selected vert to the neighbor. */ - float other_dir[3]; - sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co); - project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal); - - normalize_v3(other_dir); - - const float stroke_dot = dot_v3v3(other_dir, brush_dir); - - if (stroke_dot > stroke_dot_max) { - stroke_dot_max = stroke_dot; - color_final = data->vpd->smear.color_prev[mp->loopstart + k]; - do_color = true; - } - } - } + /* If we're painting with a texture, sample the texture color and alpha. */ + float tex_alpha = 1.0; + if (vpd->is_texbrush) { + /* NOTE: we may want to paint alpha as vertex color alpha. */ + tex_alpha = paint_and_tex_color_alpha<Color, Traits, domain>( + vp, vpd, vpd->vertexcosnos[v_index].co, &color_final); } - } - if (do_color) { - const float final_alpha = 255 * brush_fade * brush_strength * brush_alpha_pressure * - grid_alpha; + Color color_orig(0, 0, 0, 0); - /* For each poly owning this vert, - * paint each loop belonging to this vert. */ - for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { - const int p_index = gmap->vert_to_poly[v_index].indices[j]; - const int l_index = gmap->vert_to_loop[v_index].indices[j]; - BLI_assert(data->me->mloop[l_index].v == v_index); - const MPoly *mp = &data->me->mpoly[p_index]; - if (!use_face_sel || mp->flag & ME_FACE_SEL) { + if constexpr (domain == ATTR_DOMAIN_POINT) { + int v_index = vd.index; + + if (previous_color != nullptr) { /* Get the previous loop color */ - uint color_orig = 0; /* unused when array is NULL */ - if (ss->mode.vpaint.previous_color != NULL) { - /* Get the previous loop color */ - if (ss->mode.vpaint.previous_color[l_index] == 0) { - ss->mode.vpaint.previous_color[l_index] = lcol[l_index]; + if (isZero(previous_color[v_index])) { + previous_color[v_index] = lcol[v_index]; + } + color_orig = previous_color[v_index]; + } + const float final_alpha = Traits::frange * brush_fade * brush_strength * + tex_alpha * brush_alpha_pressure * grid_alpha; + + lcol[v_index] = vpaint_blend<Color, Traits>(vp, + lcol[v_index], + color_orig, + color_final, + final_alpha, + Traits::range * brush_strength); + } + else { + /* For each poly owning this vert, paint each loop belonging to this vert. */ + for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) { + const int p_index = gmap->vert_to_poly[v_index].indices[j]; + const int l_index = gmap->vert_to_loop[v_index].indices[j]; + BLI_assert(me->mloop[l_index].v == v_index); + const MPoly *mp = &me->mpoly[p_index]; + if (!use_face_sel || mp->flag & ME_FACE_SEL) { + Color color_orig = Color(0, 0, 0, 0); /* unused when array is nullptr */ + + if (previous_color != nullptr) { + /* Get the previous loop color */ + if (isZero(previous_color[l_index])) { + previous_color[l_index] = lcol[l_index]; + } + color_orig = previous_color[l_index]; } - color_orig = ss->mode.vpaint.previous_color[l_index]; + const float final_alpha = Traits::frange * brush_fade * brush_strength * + tex_alpha * brush_alpha_pressure * grid_alpha; + + /* Mix the new color with the original based on final_alpha. */ + lcol[l_index] = vpaint_blend<Color, Traits>(vp, + lcol[l_index], + color_orig, + color_final, + final_alpha, + Traits::range * brush_strength); } - /* Mix the new color with the original - * based on the brush strength and the curve. */ - lcol[l_index] = vpaint_blend(data->vp, - lcol[l_index], - color_orig, - color_final, - final_alpha, - 255 * brush_strength); - - data->vpd->smear.color_curr[l_index] = lcol[l_index]; } } } } } } + BKE_pbvh_vertex_iter_end; } - BKE_pbvh_vertex_iter_end; - } + }); } -static void calculate_average_color(SculptThreadedTaskData *data, - PBVHNode **UNUSED(nodes), - int totnode) +template<typename Color, typename Traits, AttributeDomain domain> +static void vpaint_do_blur(bContext *C, + Sculpt *sd, + VPaint *vp, + VPaintData<Color, Traits, domain> *vpd, + Object *ob, + Mesh *me, + PBVHNode **nodes, + int totnode, + Color *lcol) { - struct VPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__); - data->custom_data = accum; - - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, data, do_vpaint_brush_calc_average_color_cb_ex, &settings); - - uint accum_len = 0; - uint accum_value[3] = {0}; - uchar blend[4] = {0}; - for (int i = 0; i < totnode; i++) { - accum_len += accum[i].len; - accum_value[0] += accum[i].value[0]; - accum_value[1] += accum[i].value[1]; - accum_value[2] += accum[i].value[2]; + if constexpr (domain == ATTR_DOMAIN_POINT) { + do_vpaint_brush_blur_verts<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); } - if (accum_len != 0) { - blend[0] = round_fl_to_uchar(sqrtf(divide_round_i(accum_value[0], accum_len))); - blend[1] = round_fl_to_uchar(sqrtf(divide_round_i(accum_value[1], accum_len))); - blend[2] = round_fl_to_uchar(sqrtf(divide_round_i(accum_value[2], accum_len))); - blend[3] = 255; - data->vpd->paintcol = *((uint *)blend); + else { + do_vpaint_brush_blur_loops<Color, Traits>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); } - - MEM_SAFE_FREE(data->custom_data); /* 'accum' */ } +template<typename Color, typename Traits, AttributeDomain domain> static void vpaint_paint_leaves(bContext *C, Sculpt *sd, VPaint *vp, - struct VPaintData *vpd, + VPaintData<Color, Traits, domain> *vpd, Object *ob, Mesh *me, + Color *lcol, PBVHNode **nodes, int totnode) { + + for (int i : IndexRange(totnode)) { + SCULPT_undo_push_node(ob, nodes[i], SCULPT_UNDO_COLOR); + } + const Brush *brush = ob->sculpt->cache->brush; - SculptThreadedTaskData data = { - .C = C, - .sd = sd, - .ob = ob, - .brush = brush, - .nodes = nodes, - .vp = vp, - .vpd = vpd, - .lcol = (uint *)me->mloopcol, - .me = me, - }; - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); switch ((eBrushVertexPaintTool)brush->vertexpaint_tool) { case VPAINT_TOOL_AVERAGE: - calculate_average_color(&data, nodes, totnode); - BLI_task_parallel_range(0, totnode, &data, do_vpaint_brush_draw_task_cb_ex, &settings); + calculate_average_color<Color, Traits, domain>(vpd, ob, me, brush, lcol, nodes, totnode); + break; + case VPAINT_TOOL_DRAW: + vpaint_do_draw<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); break; case VPAINT_TOOL_BLUR: - BLI_task_parallel_range(0, totnode, &data, do_vpaint_brush_blur_task_cb_ex, &settings); + vpaint_do_blur<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); break; case VPAINT_TOOL_SMEAR: - BLI_task_parallel_range(0, totnode, &data, do_vpaint_brush_smear_task_cb_ex, &settings); + do_vpaint_brush_smear<Color, Traits, domain>(C, sd, vp, vpd, ob, me, nodes, totnode, lcol); break; - case VPAINT_TOOL_DRAW: - BLI_task_parallel_range(0, totnode, &data, do_vpaint_brush_draw_task_cb_ex, &settings); + default: break; } } +template<typename Color, typename Traits, AttributeDomain domain> static void vpaint_do_paint(bContext *C, Sculpt *sd, VPaint *vp, - struct VPaintData *vpd, + VPaintData<Color, Traits, domain> *vpd, Object *ob, Mesh *me, Brush *brush, @@ -3339,18 +3767,22 @@ static void vpaint_do_paint(bContext *C, int totnode; PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush, &totnode); + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + Color *color_data = static_cast<Color *>(layer->data); + /* Paint those leaves. */ - vpaint_paint_leaves(C, sd, vp, vpd, ob, me, nodes, totnode); + vpaint_paint_leaves<Color, Traits, domain>(C, sd, vp, vpd, ob, me, color_data, nodes, totnode); if (nodes) { MEM_freeN(nodes); } } +template<typename Color, typename Traits, AttributeDomain domain> static void vpaint_do_radial_symmetry(bContext *C, Sculpt *sd, VPaint *vp, - struct VPaintData *vpd, + VPaintData<Color, Traits, domain> *vpd, Object *ob, Mesh *me, Brush *brush, @@ -3359,17 +3791,18 @@ static void vpaint_do_radial_symmetry(bContext *C, { for (int i = 1; i < vp->radial_symm[axis - 'X']; i++) { const float angle = (2.0 * M_PI) * i / vp->radial_symm[axis - 'X']; - vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, symm, axis, i, angle); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, symm, axis, i, angle); } } /* near duplicate of: sculpt.c's, * 'do_symmetrical_brush_actions' and 'wpaint_do_symmetrical_brush_actions'. */ +template<typename Color, typename Traits, AttributeDomain domain> static void vpaint_do_symmetrical_brush_actions( - bContext *C, Sculpt *sd, VPaint *vp, struct VPaintData *vpd, Object *ob) + bContext *C, Sculpt *sd, VPaint *vp, VPaintData<Color, Traits, domain> *vpd, Object *ob) { Brush *brush = BKE_paint_brush(&vp->paint); - Mesh *me = ob->data; + Mesh *me = (Mesh *)ob->data; SculptSession *ss = ob->sculpt; StrokeCache *cache = ss->cache; const char symm = SCULPT_mesh_symmetry_xyz_get(ob); @@ -3377,10 +3810,10 @@ static void vpaint_do_symmetrical_brush_actions( /* initial stroke */ cache->mirror_symmetry_pass = 0; - vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'X'); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Y'); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Z'); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X'); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y'); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z'); cache->symmetry = symm; @@ -3393,16 +3826,16 @@ static void vpaint_do_symmetrical_brush_actions( SCULPT_cache_calc_brushdata_symm(cache, i, 0, 0); if (i & (1 << 0)) { - vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'X'); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'X'); } if (i & (1 << 1)) { - vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'Y', 0, 0); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Y'); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Y'); } if (i & (1 << 2)) { - vpaint_do_paint(C, sd, vp, vpd, ob, me, brush, i, 'Z', 0, 0); - vpaint_do_radial_symmetry(C, sd, vp, vpd, ob, me, brush, i, 'Z'); + vpaint_do_paint<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z', 0, 0); + vpaint_do_radial_symmetry<Color, Traits, domain>(C, sd, vp, vpd, ob, me, brush, i, 'Z'); } } } @@ -3411,14 +3844,13 @@ static void vpaint_do_symmetrical_brush_actions( cache->is_last_valid = true; } -static void vpaint_stroke_update_step(bContext *C, - wmOperator *UNUSED(op), - struct PaintStroke *stroke, - PointerRNA *itemptr) +template<typename Color, typename Traits, AttributeDomain domain> +static void vpaint_stroke_update_step_intern(bContext *C, PaintStroke *stroke, PointerRNA *itemptr) { Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); - struct VPaintData *vpd = paint_stroke_mode_data(stroke); + VPaintData<Color, Traits, domain> *vpd = static_cast<VPaintData<Color, Traits, domain> *>( + paint_stroke_mode_data(stroke)); VPaint *vp = ts->vpaint; ViewContext *vc = &vpd->vc; Object *ob = vc->obact; @@ -3436,15 +3868,20 @@ static void vpaint_stroke_update_step(bContext *C, swap_m4m4(vc->rv3d->persmat, mat); - vpaint_do_symmetrical_brush_actions(C, sd, vp, vpd, ob); + vpaint_do_symmetrical_brush_actions<Color, Traits, domain>(C, sd, vp, vpd, ob); swap_m4m4(vc->rv3d->persmat, mat); - BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + BKE_mesh_batch_cache_dirty_tag((Mesh *)ob->data, BKE_MESH_BATCH_DIRTY_ALL); if (vp->paint.brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) { - memcpy( - vpd->smear.color_prev, vpd->smear.color_curr, sizeof(uint) * ((Mesh *)ob->data)->totloop); + Mesh *me = BKE_object_get_original_mesh(ob); + + size_t elem_size; + int elem_num; + + elem_num = get_vcol_elements(me, &elem_size); + memcpy(vpd->smear.color_prev, vpd->smear.color_curr, elem_size * elem_num); } /* Calculate pivot for rotation around selection if needed. @@ -3458,19 +3895,47 @@ static void vpaint_stroke_update_step(bContext *C, if (vpd->use_fast_update == false) { /* recalculate modifier stack to get new colors, slow, * avoid this if we can! */ - DEG_id_tag_update(ob->data, 0); + DEG_id_tag_update((ID *)ob->data, 0); } else { /* Flush changes through DEG. */ - DEG_id_tag_update(ob->data, ID_RECALC_COPY_ON_WRITE); + DEG_id_tag_update((ID *)ob->data, ID_RECALC_COPY_ON_WRITE); } } -static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) +static void vpaint_stroke_update_step(bContext *C, + wmOperator *UNUSED(op), + PaintStroke *stroke, + PointerRNA *itemptr) { - struct VPaintData *vpd = paint_stroke_mode_data(stroke); - ViewContext *vc = &vpd->vc; - Object *ob = vc->obact; + VPaintDataBase *vpd = static_cast<VPaintDataBase *>(paint_stroke_mode_data(stroke)); + + if (vpd->domain == ATTR_DOMAIN_POINT) { + if (vpd->type == CD_PROP_COLOR) { + vpaint_stroke_update_step_intern<ColorPaint4f, FloatTraits, ATTR_DOMAIN_POINT>( + C, stroke, itemptr); + } + else if (vpd->type == CD_PROP_BYTE_COLOR) { + vpaint_stroke_update_step_intern<ColorPaint4b, ByteTraits, ATTR_DOMAIN_POINT>( + C, stroke, itemptr); + } + } + else if (vpd->domain == ATTR_DOMAIN_CORNER) { + if (vpd->type == CD_PROP_COLOR) { + vpaint_stroke_update_step_intern<ColorPaint4f, FloatTraits, ATTR_DOMAIN_CORNER>( + C, stroke, itemptr); + } + else if (vpd->type == CD_PROP_BYTE_COLOR) { + vpaint_stroke_update_step_intern<ColorPaint4b, ByteTraits, ATTR_DOMAIN_CORNER>( + C, stroke, itemptr); + } + } +} + +template<typename Color, typename Traits, AttributeDomain domain> +static void vpaint_free_vpaintdata(Object *UNUSED(ob), void *_vpd) +{ + VPaintData<Color, Traits, domain> *vpd = static_cast<VPaintData<Color, Traits, domain> *>(_vpd); if (vpd->is_texbrush) { ED_vpaint_proj_handle_free(vpd->vp_handle); @@ -3486,6 +3951,34 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) MEM_freeN(vpd->smear.color_curr); } + MEM_delete<VPaintData<Color, Traits, domain>>(vpd); +} + +static void vpaint_stroke_done(const bContext *C, PaintStroke *stroke) +{ + void *vpd_ptr = paint_stroke_mode_data(stroke); + VPaintDataBase *vpd = static_cast<VPaintDataBase *>(vpd_ptr); + + ViewContext *vc = &vpd->vc; + Object *ob = vc->obact; + + if (vpd->domain == ATTR_DOMAIN_POINT) { + if (vpd->type == CD_PROP_COLOR) { + vpaint_free_vpaintdata<ColorPaint4f, FloatTraits, ATTR_DOMAIN_POINT>(ob, vpd); + } + else if (vpd->type == CD_PROP_BYTE_COLOR) { + vpaint_free_vpaintdata<ColorPaint4b, ByteTraits, ATTR_DOMAIN_POINT>(ob, vpd); + } + } + else if (vpd->domain == ATTR_DOMAIN_CORNER) { + if (vpd->type == CD_PROP_COLOR) { + vpaint_free_vpaintdata<ColorPaint4f, FloatTraits, ATTR_DOMAIN_CORNER>(ob, vpd); + } + else if (vpd->type == CD_PROP_BYTE_COLOR) { + vpaint_free_vpaintdata<ColorPaint4b, ByteTraits, ATTR_DOMAIN_CORNER>(ob, vpd); + } + } + SculptSession *ss = ob->sculpt; if (ss->cache->alt_smooth) { @@ -3496,10 +3989,10 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke) WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); - MEM_freeN(vpd); + SCULPT_undo_push_end(ob); SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event) @@ -3511,12 +4004,20 @@ static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event) SCULPT_stroke_get_location, vpaint_stroke_test_start, vpaint_stroke_update_step, - NULL, + nullptr, vpaint_stroke_done, event->type); + Object *ob = CTX_data_active_object(C); + + if (SCULPT_has_loop_colors(ob) && ob->sculpt->pbvh) { + BKE_pbvh_ensure_node_loops(ob->sculpt->pbvh); + } + + SCULPT_undo_push_begin(ob, "Vertex Paint"); + if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) { - paint_stroke_free(C, op, op->customdata); + paint_stroke_free(C, op, (PaintStroke *)op->customdata); return OPERATOR_FINISHED; } @@ -3536,12 +4037,12 @@ static int vpaint_exec(bContext *C, wmOperator *op) SCULPT_stroke_get_location, vpaint_stroke_test_start, vpaint_stroke_update_step, - NULL, + nullptr, vpaint_stroke_done, 0); /* frees op->customdata */ - paint_stroke_exec(C, op, op->customdata); + paint_stroke_exec(C, op, (PaintStroke *)op->customdata); return OPERATOR_FINISHED; } @@ -3551,15 +4052,15 @@ static void vpaint_cancel(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob->sculpt->cache) { SCULPT_cache_free(ob->sculpt->cache); - ob->sculpt->cache = NULL; + ob->sculpt->cache = nullptr; } - paint_stroke_cancel(C, op, op->customdata); + paint_stroke_cancel(C, op, (PaintStroke *)op->customdata); } static int vpaint_modal(bContext *C, wmOperator *op, const wmEvent *event) { - return paint_stroke_modal(C, op, event, (struct PaintStroke **)&op->customdata); + return paint_stroke_modal(C, op, event, (PaintStroke **)&op->customdata); } void PAINT_OT_vertex_paint(wmOperatorType *ot) @@ -3582,4 +4083,113 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot) paint_stroke_operator_properties(ot); } +/* -------------------------------------------------------------------- */ +/** \name Set Vertex Colors Operator + * \{ */ + +template<typename Color, typename Traits, AttributeDomain domain> +static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, Color *color_layer) +{ + Mesh *me; + if (((me = BKE_mesh_from_object(ob)) == nullptr) || + (ED_mesh_color_ensure(me, nullptr) == false)) { + return false; + } + + Color paintcol = fromFloat<Color>(paintcol_in); + + const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; + const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; + + const MPoly *mp = me->mpoly; + for (int i = 0; i < me->totpoly; i++, mp++) { + if (use_face_sel && !(mp->flag & ME_FACE_SEL)) { + continue; + } + + int j = 0; + do { + uint vidx = me->mloop[mp->loopstart + j].v; + + if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) { + if constexpr (domain == ATTR_DOMAIN_CORNER) { + color_layer[mp->loopstart + j] = paintcol; + } + else { + color_layer[vidx] = paintcol; + } + } + j++; + } while (j < mp->totloop); + } + + /* remove stale me->mcol, will be added later */ + BKE_mesh_tessface_clear(me); + + DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE); + + /* NOTE: Original mesh is used for display, so tag it directly here. */ + BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL); + + return true; +} + +static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene *scene = CTX_data_scene(C); + Object *obact = CTX_data_active_object(C); + Mesh *me = BKE_object_get_original_mesh(obact); + + // uint paintcol = vpaint_get_current_color(scene, scene->toolsettings->vpaint, false); + ColorPaint4f paintcol = vpaint_get_current_col<ColorPaint4f, FloatTraits, ATTR_DOMAIN_POINT>( + scene, scene->toolsettings->vpaint, false); + + bool ok = false; + + CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + AttributeDomain domain = BKE_id_attribute_domain(&me->id, layer); + + if (domain == ATTR_DOMAIN_POINT) { + if (layer->type == CD_PROP_COLOR) { + ok = vertex_color_set<ColorPaint4f, FloatTraits, ATTR_DOMAIN_POINT>( + obact, paintcol, static_cast<ColorPaint4f *>(layer->data)); + } + else if (layer->type == CD_PROP_BYTE_COLOR) { + ok = vertex_color_set<ColorPaint4b, ByteTraits, ATTR_DOMAIN_POINT>( + obact, paintcol, static_cast<ColorPaint4b *>(layer->data)); + } + } + else { + if (layer->type == CD_PROP_COLOR) { + ok = vertex_color_set<ColorPaint4f, FloatTraits, ATTR_DOMAIN_CORNER>( + obact, paintcol, static_cast<ColorPaint4f *>(layer->data)); + } + else if (layer->type == CD_PROP_BYTE_COLOR) { + ok = vertex_color_set<ColorPaint4b, ByteTraits, ATTR_DOMAIN_CORNER>( + obact, paintcol, static_cast<ColorPaint4b *>(layer->data)); + } + } + + if (ok) { + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact); + return OPERATOR_FINISHED; + } + return OPERATOR_CANCELLED; +} + +void PAINT_OT_vertex_color_set(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Set Vertex Colors"; + ot->idname = "PAINT_OT_vertex_color_set"; + ot->description = "Fill the active vertex color layer with the current paint color"; + + /* api callbacks */ + ot->exec = vertex_color_set_exec; + ot->poll = vertex_paint_mode_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /** \} */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c index 619607408e5..9f337d8d789 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.c @@ -47,75 +47,6 @@ static void tag_object_after_update(Object *object) BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); } -/* -------------------------------------------------------------------- */ -/** \name Set Vertex Colors Operator - * \{ */ - -static bool vertex_color_set(Object *ob, uint paintcol) -{ - Mesh *me; - if (((me = BKE_mesh_from_object(ob)) == NULL) || (ED_mesh_color_ensure(me, NULL) == false)) { - return false; - } - - const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - - const MPoly *mp = me->mpoly; - for (int i = 0; i < me->totpoly; i++, mp++) { - MLoopCol *lcol = me->mloopcol + mp->loopstart; - - if (use_face_sel && !(mp->flag & ME_FACE_SEL)) { - continue; - } - - int j = 0; - do { - uint vidx = me->mloop[mp->loopstart + j].v; - if (!(use_vert_sel && !(me->mvert[vidx].flag & SELECT))) { - *(int *)lcol = paintcol; - } - lcol++; - j++; - } while (j < mp->totloop); - } - - /* remove stale me->mcol, will be added later */ - BKE_mesh_tessface_clear(me); - - tag_object_after_update(ob); - - return true; -} - -static int vertex_color_set_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Scene *scene = CTX_data_scene(C); - Object *obact = CTX_data_active_object(C); - uint paintcol = vpaint_get_current_col(scene, scene->toolsettings->vpaint, false); - - if (vertex_color_set(obact, paintcol)) { - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact); - return OPERATOR_FINISHED; - } - return OPERATOR_CANCELLED; -} - -void PAINT_OT_vertex_color_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Vertex Colors"; - ot->idname = "PAINT_OT_vertex_color_set"; - ot->description = "Fill the active vertex color layer with the current paint color"; - - /* api callbacks */ - ot->exec = vertex_color_set_exec; - ot->poll = vertex_paint_mode_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c index 8d5f39fd56e..cd099f71ccd 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_utils.c @@ -73,570 +73,3 @@ bool ED_vpaint_color_transform(struct Object *ob, return true; } - -/* -------------------------------------------------------------------- */ -/** \name Color Blending Modes - * \{ */ - -BLI_INLINE uint mcol_blend(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - if (fac >= 255) { - return col_dst; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* Updated to use the rgb squared color model which blends nicer. */ - int r1 = cp_src[0] * cp_src[0]; - int g1 = cp_src[1] * cp_src[1]; - int b1 = cp_src[2] * cp_src[2]; - int a1 = cp_src[3] * cp_src[3]; - - int r2 = cp_dst[0] * cp_dst[0]; - int g2 = cp_dst[1] * cp_dst[1]; - int b2 = cp_dst[2] * cp_dst[2]; - int a2 = cp_dst[3] * cp_dst[3]; - - cp_mix[0] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * r1 + fac * r2), 255))); - cp_mix[1] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * g1 + fac * g2), 255))); - cp_mix[2] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * b1 + fac * b2), 255))); - cp_mix[3] = round_fl_to_uchar(sqrtf(divide_round_i((mfac * a1 + fac * a2), 255))); - - return col_mix; -} - -BLI_INLINE uint mcol_add(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[0] + divide_round_i((fac * cp_dst[0]), 255); - cp_mix[0] = (temp > 254) ? 255 : temp; - temp = cp_src[1] + divide_round_i((fac * cp_dst[1]), 255); - cp_mix[1] = (temp > 254) ? 255 : temp; - temp = cp_src[2] + divide_round_i((fac * cp_dst[2]), 255); - cp_mix[2] = (temp > 254) ? 255 : temp; - temp = cp_src[3] + divide_round_i((fac * cp_dst[3]), 255); - cp_mix[3] = (temp > 254) ? 255 : temp; - - return col_mix; -} - -BLI_INLINE uint mcol_sub(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[0] - divide_round_i((fac * cp_dst[0]), 255); - cp_mix[0] = (temp < 0) ? 0 : temp; - temp = cp_src[1] - divide_round_i((fac * cp_dst[1]), 255); - cp_mix[1] = (temp < 0) ? 0 : temp; - temp = cp_src[2] - divide_round_i((fac * cp_dst[2]), 255); - cp_mix[2] = (temp < 0) ? 0 : temp; - temp = cp_src[3] - divide_round_i((fac * cp_dst[3]), 255); - cp_mix[3] = (temp < 0) ? 0 : temp; - - return col_mix; -} - -BLI_INLINE uint mcol_mul(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* first mul, then blend the fac */ - cp_mix[0] = divide_round_i(mfac * cp_src[0] * 255 + fac * cp_dst[0] * cp_src[0], 255 * 255); - cp_mix[1] = divide_round_i(mfac * cp_src[1] * 255 + fac * cp_dst[1] * cp_src[1], 255 * 255); - cp_mix[2] = divide_round_i(mfac * cp_src[2] * 255 + fac * cp_dst[2] * cp_src[2], 255 * 255); - cp_mix[3] = divide_round_i(mfac * cp_src[3] * 255 + fac * cp_dst[3] * cp_src[3], 255 * 255); - - return col_mix; -} - -BLI_INLINE uint mcol_lighten(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - if (fac >= 255) { - return col_dst; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* See if we're lighter, if so mix, else don't do anything. - * if the paint color is darker then the original, then ignore */ - if (IMB_colormanagement_get_luminance_byte(cp_src) > - IMB_colormanagement_get_luminance_byte(cp_dst)) { - return col_src; - } - - cp_mix[0] = divide_round_i(mfac * cp_src[0] + fac * cp_dst[0], 255); - cp_mix[1] = divide_round_i(mfac * cp_src[1] + fac * cp_dst[1], 255); - cp_mix[2] = divide_round_i(mfac * cp_src[2] + fac * cp_dst[2], 255); - cp_mix[3] = divide_round_i(mfac * cp_src[3] + fac * cp_dst[3], 255); - - return col_mix; -} - -BLI_INLINE uint mcol_darken(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - if (fac >= 255) { - return col_dst; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - /* See if we're darker, if so mix, else don't do anything. - * if the paint color is brighter then the original, then ignore */ - if (IMB_colormanagement_get_luminance_byte(cp_src) < - IMB_colormanagement_get_luminance_byte(cp_dst)) { - return col_src; - } - - cp_mix[0] = divide_round_i((mfac * cp_src[0] + fac * cp_dst[0]), 255); - cp_mix[1] = divide_round_i((mfac * cp_src[1] + fac * cp_dst[1]), 255); - cp_mix[2] = divide_round_i((mfac * cp_src[2] + fac * cp_dst[2]), 255); - cp_mix[3] = divide_round_i((mfac * cp_src[3] + fac * cp_dst[3]), 255); - return col_mix; -} - -BLI_INLINE uint mcol_colordodge(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = (cp_dst[0] == 255) ? 255 : min_ii((cp_src[0] * 225) / (255 - cp_dst[0]), 255); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = (cp_dst[1] == 255) ? 255 : min_ii((cp_src[1] * 225) / (255 - cp_dst[1]), 255); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = (cp_dst[2] == 255) ? 255 : min_ii((cp_src[2] * 225) / (255 - cp_dst[2]), 255); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = (cp_dst[3] == 255) ? 255 : min_ii((cp_src[3] * 225) / (255 - cp_dst[3]), 255); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_difference(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = abs(cp_src[0] - cp_dst[0]); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = abs(cp_src[1] - cp_dst[1]); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = abs(cp_src[2] - cp_dst[2]); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = abs(cp_src[3] - cp_dst[3]); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_screen(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - temp = max_ii(255 - (((255 - cp_src[0]) * (255 - cp_dst[0])) / 255), 0); - cp_mix[0] = (mfac * cp_src[0] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[1]) * (255 - cp_dst[1])) / 255), 0); - cp_mix[1] = (mfac * cp_src[1] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[2]) * (255 - cp_dst[2])) / 255), 0); - cp_mix[2] = (mfac * cp_src[2] + temp * fac) / 255; - temp = max_ii(255 - (((255 - cp_src[3]) * (255 - cp_dst[3])) / 255), 0); - cp_mix[3] = (mfac * cp_src[3] + temp * fac) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_hardlight(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - if (cp_dst[i] > 127) { - temp = 255 - ((255 - 2 * (cp_dst[i] - 127)) * (255 - cp_src[i]) / 255); - } - else { - temp = (2 * cp_dst[i] * cp_src[i]) >> 8; - } - cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); - } - return col_mix; -} - -BLI_INLINE uint mcol_overlay(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - if (cp_src[i] > 127) { - temp = 255 - ((255 - 2 * (cp_src[i] - 127)) * (255 - cp_dst[i]) / 255); - } - else { - temp = (2 * cp_dst[i] * cp_src[i]) >> 8; - } - cp_mix[i] = min_ii((mfac * cp_src[i] + temp * fac) / 255, 255); - } - return col_mix; -} - -BLI_INLINE uint mcol_softlight(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - for (int i = 0; i < 4; i++) { - if (cp_src[i] < 127) { - temp = ((2 * ((cp_dst[i] / 2) + 64)) * cp_src[i]) / 255; - } - else { - temp = 255 - (2 * (255 - ((cp_dst[i] / 2) + 64)) * (255 - cp_src[i]) / 255); - } - cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; - } - return col_mix; -} - -BLI_INLINE uint mcol_exclusion(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac, temp; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - int i = 0; - - for (i = 0; i < 4; i++) { - temp = 127 - ((2 * (cp_src[i] - 127) * (cp_dst[i] - 127)) / 255); - cp_mix[i] = (temp * fac + cp_src[i] * mfac) / 255; - } - return col_mix; -} - -BLI_INLINE uint mcol_luminosity(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - - v1 = v2; - - hsv_to_rgb(h1, s1, v1, &r, &g, &b); - - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_saturation(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - - if (s1 > EPS_SATURATION) { - s1 = s2; - } - - hsv_to_rgb(h1, s1, v1, &r, &g, &b); - - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_hue(uint col_src, uint col_dst, int fac) -{ - uchar *cp_src, *cp_dst, *cp_mix; - int mfac; - uint col_mix = 0; - - if (fac == 0) { - return col_src; - } - - mfac = 255 - fac; - - cp_src = (uchar *)&col_src; - cp_dst = (uchar *)&col_dst; - cp_mix = (uchar *)&col_mix; - - float h1, s1, v1; - float h2, s2, v2; - float r, g, b; - rgb_to_hsv(cp_src[0] / 255.0f, cp_src[1] / 255.0f, cp_src[2] / 255.0f, &h1, &s1, &v1); - rgb_to_hsv(cp_dst[0] / 255.0f, cp_dst[1] / 255.0f, cp_dst[2] / 255.0f, &h2, &s2, &v2); - - h1 = h2; - - hsv_to_rgb(h1, s1, v1, &r, &g, &b); - - cp_mix[0] = ((int)(r * 255.0f) * fac + mfac * cp_src[0]) / 255; - cp_mix[1] = ((int)(g * 255.0f) * fac + mfac * cp_src[1]) / 255; - cp_mix[2] = ((int)(b * 255.0f) * fac + mfac * cp_src[2]) / 255; - cp_mix[3] = ((int)(cp_dst[3]) * fac + mfac * cp_src[3]) / 255; - return col_mix; -} - -BLI_INLINE uint mcol_alpha_add(uint col_src, int fac) -{ - uchar *cp_src, *cp_mix; - int temp; - uint col_mix = col_src; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[3] + fac; - cp_mix[3] = (temp > 254) ? 255 : temp; - - return col_mix; -} - -BLI_INLINE uint mcol_alpha_sub(uint col_src, int fac) -{ - uchar *cp_src, *cp_mix; - int temp; - uint col_mix = col_src; - - if (fac == 0) { - return col_src; - } - - cp_src = (uchar *)&col_src; - cp_mix = (uchar *)&col_mix; - - temp = cp_src[3] - fac; - cp_mix[3] = temp < 0 ? 0 : temp; - - return col_mix; -} - -uint ED_vpaint_blend_tool(const int tool, const uint col, const uint paintcol, const int alpha_i) -{ - switch ((IMB_BlendMode)tool) { - case IMB_BLEND_MIX: - return mcol_blend(col, paintcol, alpha_i); - case IMB_BLEND_ADD: - return mcol_add(col, paintcol, alpha_i); - case IMB_BLEND_SUB: - return mcol_sub(col, paintcol, alpha_i); - case IMB_BLEND_MUL: - return mcol_mul(col, paintcol, alpha_i); - case IMB_BLEND_LIGHTEN: - return mcol_lighten(col, paintcol, alpha_i); - case IMB_BLEND_DARKEN: - return mcol_darken(col, paintcol, alpha_i); - case IMB_BLEND_COLORDODGE: - return mcol_colordodge(col, paintcol, alpha_i); - case IMB_BLEND_DIFFERENCE: - return mcol_difference(col, paintcol, alpha_i); - case IMB_BLEND_SCREEN: - return mcol_screen(col, paintcol, alpha_i); - case IMB_BLEND_HARDLIGHT: - return mcol_hardlight(col, paintcol, alpha_i); - case IMB_BLEND_OVERLAY: - return mcol_overlay(col, paintcol, alpha_i); - case IMB_BLEND_SOFTLIGHT: - return mcol_softlight(col, paintcol, alpha_i); - case IMB_BLEND_EXCLUSION: - return mcol_exclusion(col, paintcol, alpha_i); - case IMB_BLEND_LUMINOSITY: - return mcol_luminosity(col, paintcol, alpha_i); - case IMB_BLEND_SATURATION: - return mcol_saturation(col, paintcol, alpha_i); - case IMB_BLEND_HUE: - return mcol_hue(col, paintcol, alpha_i); - /* non-color */ - case IMB_BLEND_ERASE_ALPHA: - return mcol_alpha_sub(col, alpha_i); - case IMB_BLEND_ADD_ALPHA: - return mcol_alpha_add(col, alpha_i); - default: - BLI_assert(0); - return 0; - } -} - -/** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index bbbed32e316..93a60b9908e 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2780,7 +2780,7 @@ static void sculpt_pbvh_update_pixels(PaintModeSettings *paint_mode_settings, return; } - BKE_pbvh_build_pixels(ss->pbvh, mesh->mloop, &mesh->ldata, image, image_user); + BKE_pbvh_build_pixels(ss->pbvh, mesh, image, image_user); } /** \} */ @@ -3097,8 +3097,7 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) for (a = 0; a < me->totvert; a++, mvert++) { copy_v3_v3(mvert->co, vertCos[a]); } - - BKE_mesh_calc_normals(me); + BKE_mesh_normals_tag_dirty(me); } /* Apply new coords on active key block, no need to re-allocate kb->data here! */ @@ -3915,16 +3914,6 @@ bool SCULPT_mode_poll(bContext *C) return ob && ob->mode & OB_MODE_SCULPT; } -bool SCULPT_vertex_colors_poll(bContext *C) -{ - if (!SCULPT_mode_poll(C)) { - return false; - } - - Object *ob = CTX_data_active_object(C); - return ob->sculpt && SCULPT_has_colors(ob->sculpt); -} - bool SCULPT_mode_poll_view3d(bContext *C) { return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C)); @@ -4026,6 +4015,7 @@ void SCULPT_cache_free(StrokeCache *cache) MEM_SAFE_FREE(cache->detail_directions); MEM_SAFE_FREE(cache->prev_displacement); MEM_SAFE_FREE(cache->limit_surface_co); + MEM_SAFE_FREE(cache->prev_colors_vpaint); if (cache->pose_ik_chain) { SCULPT_pose_ik_chain_free(cache->pose_ik_chain); @@ -5256,6 +5246,24 @@ static bool over_mesh(bContext *C, struct wmOperator *UNUSED(op), float x, float return SCULPT_stroke_get_location(C, co, mouse); } +bool SCULPT_handles_colors_report(SculptSession *ss, ReportList *reports) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + return true; + case PBVH_BMESH: + BKE_report(reports, RPT_ERROR, "Not supported in dynamic topology mode"); + return false; + case PBVH_GRIDS: + BKE_report(reports, RPT_ERROR, "Not supported in multiresolution mode"); + return false; + } + + BLI_assert_msg(0, "PBVH corruption, type was invalid."); + + return false; +} + static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2]) { /* Don't start the stroke until mouse goes over the mesh. @@ -5438,6 +5446,12 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent sculpt_brush_stroke_init(C, op); + Object *ob = CTX_data_active_object(C); + + if (!SCULPT_handles_colors_report(ob->sculpt, op->reports)) { + return OPERATOR_CANCELLED; + } + stroke = paint_stroke_new(C, op, SCULPT_stroke_get_location, diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 5d4a2c54832..a705f6aa8a8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -24,6 +24,7 @@ #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_pbvh.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "IMB_colormanagement.h" @@ -342,10 +343,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent } /* Disable for multires and dyntopo for now */ - if (!ss->pbvh) { - return OPERATOR_CANCELLED; - } - if (BKE_pbvh_type(pbvh) != PBVH_FACES) { + if (!ss->pbvh || !SCULPT_handles_colors_report(ss, op->reports)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 3839c0e71e4..f13f1c79a7a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -219,7 +219,6 @@ typedef struct SculptThreadedTaskData { int totnode; struct VPaint *vp; - struct VPaintData *vpd; struct WPaintData *wpd; struct WeightPaintInfo *wpi; unsigned int *lcol; @@ -493,6 +492,7 @@ typedef struct StrokeCache { float mouse_event[2]; float (*prev_colors)[4]; + void *prev_colors_vpaint; /* Multires Displacement Smear. */ float (*prev_displacement)[3]; @@ -782,7 +782,17 @@ bool SCULPT_mode_poll_view3d(struct bContext *C); bool SCULPT_poll(struct bContext *C); bool SCULPT_poll_view3d(struct bContext *C); -bool SCULPT_vertex_colors_poll(struct bContext *C); +/** + * Returns true if sculpt session can handle color attributes + * (BKE_pbvh_type(ss->pbvh) == PBVH_FACES). If false an error + * message will be shown to the user. Operators should return + * OPERATOR_CANCELLED in this case. + * + * NOTE: Does not check if a color attribute actually exists. + * Calling code must handle this itself; in most cases a call to + * BKE_sculpt_color_layer_create_if_needed() is sufficient. + */ +bool SCULPT_handles_colors_report(struct SculptSession *ss, struct ReportList *reports); /** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index 9581bf2071c..e02c1b1aac3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -245,7 +245,7 @@ static int sculpt_symmetrize_exec(bContext *C, wmOperator *op) BKE_mesh_mirror_apply_mirror_on_axis(bmain, mesh, sd->symmetrize_direction, dist); ED_sculpt_undo_geometry_end(ob); - BKE_mesh_calc_normals(ob->data); + BKE_mesh_normals_tag_dirty(mesh); BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); break; @@ -627,11 +627,11 @@ static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op)) Mesh *mesh = ob->data; - const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL); + const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR); if (mloopcol_layer_n == -1) { return OPERATOR_CANCELLED; } - MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n); + MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n); const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR); if (MPropCol_layer_n == -1) { @@ -662,6 +662,21 @@ static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +static bool sculpt_colors_poll(bContext *C) +{ + if (!SCULPT_mode_poll(C)) { + return false; + } + + Object *ob = CTX_data_active_object(C); + + if (!ob->sculpt || !ob->sculpt->pbvh || BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES) { + return false; + } + + return SCULPT_has_colors(ob->sculpt); +} + static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot) { /* identifiers */ @@ -670,7 +685,7 @@ static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot) ot->idname = "SCULPT_OT_vertex_to_loop_colors"; /* api callbacks */ - ot->poll = SCULPT_vertex_colors_poll; + ot->poll = sculpt_colors_poll; ot->exec = vertex_to_loop_colors_exec; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -692,11 +707,11 @@ static int loop_to_vertex_colors_exec(bContext *C, wmOperator *UNUSED(op)) Mesh *mesh = ob->data; - const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_MLOOPCOL); + const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR); if (mloopcol_layer_n == -1) { return OPERATOR_CANCELLED; } - MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPCOL, mloopcol_layer_n); + MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n); const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR); if (MPropCol_layer_n == -1) { @@ -734,15 +749,13 @@ static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot) ot->idname = "SCULPT_OT_loop_to_vertex_colors"; /* api callbacks */ - ot->poll = SCULPT_vertex_colors_poll; + ot->poll = sculpt_colors_poll; ot->exec = loop_to_vertex_colors_exec; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int sculpt_sample_color_invoke(bContext *C, - wmOperator *UNUSED(op), - const wmEvent *UNUSED(e)) +static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Scene *scene = CTX_data_scene(C); @@ -752,11 +765,17 @@ static int sculpt_sample_color_invoke(bContext *C, int active_vertex = SCULPT_active_vertex_get(ss); float active_vertex_color[4]; - if (!SCULPT_has_colors(ss)) { + if (!SCULPT_handles_colors_report(ss, op->reports)) { return OPERATOR_CANCELLED; } - SCULPT_vertex_color_get(ss, active_vertex, active_vertex_color); + /* No color attribute? Set color to white. */ + if (!SCULPT_has_colors(ss)) { + copy_v4_fl(active_vertex_color, 1.0f); + } + else { + SCULPT_vertex_color_get(ss, active_vertex, active_vertex_color); + } float color_srgb[3]; copy_v3_v3(color_srgb, active_vertex_color); @@ -777,7 +796,7 @@ static void SCULPT_OT_sample_color(wmOperatorType *ot) /* api callbacks */ ot->invoke = sculpt_sample_color_invoke; - ot->poll = SCULPT_vertex_colors_poll; + ot->poll = SCULPT_mode_poll; ot->flag = OPTYPE_REGISTER; } @@ -1025,8 +1044,8 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); - /* Color data is not available in Multires. */ - if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) { + /* Color data is not available in multi-resolution or dynamic topology. */ + if (!SCULPT_handles_colors_report(ss, op->reports)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 1fc7551f545..df1ccc0fbe9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -330,7 +330,7 @@ static void do_paint_pixels(void *__restrict userdata, kernel_float4.init_brush_color(image_buffer); } else { - kernel_float4.init_brush_color(image_buffer); + kernel_byte4.init_brush_color(image_buffer); } for (const PackedPixelRow &pixel_row : tile_data.pixel_rows) { diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index eae90359dfd..5867dc558de 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -854,7 +854,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase if (tag_update) { Mesh *mesh = ob->data; - BKE_mesh_calc_normals(mesh); + BKE_mesh_normals_tag_dirty(mesh); BKE_sculptsession_free_deformMats(ss); } diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index eda9f89b51c..80efaf4ed9f 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -744,7 +744,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *region) for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) { if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) { const float xminc = strip->start + text_margin_x; - const float xmaxc = strip->end + text_margin_x; + const float xmaxc = strip->end - text_margin_x; /* draw the visualization of the strip */ nla_draw_strip(snla, adt, nlt, strip, v2d, ymin, ymax); diff --git a/source/blender/editors/space_node/node_geometry_attribute_search.cc b/source/blender/editors/space_node/node_geometry_attribute_search.cc index 2536496b50d..fee64da0459 100644 --- a/source/blender/editors/space_node/node_geometry_attribute_search.cc +++ b/source/blender/editors/space_node/node_geometry_attribute_search.cc @@ -135,7 +135,7 @@ static CustomDataType data_type_in_attribute_input_node(const CustomDataType typ case CD_PROP_COLOR: case CD_PROP_BOOL: return type; - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: return CD_PROP_COLOR; case CD_PROP_STRING: /* Unsupported currently. */ diff --git a/source/blender/editors/space_node/node_view.cc b/source/blender/editors/space_node/node_view.cc index f5f5a9e6f67..91a21527ac9 100644 --- a/source/blender/editors/space_node/node_view.cc +++ b/source/blender/editors/space_node/node_view.cc @@ -179,6 +179,8 @@ void NODE_OT_view_selected(wmOperatorType *ot) struct NodeViewMove { int mvalo[2]; int xmin, ymin, xmax, ymax; + /** Original Offset for cancel. */ + float xof_orig, yof_orig; }; static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event) @@ -207,13 +209,24 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *e case LEFTMOUSE: case MIDDLEMOUSE: - case RIGHTMOUSE: if (event->val == KM_RELEASE) { MEM_freeN(nvm); op->customdata = nullptr; return OPERATOR_FINISHED; } break; + case EVT_ESCKEY: + case RIGHTMOUSE: + snode->xof = nvm->xof_orig; + snode->yof = nvm->yof_orig; + ED_region_tag_redraw(region); + WM_main_add_notifier(NC_NODE | ND_DISPLAY, nullptr); + WM_main_add_notifier(NC_SPACE | ND_SPACE_NODE_VIEW, nullptr); + + MEM_freeN(nvm); + op->customdata = nullptr; + + return OPERATOR_CANCELLED; } return OPERATOR_RUNNING_MODAL; @@ -249,6 +262,9 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent * nvm->ymin = -(region->winy / 2) - (ibuf->y * (0.5f * snode->zoom)) + pad; nvm->ymax = (region->winy / 2) + (ibuf->y * (0.5f * snode->zoom)) - pad; + nvm->xof_orig = snode->xof; + nvm->yof_orig = snode->yof; + BKE_image_release_ibuf(ima, ibuf, lock); /* add modal handler */ diff --git a/source/blender/editors/space_sequencer/sequencer_channels_draw.c b/source/blender/editors/space_sequencer/sequencer_channels_draw.c index b4bb4e950f0..a777132e9fc 100644 --- a/source/blender/editors/space_sequencer/sequencer_channels_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_channels_draw.c @@ -347,6 +347,8 @@ void channel_draw_context_init(const bContext *C, void draw_channels(const bContext *C, ARegion *region) { + draw_background(); + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); if (ed == NULL) { return; @@ -357,7 +359,6 @@ void draw_channels(const bContext *C, ARegion *region) UI_view2d_view_ortho(context.v2d); - draw_background(); draw_channel_headers(&context); UI_view2d_view_restore(C); diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 8e5931b127a..95707f83d85 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -27,6 +27,7 @@ #include "SEQ_channels.h" #include "SEQ_iterator.h" +#include "SEQ_relations.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" @@ -1920,7 +1921,7 @@ static bool select_grouped_effect(SeqCollection *strips, Sequence *seq; SEQ_ITERATOR_FOREACH (seq, strips) { if (SEQ_CHANNEL_CHECK(seq, channel) && (seq->type & SEQ_TYPE_EFFECT) && - ELEM(actseq, seq->seq1, seq->seq2, seq->seq3)) { + SEQ_relation_is_effect_of_strip(seq, actseq)) { effects[seq->type] = true; } } diff --git a/source/blender/editors/space_sequencer/sequencer_thumbnails.c b/source/blender/editors/space_sequencer/sequencer_thumbnails.c index f5c5c7af4b6..43c5e004040 100644 --- a/source/blender/editors/space_sequencer/sequencer_thumbnails.c +++ b/source/blender/editors/space_sequencer/sequencer_thumbnails.c @@ -86,6 +86,11 @@ static bool check_seq_need_thumbnails(Sequence *seq, rctf *view_area) return false; } + /* Handle is moved, but not for this strip. */ + if ((G.moving & G_TRANSFORM_SEQ) != 0 && (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0) { + return false; + } + return true; } @@ -123,26 +128,13 @@ static void seq_get_thumb_image_dimensions(Sequence *seq, } } -static float seq_thumbnail_get_start_frame(Sequence *seq, float frame_step, rctf *view_area) -{ - if (seq->start > view_area->xmin && seq->start < view_area->xmax) { - return seq->start; - } - - /* Drawing and caching both check to see if strip is in view area or not before calling this - * function so assuming strip/part of strip in view. */ - - int no_invisible_thumbs = (view_area->xmin - seq->start) / frame_step; - return ((no_invisible_thumbs - 1) * frame_step) + seq->start; -} - static void thumbnail_start_job(void *data, short *stop, short *UNUSED(do_update), float *UNUSED(progress)) { ThumbnailDrawJob *tj = data; - float start_frame, frame_step; + float frame_step; GHashIterator gh_iter; @@ -155,9 +147,8 @@ static void thumbnail_start_job(void *data, if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); - start_frame = seq_thumbnail_get_start_frame(seq_orig, frame_step, tj->view_area); SEQ_render_thumbnails( - &tj->context, val->seq_dupli, seq_orig, start_frame, frame_step, tj->view_area, stop); + &tj->context, val->seq_dupli, seq_orig, frame_step, tj->view_area, stop); SEQ_relations_sequence_free_anim(val->seq_dupli); } BLI_ghashIterator_step(&gh_iter); @@ -172,7 +163,6 @@ static void thumbnail_start_job(void *data, if (check_seq_need_thumbnails(seq_orig, tj->view_area)) { seq_get_thumb_image_dimensions( val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL); - start_frame = seq_thumbnail_get_start_frame(seq_orig, frame_step, tj->view_area); SEQ_render_thumbnails_base_set(&tj->context, val->seq_dupli, seq_orig, tj->view_area, stop); SEQ_relations_sequence_free_anim(val->seq_dupli); } @@ -458,40 +448,31 @@ void draw_seq_strip_thumbnail(View2D *v2d, upper_thumb_bound = seq->enddisp; } - float thumb_x_start = seq_thumbnail_get_start_frame(seq, thumb_width, &v2d->cur); + float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, thumb_width, &v2d->cur); float thumb_x_end; - while (thumb_x_start + thumb_width < v2d->cur.xmin) { - thumb_x_start += thumb_width; - } - - /* Ignore thumbs to the left of strip. */ - while (thumb_x_start + thumb_width < seq->startdisp) { - thumb_x_start += thumb_width; - } - GSet *last_displayed_thumbnails = last_displayed_thumbnails_list_ensure(C, seq); /* Cleanup thumbnail list outside of rendered range, which is cleaned up one by one to prevent * flickering after zooming. */ if (!sequencer_thumbnail_v2d_is_navigating(C)) { - last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, -FLT_MAX, thumb_x_start); + last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, -FLT_MAX, timeline_frame); } /* Start drawing. */ - while (thumb_x_start < upper_thumb_bound) { - thumb_x_end = thumb_x_start + thumb_width; + while (timeline_frame < upper_thumb_bound) { + thumb_x_end = timeline_frame + thumb_width; clipped = false; /* Checks to make sure that thumbs are loaded only when in view and within the confines of the * strip. Some may not be required but better to have conditions for safety as x1 here is * point to start caching from and not drawing. */ - if (thumb_x_start > v2d->cur.xmax) { + if (timeline_frame > v2d->cur.xmax) { break; } /* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */ - if (IN_RANGE_INCL(seq->startdisp, thumb_x_start, thumb_x_end)) { - cut_off = seq->startdisp - thumb_x_start; + if (IN_RANGE_INCL(seq->startdisp, timeline_frame, thumb_x_end)) { + cut_off = seq->startdisp - timeline_frame; clipped = true; } @@ -499,7 +480,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, if (thumb_x_end > (upper_thumb_bound)) { thumb_x_end = upper_thumb_bound; clipped = true; - if (thumb_x_end - thumb_x_start < 1) { + if (thumb_x_end - timeline_frame < 1) { break; } } @@ -508,14 +489,12 @@ void draw_seq_strip_thumbnail(View2D *v2d, float zoom_y = thumb_height / image_height; float cropx_min = (cut_off / pixelx) / (zoom_y / pixely); - float cropx_max = ((thumb_x_end - thumb_x_start) / pixelx) / (zoom_y / pixely); - if (cropx_max == (thumb_x_end - thumb_x_start)) { + float cropx_max = ((thumb_x_end - timeline_frame) / pixelx) / (zoom_y / pixely); + if (cropx_max == (thumb_x_end - timeline_frame)) { cropx_max = cropx_max + 1; } BLI_rcti_init(&crop, (int)(cropx_min), (int)cropx_max, 0, (int)(image_height)-1); - int timeline_frame = round_fl_to_int(thumb_x_start); - /* Get the image. */ ImBuf *ibuf = SEQ_get_thumbnail(&context, seq, timeline_frame, &crop, clipped); @@ -529,7 +508,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, else if (!sequencer_thumbnail_v2d_is_navigating(C)) { /* Clear images in frame range occupied by new thumbnail. */ last_displayed_thumbnails_list_cleanup( - last_displayed_thumbnails, thumb_x_start, thumb_x_end); + last_displayed_thumbnails, timeline_frame, thumb_x_end); /* Insert new thumbnail frame to list. */ BLI_gset_add(last_displayed_thumbnails, POINTER_FROM_INT(timeline_frame)); } @@ -558,10 +537,10 @@ void draw_seq_strip_thumbnail(View2D *v2d, ED_draw_imbuf_ctx_clipping(C, ibuf, - thumb_x_start + cut_off, + timeline_frame + cut_off, y1, true, - thumb_x_start + cut_off, + timeline_frame + cut_off, y1, thumb_x_end, thumb_y_end, @@ -570,7 +549,7 @@ void draw_seq_strip_thumbnail(View2D *v2d, IMB_freeImBuf(ibuf); GPU_blend(GPU_BLEND_NONE); cut_off = 0; - thumb_x_start += thumb_width; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, thumb_width); } - last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, thumb_x_start, FLT_MAX); + last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, timeline_frame, FLT_MAX); } diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 4d245b9ddaa..c407dad623d 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -22,9 +22,11 @@ #include "RNA_define.h" +#include "SEQ_iterator.h" #include "SEQ_select.h" #include "SEQ_sequencer.h" #include "SEQ_time.h" +#include "SEQ_transform.h" /* For menu, popup, icons, etc. */ #include "ED_anim_api.h" @@ -260,14 +262,30 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot) /** \name Frame Selected Operator * \{ */ -static int sequencer_view_selected_exec(bContext *C, wmOperator *op) +static void seq_view_collection_rect_preview(Scene *scene, SeqCollection *strips, rctf *rect) +{ + float min[2], max[2]; + SEQ_image_transform_bounding_box_from_collection(scene, strips, true, min, max); + + rect->xmin = min[0]; + rect->xmax = max[0]; + rect->ymin = min[1]; + rect->ymax = max[1]; + + float minsize = min_ff(BLI_rctf_size_x(rect), BLI_rctf_size_y(rect)); + + /* If the size of the strip is smaller than a pixel, add padding to prevent division by zero. */ + if (minsize < 1.0f) { + BLI_rctf_pad(rect, 20.0f, 20.0f); + } + + /* Add padding. */ + BLI_rctf_scale(rect, 1.1f); +} + +static void seq_view_collection_rect_timeline(Scene *scene, SeqCollection *strips, rctf *rect) { - Scene *scene = CTX_data_scene(C); - View2D *v2d = UI_view2d_fromcontext(C); - ARegion *region = CTX_wm_region(C); - Editing *ed = SEQ_editing_get(scene); Sequence *seq; - rctf cur_new = v2d->cur; int xmin = MAXFRAME * 2; int xmax = -MAXFRAME * 2; @@ -278,49 +296,63 @@ static int sequencer_view_selected_exec(bContext *C, wmOperator *op) int ymargin = 1; int xmargin = FPS; - if (ed == NULL) { - return OPERATOR_CANCELLED; - } - - for (seq = ed->seqbasep->first; seq; seq = seq->next) { - if (seq->flag & SELECT) { - xmin = min_ii(xmin, seq->startdisp); - xmax = max_ii(xmax, seq->enddisp); + SEQ_ITERATOR_FOREACH (seq, strips) { + xmin = min_ii(xmin, seq->startdisp); + xmax = max_ii(xmax, seq->enddisp); - ymin = min_ii(ymin, seq->machine); - ymax = max_ii(ymax, seq->machine); - } + ymin = min_ii(ymin, seq->machine); + ymax = max_ii(ymax, seq->machine); } - if (ymax != 0) { - const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + xmax += xmargin; + xmin -= xmargin; + ymax += ymargin; + ymin -= ymargin; - xmax += xmargin; - xmin -= xmargin; - ymax += ymargin; - ymin -= ymargin; + orig_height = BLI_rctf_size_y(rect); - orig_height = BLI_rctf_size_y(&cur_new); + rect->xmin = xmin; + rect->xmax = xmax; - cur_new.xmin = xmin; - cur_new.xmax = xmax; + rect->ymin = ymin; + rect->ymax = ymax; - cur_new.ymin = ymin; - cur_new.ymax = ymax; + /* Only zoom out vertically. */ + if (orig_height > BLI_rctf_size_y(rect)) { + ymid = BLI_rctf_cent_y(rect); - /* Only zoom out vertically. */ - if (orig_height > BLI_rctf_size_y(&cur_new)) { - ymid = BLI_rctf_cent_y(&cur_new); + rect->ymin = ymid - (orig_height / 2); + rect->ymax = ymid + (orig_height / 2); + } +} - cur_new.ymin = ymid - (orig_height / 2); - cur_new.ymax = ymid + (orig_height / 2); - } +static int sequencer_view_selected_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + ARegion *region = CTX_wm_region(C); + SeqCollection *strips = selected_strips_from_context(C); + View2D *v2d = UI_view2d_fromcontext(C); + rctf cur_new = v2d->cur; - UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx); + if (SEQ_collection_len(strips) == 0) { + return OPERATOR_CANCELLED; + } - return OPERATOR_FINISHED; + if (sequencer_view_has_preview_poll(C) && !sequencer_view_preview_only_poll(C)) { + return OPERATOR_CANCELLED; } - return OPERATOR_CANCELLED; + + if (region && region->regiontype == RGN_TYPE_PREVIEW) { + seq_view_collection_rect_preview(scene, strips, &cur_new); + } + else { + seq_view_collection_rect_timeline(scene, strips, &cur_new); + } + + const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); + UI_view2d_smooth_view(C, region, &cur_new, smooth_viewtx); + + return OPERATOR_FINISHED; } void SEQUENCER_OT_view_selected(wmOperatorType *ot) diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 0a0669e02e4..89bff839481 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -331,6 +331,31 @@ static void sequencer_refresh(const bContext *C, ScrArea *area) break; } + ARegion *region_channels = sequencer_find_region(area, RGN_TYPE_CHANNELS); + if (sseq->view == SEQ_VIEW_SEQUENCE) { + if (region_channels && (region_channels->flag & RGN_FLAG_HIDDEN)) { + region_channels->flag &= ~RGN_FLAG_HIDDEN; + region_channels->v2d.flag &= ~V2D_IS_INIT; + view_changed = true; + } + if (region_channels && region_channels->alignment != RGN_ALIGN_LEFT) { + region_channels->alignment = RGN_ALIGN_LEFT; + view_changed = true; + } + } + else { + if (region_channels && !(region_channels->flag & RGN_FLAG_HIDDEN)) { + region_channels->flag |= RGN_FLAG_HIDDEN; + region_channels->v2d.flag &= ~V2D_IS_INIT; + WM_event_remove_handlers((bContext *)C, ®ion_channels->handlers); + view_changed = true; + } + if (region_channels && region_channels->alignment != RGN_ALIGN_NONE) { + region_channels->alignment = RGN_ALIGN_NONE; + view_changed = true; + } + } + if (view_changed) { ED_area_init(wm, window, area); ED_area_tag_redraw(area); diff --git a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc index 14b9dbe4b44..b3d6c395e89 100644 --- a/source/blender/editors/space_spreadsheet/space_spreadsheet.cc +++ b/source/blender/editors/space_spreadsheet/space_spreadsheet.cc @@ -300,6 +300,7 @@ static float get_default_column_width(const ColumnValues &values) return values.default_width; } static const float float_width = 3; + static const float int_width = 2; switch (values.type()) { case SPREADSHEET_VALUE_TYPE_BOOL: return 2.0f; @@ -317,6 +318,8 @@ static float get_default_column_width(const ColumnValues &values) return 8.0f; case SPREADSHEET_VALUE_TYPE_STRING: return 5.0f; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: + return 4.0f * int_width; case SPREADSHEET_VALUE_TYPE_UNKNOWN: return 2.0f; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc index 19fe61f0ed3..a29aa1fd026 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc @@ -44,6 +44,9 @@ eSpreadsheetColumnValueType cpp_type_to_column_type(const CPPType &type) if (type.is<InstanceReference>()) { return SPREADSHEET_VALUE_TYPE_INSTANCES; } + if (type.is<ColorGeometry4b>()) { + return SPREADSHEET_VALUE_TYPE_BYTE_COLOR; + } return SPREADSHEET_VALUE_TYPE_UNKNOWN; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc index db466f8ccf3..e19a343335a 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc @@ -191,6 +191,10 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { const ColorGeometry4f value = data.get<ColorGeometry4f>(real_index); this->draw_float_vector(params, Span(&value.r, 4)); } + else if (data.type().is<ColorGeometry4b>()) { + const ColorGeometry4b value = data.get<ColorGeometry4b>(real_index); + this->draw_int_vector(params, {value.r, value.g, value.b, value.a}); + } else if (data.type().is<InstanceReference>()) { const InstanceReference value = data.get<InstanceReference>(real_index); switch (value.type()) { @@ -304,6 +308,34 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer { } } + void draw_int_vector(const CellDrawParams ¶ms, const Span<int> values) const + { + BLI_assert(!values.is_empty()); + const float segment_width = (float)params.width / values.size(); + for (const int i : values.index_range()) { + const int value = values[i]; + const std::string value_str = std::to_string(value); + uiBut *but = uiDefIconTextBut(params.block, + UI_BTYPE_LABEL, + 0, + ICON_NONE, + value_str.c_str(), + params.xmin + i * segment_width, + params.ymin, + segment_width, + params.height, + nullptr, + 0, + 0, + 0, + 0, + nullptr); + /* Right-align Ints. */ + UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); + UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT); + } + } + int column_width(int column_index) const final { return spreadsheet_layout_.columns[column_index].width; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc index e45317c2a5c..eb8f111baa0 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter.cc @@ -106,10 +106,10 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, const float2 value = row_filter.value_float2; switch (row_filter.operation) { case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; + const float threshold_sq = pow2f(row_filter.threshold); apply_filter_operation( column_data.typed<float2>(), - [&](const float2 cell) { return math::distance_squared(cell, value) > threshold_sq; }, + [&](const float2 cell) { return math::distance_squared(cell, value) <= threshold_sq; }, prev_mask, new_indices); break; @@ -136,10 +136,10 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, const float3 value = row_filter.value_float3; switch (row_filter.operation) { case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; + const float threshold_sq = pow2f(row_filter.threshold); apply_filter_operation( column_data.typed<float3>(), - [&](const float3 cell) { return math::distance_squared(cell, value) > threshold_sq; }, + [&](const float3 cell) { return math::distance_squared(cell, value) <= threshold_sq; }, prev_mask, new_indices); break; @@ -168,19 +168,25 @@ static void apply_row_filter(const SpreadsheetRowFilter &row_filter, } else if (column_data.type().is<ColorGeometry4f>()) { const ColorGeometry4f value = row_filter.value_color; - switch (row_filter.operation) { - case SPREADSHEET_ROW_FILTER_EQUAL: { - const float threshold_sq = row_filter.threshold; - apply_filter_operation( - column_data.typed<ColorGeometry4f>(), - [&](const ColorGeometry4f cell) { - return len_squared_v4v4(cell, value) > threshold_sq; - }, - prev_mask, - new_indices); - break; - } - } + const float threshold_sq = pow2f(row_filter.threshold); + apply_filter_operation( + column_data.typed<ColorGeometry4f>(), + [&](const ColorGeometry4f cell) { return len_squared_v4v4(cell, value) <= threshold_sq; }, + prev_mask, + new_indices); + } + else if (column_data.type().is<ColorGeometry4b>()) { + const ColorGeometry4b value = row_filter.value_byte_color; + const float4 value_floats = {(float)value.r, (float)value.g, (float)value.b, (float)value.a}; + const float threshold_sq = pow2f(row_filter.threshold); + apply_filter_operation( + column_data.typed<ColorGeometry4b>(), + [&](const ColorGeometry4b cell) { + const float4 cell_floats = {(float)cell.r, (float)cell.g, (float)cell.b, (float)cell.a}; + return len_squared_v4v4(value_floats, cell_floats) <= threshold_sq; + }, + prev_mask, + new_indices); } else if (column_data.type().is<InstanceReference>()) { const StringRef value = row_filter.value_string; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc index 6206b2d0c03..7c1ac024c12 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_row_filter_ui.cc @@ -42,7 +42,8 @@ static std::string operation_string(const eSpreadsheetColumnValueType data_type, if (ELEM(data_type, SPREADSHEET_VALUE_TYPE_BOOL, SPREADSHEET_VALUE_TYPE_INSTANCES, - SPREADSHEET_VALUE_TYPE_COLOR)) { + SPREADSHEET_VALUE_TYPE_COLOR, + SPREADSHEET_VALUE_TYPE_BYTE_COLOR)) { return "="; } @@ -101,6 +102,14 @@ static std::string value_string(const SpreadsheetRowFilter &row_filter, } case SPREADSHEET_VALUE_TYPE_STRING: return row_filter.value_string; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: { + std::ostringstream result; + result.precision(3); + result << std::fixed << "(" << (int)row_filter.value_byte_color[0] << ", " + << (int)row_filter.value_byte_color[1] << ", " << (int)row_filter.value_byte_color[2] + << ", " << (int)row_filter.value_byte_color[3] << ")"; + return result.str(); + } case SPREADSHEET_VALUE_TYPE_UNKNOWN: return ""; } @@ -229,6 +238,10 @@ static void spreadsheet_filter_panel_draw(const bContext *C, Panel *panel) case SPREADSHEET_VALUE_TYPE_STRING: uiItemR(layout, filter_ptr, "value_string", 0, IFACE_("Value"), ICON_NONE); break; + case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: + uiItemR(layout, filter_ptr, "value_byte_color", 0, IFACE_("Value"), ICON_NONE); + uiItemR(layout, filter_ptr, "threshold", 0, nullptr, ICON_NONE); + break; case SPREADSHEET_VALUE_TYPE_UNKNOWN: uiItemL(layout, IFACE_("Unknown column type"), ICON_ERROR); break; diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c index 4048e181fde..47d0168195b 100644 --- a/source/blender/editors/space_text/text_format_py.c +++ b/source/blender/editors/space_text/text_format_py.c @@ -31,26 +31,40 @@ static int txtfmt_py_find_builtinfunc(const char *string) { int i, len; - /* list is from... + /** + * The following items are derived from this list: + * \code{.py} * ", ".join(['"%s"' % kw - * for kw in __import__("keyword").kwlist - * if kw not in {"False", "None", "True", "def", "class"}]) + * for kw in sorted(__import__("keyword").kwlist + __import__("keyword").softkwlist) + * if kw not in {"False", "None", "True", "def", "class", "_"}]) + * \endcode * - * ... and for this code: - * print("\n".join(['else if (STR_LITERAL_STARTSWITH(string, "%s", len)) i = len;' % kw - * for kw in __import__("keyword").kwlist - * if kw not in {"False", "None", "True", "def", "class"}])) + * The code below can be re-generated using: + * \code{.py} + * import keyword + * ignore = {"False", "None", "True", "def", "class", "_"} + * keywords = sorted(set(keyword.kwlist + keyword.softkwlist) - ignore) + * longest = max(len(kw) for kw in keywords) + * first = 'if (STR_LITERAL_STARTSWITH(string, "%s",%s len)) { i = len;' + * middle = '} else if (STR_LITERAL_STARTSWITH(string, "%s",%s len)) { i = len;' + * last = '} else %s { i = 0;' + * print("\n".join([(first if i==0 else middle) % (kw, ' '*(longest - len(kw))) + * for (i, kw) in enumerate(keywords)]) + "\n" + + * last % (' '*(longest-2)) + "\n" + + * "}") + * \endcode */ /* Keep aligned args for readability. */ /* clang-format off */ - if (STR_LITERAL_STARTSWITH(string, "assert", len)) { i = len; + if (STR_LITERAL_STARTSWITH(string, "and", len)) { i = len; + } else if (STR_LITERAL_STARTSWITH(string, "as", len)) { i = len; + } else if (STR_LITERAL_STARTSWITH(string, "assert", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "async", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "await", len)) { i = len; - } else if (STR_LITERAL_STARTSWITH(string, "and", len)) { i = len; - } else if (STR_LITERAL_STARTSWITH(string, "as", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "break", len)) { i = len; + } else if (STR_LITERAL_STARTSWITH(string, "case", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "continue", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "del", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "elif", len)) { i = len; @@ -65,6 +79,7 @@ static int txtfmt_py_find_builtinfunc(const char *string) } else if (STR_LITERAL_STARTSWITH(string, "in", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "is", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) { i = len; + } else if (STR_LITERAL_STARTSWITH(string, "match", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "nonlocal", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "not", len)) { i = len; } else if (STR_LITERAL_STARTSWITH(string, "or", len)) { i = len; diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 3f1483bbd03..753f82e483e 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -3459,12 +3459,6 @@ static int text_insert_exec(bContext *C, wmOperator *op) while (str[i]) { code = BLI_str_utf8_as_unicode_step(str, str_len, &i); done |= txt_add_char(text, code); - if (U.text_flag & USER_TEXT_EDIT_AUTO_CLOSE) { - if (text_closing_character_pair_get(code)) { - done |= txt_add_char(text, text_closing_character_pair_get(code)); - txt_move_left(text, false); - } - } } } @@ -3484,6 +3478,7 @@ static int text_insert_exec(bContext *C, wmOperator *op) static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event) { + uint auto_close_char = 0; int ret; /* NOTE: the "text" property is always set from key-map, @@ -3510,10 +3505,23 @@ static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event) } str[len] = '\0'; RNA_string_set(op->ptr, "text", str); + + if (U.text_flag & USER_TEXT_EDIT_AUTO_CLOSE) { + auto_close_char = BLI_str_utf8_as_unicode(str); + } } ret = text_insert_exec(C, op); + if ((ret == OPERATOR_FINISHED) && (auto_close_char != 0)) { + const uint auto_close_match = text_closing_character_pair_get(auto_close_char); + if (auto_close_match != 0) { + Text *text = CTX_data_edit_text(C); + txt_add_char(text, auto_close_match); + txt_move_left(text, false); + } + } + /* run the script while editing, evil but useful */ if (ret == OPERATOR_FINISHED && CTX_wm_space_text(C)->live_edit) { text_run_script(C, NULL); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 6cb3d629e55..1d22c2f237b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -1628,7 +1628,7 @@ void ED_view3d_buttons_region_layout_ex(const bContext *C, ARRAY_SET_ITEMS(contexts, ".greasepencil_vertex"); break; case CTX_MODE_SCULPT_CURVES: - ARRAY_SET_ITEMS(contexts, ".curves_sculpt"); + ARRAY_SET_ITEMS(contexts, ".paint_common", ".curves_sculpt"); break; default: break; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 593c4f6e755..5a27349dc7f 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -2371,7 +2371,7 @@ void ED_view3d_datamask(const bContext *C, CustomData_MeshMasks *r_cddata_masks) { if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; + r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; } else if (v3d->shading.type == OB_SOLID) { @@ -2379,7 +2379,7 @@ void ED_view3d_datamask(const bContext *C, r_cddata_masks->lmask |= CD_MASK_MLOOPUV; } if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) { - r_cddata_masks->lmask |= CD_MASK_MLOOPCOL; + r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR; r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; } } diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index 05d4372723b..298de9b8730 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -737,6 +737,10 @@ static void view3d_interactive_add_begin(bContext *C, wmOperator *op, const wmEv WM_event_drag_start_mval(event, ipd->region, mval); int flag_orig = snap_state_new->flag; snap_state_new->flag |= V3D_SNAPCURSOR_TOGGLE_ALWAYS_TRUE; + + /* Be sure to also compute the #V3DSnapCursorData.plane_omat. */ + snap_state->draw_plane = true; + ED_view3d_cursor_snap_data_get(snap_state_new, C, mval[0], mval[1]); snap_state_new->flag = flag_orig; } diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index f2fb5b26305..838b40c2040 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -251,17 +251,9 @@ static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min SEQ_filter_selected_strips(strips); int selected_strips = SEQ_collection_len(strips); if (selected_strips > 0) { - INIT_MINMAX2(r_min, r_max); has_select = true; - - Sequence *seq; - SEQ_ITERATOR_FOREACH (seq, strips) { - float quad[4][2]; - SEQ_image_transform_quad_get(scene, seq, selected_strips != 1, quad); - for (int i = 0; i < 4; i++) { - minmax_v2v2_v2(r_min, r_max, quad[i]); - } - } + SEQ_image_transform_bounding_box_from_collection( + scene, strips, selected_strips != 1, r_min, r_max); } SEQ_collection_free(strips); if (selected_strips > 1) { diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c index 348f012e300..acc6b20810f 100644 --- a/source/blender/editors/transform/transform_mode_bend.c +++ b/source/blender/editors/transform/transform_mode_bend.c @@ -106,7 +106,7 @@ static void transdata_elem_bend(const TransInfo *t, } if (t->options & CTX_GPENCIL_STROKES) { - /* grease pencil multiframe falloff */ + /* Grease pencil multi-frame falloff. */ bGPDstroke *gps = (bGPDstroke *)td->extra; if (gps != NULL) { fac_scaled = fac * td->factor * gps->runtime.multi_frame_falloff; diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index ab78ef6a5aa..abeb376a9a6 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -242,7 +242,7 @@ static SnapObjectData *snap_object_data_lookup(SnapObjectContext *sctx, Object * if (sod == nullptr) { if (sctx->cache.data_to_object_map != nullptr) { ob_eval = static_cast<Object *>( - BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->data)); + BLI_ghash_lookup(sctx->cache.data_to_object_map, ob_eval->runtime.data_orig)); /* Could be NULl when mixing edit-mode and non edit-mode objects. */ if (ob_eval != nullptr) { sod = static_cast<SnapObjectData *>(BLI_ghash_lookup(sctx->cache.object_map, ob_eval)); @@ -369,7 +369,7 @@ static SnapObjectData *snap_object_data_editmesh_get(SnapObjectContext *sctx, sctx->cache.data_to_object_map = BLI_ghash_ptr_new(__func__); } void **ob_p; - if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob_eval->data, &ob_p)) { + if (BLI_ghash_ensure_p(sctx->cache.data_to_object_map, ob_eval->runtime.data_orig, &ob_p)) { ob_eval = static_cast<Object *>(*ob_p); } else { diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index cf229c9e9ec..7715388bf52 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -21,6 +21,7 @@ #include "SEQ_channels.h" #include "SEQ_effects.h" #include "SEQ_iterator.h" +#include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_sequencer.h" @@ -102,8 +103,7 @@ static void query_strip_effects_fn(Sequence *seq_reference, /* Find all strips connected to `seq_reference`. */ LISTBASE_FOREACH (Sequence *, seq_test, seqbase) { - if (seq_test->seq1 == seq_reference || seq_test->seq2 == seq_reference || - seq_test->seq3 == seq_reference) { + if (SEQ_relation_is_effect_of_strip(seq_test, seq_reference)) { query_strip_effects_fn(seq_test, seqbase, collection); } } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 54a6bb44bad..03e9134c6c2 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -608,9 +608,9 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) // colors and transparency (the latter represented by grayscale colors) MLoopCol *colors = (MLoopCol *)CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPCOL, CD_CALLOC, nullptr, mesh->totloop, "Color"); + &mesh->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, nullptr, mesh->totloop, "Color"); MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPCOL, CD_CALLOC, nullptr, mesh->totloop, "Alpha"); + &mesh->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, nullptr, mesh->totloop, "Alpha"); mesh->mloopcol = colors; mesh->mat = (Material **)MEM_mallocN(sizeof(Material *) * mesh->totcol, "MaterialList"); diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 5a27cda0787..0005d788a3b 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -38,7 +38,7 @@ #include "BLI_vector.hh" #include "BLI_vector_set.hh" -#include "FN_multi_function_builder.hh" +#include "FN_multi_function.hh" namespace blender::fn { diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc index a2adc2ea8b6..5c43fffdd61 100644 --- a/source/blender/functions/intern/cpp_types.cc +++ b/source/blender/functions/intern/cpp_types.cc @@ -11,6 +11,7 @@ MAKE_FIELD_CPP_TYPE(FloatField, float); MAKE_FIELD_CPP_TYPE(Float2Field, blender::float2); MAKE_FIELD_CPP_TYPE(Float3Field, blender::float3); MAKE_FIELD_CPP_TYPE(ColorGeometry4fField, blender::ColorGeometry4f); +MAKE_FIELD_CPP_TYPE(ColorGeometry4bField, blender::ColorGeometry4b); MAKE_FIELD_CPP_TYPE(BoolField, bool); MAKE_FIELD_CPP_TYPE(Int8Field, int8_t); MAKE_FIELD_CPP_TYPE(Int32Field, int32_t); diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 944674c23a9..a53da717606 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -8,6 +8,7 @@ #include "BLI_vector_set.hh" #include "FN_field.hh" +#include "FN_multi_function_builder.hh" #include "FN_multi_function_procedure.hh" #include "FN_multi_function_procedure_builder.hh" #include "FN_multi_function_procedure_executor.hh" diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index 7a0b74d8039..c58ca0bb8fd 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -681,14 +681,9 @@ class VariableState : NonCopyable, NonMovable { /* Sanity check to make sure that enough indices can be destructed. */ BLI_assert(new_tot_initialized >= 0); - bool do_destruct_self = false; - switch (value_->type) { case ValueType::GVArray: { - if (mask.size() == full_mask.size()) { - do_destruct_self = true; - } - else { + if (mask.size() < full_mask.size()) { /* Not all elements are destructed. Since we can't work on the original array, we have to * create a copy first. */ this->ensure_is_mutable(full_mask, data_type, value_allocator); @@ -701,16 +696,10 @@ class VariableState : NonCopyable, NonMovable { case ValueType::Span: { const CPPType &type = data_type.single_type(); type.destruct_indices(this->value_as<VariableValue_Span>()->data, mask); - if (new_tot_initialized == 0) { - do_destruct_self = true; - } break; } case ValueType::GVVectorArray: { - if (mask.size() == full_mask.size()) { - do_destruct_self = true; - } - else { + if (mask.size() < full_mask.size()) { /* Not all elements are cleared. Since we can't work on the original vector array, we * have to create a copy first. A possible future optimization is to create the partial * copy directly. */ @@ -729,22 +718,26 @@ class VariableState : NonCopyable, NonMovable { BLI_assert(value_typed->is_initialized); UNUSED_VARS_NDEBUG(value_typed); if (mask.size() == tot_initialized_) { - do_destruct_self = true; + const CPPType &type = data_type.single_type(); + type.destruct(value_typed->data); + value_typed->is_initialized = false; } break; } case ValueType::OneVector: { auto *value_typed = this->value_as<VariableValue_OneVector>(); - UNUSED_VARS(value_typed); if (mask.size() == tot_initialized_) { - do_destruct_self = true; + value_typed->data.clear(IndexRange(1)); } break; } } tot_initialized_ = new_tot_initialized; - return do_destruct_self; + + const bool should_self_destruct = new_tot_initialized == 0 && + caller_provided_storage_ == nullptr; + return should_self_destruct; } void indices_split(IndexMask mask, IndicesSplitVectors &r_indices) diff --git a/source/blender/functions/tests/FN_multi_function_procedure_test.cc b/source/blender/functions/tests/FN_multi_function_procedure_test.cc index a196d0396ec..e7cedb40f83 100644 --- a/source/blender/functions/tests/FN_multi_function_procedure_test.cc +++ b/source/blender/functions/tests/FN_multi_function_procedure_test.cc @@ -378,4 +378,34 @@ TEST(multi_function_procedure, BufferReuse) EXPECT_EQ(results[4], 53); } +TEST(multi_function_procedure, OutputBufferReplaced) +{ + MFProcedure procedure; + MFProcedureBuilder builder{procedure}; + + const int output_value = 42; + CustomMF_GenericConstant constant_fn(CPPType::get<int>(), &output_value, false); + MFVariable &var_o = procedure.new_variable(MFDataType::ForSingle<int>()); + builder.add_output_parameter(var_o); + builder.add_call_with_all_variables(constant_fn, {&var_o}); + builder.add_destruct(var_o); + builder.add_call_with_all_variables(constant_fn, {&var_o}); + builder.add_return(); + + EXPECT_TRUE(procedure.validate()); + + MFProcedureExecutor procedure_fn{procedure}; + + Array<int> output(3, 0); + fn::MFParamsBuilder params(procedure_fn, output.size()); + params.add_uninitialized_single_output(output.as_mutable_span()); + + fn::MFContextBuilder context; + procedure_fn.call(IndexMask(output.size()), params, context); + + EXPECT_EQ(output[0], output_value); + EXPECT_EQ(output[1], output_value); + EXPECT_EQ(output[2], output_value); +} + } // namespace blender::fn::tests diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 9bb1cbb324e..e45b84632ab 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1580,10 +1580,6 @@ static Mesh *create_merged_mesh(const Mesh &mesh, BLI_assert((int)r_i == result_npolys); BLI_assert(loop_cur == result_nloops); - /* We could only update the normals of the elements in context, but the next modifier can make it - * dirty anyway which would make the work useless. */ - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 0a0f01c1ff2..f3f0e5b1fce 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1015,8 +1015,6 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, if (vertex_ids) { vertex_ids.save(); } - - BKE_mesh_normals_tag_dirty(dst_mesh); } /** \} */ diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c index e2cd1741e16..b666eb677eb 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c @@ -984,7 +984,7 @@ void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance) /* No need to care for different line types/occlusion and so on, because at this stage they * are all the same within a chain. */ - /* If p3 is within the p1-p2 segment of a width of "tolerance" */ + /* If p3 is within the p1-p2 segment of a width of "tolerance". */ if (dist_to_line_segment_v2(eci3->pos, eci->pos, eci2->pos) < tolerance) { /* And if p4 is on the extension of p1-p2 , we remove p3. */ if ((eci4 = eci3->next) && (dist_to_line_v2(eci4->pos, eci->pos, eci2->pos) < tolerance)) { diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4969d84fb54..57952887d89 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -370,7 +370,6 @@ set(GLSL_SRC shaders/material/gpu_shader_material_velvet.glsl shaders/material/gpu_shader_material_vertex_color.glsl shaders/material/gpu_shader_material_volume_absorption.glsl - shaders/material/gpu_shader_material_volume_info.glsl shaders/material/gpu_shader_material_volume_principled.glsl shaders/material/gpu_shader_material_volume_scatter.glsl shaders/material/gpu_shader_material_wireframe.glsl diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index f38b9681ad7..58bbe11b4d6 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -109,14 +109,14 @@ typedef enum eGPUMaterialStatus { GPU_MAT_SUCCESS, } eGPUMaterialStatus; -typedef enum eGPUVolumeDefaultValue { - GPU_VOLUME_DEFAULT_0, - GPU_VOLUME_DEFAULT_1, -} eGPUVolumeDefaultValue; +typedef enum eGPUDefaultValue { + GPU_DEFAULT_0 = 0, + GPU_DEFAULT_1, +} eGPUDefaultValue; typedef struct GPUCodegenOutput { char *attr_load; - /* Nodetree functions calls. */ + /* Node-tree functions calls. */ char *displacement; char *surface; char *volume; @@ -131,6 +131,10 @@ typedef void (*GPUCodegenCallbackFn)(void *thunk, GPUMaterial *mat, GPUCodegenOu GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name); +GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, + CustomDataType type, + const char *name, + eGPUDefaultValue default_value); GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli); GPUNodeLink *GPU_image(GPUMaterial *mat, struct Image *ima, @@ -142,9 +146,7 @@ GPUNodeLink *GPU_image_tiled(GPUMaterial *mat, eGPUSamplerState sampler_state); GPUNodeLink *GPU_image_tiled_mapping(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser); GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *row); -GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, - const char *name, - eGPUVolumeDefaultValue default_value); + /** * Create an implementation defined differential calculation of a float function. * The given function should return a float. @@ -237,7 +239,6 @@ struct GPUUniformBuf *GPU_material_uniform_buffer_get(GPUMaterial *material); void GPU_material_uniform_buffer_create(GPUMaterial *material, ListBase *inputs); struct GPUUniformBuf *GPU_material_create_sss_profile_ubo(void); -bool GPU_material_is_volume_shader(GPUMaterial *mat); bool GPU_material_has_surface_output(GPUMaterial *mat); bool GPU_material_has_volume_output(GPUMaterial *mat); @@ -255,9 +256,11 @@ void GPU_pass_cache_free(void); typedef struct GPUMaterialAttribute { struct GPUMaterialAttribute *next, *prev; - int type; /* CustomDataType */ - char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + int type; /* CustomDataType */ + char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char input_name[12 + 1]; /* GPU_MAX_SAFE_ATTR_NAME + 1 */ eGPUType gputype; + eGPUDefaultValue default_value; /* Only for volumes attributes. */ int id; int users; } GPUMaterialAttribute; @@ -274,18 +277,8 @@ typedef struct GPUMaterialTexture { int sampler_state; /* eGPUSamplerState */ } GPUMaterialTexture; -typedef struct GPUMaterialVolumeGrid { - struct GPUMaterialVolumeGrid *next, *prev; - char *name; - eGPUVolumeDefaultValue default_value; - char sampler_name[32]; /* Name of sampler in GLSL. */ - char transform_name[32]; /* Name of 4x4 matrix in GLSL. */ - int users; -} GPUMaterialVolumeGrid; - ListBase GPU_material_attributes(GPUMaterial *material); ListBase GPU_material_textures(GPUMaterial *material); -ListBase GPU_material_volume_grids(GPUMaterial *material); typedef struct GPUUniformAttr { struct GPUUniformAttr *next, *prev; diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index eed7685bf01..0e7ce0889c2 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -371,12 +371,6 @@ GPUShader *GPU_shader_get_builtin_shader_with_config(eGPUBuiltinShader shader, eGPUShaderConfig sh_cfg); GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader); -void GPU_shader_get_builtin_shader_code(eGPUBuiltinShader shader, - const char **r_vert, - const char **r_frag, - const char **r_geom, - const char **r_defines); - void GPU_shader_free_builtin_shaders(void); /* Vertex attributes for shaders */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 110fdfbd2d9..fed998bb33e 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -207,7 +207,7 @@ void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, int update_flags) { const MPropCol *vtcol = vcol_type == CD_PROP_COLOR ? vcol_data : NULL; - const MLoopCol *vcol = vcol_type == CD_MLOOPCOL ? vcol_data : NULL; + const MLoopCol *vcol = vcol_type == CD_PROP_BYTE_COLOR ? vcol_data : NULL; const float(*f3col)[3] = vcol_type == CD_PROP_FLOAT3 ? vcol_data : NULL; const bool color_loops = vcol_domain == ATTR_DOMAIN_CORNER; diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 8963fa45c96..048928b2312 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -49,7 +49,6 @@ using namespace blender::gpu::shader; struct GPUCodegenCreateInfo : ShaderCreateInfo { struct NameBuffer { - char attr_names[16][GPU_MAX_SAFE_ATTR_NAME + 1]; char var_names[16][8]; }; @@ -171,10 +170,6 @@ static std::ostream &operator<<(std::ostream &stream, const GPUInput *input) return stream << input->texture->sampler_name; case GPU_SOURCE_TEX_TILED_MAPPING: return stream << input->texture->tiled_mapping_name; - case GPU_SOURCE_VOLUME_GRID: - return stream << input->volume_grid->sampler_name; - case GPU_SOURCE_VOLUME_GRID_TRANSFORM: - return stream << input->volume_grid->transform_name; default: BLI_assert(0); return stream; @@ -276,28 +271,6 @@ class GPUCodegen { } }; -static char attr_prefix_get(CustomDataType type) -{ - switch (type) { - case CD_MTFACE: - return 'u'; - case CD_TANGENT: - return 't'; - case CD_MCOL: - case CD_MLOOPCOL: - return 'c'; - case CD_PROP_COLOR: - return 'c'; - case CD_AUTO_FROM_NAME: - return 'a'; - case CD_HAIRLENGTH: - return 'l'; - default: - BLI_assert_msg(0, "GPUVertAttr Prefix type not found : This should not happen!"); - return '\0'; - } -} - void GPUCodegen::generate_attribs() { if (BLI_listbase_is_empty(&graph.attributes)) { @@ -317,24 +290,9 @@ void GPUCodegen::generate_attribs() int slot = 15; LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph.attributes) { - - /* NOTE: Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ - if (attr->type == CD_ORCO) { - /* OPTI: orco is computed from local positions, but only if no modifier is present. */ - STRNCPY(info.name_buffer->attr_names[slot], "orco"); - } - else { - char *name = info.name_buffer->attr_names[slot]; - name[0] = attr_prefix_get(static_cast<CustomDataType>(attr->type)); - name[1] = '\0'; - if (attr->name[0] != '\0') { - /* XXX FIXME: see notes in mesh_render_data_create() */ - GPU_vertformat_safe_attr_name(attr->name, &name[1], GPU_MAX_SAFE_ATTR_NAME); - } - } SNPRINTF(info.name_buffer->var_names[slot], "v%d", attr->id); - blender::StringRefNull attr_name = info.name_buffer->attr_names[slot]; + blender::StringRefNull attr_name = attr->input_name; blender::StringRefNull var_name = info.name_buffer->var_names[slot]; eGPUType input_type, iface_type; @@ -395,12 +353,6 @@ void GPUCodegen::generate_resources() info.sampler(0, ImageType::FLOAT_2D, tex->sampler_name, Frequency::BATCH); } } - /* Volume Grids. */ - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, grid, &graph.volume_grids) { - info.sampler(0, ImageType::FLOAT_3D, grid->sampler_name, Frequency::BATCH); - /* TODO(@fclem): Global uniform. To put in an UBO. */ - info.push_constant(Type::MAT4, grid->transform_name); - } if (!BLI_listbase_is_empty(&ubo_inputs_)) { /* NOTE: generate_uniform_buffer() should have sorted the inputs before this. */ diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 711a3943a25..3d5e9723103 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -219,11 +219,6 @@ ListBase GPU_material_textures(GPUMaterial *material) return material->graph.textures; } -ListBase GPU_material_volume_grids(GPUMaterial *material) -{ - return material->graph.volume_grids; -} - GPUUniformAttrList *GPU_material_uniform_attributes(GPUMaterial *material) { GPUUniformAttrList *attrs = &material->graph.uniform_attrs; @@ -599,11 +594,6 @@ void GPU_material_status_set(GPUMaterial *mat, eGPUMaterialStatus status) /* Code generation */ -bool GPU_material_is_volume_shader(GPUMaterial *mat) -{ - return mat->is_volume_shader; -} - bool GPU_material_has_surface_output(GPUMaterial *mat) { return mat->has_surface_output; diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index d9143a12d5b..7f96a3b01c4 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -20,6 +20,7 @@ #include "BLI_utildefines.h" #include "GPU_texture.h" +#include "GPU_vertex_format.h" #include "gpu_material_library.h" #include "gpu_node_graph.h" @@ -102,14 +103,6 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType input->source = GPU_SOURCE_TEX_TILED_MAPPING; input->texture = link->texture; break; - case GPU_NODE_LINK_VOLUME_GRID: - input->source = GPU_SOURCE_VOLUME_GRID; - input->volume_grid = link->volume_grid; - break; - case GPU_NODE_LINK_VOLUME_GRID_TRANSFORM: - input->source = GPU_SOURCE_VOLUME_GRID_TRANSFORM; - input->volume_grid = link->volume_grid; - break; case GPU_NODE_LINK_ATTR: input->source = GPU_SOURCE_ATTR; input->attr = link->attr; @@ -335,6 +328,45 @@ void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph) /* Attributes and Textures */ +static char attr_prefix_get(CustomDataType type) +{ + switch (type) { + case CD_MTFACE: + return 'u'; + case CD_TANGENT: + return 't'; + case CD_MCOL: + case CD_PROP_BYTE_COLOR: + return 'c'; + case CD_PROP_COLOR: + return 'c'; + case CD_AUTO_FROM_NAME: + return 'a'; + case CD_HAIRLENGTH: + return 'l'; + default: + BLI_assert_msg(0, "GPUVertAttr Prefix type not found : This should not happen!"); + return '\0'; + } +} + +static void attr_input_name(GPUMaterialAttribute *attr) +{ + /* NOTE: Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ + if (attr->type == CD_ORCO) { + /* OPTI: orco is computed from local positions, but only if no modifier is present. */ + STRNCPY(attr->input_name, "orco"); + } + else { + attr->input_name[0] = attr_prefix_get(attr->type); + attr->input_name[1] = '\0'; + if (attr->name[0] != '\0') { + /* XXX FIXME: see notes in mesh_render_data_create() */ + GPU_vertformat_safe_attr_name(attr->name, &attr->input_name[1], GPU_MAX_SAFE_ATTR_NAME); + } + } +} + /** Add a new varying attribute of given type and name. Returns NULL if out of slots. */ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, CustomDataType type, @@ -360,6 +392,7 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, attr = MEM_callocN(sizeof(*attr), __func__); attr->type = type; STRNCPY(attr->name, name); + attr_input_name(attr); attr->id = num_attributes; BLI_addtail(&graph->attributes, attr); } @@ -443,35 +476,6 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, return tex; } -static GPUMaterialVolumeGrid *gpu_node_graph_add_volume_grid(GPUNodeGraph *graph, - const char *name, - eGPUVolumeDefaultValue default_value) -{ - /* Find existing volume grid. */ - int num_grids = 0; - GPUMaterialVolumeGrid *grid = graph->volume_grids.first; - for (; grid; grid = grid->next) { - if (STREQ(grid->name, name) && grid->default_value == default_value) { - break; - } - num_grids++; - } - - /* Add new requested volume grid. */ - if (grid == NULL) { - grid = MEM_callocN(sizeof(*grid), __func__); - grid->name = BLI_strdup(name); - grid->default_value = default_value; - BLI_snprintf(grid->sampler_name, sizeof(grid->sampler_name), "vsamp%d", num_grids); - BLI_snprintf(grid->transform_name, sizeof(grid->transform_name), "vtfm%d", num_grids); - BLI_addtail(&graph->volume_grids, grid); - } - - grid->users++; - - return grid; -} - /* Creating Inputs */ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const char *name) @@ -496,6 +500,18 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const ch return link; } +GPUNodeLink *GPU_attribute_with_default(GPUMaterial *mat, + const CustomDataType type, + const char *name, + eGPUDefaultValue default_value) +{ + GPUNodeLink *link = GPU_attribute(mat, type, name); + if (link->link_type == GPU_NODE_LINK_ATTR) { + link->attr->default_value = default_value; + } + return link; +} + GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli) { GPUNodeGraph *graph = gpu_material_node_graph(mat); @@ -586,39 +602,6 @@ GPUNodeLink *GPU_color_band(GPUMaterial *mat, int size, float *pixels, float *ro return link; } -GPUNodeLink *GPU_volume_grid(GPUMaterial *mat, - const char *name, - eGPUVolumeDefaultValue default_value) -{ - /* NOTE: this could be optimized by automatically merging duplicate - * lookups of the same attribute. */ - GPUNodeGraph *graph = gpu_material_node_graph(mat); - GPUNodeLink *link = gpu_node_link_create(); - link->link_type = GPU_NODE_LINK_VOLUME_GRID; - link->volume_grid = gpu_node_graph_add_volume_grid(graph, name, default_value); - - GPUNodeLink *transform_link = gpu_node_link_create(); - transform_link->link_type = GPU_NODE_LINK_VOLUME_GRID_TRANSFORM; - transform_link->volume_grid = link->volume_grid; - transform_link->volume_grid->users++; - - GPUNodeLink *cos_link = GPU_attribute(mat, CD_ORCO, ""); - - /* Two special cases, where we adjust the output values of smoke grids to - * bring the into standard range without having to modify the grid values. */ - if (STREQ(name, "color")) { - GPU_link(mat, "node_attribute_volume_color", link, transform_link, cos_link, &link); - } - else if (STREQ(name, "temperature")) { - GPU_link(mat, "node_attribute_volume_temperature", link, transform_link, cos_link, &link); - } - else { - GPU_link(mat, "node_attribute_volume", link, transform_link, cos_link, &link); - } - - return link; -} - /* Creating Nodes */ bool GPU_link(GPUMaterial *mat, const char *name, ...) @@ -767,9 +750,6 @@ static void gpu_inputs_free(ListBase *inputs) else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) { input->texture->users--; } - else if (ELEM(input->source, GPU_SOURCE_VOLUME_GRID, GPU_SOURCE_VOLUME_GRID_TRANSFORM)) { - input->volume_grid->users--; - } if (input->link) { gpu_node_link_free(input->link); @@ -816,10 +796,6 @@ void gpu_node_graph_free(GPUNodeGraph *graph) BLI_freelistN(&graph->material_functions); gpu_node_graph_free_nodes(graph); - LISTBASE_FOREACH (GPUMaterialVolumeGrid *, grid, &graph->volume_grids) { - MEM_SAFE_FREE(grid->name); - } - BLI_freelistN(&graph->volume_grids); BLI_freelistN(&graph->textures); BLI_freelistN(&graph->attributes); GPU_uniform_attr_list_free(&graph->uniform_attrs); @@ -894,14 +870,6 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph) } } - for (GPUMaterialVolumeGrid *grid = graph->volume_grids.first, *next = NULL; grid; grid = next) { - next = grid->next; - if (grid->users == 0) { - MEM_SAFE_FREE(grid->name); - BLI_freelinkN(&graph->volume_grids, grid); - } - } - GPUUniformAttrList *uattrs = &graph->uniform_attrs; LISTBASE_FOREACH_MUTABLE (GPUUniformAttr *, attr, &uattrs->list) { diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index 024119e1c24..ae472d5b7aa 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -34,8 +34,6 @@ typedef enum eGPUDataSource { GPU_SOURCE_STRUCT, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING, - GPU_SOURCE_VOLUME_GRID, - GPU_SOURCE_VOLUME_GRID_TRANSFORM, GPU_SOURCE_FUNCTION_CALL, } eGPUDataSource; @@ -48,8 +46,6 @@ typedef enum { GPU_NODE_LINK_IMAGE, GPU_NODE_LINK_IMAGE_TILED, GPU_NODE_LINK_IMAGE_TILED_MAPPING, - GPU_NODE_LINK_VOLUME_GRID, - GPU_NODE_LINK_VOLUME_GRID_TRANSFORM, GPU_NODE_LINK_OUTPUT, GPU_NODE_LINK_UNIFORM, GPU_NODE_LINK_DIFFERENTIATE_FLOAT_FN, @@ -90,8 +86,6 @@ struct GPUNodeLink { const float *data; /* GPU_NODE_LINK_COLORBAND */ struct GPUTexture **colorband; - /* GPU_NODE_LINK_VOLUME_GRID */ - struct GPUMaterialVolumeGrid *volume_grid; /* GPU_NODE_LINK_OUTPUT */ struct GPUOutput *output; /* GPU_NODE_LINK_ATTR */ @@ -134,8 +128,6 @@ typedef struct GPUInput { struct GPUMaterialAttribute *attr; /* GPU_SOURCE_UNIFORM_ATTR */ struct GPUUniformAttr *uniform_attr; - /* GPU_SOURCE_VOLUME_GRID | GPU_SOURCE_VOLUME_GRID_TRANSFORM */ - struct GPUMaterialVolumeGrid *volume_grid; /* GPU_SOURCE_FUNCTION_CALL */ char function_call[64]; }; @@ -170,7 +162,6 @@ typedef struct GPUNodeGraph { /* Requested attributes and textures. */ ListBase attributes; ListBase textures; - ListBase volume_grids; /* The list of uniform attributes. */ GPUUniformAttrList uniform_attrs; diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c index dfedb64ce61..1958ecedb28 100644 --- a/source/blender/gpu/intern/gpu_shader_builtin.c +++ b/source/blender/gpu/intern/gpu_shader_builtin.c @@ -402,19 +402,6 @@ GPUShader *GPU_shader_get_builtin_shader(eGPUBuiltinShader shader) return GPU_shader_get_builtin_shader_with_config(shader, GPU_SHADER_CFG_DEFAULT); } -void GPU_shader_get_builtin_shader_code(eGPUBuiltinShader shader, - const char **r_vert, - const char **r_frag, - const char **r_geom, - const char **r_defines) -{ - const GPUShaderStages *stages = &builtin_shader_stages[shader]; - *r_vert = stages->vert; - *r_frag = stages->frag; - *r_geom = stages->geom; - *r_defines = stages->defs; -} - void GPU_shader_free_builtin_shaders(void) { for (int i = 0; i < GPU_SHADER_CFG_LEN; i++) { diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index 3ab96d0d84a..7c827e237eb 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -627,7 +627,9 @@ struct ShaderCreateInfo { Resource res(Resource::BindType::SAMPLER, slot); res.sampler.type = type; res.sampler.name = name; - res.sampler.sampler = sampler; + /* Produces ASAN errors for the moment. */ + // res.sampler.sampler = sampler; + UNUSED_VARS(sampler); ((freq == Frequency::PASS) ? pass_resources_ : batch_resources_).append(res); interface_names_size_ += name.size() + 1; return *(Self *)this; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index 9768318f3b6..51d470ef0c1 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -855,7 +855,7 @@ static char *glsl_patch_default_get() STR_CONCAT(patch, slen, "#define gpu_InstanceIndex (gl_InstanceID + gpu_BaseInstance)\n"); /* Array compat. */ - STR_CONCAT(patch, slen, "#define array(_type) _type[]\n"); + STR_CONCAT(patch, slen, "#define gpu_Array(_type) _type[]\n"); /* Derivative sign can change depending on implementation. */ STR_CONCATF(patch, slen, "#define DFDX_SIGN %1.1f\n", GLContext::derivative_signs[0]); @@ -882,7 +882,7 @@ static char *glsl_patch_compute_get() STR_CONCAT(patch, slen, "#extension GL_ARB_compute_shader :enable\n"); /* Array compat. */ - STR_CONCAT(patch, slen, "#define array(_type) _type[]\n"); + STR_CONCAT(patch, slen, "#define gpu_Array(_type) _type[]\n"); BLI_assert(slen < sizeof(patch)); return patch; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl index faf37db3ea6..2ae53b35b3f 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl @@ -1,3 +1,17 @@ + +void node_attribute_color(vec4 attr, out vec4 out_attr) +{ + out_attr = attr_load_color_post(attr); +} + +void node_attribute_temperature(vec4 attr, out vec4 out_attr) +{ + out_attr.x = attr_load_temperature_post(attr.x); + out_attr.y = 0.0; + out_attr.z = 0.0; + out_attr.w = 1.0; +} + void node_attribute( vec4 attr, out vec4 outcol, out vec3 outvec, out float outf, out float outalpha) { diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl index 2885bf4e082..a8b4b039370 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_hair_info.glsl @@ -1,6 +1,5 @@ #pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) - void node_hair_info(float hair_length, out float is_strand, out float intercept, diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl index 1b1fed9502e..ad3d4737193 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_point_info.glsl @@ -1,6 +1,5 @@ #pragma BLENDER_REQUIRE(gpu_shader_material_hash.glsl) - void node_point_info(out vec3 position, out float radius, out float random) { #ifdef POINTCLOUD_SHADER diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl index 89091316823..da131978f72 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl @@ -1,6 +1,5 @@ #pragma BLENDER_REQUIRE(gpu_shader_material_math_util.glsl) - void node_tex_environment_equirectangular(vec3 co, out vec3 uv) { vec3 nco = normalize(co); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl deleted file mode 100644 index 464cf5227b4..00000000000 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_info.glsl +++ /dev/null @@ -1,51 +0,0 @@ - -/* Uniforms to convert smoke grid values into standard range. */ -uniform vec3 volumeColor = vec3(1.0); -uniform vec2 volumeTemperature = vec2(0.0); - -/* Generic volume attribute. */ -void node_attribute_volume(sampler3D tex, mat4 transform, vec3 cos, out vec3 outvec) -{ - /* Optional per-grid transform. */ - if (transform[3][3] != 0.0) { - cos = (transform * vec4(cos, 1.0)).xyz; - } - - outvec = texture(tex, cos).rgb; -} - -/* Special color attribute for smoke. */ -void node_attribute_volume_color(sampler3D tex, mat4 transform, vec3 cos, out vec3 outvec) -{ - /* Optional per-grid transform. */ - if (transform[3][3] != 0.0) { - cos = (transform * vec4(cos, 1.0)).xyz; - } - - /* Density is premultiplied for interpolation, divide it out here. */ - vec4 value = texture(tex, cos).rgba; - if (value.a > 1e-8) { - value.rgb /= value.a; - } - - outvec = value.rgb * volumeColor; -} - -/* Special temperature attribute for smoke. */ -void node_attribute_volume_temperature(sampler3D tex, mat4 transform, vec3 cos, out float outf) -{ - /* Optional per-grid transform. */ - if (transform[3][3] != 0.0) { - cos = (transform * vec4(cos, 1.0)).xyz; - } - - float value = texture(tex, cos).r; - if (volumeTemperature.x < volumeTemperature.y) { - outf = (value > 0.01) ? - volumeTemperature.x + value * (volumeTemperature.y - volumeTemperature.x) : - 0.0; - } - else { - outf = value; - } -} diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl index 1127c34b3ac..21c4aba0ffe 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_volume_principled.glsl @@ -10,9 +10,9 @@ void node_volume_principled(vec4 color, vec4 blackbody_tint, float temperature, float weight, - float density_attribute, + vec4 density_attribute, vec4 color_attribute, - float temperature_attribute, + vec4 temperature_attribute, sampler1DArray spectrummap, float layer, out Closure result) @@ -25,7 +25,7 @@ void node_volume_principled(vec4 color, density = max(density, 0.0); if (density > 1e-5) { - density = max(density * density_attribute, 0.0); + density = max(density * density_attribute.x, 0.0); } if (density > 1e-5) { @@ -47,7 +47,7 @@ void node_volume_principled(vec4 color, if (blackbody_intensity > 1e-3) { /* Add temperature from attribute. */ - float T = max(temperature * max(temperature_attribute, 0.0), 0.0); + float T = max(temperature * max(temperature_attribute.x, 0.0), 0.0); /* Stefan-Boltzman law. */ float T2 = T * T; diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index bbb196dc383..07b185ffd64 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -359,7 +359,7 @@ void ABCGenericMeshWriter::write_arb_geo_params(struct Mesh *me) else { arb_geom_params = abc_poly_mesh_.getSchema().getArbGeomParams(); } - write_custom_data(arb_geom_params, m_custom_data_config, &me->ldata, CD_MLOOPCOL); + write_custom_data(arb_geom_params, m_custom_data_config, &me->ldata, CD_PROP_BYTE_COLOR); } bool ABCGenericMeshWriter::get_velocities(struct Mesh *mesh, std::vector<Imath::V3f> &vels) diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index c413fbf0ff9..45bf898f3f5 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -294,7 +294,7 @@ void write_custom_data(const OCompoundProperty &prop, write_uv(prop, config, cd_data, name); } - else if (cd_data_type == CD_MLOOPCOL) { + else if (cd_data_type == CD_PROP_BYTE_COLOR) { write_mcol(prop, config, cd_data, name); } } @@ -412,7 +412,7 @@ static void read_custom_data_mcols(const std::string &iobject_full_name, /* Read the vertex colors */ void *cd_data = config.add_customdata_cb( - config.mesh, prop_header.getName().c_str(), CD_MLOOPCOL); + config.mesh, prop_header.getName().c_str(), CD_PROP_BYTE_COLOR); MCol *cfaces = static_cast<MCol *>(cd_data); MPoly *mpolys = config.mpoly; MLoop *mloops = config.mloop; diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index fe2b0470432..2d2dcfb1f42 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -245,7 +245,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) static void process_no_normals(CDStreamConfig &config) { /* Absence of normals in the Alembic mesh is interpreted as 'smooth'. */ - BKE_mesh_calc_normals(config.mesh); + BKE_mesh_normals_tag_dirty(config.mesh); } static void process_loop_normals(CDStreamConfig &config, const N3fArraySamplePtr loop_normals_ptr) @@ -382,7 +382,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type) int numloops; /* unsupported custom data type -- don't do anything. */ - if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) { + if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) { return nullptr; } diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 3b21d423df5..3952a4ae334 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -378,12 +378,12 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, } } - int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); if (totlayer_mcol > 0) { int map_index = 0; for (int a = 0; a < totlayer_mcol; a++) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); + char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, makeUrl(makeVertexColorSourceId(geom_id, layer_name)), (has_uvs) ? 3 : 2, /* all color layers have same index order */ @@ -468,7 +468,7 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) { /* Find number of vertex color layers */ - int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); + int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); if (totlayer_mcol == 0) { return; } @@ -477,11 +477,11 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) for (int a = 0; a < totlayer_mcol; a++) { map_index++; - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, a); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_PROP_BYTE_COLOR, a); COLLADASW::FloatSourceF source(mSW); - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); + char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, a); std::string layer_id = makeVertexColorSourceId(geom_id, layer_name); source.setId(layer_id); diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index fc94e912417..6e109353be8 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -471,9 +471,9 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) collada_mesh->getColors().getInputInfosArray()[i]; COLLADAFW::String colname = extract_vcolname(info->mName); CustomData_add_layer_named( - &me->ldata, CD_MLOOPCOL, CD_DEFAULT, nullptr, me->totloop, colname.c_str()); + &me->ldata, CD_PROP_BYTE_COLOR, CD_DEFAULT, nullptr, me->totloop, colname.c_str()); } - me->mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0); + me->mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_PROP_BYTE_COLOR, 0); } } } @@ -724,7 +724,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index); COLLADAFW::String colname = extract_vcolname(color_index_list.getName()); MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named( - &me->ldata, CD_MLOOPCOL, colname.c_str()); + &me->ldata, CD_PROP_BYTE_COLOR, colname.c_str()); if (mloopcol == nullptr) { fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", @@ -1057,7 +1057,6 @@ Object *MeshImporter::create_mesh_object( Mesh *new_mesh = uid_mesh_map[*geom_uid]; BKE_mesh_assign_object(m_bmain, ob, new_mesh); - BKE_mesh_calc_normals(new_mesh); /* Because BKE_mesh_assign_object would have already decreased it... */ id_us_plus(&old_mesh->id); diff --git a/source/blender/io/common/intern/string_utils.cc b/source/blender/io/common/intern/string_utils.cc index 01107b0866e..3a12250e14b 100644 --- a/source/blender/io/common/intern/string_utils.cc +++ b/source/blender/io/common/intern/string_utils.cc @@ -7,7 +7,7 @@ * their standard libraries are not quite there yet. * LLVM/libc++ only has a float parser since LLVM 14, * and gcc/libstdc++ since 11.1. So until at least these are - * the mininum spec, use an external library. */ + * the minimum spec, use an external library. */ #include "fast_float.h" #include <charconv> diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 646d1ba1fde..328b4109616 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -149,7 +149,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type int numloops; /* unsupported custom data type -- don't do anything. */ - if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) { + if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) { return nullptr; } @@ -457,7 +457,7 @@ void USDMeshReader::read_colors(Mesh *mesh, const double motionSampleTime) return; } - void *cd_ptr = add_customdata_cb(mesh, "displayColors", CD_MLOOPCOL); + void *cd_ptr = add_customdata_cb(mesh, "displayColors", CD_PROP_BYTE_COLOR); if (!cd_ptr) { std::cerr << "WARNING: Couldn't add displayColors custom data.\n"; diff --git a/source/blender/io/usd/tests/usd_tests_common.h b/source/blender/io/usd/tests/usd_tests_common.h index b298a253ddc..7f6ae558354 100644 --- a/source/blender/io/usd/tests/usd_tests_common.h +++ b/source/blender/io/usd/tests/usd_tests_common.h @@ -8,7 +8,7 @@ namespace blender::io::usd { /* Calls the function to load the USD plugins from the * USD data directory under the Blender bin directory - * that was supplied as the --test-release-dir flag to ctest. + * that was supplied as the --test-release-dir flag to `ctest`. * Thus function must be called before instantiating a USD * stage to avoid errors. The returned string is the path to * the USD data files directory from which the plugins were diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index ee78b610276..3e7a4431bf5 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -610,6 +610,8 @@ typedef enum eBrushFalloffShape { typedef enum eBrushCurvesSculptFlag { BRUSH_CURVES_SCULPT_FLAG_SCALE_UNIFORM = (1 << 0), BRUSH_CURVES_SCULPT_FLAG_GROW_SHRINK_INVERT = (1 << 1), + BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH = (1 << 2), + BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE = (1 << 3), } eBrushCurvesSculptFlag; #define MAX_BRUSH_PIXEL_RADIUS 500 diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 2d879f5afa0..7d230b7d7a3 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -144,6 +144,8 @@ typedef struct BrushCurvesSculptSettings { uint32_t flag; /** When shrinking curves, they shouldn't become shorter than this length. */ float minimum_length; + /** Length of newly added curves when it is not interpolated from other curves. */ + float curve_length; } BrushCurvesSculptSettings; typedef struct Brush { diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 305b913b19e..6e18d442ee2 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -298,6 +298,13 @@ typedef struct Curve { * original object data. */ const struct Curves *curve_eval; + /** + * If non-zero, the #editfont and #editnurb pointers are not owned by this #Curve. That means + * this curve is a container for the result of object geometry evaluation. This only works + * because evaluated object data never outlives original data. + */ + char edit_data_from_original; + char _pad3[7]; void *batch_cache; } Curve; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 858de733558..ef937fb139b 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -113,7 +113,7 @@ typedef enum CustomDataType { CD_MTEXPOLY = 15, /* deprecated */ #endif CD_MLOOPUV = 16, - CD_MLOOPCOL = 17, + CD_PROP_BYTE_COLOR = 17, CD_TANGENT = 18, CD_MDISPS = 19, CD_PREVIEW_MCOL = 20, /* for displaying weightpaint colors */ @@ -181,7 +181,7 @@ typedef enum CustomDataType { #define CD_MASK_ORCO (1 << CD_ORCO) // #define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) /* DEPRECATED */ #define CD_MASK_MLOOPUV (1 << CD_MLOOPUV) -#define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL) +#define CD_MASK_PROP_BYTE_COLOR (1 << CD_PROP_BYTE_COLOR) #define CD_MASK_TANGENT (1 << CD_TANGENT) #define CD_MASK_MDISPS (1 << CD_MDISPS) #define CD_MASK_PREVIEW_MCOL (1 << CD_PREVIEW_MCOL) @@ -224,11 +224,11 @@ typedef enum CustomDataType { /* All generic attributes. */ #define CD_MASK_PROP_ALL \ (CD_MASK_PROP_FLOAT | CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_FLOAT3 | CD_MASK_PROP_INT32 | \ - CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_MLOOPCOL | CD_MASK_PROP_BOOL | \ + CD_MASK_PROP_COLOR | CD_MASK_PROP_STRING | CD_MASK_PROP_BYTE_COLOR | CD_MASK_PROP_BOOL | \ CD_MASK_PROP_INT8) /* All color attributes */ -#define CD_MASK_COLOR_ALL (CD_MASK_PROP_COLOR | CD_MASK_MLOOPCOL) +#define CD_MASK_COLOR_ALL (CD_MASK_PROP_COLOR | CD_MASK_PROP_BYTE_COLOR) typedef struct CustomData_MeshMasks { uint64_t vmask; diff --git a/source/blender/makesdna/DNA_fluid_defaults.h b/source/blender/makesdna/DNA_fluid_defaults.h index fd48585792f..90a91c6c995 100644 --- a/source/blender/makesdna/DNA_fluid_defaults.h +++ b/source/blender/makesdna/DNA_fluid_defaults.h @@ -187,6 +187,7 @@ .cache_comp = SM_CACHE_LIGHT, \ .cache_high_comp = SM_CACHE_LIGHT, \ .cache_file_format = 0, \ + .velocity_scale = 1.0f, \ } /** \} */ diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h index 11780d99af8..5a1636879bb 100644 --- a/source/blender/makesdna/DNA_fluid_types.h +++ b/source/blender/makesdna/DNA_fluid_types.h @@ -670,7 +670,10 @@ typedef struct FluidDomainSettings { char interp_method; char gridlines_color_field; /* Simulation field used to color map onto gridlines. */ char gridlines_cell_filter; - char _pad10[7]; /* Unused. */ + char _pad10[3]; /* Unused. */ + + /* Velocity factor for motion blur rendering. */ + float velocity_scale; /* OpenVDB cache options. */ int openvdb_compression; diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 2b4858d4106..cd4676ee08e 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -221,7 +221,7 @@ typedef struct Mesh { /** * The active vertex corner color layer, if it exists. Also called "Vertex Color" in Blender's * UI, even though it is stored per face corner. - * \note This pointer is for convenient access to the #CD_MLOOPCOL layer in #ldata. + * \note This pointer is for convenient access to the #CD_PROP_BYTE_COLOR layer in #ldata. */ struct MLoopCol *mloopcol; diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d6c1040110f..bfe967fcde5 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1014,23 +1014,8 @@ typedef struct Sculpt { struct Object *gravity_object; } Sculpt; -typedef enum CurvesSculptFlag { - CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH = (1 << 0), - CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE = (1 << 1), -} CurvesSculptFlag; - typedef struct CurvesSculpt { Paint paint; - /** Minimum distance between newly added curves on a surface. */ - float distance; - - /** CurvesSculptFlag. */ - uint32_t flag; - - /** Length of newly added curves when it is not interpolated from other curves. */ - float curve_length; - - char _pad[4]; } CurvesSculpt; typedef struct UvSculpt { diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 8d527caa361..bce124a26cf 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1968,8 +1968,7 @@ typedef struct SpreadsheetRowFilter { float value_float2[2]; float value_float3[3]; float value_color[4]; - - char _pad1[4]; + uint8_t value_byte_color[4]; } SpreadsheetRowFilter; typedef enum eSpaceSpreadsheet_RowFilterFlag { @@ -2006,6 +2005,7 @@ typedef enum eSpreadsheetColumnValueType { SPREADSHEET_VALUE_TYPE_COLOR = 5, SPREADSHEET_VALUE_TYPE_INSTANCES = 6, SPREADSHEET_VALUE_TYPE_STRING = 7, + SPREADSHEET_VALUE_TYPE_BYTE_COLOR = 8, } eSpreadsheetColumnValueType; /** diff --git a/source/blender/makesdna/DNA_volume_defaults.h b/source/blender/makesdna/DNA_volume_defaults.h index 2025d664d40..ee98f0ea4fd 100644 --- a/source/blender/makesdna/DNA_volume_defaults.h +++ b/source/blender/makesdna/DNA_volume_defaults.h @@ -36,7 +36,8 @@ .frame_duration = 0, \ .display = _DNA_DEFAULT_VolumeDisplay, \ .render = _DNA_DEFAULT_VolumeRender, \ - } + .velocity_scale = 1.0f, \ +} /** \} */ diff --git a/source/blender/makesdna/DNA_volume_types.h b/source/blender/makesdna/DNA_volume_types.h index f2f53bc910f..a2e558aa790 100644 --- a/source/blender/makesdna/DNA_volume_types.h +++ b/source/blender/makesdna/DNA_volume_types.h @@ -24,6 +24,11 @@ typedef struct Volume_Runtime { /** Default simplify level for volume grids loaded from files. */ int default_simplify_level; + + /* Names for scalar grids which would need to be merged to recompose the velocity grid. */ + char velocity_x_grid[64]; + char velocity_y_grid[64]; + char velocity_z_grid[64]; } Volume_Runtime; typedef struct VolumeDisplay { @@ -75,6 +80,18 @@ typedef struct Volume { VolumeRender render; VolumeDisplay display; + /* Velocity field name. */ + char velocity_grid[64]; + + char _pad3[3]; + + /* Unit of time the velocity vectors are expressed in. + * This uses the same enumeration values as #CacheFile.velocity_unit. */ + char velocity_unit; + + /* Factor for velocity vector for artistic control. */ + float velocity_scale; + /* Draw Cache */ void *batch_cache; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index ade0fcdb13f..cfd0c986df9 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -364,7 +364,7 @@ typedef struct wmKeyMapItem { short type; /** KM_ANY, KM_PRESS, KM_NOTHING etc. */ int8_t val; - /** Use when `val == KM_CLICK_DRAG`, */ + /** Use when `val == KM_CLICK_DRAG`. */ int8_t direction; /** `oskey` also known as apple, windows-key or super. */ short shift, ctrl, alt, oskey; diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h index 6e2c898d691..6539d636697 100644 --- a/source/blender/makesrna/RNA_enum_items.h +++ b/source/blender/makesrna/RNA_enum_items.h @@ -212,6 +212,8 @@ DEF_ENUM(rna_enum_subdivision_boundary_smooth_items) DEF_ENUM(rna_enum_transform_orientation_items) +DEF_ENUM(rna_enum_velocity_unit_items) + /* Not available to RNA pre-processing (`makesrna`). * Defined in editors for example. */ #ifndef RNA_MAKESRNA diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 8d022338d7a..df92601dd0c 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -1047,6 +1047,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update"); } RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP); + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); RNA_def_property_ui_text( prop, "B-Bone Start Handle", "Bone that serves as the start handle for the B-Bone curve"); @@ -1091,6 +1092,7 @@ static void rna_def_bone_common(StructRNA *srna, int editbone) RNA_def_property_update(prop, 0, "rna_Bone_bbone_handle_update"); } RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP); + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); RNA_def_property_ui_text( prop, "B-Bone End Handle", "Bone that serves as the end handle for the B-Bone curve"); diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index b11250cf891..5efbebc9b97 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -28,7 +28,7 @@ const EnumPropertyItem rna_enum_attribute_type_items[] = { {CD_PROP_INT32, "INT", 0, "Integer", "32-bit integer"}, {CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating-point values"}, {CD_PROP_COLOR, "FLOAT_COLOR", 0, "Color", "RGBA color with floating-point values"}, - {CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit values"}, + {CD_PROP_BYTE_COLOR, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit values"}, {CD_PROP_STRING, "STRING", 0, "String", "Text string"}, {CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"}, {CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"}, @@ -42,7 +42,7 @@ const EnumPropertyItem rna_enum_attribute_type_with_auto_items[] = { {CD_PROP_INT32, "INT", 0, "Integer", "32-bit integer"}, {CD_PROP_FLOAT3, "FLOAT_VECTOR", 0, "Vector", "3D vector with floating-point values"}, {CD_PROP_COLOR, "FLOAT_COLOR", 0, "Color", "RGBA color with floating-point values"}, - {CD_MLOOPCOL, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit values"}, + {CD_PROP_BYTE_COLOR, "BYTE_COLOR", 0, "Byte Color", "RGBA color with 8-bit values"}, {CD_PROP_STRING, "STRING", 0, "String", "Text string"}, {CD_PROP_BOOL, "BOOLEAN", 0, "Boolean", "True or false"}, {CD_PROP_FLOAT2, "FLOAT2", 0, "2D Vector", "2D vector with floating-point values"}, @@ -113,7 +113,7 @@ static StructRNA *srna_by_custom_data_layer_type(const CustomDataType type) return &RNA_FloatVectorAttribute; case CD_PROP_COLOR: return &RNA_FloatColorAttribute; - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: return &RNA_ByteColorAttribute; case CD_PROP_STRING: return &RNA_StringAttribute; @@ -231,7 +231,7 @@ static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRN case CD_PROP_COLOR: struct_size = sizeof(MPropCol); break; - case CD_MLOOPCOL: + case CD_PROP_BYTE_COLOR: struct_size = sizeof(MLoopCol); break; case CD_PROP_STRING: @@ -339,9 +339,17 @@ static int rna_Attributes_layer_skip(CollectionPropertyIterator *UNUSED(iter), v return !(CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL); } -static int rna_Attributes_noncolor_layer_skip(CollectionPropertyIterator *UNUSED(iter), void *data) +static int rna_Attributes_noncolor_layer_skip(CollectionPropertyIterator *iter, void *data) { CustomDataLayer *layer = (CustomDataLayer *)data; + + /* Check valid domain here, too, keep in line with rna_AttributeGroup_color_length(). */ + ID *id = iter->parent.owner_id; + AttributeDomain domain = BKE_id_attribute_domain(id, layer); + if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { + return 1; + } + return !(CD_TYPE_AS_MASK(layer->type) & CD_MASK_COLOR_ALL) || (layer->flag & CD_FLAG_TEMPORARY); } @@ -423,7 +431,7 @@ int rna_AttributeGroup_color_length(PointerRNA *ptr) { return BKE_id_attributes_length(ptr->owner_id, ATTR_DOMAIN_MASK_POINT | ATTR_DOMAIN_MASK_CORNER, - CD_MASK_PROP_COLOR | CD_MASK_MLOOPCOL); + CD_MASK_PROP_COLOR | CD_MASK_PROP_BYTE_COLOR); } int rna_AttributeGroup_length(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 25dd87b1e74..cc5141bde03 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -119,11 +119,11 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = { {SCULPT_TOOL_CLOTH, "CLOTH", ICON_BRUSH_SCULPT_DRAW, "Cloth", ""}, {SCULPT_TOOL_SIMPLIFY, "SIMPLIFY", ICON_BRUSH_DATA, "Simplify", ""}, {SCULPT_TOOL_MASK, "MASK", ICON_BRUSH_MASK, "Mask", ""}, + {SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""}, {SCULPT_TOOL_DISPLACEMENT_ERASER, "DISPLACEMENT_ERASER", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Eraser", ""}, {SCULPT_TOOL_DISPLACEMENT_SMEAR, "DISPLACEMENT_SMEAR", ICON_BRUSH_SCULPT_DRAW, "Multires Displacement Smear", ""}, {SCULPT_TOOL_PAINT, "PAINT", ICON_BRUSH_SCULPT_DRAW, "Paint", ""}, {SCULPT_TOOL_SMEAR, "SMEAR", ICON_BRUSH_SCULPT_DRAW, "Smear", ""}, - {SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""}, {0, NULL, 0, NULL, NULL}, }; /* clang-format on */ @@ -1944,6 +1944,23 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_text( prop, "Minimum Length", "Avoid shrinking curves shorter than this length"); + + prop = RNA_def_property(srna, "interpolate_length", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH); + RNA_def_property_ui_text( + prop, "Interpolate Length", "Use length of the curves in close proximity"); + + prop = RNA_def_property(srna, "interpolate_shape", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE); + RNA_def_property_ui_text( + prop, "Interpolate Shape", "Use shape of the curves in close proximity"); + + prop = RNA_def_property(srna, "curve_length", PROP_FLOAT, PROP_DISTANCE); + RNA_def_property_range(prop, 0.0, FLT_MAX); + RNA_def_property_ui_text( + prop, + "Curve Length", + "Length of newly added curves when it is not interpolated from other curves"); } static void rna_def_brush(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_cachefile.c b/source/blender/makesrna/intern/rna_cachefile.c index 62b08ebb281..c8b154b9b04 100644 --- a/source/blender/makesrna/intern/rna_cachefile.c +++ b/source/blender/makesrna/intern/rna_cachefile.c @@ -14,6 +14,12 @@ #include "rna_internal.h" +const EnumPropertyItem rna_enum_velocity_unit_items[] = { + {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""}, + {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""}, + {0, NULL, 0, NULL, NULL}, +}; + #ifdef RNA_RUNTIME # include "BLI_math.h" @@ -350,15 +356,9 @@ static void rna_def_cachefile(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_CacheFile_update"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - static const EnumPropertyItem velocity_unit_items[] = { - {CACHEFILE_VELOCITY_UNIT_SECOND, "SECOND", 0, "Second", ""}, - {CACHEFILE_VELOCITY_UNIT_FRAME, "FRAME", 0, "Frame", ""}, - {0, NULL, 0, NULL, NULL}, - }; - prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "velocity_unit"); - RNA_def_property_enum_items(prop, velocity_unit_items); + RNA_def_property_enum_items(prop, rna_enum_velocity_unit_items); RNA_def_property_ui_text( prop, "Velocity Unit", diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c index dab3cd68d4c..e0ec146a248 100644 --- a/source/blender/makesrna/intern/rna_fluid.c +++ b/source/blender/makesrna/intern/rna_fluid.c @@ -2644,6 +2644,12 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) RNA_def_property_enum_items(prop, gridlines_cell_filter_items); RNA_def_property_ui_text(prop, "Cell Type", "Cell type to be highlighted"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL); + + prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "velocity_scale"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Velocity Scale", "Factor to control the amount of motion blur"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_update"); } static void rna_def_fluid_flow_settings(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 52af96e355d..0e7c332f6a4 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -753,9 +753,9 @@ static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value) /* vertex_color_layers */ -DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_color, ldata, CD_MLOOPCOL) +DEFINE_CUSTOMDATA_LAYER_COLLECTION(vertex_color, ldata, CD_PROP_BYTE_COLOR) DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM( - vertex_color, ldata, CD_MLOOPCOL, active, MeshLoopColorLayer) + vertex_color, ldata, CD_PROP_BYTE_COLOR, active, MeshLoopColorLayer) static void rna_MeshLoopColorLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { @@ -773,22 +773,22 @@ static int rna_MeshLoopColorLayer_data_length(PointerRNA *ptr) static bool rna_MeshLoopColorLayer_active_render_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPCOL, 1); + return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_BYTE_COLOR, 1); } static bool rna_MeshLoopColorLayer_active_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPCOL, 0); + return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_BYTE_COLOR, 0); } static void rna_MeshLoopColorLayer_active_render_set(PointerRNA *ptr, bool value) { - rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPCOL, 1); + rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_BYTE_COLOR, 1); } static void rna_MeshLoopColorLayer_active_set(PointerRNA *ptr, bool value) { - rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPCOL, 0); + rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_BYTE_COLOR, 0); } /* sculpt_vertex_color_layers */ @@ -1340,7 +1340,7 @@ static char *rna_MeshLoopColorLayer_path(PointerRNA *ptr) static char *rna_MeshColor_path(PointerRNA *ptr) { - return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_MLOOPCOL); + return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_PROP_BYTE_COLOR); } static char *rna_MeshVertColorLayer_path(PointerRNA *ptr) @@ -1564,7 +1564,7 @@ static PointerRNA rna_Mesh_vertex_color_new(struct Mesh *me, if (index != -1) { ldata = rna_mesh_ldata_helper(me); - cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_MLOOPCOL, index)]; + cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_BYTE_COLOR, index)]; } RNA_pointer_create(&me->id, &RNA_MeshLoopColorLayer, cdl, &ptr); @@ -3182,6 +3182,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_pointer_funcs( prop, "rna_Mesh_uv_layer_clone_get", "rna_Mesh_uv_layer_clone_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text( prop, "Clone UV Loop Layer", "UV loop layer to be used as cloning source"); @@ -3197,6 +3198,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_pointer_funcs( prop, "rna_Mesh_uv_layer_stencil_get", "rna_Mesh_uv_layer_stencil_set", NULL, NULL); RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE); RNA_def_property_ui_text(prop, "Mask UV Loop Layer", "UV loop layer to mask the painted area"); prop = RNA_def_property(srna, "uv_layer_stencil_index", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index b1ebe583afc..8447074a3ef 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -159,7 +159,6 @@ static void rna_Mesh_normals_split_custom_set_from_vertices(Mesh *mesh, static void rna_Mesh_transform(Mesh *mesh, float mat[16], bool shape_keys) { BKE_mesh_transform(mesh, (float(*)[4])mat, shape_keys); - BKE_mesh_normals_tag_dirty(mesh); DEG_id_tag_update(&mesh->id, 0); } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 16045e6cddf..456f774648a 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1361,13 +1361,13 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf( } } } - else if (STREQ(RNA_property_identifier(prop), "layers_vcol_select_vert_src") || - STREQ(RNA_property_identifier(prop), "layers_vcol_select_loop_src")) { + else if (STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_src") || + STREQ(RNA_property_identifier(prop), "layers_vcol_loop_select_src")) { Object *ob_src = dtmd->ob_source; if (ob_src) { AttributeDomain domain = STREQ(RNA_property_identifier(prop), - "layers_vcol_select_vert_src") ? + "layers_vcol_vert_select_src") ? ATTR_DOMAIN_POINT : ATTR_DOMAIN_CORNER; @@ -1389,7 +1389,7 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf( cdata = &me_eval->ldata; } - CustomDataType types[2] = {CD_PROP_COLOR, CD_MLOOPCOL}; + CustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; int idx = 0; for (int i = 0; i < 2; i++) { @@ -1480,12 +1480,16 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf( } else if (STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_dst") || STREQ(RNA_property_identifier(prop), "layers_vcol_loop_select_dst")) { + int multilayer_index = STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_dst") ? + DT_MULTILAYER_INDEX_VCOL_VERT : + DT_MULTILAYER_INDEX_VCOL_LOOP; + /* Only list destination layers if we have a single source! */ - if (dtmd->layers_select_src[DT_MULTILAYER_INDEX_VCOL_LOOP] >= 0) { + if (dtmd->layers_select_src[multilayer_index] >= 0) { Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */ if (ob_dst && ob_dst->data) { - CustomDataType types[2] = {CD_PROP_COLOR, CD_MLOOPCOL}; + CustomDataType types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; Mesh *me_dst = ob_dst->data; CustomData *cdata = STREQ(RNA_property_identifier(prop), "layers_vcol_vert_select_dst") ? diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 31b2d36dcfd..4195782db08 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1420,8 +1420,13 @@ static bNodeSocket *rna_NodeTree_inputs_new( bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_IN, type, name); - ED_node_tree_propagate_change(NULL, bmain, ntree); - WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); + if (sock == NULL) { + BKE_report(reports, RPT_ERROR, "Unable to create socket"); + } + else { + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); + } return sock; } @@ -1435,8 +1440,13 @@ static bNodeSocket *rna_NodeTree_outputs_new( bNodeSocket *sock = ntreeAddSocketInterface(ntree, SOCK_OUT, type, name); - ED_node_tree_propagate_change(NULL, bmain, ntree); - WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); + if (sock == NULL) { + BKE_report(reports, RPT_ERROR, "Unable to create socket"); + } + else { + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); + } return sock; } @@ -2134,8 +2144,13 @@ static void rna_GeometryNodeCompare_data_type_update(Main *bmain, Scene *scene, static bool generic_attribute_type_supported(const EnumPropertyItem *item) { - return ELEM( - item->value, CD_PROP_FLOAT, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, CD_PROP_INT32); + return ELEM(item->value, + CD_PROP_FLOAT, + CD_PROP_FLOAT3, + CD_PROP_COLOR, + CD_PROP_BOOL, + CD_PROP_INT32, + CD_PROP_BYTE_COLOR); } static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), @@ -2146,6 +2161,18 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext return itemf_function_check(rna_enum_attribute_type_items, generic_attribute_type_supported); } +static bool generic_attribute_type_supported_with_socket(const EnumPropertyItem *item) +{ + return generic_attribute_type_supported(item) && !ELEM(item->value, CD_PROP_BYTE_COLOR); +} +static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_with_socket_itemf( + bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + *r_free = true; + return itemf_function_check(rna_enum_attribute_type_items, + generic_attribute_type_supported_with_socket); +} + static bool transfer_attribute_type_supported(const EnumPropertyItem *item) { return ELEM( @@ -10209,7 +10236,8 @@ static void def_geo_raycast(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10261,7 +10289,8 @@ static void def_geo_input_named_attribute(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "The data type used to read the attribute values"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10275,7 +10304,8 @@ static void def_geo_attribute_capture(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", "Type of data stored in attribute"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10502,7 +10532,8 @@ static void def_geo_viewer(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_enum_default(prop, CD_PROP_FLOAT); RNA_def_property_ui_text(prop, "Data Type", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); @@ -10532,7 +10563,8 @@ static void def_geo_field_at_index(StructRNA *srna) prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom2"); RNA_def_property_enum_items(prop, rna_enum_attribute_type_items); - RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_itemf"); + RNA_def_property_enum_funcs( + prop, NULL, NULL, "rna_GeometryNodeAttributeType_type_with_socket_itemf"); RNA_def_property_ui_text(prop, "Data Type", ""); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 03f800d14d1..6f2264680c8 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -676,7 +676,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, int vcol_no, float r_mcol[3]) { - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); zero_v3(r_mcol); return; diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 2390fdd72f0..a80e9573657 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -1360,7 +1360,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) RNA_def_property_pointer_sdna(prop, NULL, "custom_tx"); RNA_def_property_struct_type(prop, "PoseBone"); RNA_def_property_flag(prop, PROP_EDITABLE | PROP_PTR_NO_OWNERSHIP); - RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); RNA_def_property_ui_text(prop, "Custom Shape Transform", "Bone that defines the display transform of this custom shape"); diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 373df6b7444..a7d673d3fe1 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1474,6 +1474,11 @@ static int rna_property_override_diff_propptr(Main *bmain, (is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \ RNA_property_##_typename##_set((_ptr), (_prop), (_value))) +/** + * /return `0` is matching, `-1` if `prop_a < prop_b`, `1` if `prop_a > prop_b`. Note that for + * unquantifiable properties (e.g. pointers or collections), return value should be interpreted as + * a boolean (false == matching, true == not matching). + */ int rna_property_override_diff_default(Main *bmain, PropertyRNAOrID *prop_a, PropertyRNAOrID *prop_b, @@ -1932,25 +1937,25 @@ int rna_property_override_diff_default(Main *bmain, } else if (is_id || is_valid_for_diffing) { if (equals || do_create) { - const int eq = rna_property_override_diff_propptr(bmain, - ptr_a->owner_id, - ptr_b->owner_id, - &iter_a.ptr, - &iter_b.ptr, - mode, - no_ownership, - no_prop_name, - override, - rna_path, - rna_path_len, - PROP_COLLECTION, - propname_a, - propname_b, - idx_a, - idx_b, - flags, - r_override_changed); - equals = equals && eq; + const int comp = rna_property_override_diff_propptr(bmain, + ptr_a->owner_id, + ptr_b->owner_id, + &iter_a.ptr, + &iter_b.ptr, + mode, + no_ownership, + no_prop_name, + override, + rna_path, + rna_path_len, + PROP_COLLECTION, + propname_a, + propname_b, + idx_a, + idx_b, + flags, + r_override_changed); + equals = equals && (comp == 0); } } @@ -2596,10 +2601,11 @@ bool rna_property_override_apply_default(Main *bmain, int item_index_src, item_index_ref; if (RNA_property_collection_lookup_string_index( ptr_src, prop_src, opop->subitem_local_name, &item_ptr_src, &item_index_src) && - RNA_property_collection_lookup_int( - ptr_src, prop_src, item_index_src + 1, &item_ptr_src) && - RNA_property_collection_lookup_string_index( - ptr_dst, prop_dst, opop->subitem_local_name, &item_ptr_ref, &item_index_ref)) { + RNA_property_collection_lookup_string_index(ptr_dst, + prop_dst, + opop->subitem_reference_name, + &item_ptr_ref, + &item_index_ref)) { is_valid = true; item_index_dst = item_index_ref + 1; } @@ -2607,10 +2613,10 @@ bool rna_property_override_apply_default(Main *bmain, if (!is_valid && opop->subitem_local_index >= 0) { /* Find from index. */ if (RNA_property_collection_lookup_int( - ptr_src, prop_src, opop->subitem_local_index + 1, &item_ptr_src) && + ptr_src, prop_src, opop->subitem_local_index, &item_ptr_src) && RNA_property_collection_lookup_int( - ptr_dst, prop_dst, opop->subitem_local_index, &item_ptr_ref)) { - item_index_dst = opop->subitem_local_index + 1; + ptr_dst, prop_dst, opop->subitem_reference_index, &item_ptr_ref)) { + item_index_dst = opop->subitem_reference_index + 1; is_valid = true; } } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7f0a9627a17..b647a823929 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -2630,7 +2630,7 @@ static const EnumPropertyItem *rna_UnitSettings_itemf_wrapper(const int system, EnumPropertyItem adaptive = {0}; adaptive.identifier = "ADAPTIVE"; - adaptive.name = "Adaptive"; + adaptive.name = N_("Adaptive"); adaptive.value = USER_UNIT_ADAPTIVE; RNA_enum_item_add(&items, &totitem, &adaptive); @@ -3092,7 +3092,10 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "lock_object_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "object_flag", SCE_OBJECT_MODE_LOCK); - RNA_def_property_ui_text(prop, "Lock Object Modes", "Restrict select to the current mode"); + RNA_def_property_ui_text(prop, + "Lock Object Modes", + "Restrict selection to objects using the same mode as the active " + "object, to prevent accidental mode switch when selecting"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); static const EnumPropertyItem workspace_tool_items[] = { diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 37c687ddb2b..017e8bde7a1 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -562,8 +562,8 @@ static void rna_PaintModeSettings_canvas_source_update(bContext *C, PointerRNA * { Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - /* When canvas source changes the pbvh would require updates when switching between color - * attributes. */ + /* When canvas source changes the PBVH would require updates when switching between color + * attributes. */ if (ob && ob->type == OB_MESH) { BKE_texpaint_slots_refresh_object(scene, ob); DEG_id_tag_update(&ob->id, 0); @@ -1565,35 +1565,10 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna) static void rna_def_curves_sculpt(BlenderRNA *brna) { StructRNA *srna; - PropertyRNA *prop; srna = RNA_def_struct(brna, "CurvesSculpt", "Paint"); RNA_def_struct_path_func(srna, "rna_CurvesSculpt_path"); RNA_def_struct_ui_text(srna, "Curves Sculpt Paint", ""); - - prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, FLT_MAX, 1, 6); - RNA_def_property_ui_text( - prop, "Distance", "Radius around curves roots in which no new curves can be added"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - - prop = RNA_def_property(srna, "interpolate_length", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", CURVES_SCULPT_FLAG_INTERPOLATE_LENGTH); - RNA_def_property_ui_text( - prop, "Interpolate Length", "Use length of the curves in close proximity"); - - prop = RNA_def_property(srna, "interpolate_shape", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", CURVES_SCULPT_FLAG_INTERPOLATE_SHAPE); - RNA_def_property_ui_text( - prop, "Interpolate Shape", "Use shape of the curves in close proximity"); - - prop = RNA_def_property(srna, "curve_length", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_range(prop, 0.0, FLT_MAX); - RNA_def_property_ui_text( - prop, - "Curve Length", - "Length of newly added curves when it is not interpolated from other curves"); } void RNA_def_sculpt_paint(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index a27e699ef3d..3fd87a16d28 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2169,11 +2169,12 @@ static void rna_def_channel(BlenderRNA *brna) prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CHANNEL_LOCK); RNA_def_property_ui_text(prop, "Lock channel", ""); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CHANNEL_MUTE); RNA_def_property_ui_text(prop, "Mute channel", ""); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_sound_update"); } static void rna_def_editor(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index c40a2ed9260..1f68855622f 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -424,7 +424,7 @@ static const EnumPropertyItem rna_enum_shading_color_type_items[] = { {V3D_SHADING_SINGLE_COLOR, "SINGLE", 0, "Single", "Show scene in a single color"}, {V3D_SHADING_OBJECT_COLOR, "OBJECT", 0, "Object", "Show object color"}, {V3D_SHADING_RANDOM_COLOR, "RANDOM", 0, "Random", "Show random object color"}, - {V3D_SHADING_VERTEX_COLOR, "VERTEX", 0, "Color", "Show active color attribute"}, + {V3D_SHADING_VERTEX_COLOR, "VERTEX", 0, "Attribute", "Show active color attribute"}, {V3D_SHADING_TEXTURE_COLOR, "TEXTURE", 0, "Texture", "Show texture"}, {0, NULL, 0, NULL, NULL}, }; @@ -7752,6 +7752,12 @@ static void rna_def_spreadsheet_row_filter(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Color Value", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_byte_color", PROP_INT, PROP_NONE); + RNA_def_property_array(prop, 4); + RNA_def_property_range(prop, 0, 255); + RNA_def_property_ui_text(prop, "Byte Color Value", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); + prop = RNA_def_property(srna, "value_string", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Text Value", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SPREADSHEET, NULL); diff --git a/source/blender/makesrna/intern/rna_volume.c b/source/blender/makesrna/intern/rna_volume.c index 5b323629a80..12cb35b239d 100644 --- a/source/blender/makesrna/intern/rna_volume.c +++ b/source/blender/makesrna/intern/rna_volume.c @@ -78,6 +78,15 @@ static void rna_Volume_update_is_sequence(Main *bmain, Scene *scene, PointerRNA DEG_relations_tag_update(bmain); } +static void rna_Volume_velocity_grid_set(PointerRNA *ptr, const char *value) +{ + Volume *volume = (Volume *)ptr->data; + if (!BKE_volume_set_velocity_grid_by_name(volume, value)) { + WM_reportf(RPT_ERROR, "Could not find grid with name %s", value); + } + WM_main_add_notifier(NC_GEOM | ND_DATA, volume); +} + /* Grid */ static void rna_VolumeGrid_name_get(PointerRNA *ptr, char *value) @@ -248,6 +257,7 @@ static void rna_def_volume_grid(BlenderRNA *brna) RNA_def_property_string_funcs( prop, "rna_VolumeGrid_name_get", "rna_VolumeGrid_name_length", NULL); RNA_def_property_ui_text(prop, "Name", "Volume grid name"); + RNA_def_struct_name_property(srna, prop); prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); @@ -619,6 +629,55 @@ static void rna_def_volume(BlenderRNA *brna) RNA_def_property_struct_type(prop, "VolumeRender"); RNA_def_property_ui_text(prop, "Render", "Volume render settings for 3D viewport"); + /* Velocity. */ + prop = RNA_def_property(srna, "velocity_grid", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "velocity_grid"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Volume_velocity_grid_set"); + RNA_def_property_ui_text( + prop, + "Velocity Grid", + "Name of the velocity field, or the base name if the velocity is split into multiple grids"); + + prop = RNA_def_property(srna, "velocity_unit", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "velocity_unit"); + RNA_def_property_enum_items(prop, rna_enum_velocity_unit_items); + RNA_def_property_ui_text( + prop, + "Velocity Unit", + "Define how the velocity vectors are interpreted with regard to time, 'frame' means " + "the delta time is 1 frame, 'second' means the delta time is 1 / FPS"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + + prop = RNA_def_property(srna, "velocity_scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "velocity_scale"); + RNA_def_property_range(prop, 0.0f, FLT_MAX); + RNA_def_property_ui_text(prop, "Velocity Scale", "Factor to control the amount of motion blur"); + + /* Scalar grids for velocity. */ + prop = RNA_def_property(srna, "velocity_x_grid", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_x_grid"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, + "Velocity X Grid", + "Name of the grid for the X axis component of the velocity field if it " + "was split into multiple grids"); + + prop = RNA_def_property(srna, "velocity_y_grid", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_y_grid"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, + "Velocity Y Grid", + "Name of the grid for the Y axis component of the velocity field if it " + "was split into multiple grids"); + + prop = RNA_def_property(srna, "velocity_z_grid", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "runtime.velocity_z_grid"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, + "Velocity Z Grid", + "Name of the grid for the Z axis component of the velocity field if it " + "was split into multiple grids"); + /* Common */ rna_def_animdata_common(srna); } diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 758858c8b1d..c44a4e0b438 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -789,13 +789,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, MEM_freeN(full_doubles_map); } - /* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new mesh! - * TODO: we may need to set other dirty flags as well? - */ - if (use_recalc_normals) { - BKE_mesh_normals_tag_dirty(result); - } - if (vgroup_start_cap_remap) { MEM_freeN(vgroup_start_cap_remap); } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index b6cceade4e2..a7364af10a3 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -229,8 +229,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 915428f99da..d47f2a130e3 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -501,7 +501,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); } if (result == nullptr) { @@ -536,7 +535,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); } } } diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 61959d242d8..687ff04cedf 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -263,8 +263,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct MEM_freeN(edgeMap); MEM_freeN(faceMap); - BKE_mesh_normals_tag_dirty(result); - /* TODO(sybren): also copy flags & tags? */ return result; } diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 1cb308bb2a0..593610f5bad 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -120,7 +120,7 @@ static void deformVerts(ModifierData *md, uint mvert_num = 0; BKE_mesh_vert_coords_apply(mesh_src, vertexCos); - BKE_mesh_calc_normals(mesh_src); + BKE_mesh_normals_tag_dirty(mesh_src); current_time = DEG_get_ctime(ctx->depsgraph); diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 67515478be5..70f028d6907 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -212,8 +212,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * TIMEIT_END(decim); #endif - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index f8cf80b673c..1891ac5df7c 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -91,7 +91,7 @@ static void requiredDataMask(Object *UNUSED(ob), /* mcol */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT || surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { - r_cddata_masks->lmask |= CD_MASK_MLOOPCOL; + r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR; } /* CD_MDEFORMVERT */ if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 14431e5ff2e..49ddcb9a61d 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -102,7 +102,6 @@ Mesh *doEdgeSplit(const Mesh *mesh, EdgeSplitModifierData *emd) result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 87ff648f13d..9e2bb79138e 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1102,7 +1102,6 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* finalization */ BKE_mesh_calc_edges_tessface(explode); BKE_mesh_convert_mfaces_to_mpolys(explode); - BKE_mesh_normals_tag_dirty(explode); if (psmd->psys->lattice_deform_data) { BKE_lattice_deform_data_destroy(psmd->psys->lattice_deform_data); diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index cb26bd1b26b..900dee98268 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -748,7 +748,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) } BKE_mesh_calc_edges_loose(result); - BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 7545bae43b3..85b6cf6a2cd 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -119,6 +119,7 @@ using blender::threading::EnumerableThreadSpecific; using namespace blender::fn::multi_function_types; using namespace blender::nodes::derived_node_tree_types; using geo_log::GeometryAttributeInfo; +using geo_log::NamedAttributeUsage; static void initData(ModifierData *md) { @@ -997,30 +998,34 @@ static void store_computed_output_attributes( const CustomDataType data_type = blender::bke::cpp_type_to_custom_data_type(store.data.type()); const std::optional<AttributeMetaData> meta_data = component.attribute_get_meta_data( store.name); - if (meta_data.has_value() && meta_data->domain == store.domain && - meta_data->data_type == data_type) { - /* Copy the data into an existing attribute. */ - blender::bke::WriteAttributeLookup write_attribute = component.attribute_try_get_for_write( - store.name); - if (write_attribute) { - write_attribute.varray.set_all(store.data.data()); - if (write_attribute.tag_modified_fn) { - write_attribute.tag_modified_fn(); - } - } - store.data.type().destruct_n(store.data.data(), store.data.size()); - MEM_freeN(store.data.data()); + + /* Attempt to remove the attribute if it already exists but the domain and type don't match. + * Removing the attribute won't succeed if it is built in and non-removable. */ + if (meta_data.has_value() && + (meta_data->domain != store.domain || meta_data->data_type != data_type)) { + component.attribute_try_delete(store.name); } - else { - /* Replace the existing attribute with the new data. */ - if (meta_data.has_value()) { - component.attribute_try_delete(store.name); - } - component.attribute_try_create(store.name, - store.domain, - blender::bke::cpp_type_to_custom_data_type(store.data.type()), - AttributeInitMove(store.data.data())); + + /* Try to create the attribute reusing the stored buffer. This will only succeed if the + * attribute didn't exist before, or if it existed but was removed above. */ + if (component.attribute_try_create( + store.name, + store.domain, + blender::bke::cpp_type_to_custom_data_type(store.data.type()), + AttributeInitMove(store.data.data()))) { + continue; + } + + OutputAttribute attribute = component.attribute_try_get_for_output_only( + store.name, store.domain, data_type); + if (attribute) { + attribute.varray().set_all(store.data.data()); + attribute.save(); } + + /* We were unable to reuse the data, so it must be destructed and freed. */ + store.data.type().destruct_n(store.data.data(), store.data.size()); + MEM_freeN(store.data.data()); } } @@ -1619,6 +1624,71 @@ static void output_attribute_panel_draw(const bContext *C, Panel *panel) } } +static void used_attributes_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); + NodesModifierData *nmd = static_cast<NodesModifierData *>(ptr->data); + + if (nmd->runtime_eval_log == nullptr) { + return; + } + const geo_log::ModifierLog &log = *static_cast<geo_log::ModifierLog *>(nmd->runtime_eval_log); + Map<std::string, NamedAttributeUsage> usage_by_attribute; + log.foreach_node_log([&](const geo_log::NodeLog &node_log) { + for (const geo_log::UsedNamedAttribute &used_attribute : node_log.used_named_attributes()) { + usage_by_attribute.lookup_or_add_as(used_attribute.name, + used_attribute.usage) |= used_attribute.usage; + } + }); + + if (usage_by_attribute.is_empty()) { + uiItemL(layout, IFACE_("No named attributes used"), ICON_INFO); + return; + } + + Vector<std::pair<StringRefNull, NamedAttributeUsage>> sorted_used_attribute; + for (auto &&item : usage_by_attribute.items()) { + sorted_used_attribute.append({item.key, item.value}); + } + std::sort(sorted_used_attribute.begin(), sorted_used_attribute.end()); + + for (const auto &pair : sorted_used_attribute) { + const StringRefNull attribute_name = pair.first; + const NamedAttributeUsage usage = pair.second; + + /* #uiLayoutRowWithHeading doesn't seem to work in this case. */ + uiLayout *split = uiLayoutSplit(layout, 0.4f, false); + + std::stringstream ss; + Vector<std::string> usages; + if ((usage & NamedAttributeUsage::Read) != NamedAttributeUsage::None) { + usages.append(TIP_("Read")); + } + if ((usage & NamedAttributeUsage::Write) != NamedAttributeUsage::None) { + usages.append(TIP_("Write")); + } + if ((usage & NamedAttributeUsage::Remove) != NamedAttributeUsage::None) { + usages.append(TIP_("Remove")); + } + for (const int i : usages.index_range()) { + ss << usages[i]; + if (i < usages.size() - 1) { + ss << ", "; + } + } + + uiLayout *row = uiLayoutRow(split, false); + uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_RIGHT); + uiLayoutSetActive(row, false); + uiItemL(row, ss.str().c_str(), ICON_NONE); + + row = uiLayoutRow(split, false); + uiItemL(row, attribute_name.c_str(), ICON_NONE); + } +} + static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Nodes, panel_draw); @@ -1628,6 +1698,12 @@ static void panelRegister(ARegionType *region_type) nullptr, output_attribute_panel_draw, panel_type); + modifier_subpanel_register(region_type, + "used_attributes", + N_("Used Attributes"), + nullptr, + used_attributes_panel_draw, + panel_type); } static void blendWrite(BlendWriter *writer, const ModifierData *md) diff --git a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc index 68207d84015..e43d2b4ad85 100644 --- a/source/blender/modifiers/intern/MOD_nodes_evaluator.cc +++ b/source/blender/modifiers/intern/MOD_nodes_evaluator.cc @@ -1635,10 +1635,8 @@ class GeometryNodesEvaluator { if (conversions_.is_convertible(from_base_type, to_base_type)) { if (from_field_type->is_field(from_value)) { const GField &from_field = *from_field_type->get_field_ptr(from_value); - const MultiFunction &fn = *conversions_.get_conversion_multi_function( - MFDataType::ForSingle(from_base_type), MFDataType::ForSingle(to_base_type)); - auto operation = std::make_shared<fn::FieldOperation>(fn, Vector<GField>{from_field}); - to_field_type->construct_from_field(to_value, GField(std::move(operation), 0)); + to_field_type->construct_from_field(to_value, + conversions_.try_convert(from_field, to_base_type)); } else { to_field_type->default_construct(to_value); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 6ded702ceda..b5411eee883 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -302,8 +302,6 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co } } - BKE_mesh_normals_tag_dirty(result); - return result; } @@ -361,7 +359,6 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE) { result = generate_ocean_geometry(omd, mesh, resolution); - BKE_mesh_normals_tag_dirty(result); } else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE); @@ -376,17 +373,17 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes /* add vcols before displacement - allows lookup based on position */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { - if (CustomData_number_of_layers(&result->ldata, CD_MLOOPCOL) < MAX_MCOL) { + if (CustomData_number_of_layers(&result->ldata, CD_PROP_BYTE_COLOR) < MAX_MCOL) { const int polys_num = result->totpoly; const int loops_num = result->totloop; MLoop *mloops = result->mloop; MLoopCol *mloopcols = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->foamlayername); + &result->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, NULL, loops_num, omd->foamlayername); MLoopCol *mloopcols_spray = NULL; if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) { mloopcols_spray = CustomData_add_layer_named( - &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, loops_num, omd->spraylayername); + &result->ldata, CD_PROP_BYTE_COLOR, CD_CALLOC, NULL, loops_num, omd->spraylayername); } if (mloopcols) { /* unlikely to fail */ @@ -472,6 +469,8 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } } + BKE_mesh_normals_tag_dirty(mesh); + if (allocated_ocean) { BKE_ocean_free(omd->ocean); omd->ocean = NULL; @@ -490,15 +489,7 @@ static Mesh *doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { - Mesh *result; - - result = doOcean(md, ctx, mesh); - - if (result != mesh) { - BKE_mesh_normals_tag_dirty(result); - } - - return result; + return doOcean(md, ctx, mesh); } // #define WITH_OCEANSIM static void panel_draw(const bContext *UNUSED(C), Panel *panel) diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 205a1986552..2a8d2454670 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -59,7 +59,7 @@ static void requiredDataMask(Object *UNUSED(ob), ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; if (pimd->index_layer_name[0] != '\0' || pimd->value_layer_name[0] != '\0') { - r_cddata_masks->lmask |= CD_MASK_MLOOPCOL; + r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR; } } @@ -328,9 +328,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * orig_mloop = mesh->mloop; MLoopCol *mloopcols_index = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, pimd->index_layer_name); + &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name); MLoopCol *mloopcols_value = CustomData_get_layer_named( - &result->ldata, CD_MLOOPCOL, pimd->value_layer_name); + &result->ldata, CD_PROP_BYTE_COLOR, pimd->value_layer_name); int *vert_part_index = NULL; float *vert_part_value = NULL; if (mloopcols_index != NULL) { @@ -530,8 +530,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_SAFE_FREE(vert_part_index); MEM_SAFE_FREE(vert_part_value); - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 7df7ba7c1db..032227307e7 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -158,7 +158,6 @@ static void deformVerts(ModifierData *md, /* make new mesh */ psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); BKE_mesh_vert_coords_apply(psmd->mesh_final, vertexCos); - BKE_mesh_calc_normals(psmd->mesh_final); BKE_mesh_tessface_ensure(psmd->mesh_final); diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index f6f4746f44f..288faee247f 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -206,7 +206,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) BKE_mesh_copy_parameters_for_eval(result, mesh); BKE_mesh_calc_edges(result, true, false); - BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index 4ace6404388..05072cf340c 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -384,7 +384,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mvert_new = result->mvert; float(*vert_normals_new)[3] = BKE_mesh_vertex_normals_for_write(result); - BKE_mesh_vertex_normals_clear_dirty(result); mpoly_new = result->mpoly; mloop_new = result->mloop; medge_new = result->medge; @@ -1120,7 +1119,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if ((ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f)) { - Mesh *result_prev = result; result = mesh_remove_doubles_on_axis(result, mvert_new, totvert, @@ -1128,13 +1126,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * axis_vec, ob_axis != NULL ? mtx_tx[3] : NULL, ltmd->merge_dist); - if (result != result_prev) { - BKE_mesh_normals_tag_dirty(result); - } } - if ((ltmd->flag & MOD_SCREW_NORMAL_CALC) == 0) { - BKE_mesh_normals_tag_dirty(result); + if ((ltmd->flag & MOD_SCREW_NORMAL_CALC)) { + BKE_mesh_vertex_normals_clear_dirty(result); } return result; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index b950578ff1b..7f96dcb82fb 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1950,8 +1950,6 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, origmesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); - skin_set_orig_indices(result); return result; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 8a84cd0a3bf..8a5b600974c 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -2016,8 +2016,6 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } - BKE_mesh_normals_tag_dirty(result); - /* Make edges. */ { uint i = 0; diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 3e75e325e44..c2869e590bd 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -129,7 +129,7 @@ static void deformVerts(ModifierData *md, MVert *x, *v; BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos); - BKE_mesh_calc_normals(surmd->mesh); + BKE_mesh_normals_tag_dirty(surmd->mesh); mesh_verts_num = surmd->mesh->totvert; diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index d7e57c1f6e5..f1e8ef5bf38 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -89,8 +89,6 @@ static Mesh *triangulate_mesh(Mesh *mesh, me->flag |= ME_EDGEDRAW | ME_EDGERENDER; } - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index dae7d19844e..b657ea87244 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -97,8 +97,6 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh * result = BKE_mesh_from_bmesh_for_eval_nomain(bm, NULL, mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 87f000897ed..877dc05211d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -131,8 +131,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords) } plConvexHullDelete(hull); - - BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index c3b1a141f4a..8a0c900fbde 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -1225,8 +1225,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, } BKE_mesh_calc_edges_loose(mesh_out); - /* Tag to recalculate normals later. */ - BKE_mesh_normals_tag_dirty(mesh_out); geometry_set.replace_mesh(mesh_out); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index 2894e608819..dcd9bcfb034 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -897,7 +897,6 @@ static void calc_dual_mesh(GeometrySet &geometry_set, copy_v3_v3(mesh_out->mvert[i].co, vertex_positions[i]); } memcpy(mesh_out->medge, new_edges.data(), sizeof(MEdge) * new_edges.size()); - BKE_mesh_normals_tag_dirty(mesh_out); geometry_set.replace_mesh(mesh_out); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index c03a340a0c8..84acab47661 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -41,8 +41,6 @@ static Mesh *mesh_edge_split(const Mesh &mesh, const IndexMask selection) Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, nullptr, &mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); - return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc index e53be5213f6..636ecb8ab41 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc @@ -407,7 +407,6 @@ Mesh *create_cuboid_mesh(const float3 size, calculate_polys(config, {mesh->mpoly, mesh->totpoly}, {mesh->mloop, mesh->totloop}); BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); calculate_uvs(config, mesh); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc index e1f85be0f80..3c0ccb01673 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc @@ -50,7 +50,6 @@ static void geometry_set_mesh_subdivide(GeometrySet &geometry_set, const int lev } Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in); - BKE_mesh_normals_tag_dirty(mesh_out); MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); mesh_component.replace(mesh_out); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc index 296b40c6c49..507c6e81b1f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -18,8 +18,10 @@ namespace blender::nodes::node_geo_set_material_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input<decl::Geometry>(N_("Geometry")) - .supported_type( - {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_POINT_CLOUD}); + .supported_type({GEO_COMPONENT_TYPE_MESH, + GEO_COMPONENT_TYPE_VOLUME, + GEO_COMPONENT_TYPE_POINT_CLOUD, + GEO_COMPONENT_TYPE_CURVE}); b.add_input<decl::Bool>(N_("Selection")).default_value(true).hide_value().supports_field(); b.add_input<decl::Material>(N_("Material")).hide_label(); b.add_output<decl::Geometry>(N_("Geometry")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 92614d1a31d..b51fc063ab8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -5,6 +5,8 @@ #include "NOD_socket_search_link.hh" +#include "BKE_type_conversions.hh" + #include "node_geometry_util.hh" namespace blender::nodes::node_geo_store_named_attribute_cc { @@ -55,7 +57,8 @@ static void node_update(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3); nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT); - nodeSetSocketAvailability(ntree, socket_color4f, data_type == CD_PROP_COLOR); + nodeSetSocketAvailability( + ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)); nodeSetSocketAvailability(ntree, socket_boolean, data_type == CD_PROP_BOOL); nodeSetSocketAvailability(ntree, socket_int32, data_type == CD_PROP_INT32); } @@ -149,6 +152,12 @@ static void node_geo_exec(GeoNodeExecParams params) case CD_PROP_COLOR: field = params.get_input<Field<ColorGeometry4f>>("Value_Color"); break; + case CD_PROP_BYTE_COLOR: { + field = params.get_input<Field<ColorGeometry4f>>("Value_Color"); + field = bke::get_implicit_type_conversions().try_convert(field, + CPPType::get<ColorGeometry4b>()); + break; + } case CD_PROP_BOOL: field = params.get_input<Field<bool>>("Value_Bool"); break; diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index a5fe491e12b..4832feac5bd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -119,7 +119,6 @@ static void node_geo_exec(GeoNodeExecParams params) } Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in); - BKE_mesh_normals_tag_dirty(mesh_out); mesh_component.replace(mesh_out); diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform.cc b/source/blender/nodes/geometry/nodes/node_geo_transform.cc index cc115ee3b3f..e95db205920 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform.cc @@ -43,7 +43,6 @@ static void translate_mesh(Mesh &mesh, const float3 translation) static void transform_mesh(Mesh &mesh, const float4x4 &transform) { BKE_mesh_transform(&mesh, transform.values, false); - BKE_mesh_normals_tag_dirty(&mesh); } static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc index 76cdbfb140f..992470e8279 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc @@ -62,7 +62,6 @@ static Mesh *triangulate_mesh_selection(const Mesh &mesh, BM_mesh_triangulate(bm, quad_method, ngon_method, min_vertices, true, nullptr, nullptr, nullptr); Mesh *result = BKE_mesh_from_bmesh_for_eval_nomain(bm, &cd_mask_extra, &mesh); BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); return result; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc index c30c05bdd0d..e5827c24320 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc @@ -139,7 +139,6 @@ static Mesh *create_mesh_from_volume_grids(Span<openvdb::GridBase::ConstPtr> gri } BKE_mesh_calc_edges(mesh, false, false); - BKE_mesh_normals_tag_dirty(mesh); return mesh; } diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc index d917106807c..c5f40a46ca3 100644 --- a/source/blender/nodes/shader/node_shader_tree.cc +++ b/source/blender/nodes/shader/node_shader_tree.cc @@ -722,7 +722,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node } case SH_NODE_ADD_SHADER: { /* Simple passthrough node. Each original inputs will get the same weight. */ - /* TODO(fclem) Better use some kind of reroute node? */ + /* TODO(fclem): Better use some kind of reroute node? */ nodes_copy[id] = nodeAddStaticNode(NULL, ntree, SH_NODE_MATH); nodes_copy[id]->custom1 = NODE_MATH_ADD; nodes_copy[id]->tmp_flag = -2; /* Copy */ @@ -761,14 +761,14 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node } id++; /* Reroute the weight input to the 3 processing nodes. Simplify linking later-on. */ - /* TODO(fclem) Better use some kind of reroute node? */ + /* TODO(fclem): Better use some kind of reroute node? */ nodes_copy[id] = nodeAddStaticNode(NULL, ntree, SH_NODE_MATH); nodes_copy[id]->custom1 = NODE_MATH_ADD; nodes_copy[id]->tmp_flag = -2; /* Copy */ ((bNodeSocketValueFloat *)ntree_shader_node_input_get(nodes_copy[id], 0)->default_value) ->value = 0.0f; id++; - /* Link between nodes for the substraction. */ + /* Link between nodes for the subtraction. */ fromnode = nodes_copy[id_start]; tonode = nodes_copy[id_start + 1]; fromsock = ntree_shader_node_output_get(fromnode, 0); @@ -890,8 +890,8 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node break; } - /* Manually add the link to the socket to avoid calling - * BKE_ntree_update_main_tree(G.main, oop, nullptr. */ + /* Manually add the link to the socket to avoid calling: + * `BKE_ntree_update_main_tree(G.main, oop, nullptr)`. */ fromsock->link = nodeAddLink(ntree, fromnode, fromsock, tonode, tosock); BLI_assert(fromsock->link); } @@ -957,8 +957,8 @@ static void ntree_shader_shader_to_rgba_branch(bNodeTree *ntree, bNode *output_n LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { node->tmp_flag = -1; } - /* First gather the shader_to_rgba nodes linked to the ouput. This is separate to avoid - * conflicting usage of the node->tmp_flag. */ + /* First gather the shader_to_rgba nodes linked to the output. This is separate to avoid + * conflicting usage of the `node->tmp_flag`. */ Vector<bNode *> shader_to_rgba_nodes; nodeChainIterBackwards(ntree, output_node, shader_to_rgba_node_gather, &shader_to_rgba_nodes, 0); @@ -971,7 +971,7 @@ static void ntree_shader_shader_to_rgba_branch(bNodeTree *ntree, bNode *output_n bNode *start_node_copy = ntree_shader_copy_branch( ntree, start_node, closure_node_filter, nullptr, 0); /* Replace node copy link. This assumes that every node possibly connected to the closure input - * has only one ouput. */ + * has only one output. */ bNodeSocket *closure_output = ntree_shader_node_output_get(start_node_copy, 0); nodeRemLink(ntree, closure_input->link); nodeAddLink(ntree, start_node_copy, closure_output, shader_to_rgba, closure_input); diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.cc b/source/blender/nodes/shader/nodes/node_shader_attribute.cc index bb01818e734..d01271c15d3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_attribute.cc +++ b/source/blender/nodes/shader/nodes/node_shader_attribute.cc @@ -37,24 +37,6 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, NodeShaderAttribute *attr = static_cast<NodeShaderAttribute *>(node->storage); bool is_varying = attr->type == SHD_ATTRIBUTE_GEOMETRY; - if (GPU_material_is_volume_shader(mat) && is_varying) { - if (out[0].hasoutput) { - out[0].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); - } - if (out[1].hasoutput) { - out[1].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); - } - if (out[2].hasoutput) { - out[2].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); - } - if (out[3].hasoutput) { - static const float default_alpha = 1.0f; - out[3].link = GPU_constant(&default_alpha); - } - - return 1; - } - GPUNodeLink *cd_attr; if (is_varying) { @@ -64,6 +46,13 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, cd_attr = GPU_uniform_attribute(mat, attr->name, attr->type == SHD_ATTRIBUTE_INSTANCER); } + if (STREQ(attr->name, "color")) { + GPU_link(mat, "node_attribute_color", cd_attr, &cd_attr); + } + else if (STREQ(attr->name, "temperature")) { + GPU_link(mat, "node_attribute_temperature", cd_attr, &cd_attr); + } + GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr); int i; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc index dbff092234b..df5fbac3ab5 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc @@ -37,15 +37,15 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, NodeTexImage *tex_original = (NodeTexImage *)node_original->storage; ImageUser *iuser = &tex_original->iuser; eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER; - /* TODO(fclem): For now assume mipmap is always enabled. */ + /* TODO(@fclem): For now assume mipmap is always enabled. */ if (true) { sampler |= GPU_SAMPLER_MIPMAP; } GPUNodeLink *outalpha; - /* HACK(fclem): For lookdev mode: do not compile an empty environment and just create an empty - * texture entry point. We manually bind to it after DRW_shgroup_add_material_resources(). */ + /* HACK(@fclem): For lookdev mode: do not compile an empty environment and just create an empty + * texture entry point. We manually bind to it after #DRW_shgroup_add_material_resources(). */ if (!ima && !GPU_material_flag_get(mat, GPU_MATFLAG_LOOKDEV_HACK)) { return GPU_stack_link(mat, node, "node_tex_environment_empty", in, out); } diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc index 6676a7653fe..a202312f8d8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_info.cc +++ b/source/blender/nodes/shader/nodes/node_shader_volume_info.cc @@ -20,16 +20,18 @@ static int node_shader_gpu_volume_info(GPUMaterial *mat, GPUNodeStack *out) { if (out[0].hasoutput) { - out[0].link = GPU_volume_grid(mat, "color", GPU_VOLUME_DEFAULT_0); + out[0].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "color"); + GPU_link(mat, "node_attribute_color", out[0].link, &out[0].link); } if (out[1].hasoutput) { - out[1].link = GPU_volume_grid(mat, "density", GPU_VOLUME_DEFAULT_0); + out[1].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "density"); } if (out[2].hasoutput) { - out[2].link = GPU_volume_grid(mat, "flame", GPU_VOLUME_DEFAULT_0); + out[2].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "flame"); } if (out[3].hasoutput) { - out[3].link = GPU_volume_grid(mat, "temperature", GPU_VOLUME_DEFAULT_0); + out[3].link = GPU_attribute(mat, CD_AUTO_FROM_NAME, "temperature"); + GPU_link(mat, "node_attribute_temperature", out[3].link, &out[3].link); } return true; diff --git a/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc index d414b4b2ef7..07e700e550a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc +++ b/source/blender/nodes/shader/nodes/node_shader_volume_principled.cc @@ -43,6 +43,18 @@ static void node_shader_init_volume_principled(bNodeTree *UNUSED(ntree), bNode * } } +static void attribute_post_process(GPUMaterial *mat, + const char *attribute_name, + GPUNodeLink **attribute_link) +{ + if (STREQ(attribute_name, "color")) { + GPU_link(mat, "node_attribute_color", *attribute_link, attribute_link); + } + else if (STREQ(attribute_name, "temperature")) { + GPU_link(mat, "node_attribute_temperature", *attribute_link, attribute_link); + } +} + static int node_shader_gpu_volume_principled(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), @@ -67,28 +79,29 @@ static int node_shader_gpu_volume_principled(GPUMaterial *mat, } if (STREQ(sock->name, "Density Attribute")) { - density = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_1); + density = GPU_attribute_with_default(mat, CD_AUTO_FROM_NAME, attribute_name, GPU_DEFAULT_1); + attribute_post_process(mat, attribute_name, &density); } else if (STREQ(sock->name, "Color Attribute")) { - color = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_1); + color = GPU_attribute_with_default(mat, CD_AUTO_FROM_NAME, attribute_name, GPU_DEFAULT_1); + attribute_post_process(mat, attribute_name, &color); } else if (use_blackbody && STREQ(sock->name, "Temperature Attribute")) { - temperature = GPU_volume_grid(mat, attribute_name, GPU_VOLUME_DEFAULT_0); + temperature = GPU_attribute(mat, CD_AUTO_FROM_NAME, attribute_name); + attribute_post_process(mat, attribute_name, &temperature); } } /* Default values if attributes not found. */ + static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; if (!density) { - static float one = 1.0f; - density = GPU_constant(&one); + density = GPU_constant(white); } if (!color) { - static float white[4] = {1.0f, 1.0f, 1.0f, 1.0f}; color = GPU_constant(white); } if (!temperature) { - static float one = 1.0f; - temperature = GPU_constant(&one); + temperature = GPU_constant(white); } /* Create blackbody spectrum. */ diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index e591dfa2929..58bfb922327 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -193,7 +193,7 @@ static PyGetSetDef bpy_bmlayeraccess_vert_getseters[] = { (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, bpy_bmlayeraccess_collection__color_doc, - (void *)CD_MLOOPCOL}, + (void *)CD_PROP_BYTE_COLOR}, {"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -254,7 +254,7 @@ static PyGetSetDef bpy_bmlayeraccess_edge_getseters[] = { (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, bpy_bmlayeraccess_collection__color_doc, - (void *)CD_MLOOPCOL}, + (void *)CD_PROP_BYTE_COLOR}, {"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -307,7 +307,7 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = { (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, bpy_bmlayeraccess_collection__color_doc, - (void *)CD_MLOOPCOL}, + (void *)CD_PROP_BYTE_COLOR}, {"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -365,7 +365,7 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = { (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, bpy_bmlayeraccess_collection__color_doc, - (void *)CD_MLOOPCOL}, + (void *)CD_PROP_BYTE_COLOR}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -1134,7 +1134,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) ret = BPy_BMLoopUV_CreatePyObject(value); break; } - case CD_MLOOPCOL: { + case CD_PROP_BYTE_COLOR: { ret = BPy_BMLoopColor_CreatePyObject(value); break; } @@ -1236,7 +1236,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj ret = BPy_BMLoopUV_AssignPyObject(value, py_value); break; } - case CD_MLOOPCOL: { + case CD_PROP_BYTE_COLOR: { ret = BPy_BMLoopColor_AssignPyObject(value, py_value); break; } diff --git a/source/blender/python/gpu/gpu_py_batch.c b/source/blender/python/gpu/gpu_py_batch.c index 232d4775746..02bcf80aa5d 100644 --- a/source/blender/python/gpu/gpu_py_batch.c +++ b/source/blender/python/gpu/gpu_py_batch.c @@ -82,6 +82,18 @@ static PyObject *pygpu_batch__tp_new(PyTypeObject *UNUSED(type), PyObject *args, } BLI_assert(prim_type.value_found != GPU_PRIM_NONE); + if (prim_type.value_found == GPU_PRIM_LINE_LOOP) { + PyErr_WarnEx(PyExc_DeprecationWarning, + "'LINE_LOOP' is deprecated. Please use 'LINE_STRIP' and close the segment.", + 1); + } + else if (prim_type.value_found == GPU_PRIM_TRI_FAN) { + PyErr_WarnEx( + PyExc_DeprecationWarning, + "'TRI_FAN' is deprecated. Please use 'TRI_STRIP' or 'TRIS' and try modifying your " + "vertices or indices to match the topology.", + 1); + } if (py_vertbuf == NULL) { PyErr_Format(PyExc_TypeError, exc_str_missing_arg, _keywords[1], 2); diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 9fe4bdcbaa0..77333c6dfea 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -30,17 +30,37 @@ /** \name Enum Conversion. * \{ */ -#define PYDOC_BUILTIN_SHADER_LIST \ - " - ``2D_FLAT_COLOR``\n" \ - " - ``2D_IMAGE``\n" \ - " - ``2D_SMOOTH_COLOR``\n" \ - " - ``2D_UNIFORM_COLOR``\n" \ - " - ``3D_FLAT_COLOR``\n" \ - " - ``3D_SMOOTH_COLOR``\n" \ - " - ``3D_UNIFORM_COLOR``\n" \ - " - ``3D_POLYLINE_FLAT_COLOR``\n" \ - " - ``3D_POLYLINE_SMOOTH_COLOR``\n" \ - " - ``3D_POLYLINE_UNIFORM_COLOR``\n" +#define PYDOC_BUILTIN_SHADER_DESCRIPTION \ + "``2D_FLAT_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: none\n" \ + "``2D_IMAGE``\n" \ + " :Attributes: vec3 pos, vec2 texCoord\n" \ + " :Uniforms: sampler2D image\n" \ + "``2D_SMOOTH_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: none\n" \ + "``2D_UNIFORM_COLOR``\n" \ + " :Attributes: vec3 pos\n" \ + " :Uniforms: vec4 color\n" \ + "``3D_FLAT_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: none\n" \ + "``3D_SMOOTH_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: none\n" \ + "``3D_UNIFORM_COLOR``\n" \ + " :Attributes: vec3 pos\n" \ + " :Uniforms: vec4 color\n" \ + "``3D_POLYLINE_FLAT_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: vec2 viewportSize, float lineWidth\n" \ + "``3D_POLYLINE_SMOOTH_COLOR``\n" \ + " :Attributes: vec3 pos, vec4 color\n" \ + " :Uniforms: vec2 viewportSize, float lineWidth\n" \ + "``3D_POLYLINE_UNIFORM_COLOR``\n" \ + " :Attributes: vec3 pos\n" \ + " :Uniforms: vec2 viewportSize, float lineWidth\n" static const struct PyC_StringEnumItems pygpu_shader_builtin_items[] = { {GPU_SHADER_2D_FLAT_COLOR, "2D_FLAT_COLOR"}, @@ -731,7 +751,9 @@ static PyObject *pygpu_shader_unbind(BPyGPUShader *UNUSED(self)) PyDoc_STRVAR(pygpu_shader_from_builtin_doc, ".. function:: from_builtin(shader_name, config='DEFAULT')\n" "\n" - " Shaders that are embedded in the blender internal code.\n" + " Shaders that are embedded in the blender internal code:\n" + "" PYDOC_BUILTIN_SHADER_DESCRIPTION + "\n" " They all read the uniform ``mat4 ModelViewProjectionMatrix``,\n" " which can be edited by the :mod:`gpu.matrix` module.\n" "\n" @@ -739,11 +761,7 @@ PyDoc_STRVAR(pygpu_shader_from_builtin_doc, "``CLIPPED`` value to the config parameter. Note that in this case you also need to " "manually set the value of ``mat4 ModelMatrix``.\n" "\n" - " For more details, you can check the shader code with the\n" - " :func:`gpu.shader.code_from_builtin` function.\n" - "\n" - " :param shader_name: One of these builtin shader names:\n" - "\n" PYDOC_BUILTIN_SHADER_LIST + " :param shader_name: One of the builtin shader names.\n" " :type shader_name: str\n" " :param config: One of these types of shader configuration:\n" "\n" @@ -784,52 +802,6 @@ static PyObject *pygpu_shader_from_builtin(PyObject *UNUSED(self), PyObject *arg return BPyGPUShader_CreatePyObject(shader, true); } -PyDoc_STRVAR(pygpu_shader_code_from_builtin_doc, - ".. function:: code_from_builtin(pygpu_shader_name)\n" - "\n" - " Exposes the internal shader code for consultation.\n" - "\n" - " :param pygpu_shader_name: One of these builtin shader names:\n" - "\n" PYDOC_BUILTIN_SHADER_LIST - " :type pygpu_shader_name: str\n" - " :return: Vertex, fragment and geometry shader codes.\n" - " :rtype: dict\n"); -static PyObject *pygpu_shader_code_from_builtin(BPyGPUShader *UNUSED(self), PyObject *arg) -{ - const char *vert; - const char *frag; - const char *geom; - const char *defines; - - PyObject *item, *r_dict; - - struct PyC_StringEnum pygpu_bultinshader = {pygpu_shader_builtin_items}; - if (!PyC_ParseStringEnum(arg, &pygpu_bultinshader)) { - return NULL; - } - - GPU_shader_get_builtin_shader_code( - pygpu_bultinshader.value_found, &vert, &frag, &geom, &defines); - - r_dict = PyDict_New(); - - PyDict_SetItemString(r_dict, "vertex_shader", item = PyUnicode_FromString(vert)); - Py_DECREF(item); - - PyDict_SetItemString(r_dict, "fragment_shader", item = PyUnicode_FromString(frag)); - Py_DECREF(item); - - if (geom) { - PyDict_SetItemString(r_dict, "geometry_shader", item = PyUnicode_FromString(geom)); - Py_DECREF(item); - } - if (defines) { - PyDict_SetItemString(r_dict, "defines", item = PyUnicode_FromString(defines)); - Py_DECREF(item); - } - return r_dict; -} - PyDoc_STRVAR(pygpu_shader_create_from_info_doc, ".. function:: create_from_info(shader_info)\n" "\n" @@ -868,10 +840,6 @@ static struct PyMethodDef pygpu_shader_module__tp_methods[] = { (PyCFunction)pygpu_shader_from_builtin, METH_VARARGS | METH_KEYWORDS, pygpu_shader_from_builtin_doc}, - {"code_from_builtin", - (PyCFunction)pygpu_shader_code_from_builtin, - METH_O, - pygpu_shader_code_from_builtin_doc}, {"create_from_info", (PyCFunction)pygpu_shader_create_from_info, METH_O, @@ -887,28 +855,7 @@ PyDoc_STRVAR(pygpu_shader_module__tp_doc, "All built-in shaders have the ``mat4 ModelViewProjectionMatrix`` uniform.\n" "\n" "Its value must be modified using the :class:`gpu.matrix` module.\n" - "\n" - "``2D_UNIFORM_COLOR``\n" - " :Attributes: vec3 pos\n" - " :Uniforms: vec4 color\n" - "``2D_FLAT_COLOR``\n" - " :Attributes: vec3 pos, vec4 color\n" - " :Uniforms: none\n" - "``2D_SMOOTH_COLOR``\n" - " :Attributes: vec3 pos, vec4 color\n" - " :Uniforms: none\n" - "``2D_IMAGE``\n" - " :Attributes: vec3 pos, vec2 texCoord\n" - " :Uniforms: sampler2D image\n" - "``3D_UNIFORM_COLOR``\n" - " :Attributes: vec3 pos\n" - " :Uniforms: vec4 color\n" - "``3D_FLAT_COLOR``\n" - " :Attributes: vec3 pos, vec4 color\n" - " :Uniforms: none\n" - "``3D_SMOOTH_COLOR``\n" - " :Attributes: vec3 pos, vec4 color\n" - " :Uniforms: none\n"); + "\n" PYDOC_BUILTIN_SHADER_DESCRIPTION); static PyModuleDef pygpu_shader_module_def = { PyModuleDef_HEAD_INIT, .m_name = "gpu.shader", diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 86dc5800b67..e4e198ab812 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRC bpy_rna_anim.c bpy_rna_array.c bpy_rna_callback.c + bpy_rna_context.c bpy_rna_data.c bpy_rna_driver.c bpy_rna_gizmo.c @@ -101,6 +102,7 @@ set(SRC bpy_rna.h bpy_rna_anim.h bpy_rna_callback.h + bpy_rna_context.h bpy_rna_data.h bpy_rna_driver.h bpy_rna_gizmo.h diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index db0067fc18e..95879b02295 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -60,6 +60,23 @@ static wmOperatorType *ot_lookup_from_py_string(PyObject *value, const char *py_ return ot; } +static void op_context_override_deprecated_warning(const char *action, const char *opname) +{ + if (PyErr_WarnFormat( + PyExc_DeprecationWarning, + /* Use stack level 2 as this call is wrapped by `release/scripts/modules/bpy/ops.py`, + * An extra stack level is needed to show the warning in the authors script. */ + 2, + "Passing in context overrides is deprecated in favor of " + "Context.temp_override(..), %s \"%s\"", + action, + opname) < 0) { + /* The function has no return value, the exception cannot + * be reported to the caller, so just log it. */ + PyErr_WriteUnraisable(NULL); + } +} + static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) { wmOperatorType *ot; @@ -113,7 +130,10 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) if (ELEM(context_dict, NULL, Py_None)) { context_dict = NULL; } - else if (!PyDict_Check(context_dict)) { + else if (PyDict_Check(context_dict)) { + op_context_override_deprecated_warning("polling", opname); + } + else { PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s.poll\" error, " "custom context expected a dict or None, got a %.200s", @@ -218,7 +238,10 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) if (ELEM(context_dict, NULL, Py_None)) { context_dict = NULL; } - else if (!PyDict_Check(context_dict)) { + else if (PyDict_Check(context_dict)) { + op_context_override_deprecated_warning("calling", opname); + } + else { PyErr_Format(PyExc_TypeError, "Calling operator \"bpy.ops.%s\" error, " "custom context expected a dict or None, got a %.200s", diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 5db66405403..c67f0c028cf 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -4398,7 +4398,7 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb } } - /* Fallback to standard py, delattr/setattr. */ + /* Fallback to standard Python's `delattr/setattr`. */ return PyType_Type.tp_setattro(cls, attr, value); } @@ -7872,6 +7872,50 @@ StructRNA *pyrna_struct_as_srna(PyObject *self, const bool parent, const char *e return srna; } +const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna) +{ + BPy_StructRNA *bpy_srna = (BPy_StructRNA *)py_obj; + if (!BPy_StructRNA_Check(py_obj) || !RNA_struct_is_a(bpy_srna->ptr.type, srna)) { + PyErr_Format(PyExc_TypeError, + "Expected a \"bpy.types.%.200s\" not a \"%.200s\"", + RNA_struct_identifier(srna), + Py_TYPE(py_obj)->tp_name); + return NULL; + } + PYRNA_STRUCT_CHECK_OBJ(bpy_srna); + return &bpy_srna->ptr; +} + +const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna) +{ + if (py_obj == Py_None) { + return &PointerRNA_NULL; + } + return pyrna_struct_as_ptr(py_obj, srna); +} + +int pyrna_struct_as_ptr_parse(PyObject *o, void *p) +{ + struct BPy_StructRNA_Parse *srna_parse = p; + BLI_assert(srna_parse->type != NULL); + srna_parse->ptr = pyrna_struct_as_ptr(o, srna_parse->type); + if (srna_parse->ptr == NULL) { + return 0; + } + return 1; +} + +int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p) +{ + struct BPy_StructRNA_Parse *srna_parse = p; + BLI_assert(srna_parse->type != NULL); + srna_parse->ptr = pyrna_struct_as_ptr_or_null(o, srna_parse->type); + if (srna_parse->ptr == NULL) { + return 0; + } + return 1; +} + /* Orphan functions, not sure where they should go. */ StructRNA *srna_from_self(PyObject *self, const char *error_prefix) { diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h index 573daac6e95..91fa0ea2c8d 100644 --- a/source/blender/python/intern/bpy_rna.h +++ b/source/blender/python/intern/bpy_rna.h @@ -187,6 +187,33 @@ PyObject *pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop); int pyrna_deferred_register_class(struct StructRNA *srna, PyTypeObject *py_class); +const PointerRNA *pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna); +const PointerRNA *pyrna_struct_as_ptr_or_null(PyObject *py_obj, const StructRNA *srna); + +/** + * Struct used for RNA argument parsing functions: + * - #pyrna_struct_as_ptr_parse + * - #pyrna_struct_as_ptr_or_null_parse + */ +struct BPy_StructRNA_Parse { + /** The struct RNA must match this type. */ + StructRNA *type; + /** Result, may be `PointerRNA_NULL` if #pyrna_struct_as_ptr_or_null_parse is used. */ + const PointerRNA *ptr; +}; + +/** + * Sets #BPy_StructRNA_Parse.ptr to the value in the #BPy_StructRNA.ptr (from `o`) + * or raise an error if the type isn't a #BPy_StructRNA. + * + * Use with #PyArg_ParseTuple's `O&` formatting. + */ +int pyrna_struct_as_ptr_parse(PyObject *o, void *p); +/** + * A version of #pyrna_struct_as_ptr_parse that maps Python's `None` to #PointerRNA_NULL. + */ +int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p); + void pyrna_struct_type_extend_capi(struct StructRNA *srna, struct PyMethodDef *py_method, struct PyGetSetDef *py_getset); diff --git a/source/blender/python/intern/bpy_rna_context.c b/source/blender/python/intern/bpy_rna_context.c new file mode 100644 index 00000000000..811552ce938 --- /dev/null +++ b/source/blender/python/intern/bpy_rna_context.c @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup pythonintern + * + * This file adds some helper methods to the context, that cannot fit well in RNA itself. + */ + +#include <Python.h> + +#include "BLI_listbase.h" +#include "BLI_utildefines.h" + +#include "BKE_context.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "bpy_rna_context.h" + +#include "RNA_access.h" +#include "RNA_prototypes.h" + +#include "bpy_rna.h" + +/* -------------------------------------------------------------------- */ +/** \name Temporary Context Override (Python Context Manager) + * \{ */ + +typedef struct ContextStore { + wmWindow *win; + bool win_is_set; + ScrArea *area; + bool area_is_set; + ARegion *region; + bool region_is_set; +} ContextStore; + +typedef struct BPyContextTempOverride { + PyObject_HEAD /* Required Python macro. */ + bContext *context; + + ContextStore ctx_init; + ContextStore ctx_temp; + /** Bypass Python overrides set when calling an operator from Python. */ + struct bContext_PyState py_state; + /** + * This dictionary is used to store members that don't have special handling, + * see: #bpy_context_temp_override_extract_known_args, + * these will then be accessed via #BPY_context_member_get. + * + * This also supports nested *stacking*, so a nested temp-context-overrides + * will overlay the new members on the old members (instead of ignoring them). + */ + PyObject *py_state_context_dict; +} BPyContextTempOverride; + +static void bpy_rna_context_temp_override__tp_dealloc(BPyContextTempOverride *self) +{ + PyObject_DEL(self); +} + +static PyObject *bpy_rna_context_temp_override_enter(BPyContextTempOverride *self) +{ + bContext *C = self->context; + + CTX_py_state_push(C, &self->py_state, self->py_state_context_dict); + + self->ctx_init.win = CTX_wm_window(C); + self->ctx_init.win_is_set = (self->ctx_init.win != self->ctx_temp.win); + self->ctx_init.area = CTX_wm_area(C); + self->ctx_init.area_is_set = (self->ctx_init.area != self->ctx_temp.area); + self->ctx_init.region = CTX_wm_region(C); + self->ctx_init.region_is_set = (self->ctx_init.region != self->ctx_temp.region); + + wmWindow *win = self->ctx_temp.win_is_set ? self->ctx_temp.win : self->ctx_init.win; + bScreen *screen = win ? WM_window_get_active_screen(win) : NULL; + ScrArea *area = self->ctx_temp.area_is_set ? self->ctx_temp.area : self->ctx_init.area; + ARegion *region = self->ctx_temp.region_is_set ? self->ctx_temp.region : self->ctx_init.region; + + /* Sanity check, the region is in the screen/area. */ + if (self->ctx_temp.region_is_set && (region != NULL)) { + if (area == NULL) { + PyErr_SetString(PyExc_TypeError, "Region set with NULL area"); + return NULL; + } + if ((screen && BLI_findindex(&screen->regionbase, region) == -1) && + (BLI_findindex(&area->regionbase, region) == -1)) { + PyErr_SetString(PyExc_TypeError, "Region not found in area"); + return NULL; + } + } + + if (self->ctx_temp.area_is_set && (area != NULL)) { + if (screen == NULL) { + PyErr_SetString(PyExc_TypeError, "Area set with NULL screen"); + return NULL; + } + if (BLI_findindex(&screen->areabase, area) == -1) { + PyErr_SetString(PyExc_TypeError, "Area not found in screen"); + return NULL; + } + } + + if (self->ctx_temp.win_is_set) { + CTX_wm_window_set(C, self->ctx_temp.win); + } + if (self->ctx_temp.area_is_set) { + CTX_wm_area_set(C, self->ctx_temp.area); + } + if (self->ctx_temp.region_is_set) { + CTX_wm_region_set(C, self->ctx_temp.region); + } + + Py_RETURN_NONE; +} + +static PyObject *bpy_rna_context_temp_override_exit(BPyContextTempOverride *self, + PyObject *UNUSED(args)) +{ + bContext *C = self->context; + + /* Special case where the window is expected to be freed on file-read, + * in this case the window should not be restored, see: T92818. */ + bool do_restore = true; + if (self->ctx_init.win) { + wmWindowManager *wm = CTX_wm_manager(C); + if (BLI_findindex(&wm->windows, self->ctx_init.win) == -1) { + CTX_wm_window_set(C, NULL); + do_restore = false; + } + } + + if (do_restore) { + if (self->ctx_init.win_is_set) { + CTX_wm_window_set(C, self->ctx_init.win); + } + if (self->ctx_init.area_is_set) { + CTX_wm_area_set(C, self->ctx_init.area); + } + if (self->ctx_init.region_is_set) { + CTX_wm_region_set(C, self->ctx_init.region); + } + } + + CTX_py_state_pop(C, &self->py_state); + Py_CLEAR(self->py_state_context_dict); + + Py_RETURN_NONE; +} + +static PyMethodDef bpy_rna_context_temp_override__tp_methods[] = { + {"__enter__", (PyCFunction)bpy_rna_context_temp_override_enter, METH_NOARGS}, + {"__exit__", (PyCFunction)bpy_rna_context_temp_override_exit, METH_VARARGS}, + {NULL}, +}; + +static PyTypeObject BPyContextTempOverride_Type = { + PyVarObject_HEAD_INIT(NULL, 0).tp_name = "ContextTempOverride", + .tp_basicsize = sizeof(BPyContextTempOverride), + .tp_dealloc = (destructor)bpy_rna_context_temp_override__tp_dealloc, + .tp_flags = Py_TPFLAGS_DEFAULT, + .tp_methods = bpy_rna_context_temp_override__tp_methods, +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Context Temporary Override Method + * \{ */ + +static PyObject *bpy_context_temp_override_extract_known_args(const char *const *kwds_static, + PyObject *kwds) +{ + PyObject *sentinel = Py_Ellipsis; + PyObject *kwds_parse = PyDict_New(); + for (int i = 0; kwds_static[i]; i++) { + PyObject *key = PyUnicode_FromString(kwds_static[i]); + PyObject *val = _PyDict_Pop(kwds, key, sentinel); + if (val != sentinel) { + if (PyDict_SetItem(kwds_parse, key, val) == -1) { + BLI_assert_unreachable(); + } + } + Py_DECREF(key); + Py_DECREF(val); + } + return kwds_parse; +} + +PyDoc_STRVAR(bpy_context_temp_override_doc, + ".. method:: temp_override(window, area, region, **keywords)\n" + "\n" + " Context manager to temporarily override members in the context.\n" + "\n" + " :arg window: Window override or None.\n" + " :type window: :class:`bpy.types.Window`\n" + " :arg area: Area override or None.\n" + " :type area: :class:`bpy.types.Area`\n" + " :arg region: Region override or None.\n" + " :type region: :class:`bpy.types.Region`\n" + " :arg keywords: Additional keywords override context members.\n" + " :return: The context manager .\n" + " :rtype: context manager\n"); +static PyObject *bpy_context_temp_override(PyObject *self, PyObject *args, PyObject *kwds) +{ + const PointerRNA *context_ptr = pyrna_struct_as_ptr(self, &RNA_Context); + if (context_ptr == NULL) { + return NULL; + } + + if (kwds == NULL) { + /* While this is effectively NOP, support having no keywords as it's more involved + * to return an alternative (dummy) context manager. */ + } + else { + /* Needed because the keywords copied into `kwds_parse` could contain anything. + * As the types of keys aren't checked. */ + if (!PyArg_ValidateKeywordArguments(kwds)) { + return NULL; + } + } + + struct { + struct BPy_StructRNA_Parse window; + struct BPy_StructRNA_Parse area; + struct BPy_StructRNA_Parse region; + } params = { + .window = {.type = &RNA_Window}, + .area = {.type = &RNA_Area}, + .region = {.type = &RNA_Region}, + }; + + static const char *const _keywords[] = {"window", "area", "region", NULL}; + static _PyArg_Parser _parser = { + "|$" /* Optional, keyword only arguments. */ + "O&" /* `window` */ + "O&" /* `area` */ + "O&" /* `region` */ + ":temp_override", + _keywords, + 0, + }; + /* Parse known keywords, the remaining keywords are set using #CTX_py_state_push. */ + kwds = kwds ? PyDict_Copy(kwds) : PyDict_New(); + { + PyObject *kwds_parse = bpy_context_temp_override_extract_known_args(_keywords, kwds); + const int parse_result = _PyArg_ParseTupleAndKeywordsFast(args, + kwds_parse, + &_parser, + pyrna_struct_as_ptr_or_null_parse, + ¶ms.window, + pyrna_struct_as_ptr_or_null_parse, + ¶ms.area, + pyrna_struct_as_ptr_or_null_parse, + ¶ms.region); + Py_DECREF(kwds_parse); + if (parse_result == -1) { + Py_DECREF(kwds); + return NULL; + } + } + + bContext *C = context_ptr->data; + { + /* Merge existing keys that don't exist in the keywords passed in. + * This makes it possible to nest context overrides. */ + PyObject *context_dict_current = CTX_py_dict_get(C); + if (context_dict_current != NULL) { + PyDict_Merge(kwds, context_dict_current, 0); + } + } + + ContextStore ctx_temp = {NULL}; + if (params.window.ptr != NULL) { + ctx_temp.win = params.window.ptr->data; + ctx_temp.win_is_set = true; + } + if (params.area.ptr != NULL) { + ctx_temp.area = params.area.ptr->data; + ctx_temp.area_is_set = true; + } + + if (params.region.ptr != NULL) { + ctx_temp.region = params.region.ptr->data; + ctx_temp.region_is_set = true; + } + + BPyContextTempOverride *ret = PyObject_New(BPyContextTempOverride, &BPyContextTempOverride_Type); + ret->context = C; + ret->ctx_temp = ctx_temp; + memset(&ret->ctx_init, 0, sizeof(ret->ctx_init)); + + ret->py_state_context_dict = kwds; + + return (PyObject *)ret; +} + +/** \} */ + +PyMethodDef BPY_rna_context_temp_override_method_def = { + "temp_override", + (PyCFunction)bpy_context_temp_override, + METH_VARARGS | METH_KEYWORDS, + bpy_context_temp_override_doc, +}; diff --git a/source/blender/python/intern/bpy_rna_context.h b/source/blender/python/intern/bpy_rna_context.h new file mode 100644 index 00000000000..ddd328131e6 --- /dev/null +++ b/source/blender/python/intern/bpy_rna_context.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup pythonintern + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +extern PyMethodDef BPY_rna_context_temp_override_method_def; + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/python/intern/bpy_rna_types_capi.c b/source/blender/python/intern/bpy_rna_types_capi.c index a5299bc1616..376195ab845 100644 --- a/source/blender/python/intern/bpy_rna_types_capi.c +++ b/source/blender/python/intern/bpy_rna_types_capi.c @@ -22,6 +22,7 @@ #include "bpy_library.h" #include "bpy_rna.h" #include "bpy_rna_callback.h" +#include "bpy_rna_context.h" #include "bpy_rna_data.h" #include "bpy_rna_id_collection.h" #include "bpy_rna_text.h" @@ -159,6 +160,17 @@ static struct PyGetSetDef pyrna_windowmanager_getset[] = { /** \} */ /* -------------------------------------------------------------------- */ +/** \name Context Type + * \{ */ + +static struct PyMethodDef pyrna_context_methods[] = { + {NULL, NULL, 0, NULL}, /* #BPY_rna_context_temp_override_method_def */ + {NULL, NULL, 0, NULL}, +}; + +/** \} */ + +/* -------------------------------------------------------------------- */ /** \name Space Type * \{ */ @@ -254,6 +266,10 @@ void BPY_rna_types_extend_capi(void) /* WindowManager */ pyrna_struct_type_extend_capi( &RNA_WindowManager, pyrna_windowmanager_methods, pyrna_windowmanager_getset); + + /* Context */ + ARRAY_SET_ITEMS(pyrna_context_methods, BPY_rna_context_temp_override_method_def); + pyrna_struct_type_extend_capi(&RNA_Context, pyrna_context_methods, NULL); } /** \} */ diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h index da48599fdf9..56c66df5925 100644 --- a/source/blender/render/RE_bake.h +++ b/source/blender/render/RE_bake.h @@ -19,6 +19,8 @@ extern "C" { typedef struct BakeImage { struct Image *image; + int tile_number; + float uv_offset[2]; int width; int height; size_t offset; @@ -30,7 +32,7 @@ typedef struct BakeTargets { int images_num; /* Lookup table from Material number to BakeImage. */ - int *material_to_image; + struct Image **material_to_image; int materials_num; /* Pixel buffer to bake to. */ @@ -104,7 +106,8 @@ void RE_bake_margin(struct ImBuf *ibuf, int margin, char margin_type, struct Mesh const *me, - char const *uv_layer); + char const *uv_layer, + const float uv_offset[2]); void RE_bake_normal_world_to_object(const BakePixel pixel_array[], size_t pixels_num, diff --git a/source/blender/render/RE_texture_margin.h b/source/blender/render/RE_texture_margin.h index 85bd06b9940..0c91abeaddd 100644 --- a/source/blender/render/RE_texture_margin.h +++ b/source/blender/render/RE_texture_margin.h @@ -25,13 +25,18 @@ struct Mesh; * \param me: the mesh to use the polygons of. * \param uv_layer: The UV layer to use. */ -void RE_generate_texturemargin_adjacentfaces( - struct ImBuf *ibuf, char *mask, const int margin, struct Mesh const *me, char const *uv_layer); +void RE_generate_texturemargin_adjacentfaces(struct ImBuf *ibuf, + char *mask, + const int margin, + struct Mesh const *me, + char const *uv_layer, + const float uv_offset[2]); void RE_generate_texturemargin_adjacentfaces_dm(struct ImBuf *ibuf, char *mask, const int margin, - struct DerivedMesh *dm); + struct DerivedMesh *dm, + const float uv_offset[2]); #ifdef __cplusplus } diff --git a/source/blender/render/intern/bake.c b/source/blender/render/intern/bake.c index 69235fb6cb1..5953c0f0f8f 100644 --- a/source/blender/render/intern/bake.c +++ b/source/blender/render/intern/bake.c @@ -146,12 +146,13 @@ void RE_bake_margin(ImBuf *ibuf, const int margin, const char margin_type, Mesh const *me, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { /* margin */ switch (margin_type) { case R_BAKE_ADJACENT_FACES: - RE_generate_texturemargin_adjacentfaces(ibuf, mask, margin, me, uv_layer); + RE_generate_texturemargin_adjacentfaces(ibuf, mask, margin, me, uv_layer, uv_offset); break; default: /* fall through */ @@ -746,30 +747,36 @@ void RE_bake_pixels_populate(Mesh *me, for (int i = 0; i < tottri; i++) { const MLoopTri *lt = &looptri[i]; const MPoly *mp = &me->mpoly[lt->poly]; - float vec[3][2]; - int mat_nr = mp->mat_nr; - int image_id = targets->material_to_image[mat_nr]; - if (image_id < 0) { - continue; - } - - bd.bk_image = &targets->images[image_id]; bd.primitive_id = i; - for (int a = 0; a < 3; a++) { - const float *uv = mloopuv[lt->tri[a]].uv; + /* Find images matching this material. */ + Image *image = targets->material_to_image[mp->mat_nr]; + for (int image_id = 0; image_id < targets->images_num; image_id++) { + BakeImage *bk_image = &targets->images[image_id]; + if (bk_image->image != image) { + continue; + } - /* NOTE(campbell): workaround for pixel aligned UVs which are common and can screw up our - * intersection tests where a pixel gets in between 2 faces or the middle of a quad, - * camera aligned quads also have this problem but they are less common. - * Add a small offset to the UVs, fixes bug T18685. */ - vec[a][0] = uv[0] * (float)bd.bk_image->width - (0.5f + 0.001f); - vec[a][1] = uv[1] * (float)bd.bk_image->height - (0.5f + 0.002f); - } + /* Compute triangle vertex UV coordinates. */ + float vec[3][2]; + for (int a = 0; a < 3; a++) { + const float *uv = mloopuv[lt->tri[a]].uv; + + /* NOTE(campbell): workaround for pixel aligned UVs which are common and can screw up our + * intersection tests where a pixel gets in between 2 faces or the middle of a quad, + * camera aligned quads also have this problem but they are less common. + * Add a small offset to the UVs, fixes bug T18685. */ + vec[a][0] = (uv[0] - bk_image->uv_offset[0]) * (float)bk_image->width - (0.5f + 0.001f); + vec[a][1] = (uv[1] - bk_image->uv_offset[1]) * (float)bk_image->height - (0.5f + 0.002f); + } - bake_differentials(&bd, vec[0], vec[1], vec[2]); - zspan_scanconvert(&bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel); + /* Rasterize triangle. */ + bd.bk_image = bk_image; + bake_differentials(&bd, vec[0], vec[1], vec[2]); + zspan_scanconvert( + &bd.zspan[image_id], (void *)&bd, vec[0], vec[1], vec[2], store_bake_pixel); + } } for (int i = 0; i < targets->images_num; i++) { diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c index 33d961c027d..f93397eedab 100644 --- a/source/blender/render/intern/multires_bake.c +++ b/source/blender/render/intern/multires_bake.c @@ -51,7 +51,7 @@ typedef void (*MPassKnownData)(DerivedMesh *lores_dm, const int x, const int y); -typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, Image *ima); +typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, ImBuf *ibuf); typedef void (*MFreeBakeData)(void *bake_data); typedef struct MultiresBakeResult { @@ -64,6 +64,7 @@ typedef struct { MPoly *mpoly; MLoop *mloop; MLoopUV *mloopuv; + float uv_offset[2]; const MLoopTri *mlooptri; float *pvtangent; const float (*precomputed_normals)[3]; @@ -91,7 +92,6 @@ typedef struct { typedef struct { float *heights; - Image *ima; DerivedMesh *ssdm; const int *orig_index_mp_to_orig; } MHeightBakeData; @@ -148,7 +148,8 @@ static void init_bake_rast(MBakeRast *bake_rast, static void flush_pixel(const MResolvePixelData *data, const int x, const int y) { - const float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h}; + const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0], + (y + 0.5f) / data->h + data->uv_offset[1]}; const float *st0, *st1, *st2; const float *tang0, *tang1, *tang2; float no0[3], no1[3], no2[3]; @@ -395,8 +396,12 @@ static void *do_multires_bake_thread(void *data_v) data->tri_index = tri_index; - bake_rasterize( - bake_rast, mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[2]].uv); + float uv[3][2]; + sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset); + sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]].uv, data->uv_offset); + sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]].uv, data->uv_offset); + + bake_rasterize(bake_rast, uv[0], uv[1], uv[2]); /* tag image buffer for refresh */ if (data->ibuf->rect_float) { @@ -447,6 +452,8 @@ static void init_ccgdm_arrays(DerivedMesh *dm) static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, + ImageTile *tile, + ImBuf *ibuf, bool require_tangent, MPassKnownData passKnownData, MInitBakeData initBakeData, @@ -462,7 +469,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, MultiresBakeThread *handles; MultiresBakeQueue queue; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); MVert *mvert = dm->getVertArray(dm); MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); @@ -511,7 +517,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, /* all threads shares the same custom bake data */ if (initBakeData) { - bake_data = initBakeData(bkr, ima); + bake_data = initBakeData(bkr, ibuf); } if (tot_thread > 1) { @@ -539,6 +545,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, handle->data.mvert = mvert; handle->data.vert_normals = vert_normals; handle->data.mloopuv = mloopuv; + BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); handle->data.mlooptri = mlooptri; handle->data.mloop = mloop; handle->data.pvtangent = pvtangent; @@ -590,8 +597,6 @@ static void do_multires_bake(MultiresBakeRender *bkr, MEM_freeN(handles); BKE_id_free(NULL, temp_mesh); - - BKE_image_release_ibuf(ima, ibuf, NULL); } } @@ -758,10 +763,9 @@ static void interp_barycentric_mlooptri(DerivedMesh *dm, /* **************** Displacement Baker **************** */ -static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) +static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf) { MHeightBakeData *height_data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); DerivedMesh *lodm = bkr->lores_dm; BakeImBufuserData *userdata = ibuf->userdata; @@ -772,7 +776,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); - height_data->ima = ima; height_data->heights = userdata->displacement_buffer; if (!bkr->use_lores_mesh) { @@ -794,8 +797,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); - BKE_image_release_ibuf(ima, ibuf, NULL); - return (void *)height_data; } @@ -903,7 +904,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, /* **************** Normal Maps Baker **************** */ -static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) { MNormalBakeData *normal_data; DerivedMesh *lodm = bkr->lores_dm; @@ -1099,7 +1100,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RE_rayobject_done(raytree); } -static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) { MAOBakeData *ao_data; DerivedMesh *lodm = bkr->lores_dm; @@ -1313,8 +1314,12 @@ static void apply_ao_callback(DerivedMesh *lores_dm, /* ******$***************** Post processing ************************* */ -static void bake_ibuf_filter( - ImBuf *ibuf, char *mask, const int margin, const char margin_type, DerivedMesh *dm) +static void bake_ibuf_filter(ImBuf *ibuf, + char *mask, + const int margin, + const char margin_type, + DerivedMesh *dm, + const float uv_offset[2]) { /* must check before filtering */ const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf); @@ -1322,7 +1327,7 @@ static void bake_ibuf_filter( if (margin) { switch (margin_type) { case R_BAKE_ADJACENT_FACES: - RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm); + RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm, uv_offset); break; default: /* fall through */ @@ -1427,38 +1432,54 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (ibuf->x > 0 && ibuf->y > 0) { - BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), - "MultiresBake userdata"); - userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); - ibuf->userdata = userdata; - - switch (bkr->mode) { - case RE_BAKE_NORMALS: - do_multires_bake( - bkr, ima, true, apply_tangmat_callback, init_normal_data, free_normal_data, result); - break; - case RE_BAKE_DISPLACEMENT: - do_multires_bake(bkr, - ima, - false, - apply_heights_callback, - init_heights_data, - free_heights_data, - result); - break; -/* TODO: restore ambient occlusion baking support. */ + + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; + + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + + if (ibuf->x > 0 && ibuf->y > 0) { + BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), + "MultiresBake userdata"); + userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); + ibuf->userdata = userdata; + + switch (bkr->mode) { + case RE_BAKE_NORMALS: + do_multires_bake(bkr, + ima, + tile, + ibuf, + true, + apply_tangmat_callback, + init_normal_data, + free_normal_data, + result); + break; + case RE_BAKE_DISPLACEMENT: + do_multires_bake(bkr, + ima, + tile, + ibuf, + false, + apply_heights_callback, + init_heights_data, + free_heights_data, + result); + break; + /* TODO: restore ambient occlusion baking support. */ #if 0 - case RE_BAKE_AO: - do_multires_bake(bkr, ima, false, apply_ao_callback, init_ao_data, free_ao_data, result); - break; + case RE_BAKE_AO: + do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result); + break; #endif + } } - } - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_release_ibuf(ima, ibuf, NULL); + } ima->id.tag |= LIB_TAG_DOIT; } @@ -1471,48 +1492,62 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) for (link = bkr->image.first; link; link = link->next) { Image *ima = (Image *)link->data; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; - if (ibuf->x <= 0 || ibuf->y <= 0) { - continue; - } + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + ImageUser iuser; + BKE_imageuser_default(&iuser); + iuser.tile = tile->tile_number; - if (use_displacement_buffer) { - bake_ibuf_normalize_displacement(ibuf, - userdata->displacement_buffer, - userdata->mask_buffer, - result->height_min, - result->height_max); - } + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; - bake_ibuf_filter( - ibuf, userdata->mask_buffer, bkr->bake_margin, bkr->bake_margin_type, bkr->lores_dm); + if (ibuf->x <= 0 || ibuf->y <= 0) { + continue; + } - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - BKE_image_mark_dirty(ima, ibuf); + if (use_displacement_buffer) { + bake_ibuf_normalize_displacement(ibuf, + userdata->displacement_buffer, + userdata->mask_buffer, + result->height_min, + result->height_max); + } - if (ibuf->rect_float) { - ibuf->userflags |= IB_RECT_INVALID; - } + float uv_offset[2]; + BKE_image_get_tile_uv(ima, tile->tile_number, uv_offset); - if (ibuf->mipmap[0]) { - ibuf->userflags |= IB_MIPMAP_INVALID; - imb_freemipmapImBuf(ibuf); - } + bake_ibuf_filter(ibuf, + userdata->mask_buffer, + bkr->bake_margin, + bkr->bake_margin_type, + bkr->lores_dm, + uv_offset); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + BKE_image_mark_dirty(ima, ibuf); - if (ibuf->userdata) { - if (userdata->displacement_buffer) { - MEM_freeN(userdata->displacement_buffer); + if (ibuf->rect_float) { + ibuf->userflags |= IB_RECT_INVALID; } - MEM_freeN(userdata->mask_buffer); - MEM_freeN(userdata); - ibuf->userdata = NULL; - } + if (ibuf->mipmap[0]) { + ibuf->userflags |= IB_MIPMAP_INVALID; + imb_freemipmapImBuf(ibuf); + } + + if (ibuf->userdata) { + if (userdata->displacement_buffer) { + MEM_freeN(userdata->displacement_buffer); + } - BKE_image_release_ibuf(ima, ibuf, NULL); - DEG_id_tag_update(&ima->id, 0); + MEM_freeN(userdata->mask_buffer); + MEM_freeN(userdata); + ibuf->userdata = NULL; + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + DEG_id_tag_update(&ima->id, 0); + } } } diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index d01c0dbea71..2d68148a86a 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -46,6 +46,7 @@ class TextureMarginMap { Vector<int> loop_to_poly_map_; int w_, h_; + float uv_offset_[2]; Vector<uint32_t> pixel_data_; ZSpan zspan_; uint32_t value_to_store_; @@ -61,6 +62,7 @@ class TextureMarginMap { public: TextureMarginMap(size_t w, size_t h, + const float uv_offset[2], MPoly const *mpoly, MLoop const *mloop, MLoopUV const *mloopuv, @@ -76,6 +78,8 @@ class TextureMarginMap { totloop_(totloop), totedge_(totedge) { + copy_v2_v2(uv_offset_, uv_offset); + pixel_data_.resize(w_ * h_, 0xFFFFFFFF); zbuf_alloc_span(&zspan_, w_, h_); @@ -277,8 +281,8 @@ class TextureMarginMap { float2 uv_to_xy(MLoopUV const &mloopuv) const { float2 ret; - ret.x = ((mloopuv.uv[0] * w_) - (0.5f + 0.001f)); - ret.y = ((mloopuv.uv[1] * h_) - (0.5f + 0.001f)); + ret.x = (((mloopuv.uv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f)); + ret.y = (((mloopuv.uv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f)); return ret; } @@ -482,7 +486,8 @@ static void generate_margin(ImBuf *ibuf, const int margin, const Mesh *me, DerivedMesh *dm, - char const *uv_layer) + char const *uv_layer, + const float uv_offset[2]) { MPoly *mpoly; @@ -531,7 +536,8 @@ static void generate_margin(ImBuf *ibuf, tottri = dm->getNumLoopTri(dm); } - TextureMarginMap map(ibuf->x, ibuf->y, mpoly, mloop, mloopuv, totpoly, totloop, totedge); + TextureMarginMap map( + ibuf->x, ibuf->y, uv_offset, mpoly, mloop, mloopuv, totpoly, totloop, totedge); bool draw_new_mask = false; /* Now the map contains 3 sorts of values: 0xFFFFFFFF for empty pixels, `0x80000000 + polyindex` @@ -555,8 +561,8 @@ static void generate_margin(ImBuf *ibuf, * intersection tests where a pixel gets in between 2 faces or the middle of a quad, * camera aligned quads also have this problem but they are less common. * Add a small offset to the UVs, fixes bug T18685. */ - vec[a][0] = uv[0] * (float)ibuf->x - (0.5f + 0.001f); - vec[a][1] = uv[1] * (float)ibuf->y - (0.5f + 0.002f); + vec[a][0] = (uv[0] - uv_offset[0]) * (float)ibuf->x - (0.5f + 0.001f); + vec[a][1] = (uv[1] - uv_offset[1]) * (float)ibuf->y - (0.5f + 0.002f); } /* NOTE: we need the top bit for the dijkstra distance map. */ @@ -592,16 +598,20 @@ static void generate_margin(ImBuf *ibuf, } // namespace blender::render::texturemargin -void RE_generate_texturemargin_adjacentfaces( - ImBuf *ibuf, char *mask, const int margin, const Mesh *me, char const *uv_layer) +void RE_generate_texturemargin_adjacentfaces(ImBuf *ibuf, + char *mask, + const int margin, + const Mesh *me, + char const *uv_layer, + const float uv_offset[2]) { - blender::render::texturemargin::generate_margin(ibuf, mask, margin, me, nullptr, uv_layer); + blender::render::texturemargin::generate_margin( + ibuf, mask, margin, me, nullptr, uv_layer, uv_offset); } -void RE_generate_texturemargin_adjacentfaces_dm(ImBuf *ibuf, - char *mask, - const int margin, - DerivedMesh *dm) +void RE_generate_texturemargin_adjacentfaces_dm( + ImBuf *ibuf, char *mask, const int margin, DerivedMesh *dm, const float uv_offset[2]) { - blender::render::texturemargin::generate_margin(ibuf, mask, margin, nullptr, dm, nullptr); + blender::render::texturemargin::generate_margin( + ibuf, mask, margin, nullptr, dm, nullptr, uv_offset); } diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index bb313d4962c..8ba3bac7cad 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -277,11 +277,12 @@ static void pointdensity_cache_vertex_color(PointDensity *pd, BLI_assert(data_color); - if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPCOL)) { + if (!CustomData_has_layer(&mesh->ldata, CD_PROP_BYTE_COLOR)) { return; } - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPCOL, pd->vertex_attribute_name, layername); - mcol = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, layername); + CustomData_validate_layer_name( + &mesh->ldata, CD_PROP_BYTE_COLOR, pd->vertex_attribute_name, layername); + mcol = CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, layername); if (!mcol) { return; } @@ -372,7 +373,7 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) mask.fmask |= CD_MASK_MTFACE | CD_MASK_MCOL; switch (pd->ob_color_source) { case TEX_PD_COLOR_VERTCOL: - mask.lmask |= CD_MASK_MLOOPCOL; + mask.lmask |= CD_MASK_PROP_BYTE_COLOR; break; case TEX_PD_COLOR_VERTWEIGHT: mask.vmask |= CD_MASK_MDEFORMVERT; diff --git a/source/blender/sequencer/SEQ_channels.h b/source/blender/sequencer/SEQ_channels.h index 1d87875fb26..9436d5dfa32 100644 --- a/source/blender/sequencer/SEQ_channels.h +++ b/source/blender/sequencer/SEQ_channels.h @@ -15,6 +15,7 @@ struct Editing; struct ListBase; struct Scene; struct SeqTimelineChannel; +struct Sequence; struct ListBase *SEQ_channels_displayed_get(struct Editing *ed); void SEQ_channels_displayed_set(struct Editing *ed, struct ListBase *channels); @@ -28,6 +29,7 @@ char *SEQ_channel_name_get(struct ListBase *channels, const int channel_index); bool SEQ_channel_is_locked(const struct SeqTimelineChannel *channel); bool SEQ_channel_is_muted(const struct SeqTimelineChannel *channel); int SEQ_channel_index_get(const struct SeqTimelineChannel *channel); +ListBase *SEQ_get_channels_by_seq(struct ListBase *seqbase, const struct Sequence *seq); #ifdef __cplusplus } diff --git a/source/blender/sequencer/SEQ_relations.h b/source/blender/sequencer/SEQ_relations.h index 735b5659ca9..917f549f16d 100644 --- a/source/blender/sequencer/SEQ_relations.h +++ b/source/blender/sequencer/SEQ_relations.h @@ -19,6 +19,10 @@ struct Scene; struct Sequence; /** + * Check if one sequence is input to the other. + */ +bool SEQ_relation_is_effect_of_strip(const struct Sequence *effect, const struct Sequence *input); +/** * Function to free imbuf and anim data on changes. */ void SEQ_relations_sequence_free_anim(struct Sequence *seq); @@ -64,6 +68,7 @@ void SEQ_cache_iterate( struct Sequence *SEQ_find_metastrip_by_sequence(ListBase *seqbase /* = ed->seqbase */, struct Sequence *meta /* = NULL */, struct Sequence *seq); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/SEQ_render.h b/source/blender/sequencer/SEQ_render.h index bfe10d3eae9..a74eba5fc6f 100644 --- a/source/blender/sequencer/SEQ_render.h +++ b/source/blender/sequencer/SEQ_render.h @@ -17,6 +17,7 @@ struct ListBase; struct Main; struct Scene; struct Sequence; +struct rctf; typedef enum eSeqTaskId { SEQ_TASK_MAIN_RENDER, @@ -64,7 +65,6 @@ struct ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, void SEQ_render_thumbnails(const struct SeqRenderData *context, struct Sequence *seq, struct Sequence *seq_orig, - float start_frame, float frame_step, rctf *view_area, const short *stop); @@ -77,6 +77,18 @@ struct ImBuf *SEQ_get_thumbnail(const struct SeqRenderData *context, rcti *crop, bool clipped); /** + * Get frame for first thumbnail. + */ +float SEQ_render_thumbnail_first_frame_get(struct Sequence *seq, + float frame_step, + struct rctf *view_area); +/** + * Get frame for first thumbnail. + */ +float SEQ_render_thumbnail_next_frame_get(struct Sequence *seq, + float last_frame, + float frame_step); +/** * Get frame step for equally spaced thumbnails. These thumbnails should always be present in * memory, so they can be used when zooming. */ diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index eb910a5a5d1..a342dfe10a2 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -119,6 +119,22 @@ void SEQ_image_preview_unit_from_px(const struct Scene *scene, const float co_src[2], float co_dst[2]); +/** + * Get viewport axis aligned bounding box from a collection of sequences. + * The collection must have one or more strips + * + * \param scene: Scene in which strips are located + * \param strips: Collection of strips to get the bounding box from + * \param apply_rotation: Include sequence rotation transform in the bounding box calculation + * \param r_min: Minimum x and y values + * \param r_max: Maximum x and y values + */ +void SEQ_image_transform_bounding_box_from_collection(struct Scene *scene, + struct SeqCollection *strips, + bool apply_rotation, + float r_min[2], + float r_max[2]); + #ifdef __cplusplus } #endif diff --git a/source/blender/sequencer/intern/channels.c b/source/blender/sequencer/intern/channels.c index e8e82af03f5..21e3461c7d0 100644 --- a/source/blender/sequencer/intern/channels.c +++ b/source/blender/sequencer/intern/channels.c @@ -81,3 +81,19 @@ bool SEQ_channel_is_muted(const SeqTimelineChannel *channel) { return (channel->flag & SEQ_CHANNEL_MUTE) != 0; } + +ListBase *SEQ_get_channels_by_seq(ListBase *seqbase, const Sequence *seq) +{ + ListBase *lb = NULL; + + LISTBASE_FOREACH (Sequence *, iseq, seqbase) { + if (seq == iseq) { + return seqbase; + } + if ((lb = SEQ_get_channels_by_seq(&iseq->seqbase, seq))) { + return lb; + } + } + + return NULL; +} diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index 0192f4f625c..f4fc79a6572 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -44,6 +44,7 @@ #include "RE_pipeline.h" +#include "SEQ_channels.h" #include "SEQ_effects.h" #include "SEQ_proxy.h" #include "SEQ_relations.h" @@ -2421,8 +2422,6 @@ static ImBuf *do_multicam(const SeqRenderData *context, { ImBuf *out; Editing *ed; - ListBase *seqbasep; - ListBase *channels = &seq->channels; if (seq->multicam_source == 0 || seq->multicam_source >= seq->machine) { return NULL; @@ -2432,7 +2431,8 @@ static ImBuf *do_multicam(const SeqRenderData *context, if (!ed) { return NULL; } - seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, seq); if (!seqbasep) { return NULL; } @@ -2463,13 +2463,12 @@ static int early_out_adjustment(Sequence *UNUSED(seq), float UNUSED(fac)) static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, float timeline_frame) { Editing *ed; - ListBase *seqbasep; - ListBase *channels = &seq->channels; ImBuf *i = NULL; ed = context->scene->ed; - seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *seqbasep = SEQ_get_seqbase_by_seq(&ed->seqbase, seq); + ListBase *channels = SEQ_get_channels_by_seq(&ed->seqbase, seq); /* Clamp timeline_frame to strip range so it behaves as if it had "still frame" offset (last * frame is static after end of strip). This is how most strips behave. This way transition diff --git a/source/blender/sequencer/intern/iterator.c b/source/blender/sequencer/intern/iterator.c index a4d8cf79d1f..2710edd6e80 100644 --- a/source/blender/sequencer/intern/iterator.c +++ b/source/blender/sequencer/intern/iterator.c @@ -20,6 +20,7 @@ #include "BKE_scene.h" #include "SEQ_iterator.h" +#include "SEQ_relations.h" #include "SEQ_render.h" #include "SEQ_time.h" #include "render.h" @@ -241,15 +242,6 @@ static void collection_filter_channel_up_to_incl(SeqCollection *collection, cons } } -static bool seq_is_effect_of(const Sequence *seq_effect, const Sequence *possibly_input) -{ - if (seq_effect->seq1 == possibly_input || seq_effect->seq2 == possibly_input || - seq_effect->seq3 == possibly_input) { - return true; - } - return false; -} - /* Check if seq must be rendered. This depends on whole stack in some cases, not only seq itself. * Order of applying these conditions is important. */ static bool must_render_strip(const Sequence *seq, SeqCollection *strips_at_timeline_frame) @@ -262,7 +254,8 @@ static bool must_render_strip(const Sequence *seq, SeqCollection *strips_at_time return false; } - if ((seq_iter->type & SEQ_TYPE_EFFECT) != 0 && seq_is_effect_of(seq_iter, seq)) { + if ((seq_iter->type & SEQ_TYPE_EFFECT) != 0 && + SEQ_relation_is_effect_of_strip(seq_iter, seq)) { /* Strips in same channel or higher than its effect are rendered. */ if (seq->machine >= seq_iter->machine) { return true; diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 18b0794dc72..8d8a13be09e 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -1992,6 +1992,32 @@ ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, return ibuf; } +float SEQ_render_thumbnail_first_frame_get(Sequence *seq, float frame_step, rctf *view_area) +{ + int first_drawable_frame = max_iii(seq->startdisp, seq->start, view_area->xmin); + + /* First frame should correspond to handle position. */ + if (first_drawable_frame == seq->startdisp) { + return seq->startdisp; + } + + float aligned_frame_offset = (int)((first_drawable_frame - seq->start) / frame_step) * + frame_step; + return seq->start + aligned_frame_offset; +} + +float SEQ_render_thumbnail_next_frame_get(Sequence *seq, float last_frame, float frame_step) +{ + float next_frame = last_frame + frame_step; + + /* If handle position was displayed, align next frame with `seq->start`. */ + if (last_frame == seq->startdisp) { + next_frame = seq->start + ((int)((last_frame - seq->start) / frame_step) + 1) * frame_step; + } + + return next_frame; +} + /* Gets the direct image from source and scales to thumbnail size. */ static ImBuf *seq_get_uncached_thumbnail(const SeqRenderData *context, SeqRenderState *state, @@ -2053,7 +2079,6 @@ ImBuf *SEQ_get_thumbnail( void SEQ_render_thumbnails(const SeqRenderData *context, Sequence *seq, Sequence *seq_orig, - float start_frame, float frame_step, rctf *view_area, const short *stop) @@ -2063,24 +2088,24 @@ void SEQ_render_thumbnails(const SeqRenderData *context, /* Adding the hold offset value (seq->anim_startofs) to the start frame. Position of image not * affected, but frame loaded affected. */ - start_frame = start_frame - frame_step; float upper_thumb_bound = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp; upper_thumb_bound = (upper_thumb_bound > view_area->xmax) ? view_area->xmax + frame_step : upper_thumb_bound; - while ((start_frame < upper_thumb_bound) & !*stop) { + float timeline_frame = SEQ_render_thumbnail_first_frame_get(seq, frame_step, view_area); + while ((timeline_frame < upper_thumb_bound) & !*stop) { ImBuf *ibuf = seq_cache_get( - context, seq_orig, round_fl_to_int(start_frame), SEQ_CACHE_STORE_THUMBNAIL); + context, seq_orig, round_fl_to_int(timeline_frame), SEQ_CACHE_STORE_THUMBNAIL); if (ibuf) { IMB_freeImBuf(ibuf); - start_frame += frame_step; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); continue; } - ibuf = seq_get_uncached_thumbnail(context, &state, seq, round_fl_to_int(start_frame)); + ibuf = seq_get_uncached_thumbnail(context, &state, seq, round_fl_to_int(timeline_frame)); if (ibuf) { - seq_cache_thumbnail_put(context, seq_orig, round_fl_to_int(start_frame), ibuf, view_area); + seq_cache_thumbnail_put(context, seq_orig, round_fl_to_int(timeline_frame), ibuf, view_area); IMB_freeImBuf(ibuf); seq_orig->flag &= ~SEQ_FLAG_SKIP_THUMBNAILS; } @@ -2090,7 +2115,7 @@ void SEQ_render_thumbnails(const SeqRenderData *context, return; } - start_frame += frame_step; + timeline_frame = SEQ_render_thumbnail_next_frame_get(seq, timeline_frame, frame_step); } } diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 7aa81f5ae8a..6c7bb71cb75 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -154,8 +154,7 @@ static void sequencer_flag_users_for_removal(Scene *scene, ListBase *seqbase, Se } /* Remove effects, that use seq. */ - if ((user_seq->seq1 && user_seq->seq1 == seq) || (user_seq->seq2 && user_seq->seq2 == seq) || - (user_seq->seq3 && user_seq->seq3 == seq)) { + if (SEQ_relation_is_effect_of_strip(user_seq, seq)) { user_seq->flag |= SEQ_FLAG_DELETE; /* Strips can be used as mask even if not in same seqbase. */ sequencer_flag_users_for_removal(scene, &scene->ed->seqbase, user_seq); diff --git a/source/blender/sequencer/intern/strip_relations.c b/source/blender/sequencer/intern/strip_relations.c index a65a331c650..1899cc99263 100644 --- a/source/blender/sequencer/intern/strip_relations.c +++ b/source/blender/sequencer/intern/strip_relations.c @@ -34,10 +34,15 @@ #include "image_cache.h" #include "utils.h" +bool SEQ_relation_is_effect_of_strip(const Sequence *effect, const Sequence *input) +{ + return ELEM(input, effect->seq1, effect->seq2); +} + /* check whether sequence cur depends on seq */ static bool seq_relations_check_depend(Sequence *seq, Sequence *cur) { - if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq) { + if (SEQ_relation_is_effect_of_strip(cur, seq)) { return true; } diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 087e2610bd6..2c9ab0a3335 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -297,6 +297,9 @@ static int shuffle_seq_time_offset_test(SeqCollection *strips_to_shuffle, if (!SEQ_transform_test_overlap_seq_seq(seq, seq_other)) { continue; } + if (SEQ_relation_is_effect_of_strip(seq_other, seq)) { + continue; + } if (UNLIKELY(SEQ_collection_has_strip(seq_other, strips_to_shuffle))) { CLOG_WARN(&LOG, "Strip overlaps with itself or another strip, that is to be shuffled. " @@ -517,3 +520,18 @@ void SEQ_image_preview_unit_from_px(const Scene *scene, const float co_src[2], f co_dst[0] = co_src[0] / scene->r.xsch; co_dst[1] = co_src[1] / scene->r.ysch; } + +void SEQ_image_transform_bounding_box_from_collection( + Scene *scene, SeqCollection *strips, bool apply_rotation, float r_min[2], float r_max[2]) +{ + Sequence *seq; + + INIT_MINMAX2(r_min, r_max); + SEQ_ITERATOR_FOREACH (seq, strips) { + float quad[4][2]; + SEQ_image_transform_quad_get(scene, seq, apply_rotation, quad); + for (int i = 0; i < 4; i++) { + minmax_v2v2_v2(r_min, r_max, quad[i]); + } + } +} diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h index ef6bee0c1fe..992c7a9b2ec 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_intern.h @@ -124,7 +124,7 @@ struct wmGizmoMap { /** * This is a container for all gizmo types that can be instantiated in a region. - * (similar to dropboxes). + * (similar to drop-boxes). * * \note There is only ever one of these for every (area, region) combination. */ diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index d17afad0918..7457358698d 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -896,16 +896,32 @@ elseif(WIN32) endif() if(WITH_CODEC_FFMPEG) - install( - FILES - ${LIBDIR}/ffmpeg/lib/avcodec-58.dll - ${LIBDIR}/ffmpeg/lib/avformat-58.dll - ${LIBDIR}/ffmpeg/lib/avdevice-58.dll - ${LIBDIR}/ffmpeg/lib/avutil-56.dll - ${LIBDIR}/ffmpeg/lib/swscale-5.dll - ${LIBDIR}/ffmpeg/lib/swresample-3.dll - DESTINATION "." - ) + # Filenames change slightly between ffmpeg versions + # check both 5.0 and fallback to 4.4 to ease the transition + # between versions. + if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-59.dll") + install( + FILES + ${LIBDIR}/ffmpeg/lib/avcodec-59.dll + ${LIBDIR}/ffmpeg/lib/avformat-59.dll + ${LIBDIR}/ffmpeg/lib/avdevice-59.dll + ${LIBDIR}/ffmpeg/lib/avutil-57.dll + ${LIBDIR}/ffmpeg/lib/swscale-6.dll + ${LIBDIR}/ffmpeg/lib/swresample-4.dll + DESTINATION "." + ) + else() + install( + FILES + ${LIBDIR}/ffmpeg/lib/avcodec-58.dll + ${LIBDIR}/ffmpeg/lib/avformat-58.dll + ${LIBDIR}/ffmpeg/lib/avdevice-58.dll + ${LIBDIR}/ffmpeg/lib/avutil-56.dll + ${LIBDIR}/ffmpeg/lib/swscale-5.dll + ${LIBDIR}/ffmpeg/lib/swresample-3.dll + DESTINATION "." + ) + endif() endif() if(WITH_TBB) install( diff --git a/source/tools b/source/tools -Subproject 4c1e01e3e309282beb1af3b1eddb2c7f9a666b5 +Subproject 1e658ca996f11e5ff3398d89bd81f5b719304a5 diff --git a/tests/performance/benchmark b/tests/performance/benchmark index 80556674dcc..28e8cda5098 100755 --- a/tests/performance/benchmark +++ b/tests/performance/benchmark @@ -11,24 +11,30 @@ import sys import time from typing import List + def find_blender_git_dir() -> pathlib.Path: # Find .git directory of the repository we are in. cwd = pathlib.Path.cwd() for path in [cwd] + list(cwd.parents): if (path / '.git').exists(): - return path + return path return None + def get_tests_base_dir(blender_git_dir: pathlib.Path) -> pathlib.Path: # Benchmarks dir is next to the Blender source folder. return blender_git_dir.parent / 'benchmark' + def use_revision_columns(config: api.TestConfig) -> bool: - return config.benchmark_type == "comparison" and \ - len(config.queue.entries) > 0 and \ - not config.queue.has_multiple_revisions_to_build + return ( + config.benchmark_type == "comparison" and + len(config.queue.entries) > 0 and + not config.queue.has_multiple_revisions_to_build + ) + def print_header(config: api.TestConfig) -> None: # Print header with revision columns headers. @@ -42,6 +48,7 @@ def print_header(config: api.TestConfig) -> None: header += f"{revision_name: <20} " print(header) + def print_row(config: api.TestConfig, entries: List, end='\n') -> None: # Print one or more test entries on a row. row = "" @@ -79,10 +86,13 @@ def print_row(config: api.TestConfig, entries: List, end='\n') -> None: def match_entry(entry: api.TestEntry, args: argparse.Namespace): # Filter tests by name and category. - return fnmatch.fnmatch(entry.test, args.test) or \ - fnmatch.fnmatch(entry.category, args.test) or \ - entry.test.find(args.test) != -1 or \ - entry.category.find(args.test) != -1 + return ( + fnmatch.fnmatch(entry.test, args.test) or + fnmatch.fnmatch(entry.category, args.test) or + entry.test.find(args.test) != -1 or + entry.category.find(args.test) != -1 + ) + def run_entry(env: api.TestEnvironment, config: api.TestConfig, @@ -159,6 +169,7 @@ def run_entry(env: api.TestEnvironment, return True + def cmd_init(env: api.TestEnvironment, argv: List): # Initialize benchmarks folder. parser = argparse.ArgumentParser() @@ -168,6 +179,7 @@ def cmd_init(env: api.TestEnvironment, argv: List): env.init(args.build) env.unset_log_file() + def cmd_list(env: api.TestEnvironment, argv: List) -> None: # List devices, tests and configurations. print('DEVICES') @@ -188,6 +200,7 @@ def cmd_list(env: api.TestEnvironment, argv: List) -> None: for config_name in configs: print(config_name) + def cmd_status(env: api.TestEnvironment, argv: List): # Print status of tests in configurations. parser = argparse.ArgumentParser() @@ -210,6 +223,7 @@ def cmd_status(env: api.TestEnvironment, argv: List): if match_entry(row[0], args): print_row(config, row) + def cmd_reset(env: api.TestEnvironment, argv: List): # Reset tests to re-run them. parser = argparse.ArgumentParser() @@ -232,6 +246,7 @@ def cmd_reset(env: api.TestEnvironment, argv: List): if args.test == '*': shutil.rmtree(config.logs_dir) + def cmd_run(env: api.TestEnvironment, argv: List, update_only: bool): # Run tests. parser = argparse.ArgumentParser() @@ -271,6 +286,7 @@ def cmd_run(env: api.TestEnvironment, argv: List, update_only: bool): print("\nfile://" + str(html_filepath)) + def cmd_graph(argv: List): # Create graph from a given JSON results file. parser = argparse.ArgumentParser() @@ -291,6 +307,7 @@ def cmd_graph(argv: List): graph = api.TestGraph(json_files) graph.write(pathlib.Path(args.output)) + def main(): usage = ('benchmark <command> [<args>]\n' '\n' @@ -316,9 +333,9 @@ def main(): argv = sys.argv[2:] blender_git_dir = find_blender_git_dir() - if blender_git_dir == None: - sys.stderr.write('Error: no blender git repository found from current working directory\n') - sys.exit(1) + if blender_git_dir is None: + sys.stderr.write('Error: no blender git repository found from current working directory\n') + sys.exit(1) if args.command == 'graph': cmd_graph(argv) @@ -349,5 +366,6 @@ def main(): else: sys.stderr.write(f'Unknown command: {args.command}\n') + if __name__ == '__main__': main() |