Merge branch 'master' into refactor-mesh-position-generic
This commit is contained in:
commit
fd395c9a0a
|
@ -26,13 +26,13 @@ set(SBOMCONTENTS)
|
|||
get_cmake_property(_variableNames VARIABLES)
|
||||
foreach (_variableName ${_variableNames})
|
||||
if(_variableName MATCHES "CPE$")
|
||||
string(REPLACE ":" ";" CPE_LIST ${${_variableName}})
|
||||
string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName})
|
||||
list(GET CPE_LIST 3 CPE_VENDOR)
|
||||
list(GET CPE_LIST 4 CPE_NAME)
|
||||
list(GET CPE_LIST 5 CPE_VERSION)
|
||||
set(${CPE_DEPNAME} "${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}")
|
||||
set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION},,,\n")
|
||||
string(REPLACE ":" ";" CPE_LIST ${${_variableName}})
|
||||
string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName})
|
||||
list(GET CPE_LIST 3 CPE_VENDOR)
|
||||
list(GET CPE_LIST 4 CPE_NAME)
|
||||
list(GET CPE_LIST 5 CPE_VERSION)
|
||||
set(${CPE_DEPNAME} "${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}")
|
||||
set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION},,,\n")
|
||||
endif()
|
||||
endforeach()
|
||||
configure_file(${CMAKE_SOURCE_DIR}/cmake/cve_check.csv.in ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv @ONLY)
|
||||
|
|
|
@ -32,12 +32,13 @@ function(download_source dep)
|
|||
message("Checking source : ${dep} (${TARGET_FILE})")
|
||||
if(NOT EXISTS ${TARGET_FILE})
|
||||
message("Checking source : ${dep} - source not found downloading from ${TARGET_URI}")
|
||||
file(DOWNLOAD ${TARGET_URI} ${TARGET_FILE}
|
||||
TIMEOUT 1800 # seconds
|
||||
EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH}
|
||||
TLS_VERIFY ON
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
file(
|
||||
DOWNLOAD ${TARGET_URI} ${TARGET_FILE}
|
||||
TIMEOUT 1800 # seconds
|
||||
EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH}
|
||||
TLS_VERIFY ON
|
||||
SHOW_PROGRESS
|
||||
)
|
||||
endif()
|
||||
if(EXISTS ${TARGET_FILE})
|
||||
# Sometimes the download fails, but that is not a
|
||||
|
|
|
@ -1,9 +1,55 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(FFMPEG_CFLAGS "-I${mingw_LIBDIR}/lame/include -I${mingw_LIBDIR}/openjpeg/include/ -I${mingw_LIBDIR}/ogg/include -I${mingw_LIBDIR}/vorbis/include -I${mingw_LIBDIR}/theora/include -I${mingw_LIBDIR}/opus/include -I${mingw_LIBDIR}/vpx/include -I${mingw_LIBDIR}/x264/include -I${mingw_LIBDIR}/xvidcore/include -I${mingw_LIBDIR}/zlib/include -I${mingw_LIBDIR}/aom/include")
|
||||
set(FFMPEG_LDFLAGS "-L${mingw_LIBDIR}/lame/lib -L${mingw_LIBDIR}/openjpeg/lib -L${mingw_LIBDIR}/ogg/lib -L${mingw_LIBDIR}/vorbis/lib -L${mingw_LIBDIR}/theora/lib -L${mingw_LIBDIR}/opus/lib -L${mingw_LIBDIR}/vpx/lib -L${mingw_LIBDIR}/x264/lib -L${mingw_LIBDIR}/xvidcore/lib -L${mingw_LIBDIR}/zlib/lib -L${mingw_LIBDIR}/aom/lib")
|
||||
set(FFMPEG_EXTRA_FLAGS --pkg-config-flags=--static --extra-cflags=${FFMPEG_CFLAGS} --extra-ldflags=${FFMPEG_LDFLAGS})
|
||||
set(FFMPEG_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/openjpeg/lib/pkgconfig:${mingw_LIBDIR}/x264/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}:${mingw_LIBDIR}/vpx/lib/pkgconfig:${mingw_LIBDIR}/theora/lib/pkgconfig:${mingw_LIBDIR}/openjpeg/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR}/aom/lib/pkgconfig:)
|
||||
if(WIN32)
|
||||
set(temp_LIBDIR ${mingw_LIBDIR})
|
||||
else()
|
||||
set(temp_LIBDIR ${LIBDIR})
|
||||
endif()
|
||||
|
||||
set(FFMPEG_CFLAGS "\
|
||||
-I${temp_LIBDIR}/lame/include \
|
||||
-I${temp_LIBDIR}/openjpeg/include/ \
|
||||
-I${temp_LIBDIR}/ogg/include \
|
||||
-I${temp_LIBDIR}/vorbis/include \
|
||||
-I${temp_LIBDIR}/theora/include \
|
||||
-I${temp_LIBDIR}/opus/include \
|
||||
-I${temp_LIBDIR}/vpx/include \
|
||||
-I${temp_LIBDIR}/x264/include \
|
||||
-I${temp_LIBDIR}/xvidcore/include \
|
||||
-I${temp_LIBDIR}/zlib/include \
|
||||
-I${temp_LIBDIR}/aom/include"
|
||||
)
|
||||
set(FFMPEG_LDFLAGS "\
|
||||
-L${temp_LIBDIR}/lame/lib \
|
||||
-L${temp_LIBDIR}/openjpeg/lib \
|
||||
-L${temp_LIBDIR}/ogg/lib \
|
||||
-L${temp_LIBDIR}/vorbis/lib \
|
||||
-L${temp_LIBDIR}/theora/lib \
|
||||
-L${temp_LIBDIR}/opus/lib \
|
||||
-L${temp_LIBDIR}/vpx/lib \
|
||||
-L${temp_LIBDIR}/x264/lib \
|
||||
-L${temp_LIBDIR}/xvidcore/lib \
|
||||
-L${temp_LIBDIR}/zlib/lib \
|
||||
-L${temp_LIBDIR}/aom/lib"
|
||||
)
|
||||
set(FFMPEG_EXTRA_FLAGS
|
||||
--pkg-config-flags=--static
|
||||
--extra-cflags=${FFMPEG_CFLAGS}
|
||||
--extra-ldflags=${FFMPEG_LDFLAGS}
|
||||
)
|
||||
set(FFMPEG_ENV "PKG_CONFIG_PATH=\
|
||||
${temp_LIBDIR}/openjpeg/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/x264/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/vorbis/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/ogg/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/vpx/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/theora/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/openjpeg/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/opus/lib/pkgconfig:\
|
||||
${temp_LIBDIR}/aom/lib/pkgconfig"
|
||||
)
|
||||
|
||||
unset(temp_LIBDIR)
|
||||
|
||||
if(WIN32)
|
||||
set(FFMPEG_ENV set ${FFMPEG_ENV} &&)
|
||||
|
|
|
@ -32,9 +32,10 @@ add_dependencies(
|
|||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_freetype after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype
|
||||
# harfbuzz *NEEDS* to find freetype.lib and will not be conviced to take alternative names so just give it
|
||||
# what it wants.
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/freetype/lib/freetype2st.lib ${LIBDIR}/freetype/lib/freetype.lib
|
||||
# harfbuzz *NEEDS* to find freetype.lib and will not be conviced to take alternative names so just give it
|
||||
# what it wants.
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/freetype/lib/freetype2st.lib ${LIBDIR}/freetype/lib/freetype.lib
|
||||
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -40,19 +40,21 @@ endif()
|
|||
|
||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_gmp after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include
|
||||
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
if(BUILD_MODE STREQUAL Debug AND WIN32)
|
||||
ExternalProject_Add_Step(external_gmp after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
ExternalProject_Add_Step(external_gmp after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def
|
||||
COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib
|
||||
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -5,7 +5,12 @@ if(WIN32)
|
|||
set(HARFBUZZ_PKG_ENV FREETYPE_DIR=${LIBDIR}/freetype)
|
||||
else()
|
||||
set(HARFBUZZ_CONFIGURE_ENV ${CONFIGURE_ENV})
|
||||
set(HARFBUZZ_PKG_ENV PKG_CONFIG_PATH=${LIBDIR}/freetype/lib/pkgconfig:${LIBDIR}/brotli/lib/pkgconfig:${LIBDIR}/lib/python3.10/pkgconfig:$PKG_CONFIG_PATH)
|
||||
set(HARFBUZZ_PKG_ENV "PKG_CONFIG_PATH=\
|
||||
${LIBDIR}/freetype/lib/pkgconfig:\
|
||||
${LIBDIR}/brotli/lib/pkgconfig:\
|
||||
${LIBDIR}/lib/python3.10/pkgconfig:\
|
||||
$PKG_CONFIG_PATH"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(HARFBUZZ_EXTRA_OPTIONS
|
||||
|
@ -23,8 +28,16 @@ ExternalProject_Add(external_harfbuzz
|
|||
URL_HASH ${HARFBUZZ_HASH_TYPE}=${HARFBUZZ_HASH}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
PREFIX ${BUILD_DIR}/harfbuzz
|
||||
|
||||
CONFIGURE_COMMAND ${HARFBUZZ_CONFIGURE_ENV} &&
|
||||
${CMAKE_COMMAND} -E env ${HARFBUZZ_PKG_ENV} ${MESON} setup --prefix ${LIBDIR}/harfbuzz ${HARFBUZZ_EXTRA_OPTIONS} --default-library static --libdir lib ${BUILD_DIR}/harfbuzz/src/external_harfbuzz-build ${BUILD_DIR}/harfbuzz/src/external_harfbuzz
|
||||
${CMAKE_COMMAND} -E env ${HARFBUZZ_PKG_ENV}
|
||||
${MESON} setup
|
||||
--prefix ${LIBDIR}/harfbuzz ${HARFBUZZ_EXTRA_OPTIONS}
|
||||
--default-library static
|
||||
--libdir lib
|
||||
${BUILD_DIR}/harfbuzz/src/external_harfbuzz-build
|
||||
${BUILD_DIR}/harfbuzz/src/external_harfbuzz
|
||||
|
||||
BUILD_COMMAND ninja
|
||||
INSTALL_COMMAND ninja install
|
||||
INSTALL_DIR ${LIBDIR}/harfbuzz
|
||||
|
@ -33,6 +46,7 @@ ExternalProject_Add(external_harfbuzz
|
|||
add_dependencies(
|
||||
external_harfbuzz
|
||||
external_python
|
||||
external_freetype
|
||||
# Needed for `MESON`.
|
||||
external_python_site_packages
|
||||
)
|
||||
|
@ -45,4 +59,3 @@ if(BUILD_MODE STREQUAL Release AND WIN32)
|
|||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -14,14 +14,14 @@ if(WIN32)
|
|||
if(BUILD_MODE STREQUAL Release)
|
||||
add_custom_target(Harvest_Release_Results
|
||||
COMMAND # jpeg rename libfile + copy 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/ &&
|
||||
# freeglut-> opengl
|
||||
${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/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/ &&
|
||||
# freeglut-> opengl
|
||||
${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ &&
|
||||
DEPENDS
|
||||
)
|
||||
endif()
|
||||
|
@ -271,7 +271,9 @@ harvest(zstd/lib zstd/lib "*.a")
|
|||
harvest(shaderc shaderc "*")
|
||||
harvest(vulkan_headers vulkan "*")
|
||||
harvest_rpath_lib(vulkan_loader/lib vulkan/lib "*${SHAREDLIBEXT}*")
|
||||
harvest(vulkan_loader/loader vulkan/loader "*")
|
||||
if(APPLE)
|
||||
harvest(vulkan_loader/loader vulkan/loader "*")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
harvest(libglu/lib mesa/lib "*${SHAREDLIBEXT}*")
|
||||
|
|
|
@ -34,21 +34,21 @@ elseif(UNIX)
|
|||
endif()
|
||||
|
||||
set(ISPC_EXTRA_ARGS
|
||||
-DISPC_NO_DUMPS=On
|
||||
-DISPC_INCLUDE_EXAMPLES=Off
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm
|
||||
-DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib
|
||||
-DCLANG_EXECUTABLE=${LIBDIR}/llvm/bin/clang
|
||||
-DCLANGPP_EXECUTABLE=${LIBDIR}/llvm/bin/clang++
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DCLANG_LIBRARY_DIR=${LIBDIR}/llvm/lib
|
||||
-DCLANG_INCLUDE_DIRS=${LIBDIR}/llvm/include
|
||||
-DPython3_ROOT_DIR=${LIBDIR}/python/
|
||||
-DPython3_EXECUTABLE=${PYTHON_BINARY}
|
||||
${ISPC_EXTRA_ARGS_WIN}
|
||||
${ISPC_EXTRA_ARGS_APPLE}
|
||||
${ISPC_EXTRA_ARGS_UNIX}
|
||||
-DISPC_NO_DUMPS=On
|
||||
-DISPC_INCLUDE_EXAMPLES=Off
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm
|
||||
-DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib
|
||||
-DCLANG_EXECUTABLE=${LIBDIR}/llvm/bin/clang
|
||||
-DCLANGPP_EXECUTABLE=${LIBDIR}/llvm/bin/clang++
|
||||
-DISPC_INCLUDE_TESTS=Off
|
||||
-DCLANG_LIBRARY_DIR=${LIBDIR}/llvm/lib
|
||||
-DCLANG_INCLUDE_DIRS=${LIBDIR}/llvm/include
|
||||
-DPython3_ROOT_DIR=${LIBDIR}/python/
|
||||
-DPython3_EXECUTABLE=${PYTHON_BINARY}
|
||||
${ISPC_EXTRA_ARGS_WIN}
|
||||
${ISPC_EXTRA_ARGS_APPLE}
|
||||
${ISPC_EXTRA_ARGS_UNIX}
|
||||
)
|
||||
|
||||
ExternalProject_Add(external_ispc
|
||||
|
|
|
@ -105,10 +105,10 @@ if(WIN32)
|
|||
)
|
||||
endif()
|
||||
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 ${LIBDIR}/pystring/lib/libpystring.a ${LIBDIR}/opencolorio/lib/
|
||||
DEPENDEES install
|
||||
)
|
||||
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 ${LIBDIR}/pystring/lib/libpystring.a ${LIBDIR}/opencolorio/lib/
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -39,8 +39,10 @@ if(MSVC)
|
|||
)
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
ExternalProject_Add_Step(external_openjpeg_msvc after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/lib ${HARVEST_TARGET}/openjpeg/lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/include ${HARVEST_TARGET}/openjpeg/include
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/lib ${HARVEST_TARGET}/openjpeg/lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/include ${HARVEST_TARGET}/openjpeg/include
|
||||
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
# library itself does not depend on them, so should give no problems.
|
||||
|
||||
set(OPENPGL_EXTRA_ARGS
|
||||
-DOPENPGL_BUILD_STATIC=ON
|
||||
-DOPENPGL_TBB_ROOT=${LIBDIR}/tbb
|
||||
-DTBB_ROOT=${LIBDIR}/tbb
|
||||
-DCMAKE_DEBUG_POSTFIX=_d
|
||||
-DOPENPGL_BUILD_STATIC=ON
|
||||
-DOPENPGL_TBB_ROOT=${LIBDIR}/tbb
|
||||
-DTBB_ROOT=${LIBDIR}/tbb
|
||||
-DCMAKE_DEBUG_POSTFIX=_d
|
||||
)
|
||||
|
||||
if(TBB_STATIC_LIBRARY)
|
||||
|
@ -18,17 +18,17 @@ if(TBB_STATIC_LIBRARY)
|
|||
endif()
|
||||
|
||||
ExternalProject_Add(external_openpgl
|
||||
URL file://${PACKAGE_DIR}/${OPENPGL_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${OPENPGL_HASH_TYPE}=${OPENPGL_HASH}
|
||||
PREFIX ${BUILD_DIR}/openpgl
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openpgl ${DEFAULT_CMAKE_FLAGS} ${OPENPGL_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/openpgl
|
||||
URL file://${PACKAGE_DIR}/${OPENPGL_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${OPENPGL_HASH_TYPE}=${OPENPGL_HASH}
|
||||
PREFIX ${BUILD_DIR}/openpgl
|
||||
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openpgl ${DEFAULT_CMAKE_FLAGS} ${OPENPGL_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/openpgl
|
||||
)
|
||||
|
||||
add_dependencies(
|
||||
external_openpgl
|
||||
external_tbb
|
||||
external_openpgl
|
||||
external_tbb
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
|
|
|
@ -15,8 +15,8 @@ if((WIN32 AND BUILD_MODE STREQUAL Release) OR UNIX)
|
|||
)
|
||||
if(WIN32)
|
||||
ExternalProject_Add_Step(external_potrace after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/potrace ${HARVEST_TARGET}/potrace
|
||||
DEPENDEES install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/potrace ${HARVEST_TARGET}/potrace
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -2,37 +2,36 @@
|
|||
|
||||
if(WIN32)
|
||||
|
||||
if(MSVC14) # vs2015 has timespec
|
||||
set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H /D_TIMESPEC_DEFINED ")
|
||||
else() # everything before doesn't
|
||||
set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H ")
|
||||
endif()
|
||||
if(MSVC14) # vs2015 has timespec
|
||||
set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H /D_TIMESPEC_DEFINED ")
|
||||
else() # everything before doesn't
|
||||
set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H ")
|
||||
endif()
|
||||
|
||||
set(PTHREADS_BUILD cd ${BUILD_DIR}/pthreads/src/external_pthreads/ && cd && nmake VC-static /e CPPFLAGS=${PTHREAD_CPPFLAGS})
|
||||
set(PTHREADS_BUILD cd ${BUILD_DIR}/pthreads/src/external_pthreads/ && cd && nmake VC-static /e CPPFLAGS=${PTHREAD_CPPFLAGS})
|
||||
|
||||
ExternalProject_Add(external_pthreads
|
||||
URL file://${PACKAGE_DIR}/${PTHREADS_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${PTHREADS_HASH_TYPE}=${PTHREADS_HASH}
|
||||
PREFIX ${BUILD_DIR}/pthreads
|
||||
CONFIGURE_COMMAND echo .
|
||||
PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/pthreads/src/external_pthreads < ${PATCH_DIR}/pthreads.diff
|
||||
BUILD_COMMAND ${PTHREADS_BUILD}
|
||||
INSTALL_COMMAND COMMAND
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/libpthreadVC3${LIBEXT} ${LIBDIR}/pthreads/lib/pthreadVC3${LIBEXT} &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthread.h ${LIBDIR}/pthreads/inc/pthread.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/sched.h ${LIBDIR}/pthreads/inc/sched.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/semaphore.h ${LIBDIR}/pthreads/inc/semaphore.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/_ptw32.h ${LIBDIR}/pthreads/inc/_ptw32.h
|
||||
INSTALL_DIR ${LIBDIR}/pthreads
|
||||
ExternalProject_Add(external_pthreads
|
||||
URL file://${PACKAGE_DIR}/${PTHREADS_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${PTHREADS_HASH_TYPE}=${PTHREADS_HASH}
|
||||
PREFIX ${BUILD_DIR}/pthreads
|
||||
CONFIGURE_COMMAND echo .
|
||||
PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/pthreads/src/external_pthreads < ${PATCH_DIR}/pthreads.diff
|
||||
BUILD_COMMAND ${PTHREADS_BUILD}
|
||||
INSTALL_COMMAND COMMAND
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/libpthreadVC3${LIBEXT} ${LIBDIR}/pthreads/lib/pthreadVC3${LIBEXT} &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthread.h ${LIBDIR}/pthreads/inc/pthread.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/sched.h ${LIBDIR}/pthreads/inc/sched.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/semaphore.h ${LIBDIR}/pthreads/inc/semaphore.h &&
|
||||
${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/_ptw32.h ${LIBDIR}/pthreads/inc/_ptw32.h
|
||||
INSTALL_DIR ${LIBDIR}/pthreads
|
||||
)
|
||||
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
ExternalProject_Add_Step(external_pthreads after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib
|
||||
DEPENDEES install
|
||||
)
|
||||
|
||||
if(BUILD_MODE STREQUAL Release)
|
||||
ExternalProject_Add_Step(external_pthreads after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -4,7 +4,12 @@ set(SNDFILE_EXTRA_ARGS)
|
|||
set(SNDFILE_ENV)
|
||||
|
||||
if(WIN32)
|
||||
set(SNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR})
|
||||
set(SNDFILE_ENV "PKG_CONFIG_PATH=\
|
||||
${mingw_LIBDIR}/ogg/lib/pkgconfig:\
|
||||
${mingw_LIBDIR}/vorbis/lib/pkgconfig:\
|
||||
${mingw_LIBDIR}/flac/lib/pkgconfig:\
|
||||
${mingw_LIBDIR}/opus/lib/pkgconfig"
|
||||
)
|
||||
set(SNDFILE_ENV set ${SNDFILE_ENV} &&)
|
||||
# Shared for windows because static libs will drag in a libgcc dependency.
|
||||
set(SNDFILE_OPTIONS --disable-static --enable-shared )
|
||||
|
@ -19,7 +24,10 @@ if(UNIX AND NOT APPLE)
|
|||
#
|
||||
# Replace: Cflags: -I${includedir}/opus
|
||||
# With: Cflags: -I${includedir}
|
||||
set(SNDFILE_ENV sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc && ${SNDFILE_ENV})
|
||||
set(SNDFILE_ENV
|
||||
sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc &&
|
||||
${SNDFILE_ENV}
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_sndfile
|
||||
|
@ -52,10 +60,10 @@ endif()
|
|||
|
||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_sndfile after_install
|
||||
COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h
|
||||
COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h
|
||||
|
||||
DEPENDEES install
|
||||
)
|
||||
|
|
|
@ -5,7 +5,20 @@ ExternalProject_Add(external_spnav
|
|||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${SPNAV_HASH_TYPE}=${SPNAV_HASH}
|
||||
PREFIX ${BUILD_DIR}/spnav
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/spnav --disable-shared --enable-static --with-pic
|
||||
|
||||
CONFIGURE_COMMAND
|
||||
${CONFIGURE_ENV} &&
|
||||
cd ${BUILD_DIR}/spnav/src/external_spnav/ &&
|
||||
${CONFIGURE_COMMAND}
|
||||
--prefix=${LIBDIR}/spnav
|
||||
# X11 is not needed as Blender polls the device as part of the GHOST event loop.
|
||||
# This is used to support `3dxserv`, however this is no longer supported by 3DCONNEXION.
|
||||
# Disable so building without X11 is supported (WAYLAND only).
|
||||
--disable-x11
|
||||
--disable-shared
|
||||
--enable-static
|
||||
--with-pic
|
||||
|
||||
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make -j${MAKE_THREADS}
|
||||
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make install
|
||||
INSTALL_DIR ${LIBDIR}/spnav
|
||||
|
|
|
@ -235,11 +235,11 @@ set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz)
|
|||
# ------------------------------------------------------------------------------
|
||||
# Python Modules
|
||||
|
||||
# Needed by: TODO.
|
||||
# Needed by: `requests` module (so the version doesn't change on rebuild).
|
||||
set(IDNA_VERSION 3.3)
|
||||
# Needed by: TODO.
|
||||
# Needed by: `requests` module (so the version doesn't change on rebuild).
|
||||
set(CHARSET_NORMALIZER_VERSION 2.0.10)
|
||||
# Needed by: TODO.
|
||||
# Needed by: `requests` module (so the version doesn't change on rebuild).
|
||||
set(URLLIB3_VERSION 1.26.8)
|
||||
set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*")
|
||||
# Needed by: Python's `requests` module (so add-ons can authenticate against trusted certificates).
|
||||
|
@ -369,9 +369,9 @@ set(WEBP_HASH_TYPE MD5)
|
|||
set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz)
|
||||
set(WEBP_CPE "cpe:2.3:a:webmproject:libwebp:${WEBP_VERSION}:*:*:*:*:*:*:*")
|
||||
|
||||
set(SPNAV_VERSION 0.2.3)
|
||||
set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
|
||||
set(SPNAV_HASH 44d840540d53326d4a119c0f1aa7bf0a)
|
||||
set(SPNAV_VERSION 1.1)
|
||||
set(SPNAV_URI https://github.com/FreeSpacenav/libspnav/releases/download/v${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
|
||||
set(SPNAV_HASH 7c0032034672dfba3c4bb9b49a440e70)
|
||||
set(SPNAV_HASH_TYPE MD5)
|
||||
set(SPNAV_FILE libspnav-${SPNAV_VERSION}.tar.gz)
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ if(WIN32)
|
|||
set(YAMLCPP_EXTRA_ARGS
|
||||
${YAMLCPP_EXTRA_ARGS}
|
||||
-DBUILD_GMOCK=OFF
|
||||
-DYAML_MSVC_SHARED_RT=ON)
|
||||
-DYAML_MSVC_SHARED_RT=ON
|
||||
)
|
||||
endif()
|
||||
|
||||
ExternalProject_Add(external_yamlcpp
|
||||
|
|
|
@ -6,6 +6,7 @@ import re
|
|||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
# Strip version numbers from dependenciesm macOS notarizatiom fails
|
||||
# with version symlinks.
|
||||
def strip_lib_version(name):
|
||||
|
@ -14,6 +15,7 @@ def strip_lib_version(name):
|
|||
name = re.sub(r'(\.[0-9]+)+.cpython', '.cpython', name)
|
||||
return name
|
||||
|
||||
|
||||
rpath = sys.argv[1]
|
||||
file = sys.argv[2]
|
||||
|
||||
|
|
|
@ -11,19 +11,31 @@ if [ `id -u` -ne 0 ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# yum-config-manager does not come in the default minimal install,
|
||||
# Required by: config manager command below to enable powertools.
|
||||
dnf install 'dnf-command(config-manager)'
|
||||
|
||||
# Packages `ninja-build` and `meson` are not available unless CBR or PowerTools repositories are enabled.
|
||||
# See: https://wiki.rockylinux.org/rocky/repo/#notes-on-unlisted-repositories
|
||||
dnf config-manager --set-enabled powertools
|
||||
|
||||
# Required by: epel-release has the patchelf and rubygem-asciidoctor packages
|
||||
dnf install epel-release
|
||||
|
||||
# `yum-config-manager` does not come in the default minimal install,
|
||||
# so make sure it is installed and available.
|
||||
yum -y update
|
||||
yum -y install yum-utils
|
||||
|
||||
# Install all the packages needed for a new toolchain.
|
||||
# Install all the packages needed for a new tool-chain.
|
||||
#
|
||||
# NOTE: Keep this separate from the packages install, since otherwise
|
||||
# older toolchain will be installed.
|
||||
# older tool-chain will be installed.
|
||||
yum -y update
|
||||
yum -y install epel-release
|
||||
yum -y install centos-release-scl
|
||||
yum -y install devtoolset-9
|
||||
yum -y install scl-utils
|
||||
yum -y install scl-utils-build
|
||||
|
||||
# Currently this is defined by the VFX platform (CY2023), see: https://vfxplatform.com
|
||||
yum -y install gcc-toolset-11
|
||||
|
||||
# Install packages needed for Blender's dependencies.
|
||||
PACKAGES_FOR_LIBS=(
|
||||
|
@ -47,19 +59,12 @@ PACKAGES_FOR_LIBS=(
|
|||
automake
|
||||
libtool
|
||||
|
||||
# Meta-build system used by various packages.
|
||||
meson
|
||||
# TODO: why is this needed?
|
||||
patchelf
|
||||
|
||||
# Builds generated by meson use Ninja for the actual build.
|
||||
ninja-build
|
||||
|
||||
# Required by Blender build option: `WITH_GHOST_X11`.
|
||||
libXrandr-devel
|
||||
libXinerama-devel
|
||||
libXcursor-devel
|
||||
libXi-devel
|
||||
libX11-devel
|
||||
libXt-devel
|
||||
|
||||
# Required by Blender build option: `WITH_GHOST_WAYLAND`.
|
||||
mesa-libEGL-devel
|
||||
# Required by: Blender & `external_opensubdiv` (probably others).
|
||||
|
@ -79,52 +84,47 @@ PACKAGES_FOR_LIBS=(
|
|||
# Why are both needed?
|
||||
yasm
|
||||
|
||||
# Required by: `meson` (Python based build system).
|
||||
python36
|
||||
# Required by: `mako` (Python module used for building `external_mesa`)
|
||||
python-setuptools
|
||||
# NOTE(@campbellbarton): while `python39` is available, the default Python version is 3.6.
|
||||
# This is used for the `python3-mako` package for e.g.
|
||||
# So use the "default" system Python since it means it's most compatible with other packages.
|
||||
python3
|
||||
# Required by: `external_mesa`.
|
||||
python3-mako
|
||||
|
||||
# Required by: `external_mesa`.
|
||||
expat-devel
|
||||
|
||||
# Required by: `external_igc` & `external_osl` as a build-time dependency.
|
||||
bison
|
||||
# Required by: `external_osl` as a build-time dependency.
|
||||
flex
|
||||
# TODO: dependencies build without this, consider removal.
|
||||
|
||||
# Required by: `external_ispc`.
|
||||
ncurses-devel
|
||||
# Required by: `external_ispc` (when building with CLANG).
|
||||
libstdc++-static
|
||||
)
|
||||
|
||||
# Additional packages needed for building Blender.
|
||||
PACKAGES_FOR_BLENDER=(
|
||||
# Required by Blender build option: `WITH_GHOST_WAYLAND`.
|
||||
libxkbcommon-devel
|
||||
|
||||
# Required by Blender build option: `WITH_GHOST_X11`.
|
||||
libX11-devel
|
||||
libXcursor-devel
|
||||
libXi-devel
|
||||
libXinerama-devel
|
||||
libXrandr-devel
|
||||
libXt-devel
|
||||
libXxf86vm-devel
|
||||
)
|
||||
|
||||
yum -y install -y ${PACKAGES_FOR_LIBS[@]} ${PACKAGES_FOR_BLENDER[@]}
|
||||
|
||||
# Dependencies for Mesa
|
||||
yum -y install expat-devel
|
||||
python3 -m pip install mako
|
||||
|
||||
# Dependencies for pip (needed for buildbot-worker).
|
||||
yum -y install python36-pip python36-devel
|
||||
# Dependencies for pip (needed for `buildbot-worker`), uses Python3.6.
|
||||
yum -y install python3 python3-pip python3-devel
|
||||
|
||||
# Dependencies for asound.
|
||||
yum -y install -y \
|
||||
alsa-lib-devel pulseaudio-libs-devel
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \
|
||||
--family cmake
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
|
||||
--family cmake
|
||||
|
||||
alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \
|
||||
--slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \
|
||||
--slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \
|
||||
--slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \
|
||||
--family cmake
|
|
@ -90,3 +90,25 @@ diff -Naur orig/openvdb/openvdb/tree/ValueAccessor.h openvdb/openvdb/openvdb/tre
|
|||
|
||||
CacheItem(TreeCacheT& parent)
|
||||
: mParent(&parent)
|
||||
diff --git a/nanovdb/nanovdb/NanoVDB.h b/nanovdb/nanovdb/NanoVDB.h
|
||||
index f7fc304..fde5c47 100644
|
||||
--- a/nanovdb/nanovdb/NanoVDB.h
|
||||
+++ b/nanovdb/nanovdb/NanoVDB.h
|
||||
@@ -1877,7 +1877,7 @@ __hostdev__ static inline uint32_t FindLowestOn(uint64_t v)
|
||||
{
|
||||
NANOVDB_ASSERT(v);
|
||||
#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
|
||||
- return __ffsll(v);
|
||||
+ return __ffsll(static_cast<unsigned long long int>(v));
|
||||
#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
|
||||
unsigned long index;
|
||||
_BitScanForward64(&index, v);
|
||||
@@ -2592,7 +2592,7 @@ public:
|
||||
///
|
||||
/// @note This method is only defined for IndexGrid = NanoGrid<ValueIndex>
|
||||
template <typename T = BuildType>
|
||||
- __hostdev__ typename enable_if<is_same<T, ValueIndex>::value, uint64_t>::type valueCount() const {return DataType::mData1;}
|
||||
+ __hostdev__ typename enable_if<is_same<T, ValueIndex>::value, const uint64_t&>::type valueCount() const {return DataType::mData1;}
|
||||
|
||||
/// @brief Return a const reference to the tree
|
||||
__hostdev__ const TreeT& tree() const { return *reinterpret_cast<const TreeT*>(this->treePtr()); }
|
||||
|
|
|
@ -370,7 +370,7 @@ def main():
|
|||
|
||||
args_in_wash = get_args_wash(args_in, args_in_index, False)
|
||||
|
||||
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([print_arg_in(arg) for arg in args_in_wash])))
|
||||
fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([arg_name_with_default(arg) for arg in args_in_wash])))
|
||||
|
||||
# -- wash the comment
|
||||
comment_washed = []
|
||||
|
@ -423,8 +423,8 @@ def main():
|
|||
print(OUT_RST)
|
||||
|
||||
|
||||
def print_arg_in(arg):
|
||||
(name, default_value, _, _) = arg
|
||||
def arg_name_with_default(arg):
|
||||
name, default_value, _, _ = arg
|
||||
if default_value is None:
|
||||
return name
|
||||
return name + '=' + default_value
|
||||
|
|
|
@ -92,7 +92,7 @@ class AddPresetPerformance(AddPresetBase, Operator):
|
|||
|
||||
preset_defines = [
|
||||
"render = bpy.context.scene.render",
|
||||
"cycles = bpy.context.scene.cycles"
|
||||
"cycles = bpy.context.scene.cycles",
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
|
|
|
@ -82,8 +82,8 @@ enum_use_layer_samples = (
|
|||
)
|
||||
|
||||
enum_sampling_pattern = (
|
||||
('SOBOL', "Sobol-Burley", "Use Sobol-Burley random sampling pattern", 0),
|
||||
('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
|
||||
('SOBOL_BURLEY', "Sobol-Burley", "Use on-the-fly computed Owen-scrambled Sobol for random sampling", 0),
|
||||
('TABULATED_SOBOL', "Tabulated Sobol", "Use precomputed tables of Owen-scrambled Sobol for random sampling", 1),
|
||||
)
|
||||
|
||||
enum_emission_sampling = (
|
||||
|
@ -412,9 +412,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||
|
||||
sampling_pattern: EnumProperty(
|
||||
name="Sampling Pattern",
|
||||
description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol-Burley",
|
||||
description="Random sampling pattern used by the integrator",
|
||||
items=enum_sampling_pattern,
|
||||
default='PROGRESSIVE_MULTI_JITTER',
|
||||
default='TABULATED_SOBOL',
|
||||
)
|
||||
|
||||
scrambling_distance: FloatProperty(
|
||||
|
|
|
@ -364,16 +364,13 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
|||
row.prop(cscene, "seed")
|
||||
row.prop(cscene, "use_animated_seed", text="", icon='TIME')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "sampling_pattern", text="Pattern")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "sample_offset")
|
||||
|
||||
layout.separator()
|
||||
|
||||
heading = layout.column(align=True, heading="Scrambling Distance")
|
||||
heading.active = cscene.sampling_pattern != 'SOBOL'
|
||||
heading.active = cscene.sampling_pattern == 'TABULATED_SOBOL'
|
||||
heading.prop(cscene, "auto_scrambling_distance", text="Automatic")
|
||||
heading.prop(cscene, "preview_scrambling_distance", text="Viewport")
|
||||
heading.prop(cscene, "scrambling_distance", text="Multiplier")
|
||||
|
@ -396,11 +393,6 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel):
|
|||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
@ -416,6 +408,23 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel):
|
|||
sub.active = not cscene.use_light_tree
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_sampling_debug(CyclesDebugButtonsPanel, Panel):
|
||||
bl_label = "Debug"
|
||||
bl_parent_id = "CYCLES_RENDER_PT_sampling"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
scene = context.scene
|
||||
cscene = scene.cycles
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(cscene, "sampling_pattern", text="Pattern")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Subdivision"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
@ -2391,6 +2400,7 @@ classes = (
|
|||
CYCLES_RENDER_PT_sampling_path_guiding_debug,
|
||||
CYCLES_RENDER_PT_sampling_lights,
|
||||
CYCLES_RENDER_PT_sampling_advanced,
|
||||
CYCLES_RENDER_PT_sampling_debug,
|
||||
CYCLES_RENDER_PT_light_paths,
|
||||
CYCLES_RENDER_PT_light_paths_max_bounces,
|
||||
CYCLES_RENDER_PT_light_paths_clamping,
|
||||
|
|
|
@ -228,7 +228,7 @@ def do_versions(self):
|
|||
cscene.use_preview_denoising = False
|
||||
if not cscene.is_property_set("sampling_pattern") or \
|
||||
cscene.get('sampling_pattern') >= 2:
|
||||
cscene.sampling_pattern = 'PROGRESSIVE_MULTI_JITTER'
|
||||
cscene.sampling_pattern = 'TABULATED_SOBOL'
|
||||
|
||||
# Removal of square samples.
|
||||
cscene = scene.cycles
|
||||
|
@ -241,6 +241,12 @@ def do_versions(self):
|
|||
layer.samples *= layer.samples
|
||||
cscene["use_square_samples"] = False
|
||||
|
||||
# Disable light tree for existing scenes.
|
||||
if version <= (3, 5, 3):
|
||||
cscene = scene.cycles
|
||||
if not cscene.is_property_set("use_light_tree"):
|
||||
cscene.use_light_tree = False
|
||||
|
||||
# Lamps
|
||||
for light in bpy.data.lights:
|
||||
if light.library not in libraries:
|
||||
|
|
|
@ -57,7 +57,6 @@ int BlenderDisplayShader::get_tex_coord_attrib_location()
|
|||
|
||||
/* TODO move shaders to standalone .glsl file. */
|
||||
static const char *FALLBACK_VERTEX_SHADER =
|
||||
"#version 330\n"
|
||||
"uniform vec2 fullscreen;\n"
|
||||
"in vec2 texCoord;\n"
|
||||
"in vec2 pos;\n"
|
||||
|
@ -75,7 +74,6 @@ static const char *FALLBACK_VERTEX_SHADER =
|
|||
"}\n\0";
|
||||
|
||||
static const char *FALLBACK_FRAGMENT_SHADER =
|
||||
"#version 330\n"
|
||||
"uniform sampler2D image_texture;\n"
|
||||
"in vec2 texCoord_interp;\n"
|
||||
"out vec4 fragColor;\n"
|
||||
|
|
|
@ -367,13 +367,11 @@ static void attr_create_generic(Scene *scene,
|
|||
{
|
||||
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
|
||||
static const ustring u_velocity("velocity");
|
||||
|
||||
int attribute_index = 0;
|
||||
int render_color_index = b_mesh.attributes.render_color_index();
|
||||
const ustring default_color_name{b_mesh.attributes.default_color_name().c_str()};
|
||||
|
||||
for (BL::Attribute &b_attribute : b_mesh.attributes) {
|
||||
const ustring name{b_attribute.name().c_str()};
|
||||
const bool is_render_color = (attribute_index++ == render_color_index);
|
||||
const bool is_render_color = name == default_color_name;
|
||||
|
||||
if (need_motion && name == u_velocity) {
|
||||
attr_create_motion(mesh, b_attribute, motion_scale);
|
||||
|
|
|
@ -357,7 +357,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
|||
}
|
||||
|
||||
SamplingPattern sampling_pattern = (SamplingPattern)get_enum(
|
||||
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_PMJ);
|
||||
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_TABULATED_SOBOL);
|
||||
integrator->set_sampling_pattern(sampling_pattern);
|
||||
|
||||
int samples = 1;
|
||||
|
|
|
@ -952,6 +952,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
|
|||
case EXTENSION_CLIP:
|
||||
address_mode = CU_TR_ADDRESS_MODE_BORDER;
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
address_mode = CU_TR_ADDRESS_MODE_MIRROR;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
|
|
@ -909,6 +909,9 @@ void HIPDevice::tex_alloc(device_texture &mem)
|
|||
* because it's unsupported in HIP. */
|
||||
address_mode = hipAddressModeClamp;
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
address_mode = hipAddressModeMirror;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
|
|
@ -856,7 +856,7 @@ void MetalDevice::tex_alloc(device_texture &mem)
|
|||
/* sampler_index maps into the GPU's constant 'metal_samplers' array */
|
||||
uint64_t sampler_index = mem.info.extension;
|
||||
if (mem.info.interpolation != INTERPOLATION_CLOSEST) {
|
||||
sampler_index += 3;
|
||||
sampler_index += 4;
|
||||
}
|
||||
|
||||
/* Image Texture Storage */
|
||||
|
|
|
@ -299,12 +299,12 @@ set(SRC_KERNEL_LIGHT_HEADERS
|
|||
)
|
||||
|
||||
set(SRC_KERNEL_SAMPLE_HEADERS
|
||||
sample/jitter.h
|
||||
sample/lcg.h
|
||||
sample/mapping.h
|
||||
sample/mis.h
|
||||
sample/pattern.h
|
||||
sample/sobol_burley.h
|
||||
sample/tabulated_sobol.h
|
||||
sample/util.h
|
||||
)
|
||||
|
||||
|
|
|
@ -580,11 +580,11 @@ ccl_device_inline
|
|||
case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_ggx_eval(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
|
||||
eval = bsdf_microfacet_multi_ggx_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->I, omega_in, pdf, &sd->lcg_state);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID:
|
||||
|
@ -592,10 +592,10 @@ ccl_device_inline
|
|||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
eval = bsdf_microfacet_beckmann_eval(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID:
|
||||
eval = bsdf_ashikhmin_shirley_eval(sc, sd->I, omega_in, pdf);
|
||||
eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
|
||||
eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf);
|
||||
|
|
|
@ -40,11 +40,13 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough
|
|||
}
|
||||
|
||||
ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 Ng,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
const float cosNgI = dot(Ng, omega_in);
|
||||
float3 N = bsdf->N;
|
||||
|
||||
float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */
|
||||
|
@ -52,7 +54,8 @@ ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const Sh
|
|||
|
||||
float out = 0.0f;
|
||||
|
||||
if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || !(NdotI > 0.0f && NdotO > 0.0f)) {
|
||||
if ((cosNgI < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f ||
|
||||
!(NdotI > 0.0f && NdotO > 0.0f)) {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
@ -210,7 +213,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc
|
|||
}
|
||||
else {
|
||||
/* leave the rest to eval */
|
||||
*eval = bsdf_ashikhmin_shirley_eval(sc, I, *omega_in, pdf);
|
||||
*eval = bsdf_ashikhmin_shirley_eval(sc, N, I, *omega_in, pdf);
|
||||
}
|
||||
|
||||
return label;
|
||||
|
|
|
@ -517,27 +517,30 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const Microfac
|
|||
}
|
||||
|
||||
ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 Ng,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
const float alpha_x = bsdf->alpha_x;
|
||||
const float alpha_y = bsdf->alpha_y;
|
||||
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
const float3 N = bsdf->N;
|
||||
const float cosNO = dot(N, I);
|
||||
const float cosNI = dot(N, omega_in);
|
||||
const float cosNgI = dot(Ng, omega_in);
|
||||
|
||||
if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
|
||||
if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
||||
return (cosNI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
|
||||
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
|
||||
bsdf_microfacet_ggx_eval_reflect(
|
||||
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
|
||||
const float3 N = bsdf->N;
|
||||
const float cosNO = dot(N, I);
|
||||
const float cosNI = dot(N, omega_in);
|
||||
|
||||
return (cosNgI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit(
|
||||
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
|
||||
bsdf_microfacet_ggx_eval_reflect(
|
||||
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg,
|
||||
|
@ -942,23 +945,26 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Mic
|
|||
}
|
||||
|
||||
ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 Ng,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
|
||||
const float alpha_x = bsdf->alpha_x;
|
||||
const float alpha_y = bsdf->alpha_y;
|
||||
const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
|
||||
const float3 N = bsdf->N;
|
||||
const float cosNO = dot(N, I);
|
||||
const float cosNI = dot(N, omega_in);
|
||||
const float cosNgI = dot(Ng, omega_in);
|
||||
|
||||
if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
|
||||
if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
||||
const float3 N = bsdf->N;
|
||||
const float cosNO = dot(N, I);
|
||||
const float cosNI = dot(N, omega_in);
|
||||
|
||||
return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit(
|
||||
bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) :
|
||||
bsdf_microfacet_beckmann_eval_reflect(
|
||||
|
|
|
@ -416,14 +416,16 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet
|
|||
}
|
||||
|
||||
ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc,
|
||||
const float3 Ng,
|
||||
const float3 I,
|
||||
const float3 omega_in,
|
||||
ccl_private float *pdf,
|
||||
ccl_private uint *lcg_state)
|
||||
{
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
const float cosNgI = dot(Ng, omega_in);
|
||||
|
||||
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
|
||||
if ((cosNgI < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
|
||||
*pdf = 0.0f;
|
||||
return zero_spectrum();
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ KERNEL_DATA_ARRAY(KernelShader, shaders)
|
|||
/* lookup tables */
|
||||
KERNEL_DATA_ARRAY(float, lookup_table)
|
||||
|
||||
/* PMJ sample pattern */
|
||||
/* tabulated Sobol sample pattern */
|
||||
KERNEL_DATA_ARRAY(float, sample_pattern_lut)
|
||||
|
||||
/* image textures */
|
||||
|
|
|
@ -179,7 +179,8 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect)
|
|||
KERNEL_STRUCT_MEMBER(integrator, int, use_caustics)
|
||||
/* Sampling pattern. */
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern)
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, pmj_sequence_size)
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size)
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask)
|
||||
KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance)
|
||||
/* Volume render. */
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, use_volumes)
|
||||
|
@ -204,7 +205,6 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights)
|
|||
|
||||
/* Padding. */
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, pad1)
|
||||
KERNEL_STRUCT_MEMBER(integrator, int, pad2)
|
||||
KERNEL_STRUCT_END(KernelIntegrator)
|
||||
|
||||
/* SVM. For shader specialization. */
|
||||
|
|
|
@ -202,6 +202,14 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
return clamp(x, 0, width - 1);
|
||||
}
|
||||
|
||||
static ccl_always_inline int wrap_mirror(int x, int width)
|
||||
{
|
||||
const int m = abs(x + (x < 0)) % (2 * width);
|
||||
if (m >= width)
|
||||
return 2 * width - m - 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
/* ******** 2D interpolation ******** */
|
||||
|
||||
static ccl_always_inline OutT interp_closest(const TextureInfo &info, float x, float y)
|
||||
|
@ -226,6 +234,10 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
ix = wrap_clamp(ix, width);
|
||||
iy = wrap_clamp(iy, height);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
ix = wrap_mirror(ix, width);
|
||||
iy = wrap_mirror(iy, height);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
@ -268,6 +280,12 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
niy = wrap_clamp(iy + 1, height);
|
||||
iy = wrap_clamp(iy, height);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
nix = wrap_mirror(ix + 1, width);
|
||||
ix = wrap_mirror(ix, width);
|
||||
niy = wrap_mirror(iy + 1, height);
|
||||
iy = wrap_mirror(iy, height);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
@ -331,6 +349,17 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
nniy = wrap_clamp(iy + 2, height);
|
||||
iy = wrap_clamp(iy, height);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
pix = wrap_mirror(ix - 1, width);
|
||||
nix = wrap_mirror(ix + 1, width);
|
||||
nnix = wrap_mirror(ix + 2, width);
|
||||
ix = wrap_mirror(ix, width);
|
||||
|
||||
piy = wrap_mirror(iy - 1, height);
|
||||
niy = wrap_mirror(iy + 1, height);
|
||||
nniy = wrap_mirror(iy + 2, height);
|
||||
iy = wrap_mirror(iy, height);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
@ -403,6 +432,11 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
iy = wrap_clamp(iy, height);
|
||||
iz = wrap_clamp(iz, depth);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
ix = wrap_mirror(ix, width);
|
||||
iy = wrap_mirror(iy, height);
|
||||
iz = wrap_mirror(iz, depth);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
@ -480,6 +514,16 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
niz = wrap_clamp(iz + 1, depth);
|
||||
iz = wrap_clamp(iz, depth);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
nix = wrap_mirror(ix + 1, width);
|
||||
ix = wrap_mirror(ix, width);
|
||||
|
||||
niy = wrap_mirror(iy + 1, height);
|
||||
iy = wrap_mirror(iy, height);
|
||||
|
||||
niz = wrap_mirror(iz + 1, depth);
|
||||
iz = wrap_mirror(iz, depth);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
@ -595,6 +639,22 @@ template<typename TexT, typename OutT = float4> struct TextureInterpolator {
|
|||
nniz = wrap_clamp(iz + 2, depth);
|
||||
iz = wrap_clamp(iz, depth);
|
||||
break;
|
||||
case EXTENSION_MIRROR:
|
||||
pix = wrap_mirror(ix - 1, width);
|
||||
nix = wrap_mirror(ix + 1, width);
|
||||
nnix = wrap_mirror(ix + 2, width);
|
||||
ix = wrap_mirror(ix, width);
|
||||
|
||||
piy = wrap_mirror(iy - 1, height);
|
||||
niy = wrap_mirror(iy + 1, height);
|
||||
nniy = wrap_mirror(iy + 2, height);
|
||||
iy = wrap_mirror(iy, height);
|
||||
|
||||
piz = wrap_mirror(iz - 1, depth);
|
||||
niz = wrap_mirror(iz + 1, depth);
|
||||
nniz = wrap_mirror(iz + 2, depth);
|
||||
iz = wrap_mirror(iz, depth);
|
||||
break;
|
||||
default:
|
||||
kernel_assert(0);
|
||||
return zero();
|
||||
|
|
|
@ -301,10 +301,12 @@ enum SamplerType {
|
|||
SamplerFilterNearest_AddressRepeat,
|
||||
SamplerFilterNearest_AddressClampEdge,
|
||||
SamplerFilterNearest_AddressClampZero,
|
||||
SamplerFilterNearest_AddressMirroredRepeat,
|
||||
|
||||
SamplerFilterLinear_AddressRepeat,
|
||||
SamplerFilterLinear_AddressClampEdge,
|
||||
SamplerFilterLinear_AddressClampZero,
|
||||
SamplerFilterLinear_AddressMirroredRepeat,
|
||||
|
||||
SamplerCount
|
||||
};
|
||||
|
@ -313,7 +315,9 @@ constant constexpr array<sampler, SamplerCount> metal_samplers = {
|
|||
sampler(address::repeat, filter::nearest),
|
||||
sampler(address::clamp_to_edge, filter::nearest),
|
||||
sampler(address::clamp_to_zero, filter::nearest),
|
||||
sampler(address::mirrored_repeat, filter::nearest),
|
||||
sampler(address::repeat, filter::linear),
|
||||
sampler(address::clamp_to_edge, filter::linear),
|
||||
sampler(address::clamp_to_zero, filter::linear),
|
||||
sampler(address::mirrored_repeat, filter::linear),
|
||||
};
|
||||
|
|
|
@ -47,9 +47,11 @@ class MetalKernelContext {
|
|||
case 0: return texture_array[tid].tex.sample(sampler(address::repeat, filter::nearest), coords);
|
||||
case 1: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::nearest), coords);
|
||||
case 2: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::nearest), coords);
|
||||
case 3: return texture_array[tid].tex.sample(sampler(address::repeat, filter::linear), coords);
|
||||
case 4: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::linear), coords);
|
||||
case 5: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::linear), coords);
|
||||
case 3: return texture_array[tid].tex.sample(sampler(address::mirrored_repeat, filter::nearest), coords);
|
||||
case 4: return texture_array[tid].tex.sample(sampler(address::repeat, filter::linear), coords);
|
||||
case 5: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::linear), coords);
|
||||
case 6: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::linear), coords);
|
||||
case 7: return texture_array[tid].tex.sample(sampler(address::mirrored_repeat, filter::linear), coords);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,14 @@ ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width)
|
|||
return clamp(x, 0, width - 1);
|
||||
}
|
||||
|
||||
ccl_device_inline int svm_image_texture_wrap_mirror(int x, int width)
|
||||
{
|
||||
const int m = abs(x + (x < 0)) % (2 * width);
|
||||
if (m >= width)
|
||||
return 2 * width - m - 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
ccl_device_inline float4 svm_image_texture_read(const TextureInfo &info, int x, int y, int z)
|
||||
{
|
||||
const int data_offset = x + info.width * y + info.width * info.height * z;
|
||||
|
@ -85,6 +93,10 @@ ccl_device_inline float4 svm_image_texture_read_2d(int id, int x, int y)
|
|||
x = svm_image_texture_wrap_clamp(x, info.width);
|
||||
y = svm_image_texture_wrap_clamp(y, info.height);
|
||||
}
|
||||
else if (info.extension == EXTENSION_MIRROR) {
|
||||
x = svm_image_texture_wrap_mirror(x, info.width);
|
||||
y = svm_image_texture_wrap_mirror(y, info.height);
|
||||
}
|
||||
else {
|
||||
if (x < 0 || x >= info.width || y < 0 || y >= info.height) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
@ -109,6 +121,11 @@ ccl_device_inline float4 svm_image_texture_read_3d(int id, int x, int y, int z)
|
|||
y = svm_image_texture_wrap_clamp(y, info.height);
|
||||
z = svm_image_texture_wrap_clamp(z, info.depth);
|
||||
}
|
||||
else if (info.extension == EXTENSION_MIRROR) {
|
||||
x = svm_image_texture_wrap_mirror(x, info.width);
|
||||
y = svm_image_texture_wrap_mirror(y, info.height);
|
||||
z = svm_image_texture_wrap_mirror(z, info.depth);
|
||||
}
|
||||
else {
|
||||
if (x < 0 || x >= info.width || y < 0 || y >= info.height || z < 0 || z >= info.depth) {
|
||||
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
|
|
@ -26,18 +26,22 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg,
|
|||
const float2 rand_filter = (sample == 0) ? make_float2(0.5f, 0.5f) :
|
||||
path_rng_2D(kg, rng_hash, sample, PRNG_FILTER);
|
||||
|
||||
/* Depth of field sampling. */
|
||||
const float2 rand_lens = (kernel_data.cam.aperturesize > 0.0f) ?
|
||||
path_rng_2D(kg, rng_hash, sample, PRNG_LENS) :
|
||||
zero_float2();
|
||||
|
||||
/* Motion blur time sampling. */
|
||||
const float rand_time = (kernel_data.cam.shuttertime != -1.0f) ?
|
||||
path_rng_1D(kg, rng_hash, sample, PRNG_TIME) :
|
||||
0.0f;
|
||||
/* Motion blur (time) and depth of field (lens) sampling. (time, lens_x, lens_y) */
|
||||
const float3 rand_time_lens = (kernel_data.cam.shuttertime != -1.0f ||
|
||||
kernel_data.cam.aperturesize > 0.0f) ?
|
||||
path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) :
|
||||
zero_float3();
|
||||
|
||||
/* Generate camera ray. */
|
||||
camera_sample(kg, x, y, rand_filter.x, rand_filter.y, rand_lens.x, rand_lens.y, rand_time, ray);
|
||||
camera_sample(kg,
|
||||
x,
|
||||
y,
|
||||
rand_filter.x,
|
||||
rand_filter.y,
|
||||
rand_time_lens.y,
|
||||
rand_time_lens.z,
|
||||
rand_time_lens.x,
|
||||
ray);
|
||||
}
|
||||
|
||||
/* Return false to indicate that this pixel is finished.
|
||||
|
|
|
@ -336,6 +336,14 @@ ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg,
|
|||
kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg,
|
||||
ccl_private const RNGState *rng_state,
|
||||
const int dimension)
|
||||
{
|
||||
return path_rng_3D(
|
||||
kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension);
|
||||
}
|
||||
|
||||
ccl_device_inline float path_branched_rng_1D(KernelGlobals kg,
|
||||
ccl_private const RNGState *rng_state,
|
||||
const int branch,
|
||||
|
@ -360,6 +368,18 @@ ccl_device_inline float2 path_branched_rng_2D(KernelGlobals kg,
|
|||
rng_state->rng_offset + dimension);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 path_branched_rng_3D(KernelGlobals kg,
|
||||
ccl_private const RNGState *rng_state,
|
||||
const int branch,
|
||||
const int num_branches,
|
||||
const int dimension)
|
||||
{
|
||||
return path_rng_3D(kg,
|
||||
rng_state->rng_hash,
|
||||
rng_state->sample * num_branches + branch,
|
||||
rng_state->rng_offset + dimension);
|
||||
}
|
||||
|
||||
/* Utility functions to get light termination value,
|
||||
* since it might not be needed in many cases.
|
||||
*/
|
||||
|
|
|
@ -147,10 +147,11 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg,
|
|||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
const uint bounce = INTEGRATOR_STATE(state, path, bounce);
|
||||
const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT);
|
||||
const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
|
||||
|
||||
if (!light_sample_from_position(kg,
|
||||
rng_state,
|
||||
rand_light.z,
|
||||
rand_light.x,
|
||||
rand_light.y,
|
||||
sd->time,
|
||||
|
|
|
@ -702,10 +702,11 @@ ccl_device_forceinline bool integrate_volume_equiangular_sample_light(
|
|||
/* Sample position on a light. */
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
const uint bounce = INTEGRATOR_STATE(state, path, bounce);
|
||||
const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT);
|
||||
const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
|
||||
|
||||
LightSample ls ccl_optional_struct_init;
|
||||
if (!light_sample_from_volume_segment(kg,
|
||||
rand_light.z,
|
||||
rand_light.x,
|
||||
rand_light.y,
|
||||
sd->time,
|
||||
|
@ -765,10 +766,11 @@ ccl_device_forceinline void integrate_volume_direct_light(
|
|||
{
|
||||
const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag);
|
||||
const uint bounce = INTEGRATOR_STATE(state, path, bounce);
|
||||
const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT);
|
||||
const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT);
|
||||
|
||||
if (!light_sample_from_position(kg,
|
||||
rng_state,
|
||||
rand_light.z,
|
||||
rand_light.x,
|
||||
rand_light.y,
|
||||
sd->time,
|
||||
|
|
|
@ -11,7 +11,7 @@ CCL_NAMESPACE_BEGIN
|
|||
/* Simple CDF based sampling over all lights in the scene, without taking into
|
||||
* account shading position or normal. */
|
||||
|
||||
ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *randu)
|
||||
ccl_device int light_distribution_sample(KernelGlobals kg, const float randn)
|
||||
{
|
||||
/* This is basically std::upper_bound as used by PBRT, to find a point light or
|
||||
* triangle to emit from, proportional to area. a good improvement would be to
|
||||
|
@ -19,7 +19,7 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra
|
|||
* arbitrary shaders. */
|
||||
int first = 0;
|
||||
int len = kernel_data.integrator.num_distribution + 1;
|
||||
float r = *randu;
|
||||
float r = randn;
|
||||
|
||||
do {
|
||||
int half_len = len >> 1;
|
||||
|
@ -38,18 +38,13 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra
|
|||
* make this fail on rare occasions. */
|
||||
int index = clamp(first - 1, 0, kernel_data.integrator.num_distribution - 1);
|
||||
|
||||
/* Rescale to reuse random number. this helps the 2D samples within
|
||||
* each area light be stratified as well. */
|
||||
float distr_min = kernel_data_fetch(light_distribution, index).totarea;
|
||||
float distr_max = kernel_data_fetch(light_distribution, index + 1).totarea;
|
||||
*randu = (r - distr_min) / (distr_max - distr_min);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
template<bool in_volume_segment>
|
||||
ccl_device_noinline bool light_distribution_sample(KernelGlobals kg,
|
||||
float randu,
|
||||
const float randn,
|
||||
const float randu,
|
||||
const float randv,
|
||||
const float time,
|
||||
const float3 P,
|
||||
|
@ -58,7 +53,7 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg,
|
|||
ccl_private LightSample *ls)
|
||||
{
|
||||
/* Sample light index from distribution. */
|
||||
const int index = light_distribution_sample(kg, &randu);
|
||||
const int index = light_distribution_sample(kg, randn);
|
||||
const float pdf_selection = kernel_data.integrator.distribution_pdf_lights;
|
||||
return light_sample<in_volume_segment>(
|
||||
kg, randu, randv, time, P, bounce, path_flag, index, pdf_selection, ls);
|
||||
|
|
|
@ -324,7 +324,8 @@ ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg,
|
|||
* Uses either a flat distribution or light tree. */
|
||||
|
||||
ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg,
|
||||
float randu,
|
||||
const float randn,
|
||||
const float randu,
|
||||
const float randv,
|
||||
const float time,
|
||||
const float3 P,
|
||||
|
@ -337,17 +338,19 @@ ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg,
|
|||
#ifdef __LIGHT_TREE__
|
||||
if (kernel_data.integrator.use_light_tree) {
|
||||
return light_tree_sample<true>(
|
||||
kg, randu, randv, time, P, D, t, SD_BSDF_HAS_TRANSMISSION, bounce, path_flag, ls);
|
||||
kg, randn, randu, randv, time, P, D, t, SD_BSDF_HAS_TRANSMISSION, bounce, path_flag, ls);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return light_distribution_sample<true>(kg, randu, randv, time, P, bounce, path_flag, ls);
|
||||
return light_distribution_sample<true>(
|
||||
kg, randn, randu, randv, time, P, bounce, path_flag, ls);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device bool light_sample_from_position(KernelGlobals kg,
|
||||
ccl_private const RNGState *rng_state,
|
||||
const float randn,
|
||||
const float randu,
|
||||
const float randv,
|
||||
const float time,
|
||||
|
@ -361,12 +364,13 @@ ccl_device bool light_sample_from_position(KernelGlobals kg,
|
|||
#ifdef __LIGHT_TREE__
|
||||
if (kernel_data.integrator.use_light_tree) {
|
||||
return light_tree_sample<false>(
|
||||
kg, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls);
|
||||
kg, randn, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
return light_distribution_sample<false>(kg, randu, randv, time, P, bounce, path_flag, ls);
|
||||
return light_distribution_sample<false>(
|
||||
kg, randn, randu, randv, time, P, bounce, path_flag, ls);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -551,8 +551,9 @@ ccl_device bool get_left_probability(KernelGlobals kg,
|
|||
|
||||
template<bool in_volume_segment>
|
||||
ccl_device_noinline bool light_tree_sample(KernelGlobals kg,
|
||||
float randu,
|
||||
float randv,
|
||||
float randn,
|
||||
const float randu,
|
||||
const float randv,
|
||||
const float time,
|
||||
const float3 P,
|
||||
const float3 N_or_D,
|
||||
|
@ -580,7 +581,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg,
|
|||
if (knode->child_index <= 0) {
|
||||
/* At a leaf node, we pick an emitter. */
|
||||
selected_emitter = light_tree_cluster_select_emitter<in_volume_segment>(
|
||||
kg, randv, P, N_or_D, t, has_transmission, knode, &pdf_selection);
|
||||
kg, randn, P, N_or_D, t, has_transmission, knode, &pdf_selection);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -598,7 +599,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg,
|
|||
float discard;
|
||||
float total_prob = left_prob;
|
||||
node_index = left_index;
|
||||
sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randu);
|
||||
sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randn);
|
||||
pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,111 +14,111 @@
|
|||
namespace DeviceStrings {
|
||||
|
||||
/* "" */
|
||||
ccl_device_constant DeviceString _emptystring_ = {0ull};
|
||||
ccl_device_constant DeviceString _emptystring_ = 0ull;
|
||||
/* "common" */
|
||||
ccl_device_constant DeviceString u_common = {14645198576927606093ull};
|
||||
ccl_device_constant DeviceString u_common = 14645198576927606093ull;
|
||||
/* "world" */
|
||||
ccl_device_constant DeviceString u_world = {16436542438370751598ull};
|
||||
ccl_device_constant DeviceString u_world = 16436542438370751598ull;
|
||||
/* "shader" */
|
||||
ccl_device_constant DeviceString u_shader = {4279676006089868ull};
|
||||
ccl_device_constant DeviceString u_shader = 4279676006089868ull;
|
||||
/* "object" */
|
||||
ccl_device_constant DeviceString u_object = {973692718279674627ull};
|
||||
ccl_device_constant DeviceString u_object = 973692718279674627ull;
|
||||
/* "NDC" */
|
||||
ccl_device_constant DeviceString u_ndc = {5148305047403260775ull};
|
||||
ccl_device_constant DeviceString u_ndc = 5148305047403260775ull;
|
||||
/* "screen" */
|
||||
ccl_device_constant DeviceString u_screen = {14159088609039777114ull};
|
||||
ccl_device_constant DeviceString u_screen = 14159088609039777114ull;
|
||||
/* "camera" */
|
||||
ccl_device_constant DeviceString u_camera = {2159505832145726196ull};
|
||||
ccl_device_constant DeviceString u_camera = 2159505832145726196ull;
|
||||
/* "raster" */
|
||||
ccl_device_constant DeviceString u_raster = {7759263238610201778ull};
|
||||
ccl_device_constant DeviceString u_raster = 7759263238610201778ull;
|
||||
/* "hsv" */
|
||||
ccl_device_constant DeviceString u_hsv = {2177035556331879497ull};
|
||||
ccl_device_constant DeviceString u_hsv = 2177035556331879497ull;
|
||||
/* "hsl" */
|
||||
ccl_device_constant DeviceString u_hsl = {7749766809258288148ull};
|
||||
ccl_device_constant DeviceString u_hsl = 7749766809258288148ull;
|
||||
/* "XYZ" */
|
||||
ccl_device_constant DeviceString u_xyz = {4957977063494975483ull};
|
||||
ccl_device_constant DeviceString u_xyz = 4957977063494975483ull;
|
||||
/* "xyY" */
|
||||
ccl_device_constant DeviceString u_xyy = {5138822319725660255ull};
|
||||
ccl_device_constant DeviceString u_xyy = 5138822319725660255ull;
|
||||
/* "sRGB" */
|
||||
ccl_device_constant DeviceString u_srgb = {15368599878474175032ull};
|
||||
ccl_device_constant DeviceString u_srgb = 15368599878474175032ull;
|
||||
/* "object:location" */
|
||||
ccl_device_constant DeviceString u_object_location = {7846190347358762897ull};
|
||||
ccl_device_constant DeviceString u_object_location = 7846190347358762897ull;
|
||||
/* "object:color" */
|
||||
ccl_device_constant DeviceString u_object_color = {12695623857059169556ull};
|
||||
ccl_device_constant DeviceString u_object_color = 12695623857059169556ull;
|
||||
/* "object:alpha" */
|
||||
ccl_device_constant DeviceString u_object_alpha = {11165053919428293151ull};
|
||||
ccl_device_constant DeviceString u_object_alpha = 11165053919428293151ull;
|
||||
/* "object:index" */
|
||||
ccl_device_constant DeviceString u_object_index = {6588325838217472556ull};
|
||||
ccl_device_constant DeviceString u_object_index = 6588325838217472556ull;
|
||||
/* "geom:dupli_generated" */
|
||||
ccl_device_constant DeviceString u_geom_dupli_generated = {6715607178003388908ull};
|
||||
ccl_device_constant DeviceString u_geom_dupli_generated = 6715607178003388908ull;
|
||||
/* "geom:dupli_uv" */
|
||||
ccl_device_constant DeviceString u_geom_dupli_uv = {1294253317490155849ull};
|
||||
ccl_device_constant DeviceString u_geom_dupli_uv = 1294253317490155849ull;
|
||||
/* "material:index" */
|
||||
ccl_device_constant DeviceString u_material_index = {741770758159634623ull};
|
||||
ccl_device_constant DeviceString u_material_index = 741770758159634623ull;
|
||||
/* "object:random" */
|
||||
ccl_device_constant DeviceString u_object_random = {15789063994977955884ull};
|
||||
ccl_device_constant DeviceString u_object_random = 15789063994977955884ull;
|
||||
/* "particle:index" */
|
||||
ccl_device_constant DeviceString u_particle_index = {9489711748229903784ull};
|
||||
ccl_device_constant DeviceString u_particle_index = 9489711748229903784ull;
|
||||
/* "particle:random" */
|
||||
ccl_device_constant DeviceString u_particle_random = {17993722202766855761ull};
|
||||
ccl_device_constant DeviceString u_particle_random = 17993722202766855761ull;
|
||||
/* "particle:age" */
|
||||
ccl_device_constant DeviceString u_particle_age = {7380730644710951109ull};
|
||||
ccl_device_constant DeviceString u_particle_age = 7380730644710951109ull;
|
||||
/* "particle:lifetime" */
|
||||
ccl_device_constant DeviceString u_particle_lifetime = {16576828923156200061ull};
|
||||
ccl_device_constant DeviceString u_particle_lifetime = 16576828923156200061ull;
|
||||
/* "particle:location" */
|
||||
ccl_device_constant DeviceString u_particle_location = {10309536211423573010ull};
|
||||
ccl_device_constant DeviceString u_particle_location = 10309536211423573010ull;
|
||||
/* "particle:rotation" */
|
||||
ccl_device_constant DeviceString u_particle_rotation = {17858543768041168459ull};
|
||||
ccl_device_constant DeviceString u_particle_rotation = 17858543768041168459ull;
|
||||
/* "particle:size" */
|
||||
ccl_device_constant DeviceString u_particle_size = {16461524249715420389ull};
|
||||
ccl_device_constant DeviceString u_particle_size = 16461524249715420389ull;
|
||||
/* "particle:velocity" */
|
||||
ccl_device_constant DeviceString u_particle_velocity = {13199101248768308863ull};
|
||||
ccl_device_constant DeviceString u_particle_velocity = 13199101248768308863ull;
|
||||
/* "particle:angular_velocity" */
|
||||
ccl_device_constant DeviceString u_particle_angular_velocity = {16327930120486517910ull};
|
||||
ccl_device_constant DeviceString u_particle_angular_velocity = 16327930120486517910ull;
|
||||
/* "geom:numpolyvertices" */
|
||||
ccl_device_constant DeviceString u_geom_numpolyvertices = {382043551489988826ull};
|
||||
ccl_device_constant DeviceString u_geom_numpolyvertices = 382043551489988826ull;
|
||||
/* "geom:trianglevertices" */
|
||||
ccl_device_constant DeviceString u_geom_trianglevertices = {17839267571524187074ull};
|
||||
ccl_device_constant DeviceString u_geom_trianglevertices = 17839267571524187074ull;
|
||||
/* "geom:polyvertices" */
|
||||
ccl_device_constant DeviceString u_geom_polyvertices = {1345577201967881769ull};
|
||||
ccl_device_constant DeviceString u_geom_polyvertices = 1345577201967881769ull;
|
||||
/* "geom:name" */
|
||||
ccl_device_constant DeviceString u_geom_name = {13606338128269760050ull};
|
||||
ccl_device_constant DeviceString u_geom_name = 13606338128269760050ull;
|
||||
/* "geom:undisplaced" */
|
||||
ccl_device_constant DeviceString u_geom_undisplaced = {12431586303019276305ull};
|
||||
ccl_device_constant DeviceString u_geom_undisplaced = 12431586303019276305ull;
|
||||
/* "geom:is_smooth" */
|
||||
ccl_device_constant DeviceString u_is_smooth = {857544214094480123ull};
|
||||
ccl_device_constant DeviceString u_is_smooth = 857544214094480123ull;
|
||||
/* "geom:is_curve" */
|
||||
ccl_device_constant DeviceString u_is_curve = {129742495633653138ull};
|
||||
ccl_device_constant DeviceString u_is_curve = 129742495633653138ull;
|
||||
/* "geom:curve_thickness" */
|
||||
ccl_device_constant DeviceString u_curve_thickness = {10605802038397633852ull};
|
||||
ccl_device_constant DeviceString u_curve_thickness = 10605802038397633852ull;
|
||||
/* "geom:curve_length" */
|
||||
ccl_device_constant DeviceString u_curve_length = {11423459517663715453ull};
|
||||
ccl_device_constant DeviceString u_curve_length = 11423459517663715453ull;
|
||||
/* "geom:curve_tangent_normal" */
|
||||
ccl_device_constant DeviceString u_curve_tangent_normal = {12301397394034985633ull};
|
||||
ccl_device_constant DeviceString u_curve_tangent_normal = 12301397394034985633ull;
|
||||
/* "geom:curve_random" */
|
||||
ccl_device_constant DeviceString u_curve_random = {15293085049960492358ull};
|
||||
ccl_device_constant DeviceString u_curve_random = 15293085049960492358ull;
|
||||
/* "geom:is_point" */
|
||||
ccl_device_constant DeviceString u_is_point = {2511357849436175953ull};
|
||||
ccl_device_constant DeviceString u_is_point = 2511357849436175953ull;
|
||||
/* "geom:point_radius" */
|
||||
ccl_device_constant DeviceString u_point_radius = {9956381140398668479ull};
|
||||
ccl_device_constant DeviceString u_point_radius = 9956381140398668479ull;
|
||||
/* "geom:point_position" */
|
||||
ccl_device_constant DeviceString u_point_position = {15684484280742966916ull};
|
||||
ccl_device_constant DeviceString u_point_position = 15684484280742966916ull;
|
||||
/* "geom:point_random" */
|
||||
ccl_device_constant DeviceString u_point_random = {5632627207092325544ull};
|
||||
ccl_device_constant DeviceString u_point_random = 5632627207092325544ull;
|
||||
/* "geom:normal_map_normal" */
|
||||
ccl_device_constant DeviceString u_normal_map_normal = {10718948685686827073};
|
||||
ccl_device_constant DeviceString u_normal_map_normal = 10718948685686827073;
|
||||
/* "path:ray_length" */
|
||||
ccl_device_constant DeviceString u_path_ray_length = {16391985802412544524ull};
|
||||
ccl_device_constant DeviceString u_path_ray_length = 16391985802412544524ull;
|
||||
/* "path:ray_depth" */
|
||||
ccl_device_constant DeviceString u_path_ray_depth = {16643933224879500399ull};
|
||||
ccl_device_constant DeviceString u_path_ray_depth = 16643933224879500399ull;
|
||||
/* "path:diffuse_depth" */
|
||||
ccl_device_constant DeviceString u_path_diffuse_depth = {13191651286699118408ull};
|
||||
ccl_device_constant DeviceString u_path_diffuse_depth = 13191651286699118408ull;
|
||||
/* "path:glossy_depth" */
|
||||
ccl_device_constant DeviceString u_path_glossy_depth = {15717768399057252940ull};
|
||||
ccl_device_constant DeviceString u_path_glossy_depth = 15717768399057252940ull;
|
||||
/* "path:transparent_depth" */
|
||||
ccl_device_constant DeviceString u_path_transparent_depth = {7821650266475578543ull};
|
||||
ccl_device_constant DeviceString u_path_transparent_depth = 7821650266475578543ull;
|
||||
/* "path:transmission_depth" */
|
||||
ccl_device_constant DeviceString u_path_transmission_depth = {15113408892323917624ull};
|
||||
ccl_device_constant DeviceString u_path_transmission_depth = 15113408892323917624ull;
|
||||
|
||||
} // namespace DeviceStrings
|
||||
|
||||
|
@ -1275,9 +1275,7 @@ ccl_device_extern bool osl_get_attribute(ccl_private ShaderGlobals *sg,
|
|||
object = sd->object;
|
||||
}
|
||||
|
||||
const uint64_t id = name.hash();
|
||||
|
||||
const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, sd->type, id);
|
||||
const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, sd->type, name);
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
return get_object_attribute(kg, sd, desc, type, derivatives, res);
|
||||
}
|
||||
|
|
|
@ -5,47 +5,26 @@
|
|||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
struct DeviceString {
|
||||
#if defined(__KERNEL_GPU__)
|
||||
/* Strings are represented by their hashes in CUDA and OptiX. */
|
||||
size_t str_;
|
||||
|
||||
ccl_device_inline_method uint64_t hash() const
|
||||
{
|
||||
return str_;
|
||||
}
|
||||
/* Strings are represented by their hashes on the GPU. */
|
||||
typedef size_t DeviceString;
|
||||
#elif defined(OPENIMAGEIO_USTRING_H)
|
||||
ustring str_;
|
||||
|
||||
ccl_device_inline_method uint64_t hash() const
|
||||
{
|
||||
return str_.hash();
|
||||
}
|
||||
typedef ustring DeviceString;
|
||||
#else
|
||||
const char *str_;
|
||||
typedef const char *DeviceString;
|
||||
#endif
|
||||
|
||||
ccl_device_inline_method bool operator==(DeviceString b) const
|
||||
{
|
||||
return str_ == b.str_;
|
||||
}
|
||||
ccl_device_inline_method bool operator!=(DeviceString b) const
|
||||
{
|
||||
return str_ != b.str_;
|
||||
}
|
||||
};
|
||||
|
||||
ccl_device_inline DeviceString make_string(const char *str, size_t hash)
|
||||
{
|
||||
#if defined(__KERNEL_GPU__)
|
||||
(void)str;
|
||||
return {hash};
|
||||
return hash;
|
||||
#elif defined(OPENIMAGEIO_USTRING_H)
|
||||
(void)hash;
|
||||
return {ustring(str)};
|
||||
return ustring(str);
|
||||
#else
|
||||
(void)hash;
|
||||
return {str};
|
||||
return str;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include "kernel/sample/util.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
#pragma once
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device uint pmj_shuffled_sample_index(KernelGlobals kg, uint sample, uint dimension, uint seed)
|
||||
{
|
||||
const uint sample_count = kernel_data.integrator.pmj_sequence_size;
|
||||
|
||||
/* Shuffle the pattern order and sample index to better decorrelate
|
||||
* dimensions and make the most of the finite patterns we have.
|
||||
* The funky sample mask stuff is to ensure that we only shuffle
|
||||
* *within* the current sample pattern, which is necessary to avoid
|
||||
* early repeat pattern use. */
|
||||
const uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed);
|
||||
/* sample_count should always be a power of two, so this results in a mask. */
|
||||
const uint sample_mask = sample_count - 1;
|
||||
const uint sample_shuffled = nested_uniform_scramble(sample,
|
||||
hash_wang_seeded_uint(dimension, seed));
|
||||
sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask);
|
||||
|
||||
return ((pattern_i * sample_count) + sample) % (sample_count * NUM_PMJ_PATTERNS);
|
||||
}
|
||||
|
||||
ccl_device float pmj_sample_1D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = pmj_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
x -= floorf(x);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
ccl_device float2 pmj_sample_2D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = pmj_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS);
|
||||
float y = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS + 1);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
y += jitter_y;
|
||||
x -= floorf(x);
|
||||
y -= floorf(y);
|
||||
}
|
||||
|
||||
return make_float2(x, y);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "kernel/sample/jitter.h"
|
||||
#include "kernel/sample/sobol_burley.h"
|
||||
#include "kernel/sample/tabulated_sobol.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@ -23,10 +23,11 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg,
|
|||
#endif
|
||||
|
||||
if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) {
|
||||
return sobol_burley_sample_1D(sample, dimension, rng_hash);
|
||||
const uint index_mask = kernel_data.integrator.sobol_index_mask;
|
||||
return sobol_burley_sample_1D(sample, dimension, rng_hash, index_mask);
|
||||
}
|
||||
else {
|
||||
return pmj_sample_1D(kg, sample, rng_hash, dimension);
|
||||
return tabulated_sobol_sample_1D(kg, sample, rng_hash, dimension);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,10 +41,47 @@ ccl_device_forceinline float2 path_rng_2D(KernelGlobals kg,
|
|||
#endif
|
||||
|
||||
if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) {
|
||||
return sobol_burley_sample_2D(sample, dimension, rng_hash);
|
||||
const uint index_mask = kernel_data.integrator.sobol_index_mask;
|
||||
return sobol_burley_sample_2D(sample, dimension, rng_hash, index_mask);
|
||||
}
|
||||
else {
|
||||
return pmj_sample_2D(kg, sample, rng_hash, dimension);
|
||||
return tabulated_sobol_sample_2D(kg, sample, rng_hash, dimension);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline float3 path_rng_3D(KernelGlobals kg,
|
||||
uint rng_hash,
|
||||
int sample,
|
||||
int dimension)
|
||||
{
|
||||
#ifdef __DEBUG_CORRELATION__
|
||||
return make_float3((float)drand48(), (float)drand48(), (float)drand48());
|
||||
#endif
|
||||
|
||||
if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) {
|
||||
const uint index_mask = kernel_data.integrator.sobol_index_mask;
|
||||
return sobol_burley_sample_3D(sample, dimension, rng_hash, index_mask);
|
||||
}
|
||||
else {
|
||||
return tabulated_sobol_sample_3D(kg, sample, rng_hash, dimension);
|
||||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline float4 path_rng_4D(KernelGlobals kg,
|
||||
uint rng_hash,
|
||||
int sample,
|
||||
int dimension)
|
||||
{
|
||||
#ifdef __DEBUG_CORRELATION__
|
||||
return make_float4((float)drand48(), (float)drand48(), (float)drand48(), (float)drand48());
|
||||
#endif
|
||||
|
||||
if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) {
|
||||
const uint index_mask = kernel_data.integrator.sobol_index_mask;
|
||||
return sobol_burley_sample_4D(sample, dimension, rng_hash, index_mask);
|
||||
}
|
||||
else {
|
||||
return tabulated_sobol_sample_4D(kg, sample, rng_hash, dimension);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,7 +135,7 @@ ccl_device_inline uint path_rng_hash_init(KernelGlobals kg,
|
|||
ccl_device_inline bool sample_is_class_A(int pattern, int sample)
|
||||
{
|
||||
#if 0
|
||||
if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
|
||||
if (!(pattern == SAMPLING_PATTERN_TABULATED_SOBOL || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) {
|
||||
/* Fallback: assign samples randomly.
|
||||
* This is guaranteed to work "okay" for any sampler, but isn't good.
|
||||
* (NOTE: the seed constant is just a random number to guard against
|
||||
|
@ -114,8 +152,8 @@ ccl_device_inline bool sample_is_class_A(int pattern, int sample)
|
|||
* Multi-Jittered Sample Sequences" by Christensen et al., but
|
||||
* implemented with efficient bit-fiddling.
|
||||
*
|
||||
* This approach also turns out to work equally well with Sobol-Burley
|
||||
* (see https://developer.blender.org/D15746#429471).
|
||||
* This approach also turns out to work equally well with Owen
|
||||
* scrambled and shuffled Sobol (see https://developer.blender.org/D15746#429471).
|
||||
*/
|
||||
return popcount(uint(sample) & 0xaaaaaaaa) & 1;
|
||||
}
|
||||
|
|
|
@ -65,31 +65,75 @@ ccl_device_forceinline float sobol_burley(uint rev_bit_index,
|
|||
}
|
||||
|
||||
/*
|
||||
* Computes a 1D Owen-scrambled and shuffled Sobol sample.
|
||||
* NOTE: the functions below intentionally produce samples that are
|
||||
* uncorrelated between functions. For example, a 1D sample and 2D
|
||||
* sample produced with the same index, dimension, and seed are
|
||||
* uncorrelated with each other. This allows more care-free usage
|
||||
* of the functions together, without having to worry about
|
||||
* e.g. 1D and 2D samples being accidentally correlated with each
|
||||
* other.
|
||||
*/
|
||||
ccl_device float sobol_burley_sample_1D(uint index, uint const dimension, uint seed)
|
||||
|
||||
/*
|
||||
* Computes a 1D Owen-scrambled and shuffled Sobol sample.
|
||||
*
|
||||
* `index` is the index of the sample in the sequence.
|
||||
*
|
||||
* `dimension` is which dimensions of the sample you want to fetch. Note
|
||||
* that different 1D dimensions are uncorrelated. For samples with > 1D
|
||||
* stratification, use the multi-dimensional sampling methods below.
|
||||
*
|
||||
* `seed`: different seeds produce statistically independent,
|
||||
* uncorrelated sequences.
|
||||
*
|
||||
* `shuffled_index_mask` limits the sample sequence length, improving
|
||||
* performance. It must be a string of binary 1 bits followed by a
|
||||
* string of binary 0 bits (e.g. 0xffff0000) for the sampler to operate
|
||||
* correctly. In general, `reverse_integer_bits(shuffled_index_mask)`
|
||||
* should be >= the maximum number of samples expected to be taken. A safe
|
||||
* default (but least performant) is 0xffffffff, for maximum sequence
|
||||
* length.
|
||||
*/
|
||||
ccl_device float sobol_burley_sample_1D(uint index,
|
||||
uint const dimension,
|
||||
uint seed,
|
||||
uint shuffled_index_mask)
|
||||
{
|
||||
/* Include the dimension in the seed, so we get decorrelated
|
||||
* sequences for different dimensions via shuffling. */
|
||||
seed ^= hash_hp_uint(dimension);
|
||||
|
||||
/* Shuffle. */
|
||||
/* Shuffle and mask. The masking is just for better
|
||||
* performance at low sample counts. */
|
||||
index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xbff95bfe);
|
||||
index &= shuffled_index_mask;
|
||||
|
||||
return sobol_burley(index, 0, seed ^ 0x635c77bd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Computes a 2D Owen-scrambled and shuffled Sobol sample.
|
||||
*
|
||||
* `dimension_set` is which two dimensions of the sample you want to
|
||||
* fetch. For example, 0 is the first two, 1 is the second two, etc.
|
||||
* The dimensions within a single set are stratified, but different sets
|
||||
* are uncorrelated.
|
||||
*
|
||||
* See sobol_burley_sample_1D for further usage details.
|
||||
*/
|
||||
ccl_device float2 sobol_burley_sample_2D(uint index, const uint dimension_set, uint seed)
|
||||
ccl_device float2 sobol_burley_sample_2D(uint index,
|
||||
const uint dimension_set,
|
||||
uint seed,
|
||||
uint shuffled_index_mask)
|
||||
{
|
||||
/* Include the dimension set in the seed, so we get decorrelated
|
||||
* sequences for different dimension sets via shuffling. */
|
||||
seed ^= hash_hp_uint(dimension_set);
|
||||
|
||||
/* Shuffle. */
|
||||
/* Shuffle and mask. The masking is just for better
|
||||
* performance at low sample counts. */
|
||||
index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xf8ade99a);
|
||||
index &= shuffled_index_mask;
|
||||
|
||||
return make_float2(sobol_burley(index, 0, seed ^ 0xe0aaaf76),
|
||||
sobol_burley(index, 1, seed ^ 0x94964d4e));
|
||||
|
@ -97,15 +141,27 @@ ccl_device float2 sobol_burley_sample_2D(uint index, const uint dimension_set, u
|
|||
|
||||
/*
|
||||
* Computes a 3D Owen-scrambled and shuffled Sobol sample.
|
||||
*
|
||||
* `dimension_set` is which three dimensions of the sample you want to
|
||||
* fetch. For example, 0 is the first three, 1 is the second three, etc.
|
||||
* The dimensions within a single set are stratified, but different sets
|
||||
* are uncorrelated.
|
||||
*
|
||||
* See sobol_burley_sample_1D for further usage details.
|
||||
*/
|
||||
ccl_device float3 sobol_burley_sample_3D(uint index, const uint dimension_set, uint seed)
|
||||
ccl_device float3 sobol_burley_sample_3D(uint index,
|
||||
const uint dimension_set,
|
||||
uint seed,
|
||||
uint shuffled_index_mask)
|
||||
{
|
||||
/* Include the dimension set in the seed, so we get decorrelated
|
||||
* sequences for different dimension sets via shuffling. */
|
||||
seed ^= hash_hp_uint(dimension_set);
|
||||
|
||||
/* Shuffle. */
|
||||
/* Shuffle and mask. The masking is just for better
|
||||
* performance at low sample counts. */
|
||||
index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xcaa726ac);
|
||||
index &= shuffled_index_mask;
|
||||
|
||||
return make_float3(sobol_burley(index, 0, seed ^ 0x9e78e391),
|
||||
sobol_burley(index, 1, seed ^ 0x67c33241),
|
||||
|
@ -114,15 +170,27 @@ ccl_device float3 sobol_burley_sample_3D(uint index, const uint dimension_set, u
|
|||
|
||||
/*
|
||||
* Computes a 4D Owen-scrambled and shuffled Sobol sample.
|
||||
*
|
||||
* `dimension_set` is which four dimensions of the sample you want to
|
||||
* fetch. For example, 0 is the first four, 1 is the second four, etc.
|
||||
* The dimensions within a single set are stratified, but different sets
|
||||
* are uncorrelated.
|
||||
*
|
||||
* See sobol_burley_sample_1D for further usage details.
|
||||
*/
|
||||
ccl_device float4 sobol_burley_sample_4D(uint index, const uint dimension_set, uint seed)
|
||||
ccl_device float4 sobol_burley_sample_4D(uint index,
|
||||
const uint dimension_set,
|
||||
uint seed,
|
||||
uint shuffled_index_mask)
|
||||
{
|
||||
/* Include the dimension set in the seed, so we get decorrelated
|
||||
* sequences for different dimension sets via shuffling. */
|
||||
seed ^= hash_hp_uint(dimension_set);
|
||||
|
||||
/* Shuffle. */
|
||||
/* Shuffle and mask. The masking is just for better
|
||||
* performance at low sample counts. */
|
||||
index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xc2c1a055);
|
||||
index &= shuffled_index_mask;
|
||||
|
||||
return make_float4(sobol_burley(index, 0, seed ^ 0x39468210),
|
||||
sobol_burley(index, 1, seed ^ 0xe9d8a845),
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include "kernel/sample/util.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
#pragma once
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device uint tabulated_sobol_shuffled_sample_index(KernelGlobals kg,
|
||||
uint sample,
|
||||
uint dimension,
|
||||
uint seed)
|
||||
{
|
||||
const uint sample_count = kernel_data.integrator.tabulated_sobol_sequence_size;
|
||||
|
||||
/* Shuffle the pattern order and sample index to decorrelate
|
||||
* dimensions and make the most of the finite patterns we have.
|
||||
* The funky sample mask stuff is to ensure that we only shuffle
|
||||
* *within* the current sample pattern, which is necessary to avoid
|
||||
* early repeat pattern use. */
|
||||
const uint pattern_i = hash_shuffle_uint(dimension, NUM_TAB_SOBOL_PATTERNS, seed);
|
||||
/* sample_count should always be a power of two, so this results in a mask. */
|
||||
const uint sample_mask = sample_count - 1;
|
||||
const uint sample_shuffled = nested_uniform_scramble(sample,
|
||||
hash_wang_seeded_uint(dimension, seed));
|
||||
sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask);
|
||||
|
||||
return ((pattern_i * sample_count) + sample) % (sample_count * NUM_TAB_SOBOL_PATTERNS);
|
||||
}
|
||||
|
||||
ccl_device float tabulated_sobol_sample_1D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
x -= floorf(x);
|
||||
}
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
ccl_device float2 tabulated_sobol_sample_2D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
|
||||
float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
y += jitter_y;
|
||||
x -= floorf(x);
|
||||
y -= floorf(y);
|
||||
}
|
||||
|
||||
return make_float2(x, y);
|
||||
}
|
||||
|
||||
ccl_device float3 tabulated_sobol_sample_3D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
|
||||
float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
|
||||
float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
y += jitter_y;
|
||||
z += jitter_z;
|
||||
x -= floorf(x);
|
||||
y -= floorf(y);
|
||||
z -= floorf(z);
|
||||
}
|
||||
|
||||
return make_float3(x, y, z);
|
||||
}
|
||||
|
||||
ccl_device float4 tabulated_sobol_sample_4D(KernelGlobals kg,
|
||||
uint sample,
|
||||
const uint rng_hash,
|
||||
const uint dimension)
|
||||
{
|
||||
uint seed = rng_hash;
|
||||
|
||||
/* Use the same sample sequence seed for all pixels when using
|
||||
* scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
seed = kernel_data.integrator.seed;
|
||||
}
|
||||
|
||||
/* Fetch the sample. */
|
||||
const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed);
|
||||
float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS);
|
||||
float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1);
|
||||
float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2);
|
||||
float w = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 3);
|
||||
|
||||
/* Do limited Cranley-Patterson rotation when using scrambling distance. */
|
||||
if (kernel_data.integrator.scrambling_distance < 1.0f) {
|
||||
const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
const float jitter_w = hash_wang_seeded_float(dimension, rng_hash ^ 0x99634d1d) *
|
||||
kernel_data.integrator.scrambling_distance;
|
||||
x += jitter_x;
|
||||
y += jitter_y;
|
||||
z += jitter_z;
|
||||
w += jitter_w;
|
||||
x -= floorf(x);
|
||||
y -= floorf(y);
|
||||
z -= floorf(z);
|
||||
w -= floorf(w);
|
||||
}
|
||||
|
||||
return make_float4(x, y, z, w);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -148,8 +148,7 @@ CCL_NAMESPACE_BEGIN
|
|||
enum PathTraceDimension {
|
||||
/* Init bounce */
|
||||
PRNG_FILTER = 0,
|
||||
PRNG_LENS = 1,
|
||||
PRNG_TIME = 2,
|
||||
PRNG_LENS_TIME = 1,
|
||||
|
||||
/* Shade bounce */
|
||||
PRNG_TERMINATE = 0,
|
||||
|
@ -187,7 +186,7 @@ enum PathTraceDimension {
|
|||
|
||||
enum SamplingPattern {
|
||||
SAMPLING_PATTERN_SOBOL_BURLEY = 0,
|
||||
SAMPLING_PATTERN_PMJ = 1,
|
||||
SAMPLING_PATTERN_TABULATED_SOBOL = 1,
|
||||
|
||||
SAMPLING_NUM_PATTERNS,
|
||||
};
|
||||
|
@ -1032,13 +1031,28 @@ typedef struct LocalIntersection {
|
|||
typedef struct KernelCamera {
|
||||
/* type */
|
||||
int type;
|
||||
int use_dof_or_motion_blur;
|
||||
|
||||
/* depth of field */
|
||||
float aperturesize;
|
||||
float blades;
|
||||
float bladesrotation;
|
||||
float focaldistance;
|
||||
|
||||
/* motion blur */
|
||||
float shuttertime;
|
||||
int num_motion_steps, have_perspective_motion;
|
||||
|
||||
int pad1;
|
||||
int pad2;
|
||||
int pad3;
|
||||
|
||||
/* panorama */
|
||||
int panorama_type;
|
||||
float fisheye_fov;
|
||||
float fisheye_lens;
|
||||
float4 equirectangular_range;
|
||||
float fisheye_lens_polynomial_bias;
|
||||
float4 equirectangular_range;
|
||||
float4 fisheye_lens_polynomial_coefficients;
|
||||
|
||||
/* stereo */
|
||||
|
@ -1055,16 +1069,6 @@ typedef struct KernelCamera {
|
|||
float4 dx;
|
||||
float4 dy;
|
||||
|
||||
/* depth of field */
|
||||
float aperturesize;
|
||||
float blades;
|
||||
float bladesrotation;
|
||||
float focaldistance;
|
||||
|
||||
/* motion blur */
|
||||
float shuttertime;
|
||||
int num_motion_steps, have_perspective_motion;
|
||||
|
||||
/* clipping */
|
||||
float nearclip;
|
||||
float cliplength;
|
||||
|
@ -1075,7 +1079,6 @@ typedef struct KernelCamera {
|
|||
|
||||
/* render size */
|
||||
float width, height;
|
||||
int pad1;
|
||||
|
||||
/* anamorphic lens bokeh */
|
||||
float inv_aperture_ratio;
|
||||
|
@ -1466,15 +1469,15 @@ typedef struct KernelShaderEvalInput {
|
|||
} KernelShaderEvalInput;
|
||||
static_assert_align(KernelShaderEvalInput, 16);
|
||||
|
||||
/* Pre-computed sample table sizes for PMJ02 sampler.
|
||||
/* Pre-computed sample table sizes for the tabulated Sobol sampler.
|
||||
*
|
||||
* NOTE: min and max samples *must* be a power of two, and patterns
|
||||
* ideally should be as well.
|
||||
*/
|
||||
#define MIN_PMJ_SAMPLES 256
|
||||
#define MAX_PMJ_SAMPLES 8192
|
||||
#define NUM_PMJ_DIMENSIONS 2
|
||||
#define NUM_PMJ_PATTERNS 256
|
||||
#define MIN_TAB_SOBOL_SAMPLES 256
|
||||
#define MAX_TAB_SOBOL_SAMPLES 8192
|
||||
#define NUM_TAB_SOBOL_DIMENSIONS 4
|
||||
#define NUM_TAB_SOBOL_PATTERNS 256
|
||||
|
||||
/* Device kernels.
|
||||
*
|
||||
|
|
|
@ -23,7 +23,6 @@ set(SRC
|
|||
image_sky.cpp
|
||||
image_vdb.cpp
|
||||
integrator.cpp
|
||||
jitter.cpp
|
||||
light.cpp
|
||||
light_tree.cpp
|
||||
mesh.cpp
|
||||
|
@ -43,6 +42,7 @@ set(SRC
|
|||
stats.cpp
|
||||
svm.cpp
|
||||
tables.cpp
|
||||
tabulated_sobol.cpp
|
||||
volume.cpp
|
||||
)
|
||||
|
||||
|
@ -65,7 +65,6 @@ set(SRC_HEADERS
|
|||
integrator.h
|
||||
light.h
|
||||
light_tree.h
|
||||
jitter.h
|
||||
mesh.h
|
||||
object.h
|
||||
osl.h
|
||||
|
@ -81,6 +80,7 @@ set(SRC_HEADERS
|
|||
stats.h
|
||||
svm.h
|
||||
tables.h
|
||||
tabulated_sobol.h
|
||||
volume.h
|
||||
)
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
#include "scene/camera.h"
|
||||
#include "scene/film.h"
|
||||
#include "scene/integrator.h"
|
||||
#include "scene/jitter.h"
|
||||
#include "scene/light.h"
|
||||
#include "scene/object.h"
|
||||
#include "scene/scene.h"
|
||||
#include "scene/shader.h"
|
||||
#include "scene/stats.h"
|
||||
#include "scene/tabulated_sobol.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
|
||||
|
@ -107,8 +107,11 @@ NODE_DEFINE(Integrator)
|
|||
|
||||
static NodeEnum sampling_pattern_enum;
|
||||
sampling_pattern_enum.insert("sobol_burley", SAMPLING_PATTERN_SOBOL_BURLEY);
|
||||
sampling_pattern_enum.insert("pmj", SAMPLING_PATTERN_PMJ);
|
||||
SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_PMJ);
|
||||
sampling_pattern_enum.insert("tabulated_sobol", SAMPLING_PATTERN_TABULATED_SOBOL);
|
||||
SOCKET_ENUM(sampling_pattern,
|
||||
"Sampling Pattern",
|
||||
sampling_pattern_enum,
|
||||
SAMPLING_PATTERN_TABULATED_SOBOL);
|
||||
SOCKET_FLOAT(scrambling_distance, "Scrambling Distance", 1.0f);
|
||||
|
||||
static NodeEnum denoiser_type_enum;
|
||||
|
@ -250,6 +253,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||
|
||||
kintegrator->sampling_pattern = sampling_pattern;
|
||||
kintegrator->scrambling_distance = scrambling_distance;
|
||||
kintegrator->sobol_index_mask = reverse_integer_bits(next_power_of_two(aa_samples - 1) - 1);
|
||||
|
||||
kintegrator->use_light_tree = scene->integrator->use_light_tree;
|
||||
if (light_sampling_threshold > 0.0f) {
|
||||
|
@ -259,23 +263,23 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
|
|||
kintegrator->light_inv_rr_threshold = 0.0f;
|
||||
}
|
||||
|
||||
constexpr int num_sequences = NUM_PMJ_PATTERNS;
|
||||
int sequence_size = clamp(next_power_of_two(aa_samples - 1), MIN_PMJ_SAMPLES, MAX_PMJ_SAMPLES);
|
||||
if (kintegrator->sampling_pattern == SAMPLING_PATTERN_PMJ &&
|
||||
/* Build pre-tabulated Sobol samples if needed. */
|
||||
int sequence_size = clamp(
|
||||
next_power_of_two(aa_samples - 1), MIN_TAB_SOBOL_SAMPLES, MAX_TAB_SOBOL_SAMPLES);
|
||||
if (kintegrator->sampling_pattern == SAMPLING_PATTERN_TABULATED_SOBOL &&
|
||||
dscene->sample_pattern_lut.size() !=
|
||||
(sequence_size * NUM_PMJ_DIMENSIONS * NUM_PMJ_PATTERNS)) {
|
||||
kintegrator->pmj_sequence_size = sequence_size;
|
||||
(sequence_size * NUM_TAB_SOBOL_PATTERNS * NUM_TAB_SOBOL_DIMENSIONS)) {
|
||||
kintegrator->tabulated_sobol_sequence_size = sequence_size;
|
||||
|
||||
if (dscene->sample_pattern_lut.size() != 0) {
|
||||
dscene->sample_pattern_lut.free();
|
||||
}
|
||||
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences *
|
||||
NUM_PMJ_DIMENSIONS);
|
||||
float4 *directions = (float4 *)dscene->sample_pattern_lut.alloc(
|
||||
sequence_size * NUM_TAB_SOBOL_PATTERNS * NUM_TAB_SOBOL_DIMENSIONS);
|
||||
TaskPool pool;
|
||||
for (int j = 0; j < num_sequences; ++j) {
|
||||
float2 *sequence = directions + j * sequence_size;
|
||||
pool.push(
|
||||
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
|
||||
for (int j = 0; j < NUM_TAB_SOBOL_PATTERNS; ++j) {
|
||||
float4 *sequence = directions + j * sequence_size;
|
||||
pool.push(function_bind(&tabulated_sobol_generate_4D, sequence, sequence_size, j));
|
||||
}
|
||||
pool.wait_work();
|
||||
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2019-2022 Blender Foundation */
|
||||
|
||||
/* This file is based on "Progressive Multi-Jittered Sample Sequences"
|
||||
* by Christensen, Kensler, and Kilpatrick, but with a much simpler and
|
||||
* faster implementation based on "Stochastic Generation of (t, s)
|
||||
* Sample Sequences" by Helmer, Christensen, and Kensler.
|
||||
*/
|
||||
|
||||
#include "scene/jitter.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void progressive_multi_jitter_02_generate_2D(float2 points[], int size, int rng_seed)
|
||||
{
|
||||
/* Xor values for generating the PMJ02 sequence. These permute the
|
||||
* order we visit the strata in, which is what makes the code below
|
||||
* produce the PMJ02 sequence. Other choices are also possible, but
|
||||
* result in different sequences. */
|
||||
static uint xors[2][32] = {
|
||||
{0x00000000, 0x00000000, 0x00000002, 0x00000006, 0x00000006, 0x0000000e, 0x00000036,
|
||||
0x0000004e, 0x00000016, 0x0000002e, 0x00000276, 0x000006ce, 0x00000716, 0x00000c2e,
|
||||
0x00003076, 0x000040ce, 0x00000116, 0x0000022e, 0x00020676, 0x00060ece, 0x00061716,
|
||||
0x000e2c2e, 0x00367076, 0x004ec0ce, 0x00170116, 0x002c022e, 0x02700676, 0x06c00ece,
|
||||
0x07001716, 0x0c002c2e, 0x30007076, 0x4000c0ce},
|
||||
{0x00000000, 0x00000001, 0x00000003, 0x00000003, 0x00000007, 0x0000001b, 0x00000027,
|
||||
0x0000000b, 0x00000017, 0x0000013b, 0x00000367, 0x0000038b, 0x00000617, 0x0000183b,
|
||||
0x00002067, 0x0000008b, 0x00000117, 0x0001033b, 0x00030767, 0x00030b8b, 0x00071617,
|
||||
0x001b383b, 0x00276067, 0x000b808b, 0x00160117, 0x0138033b, 0x03600767, 0x03800b8b,
|
||||
0x06001617, 0x1800383b, 0x20006067, 0x0000808b}};
|
||||
|
||||
uint rng_i = rng_seed;
|
||||
|
||||
points[0].x = hash_hp_float(rng_i++);
|
||||
points[0].y = hash_hp_float(rng_i++);
|
||||
|
||||
/* Subdivide the domain into smaller and smaller strata, filling in new
|
||||
* points as we go. */
|
||||
for (int log_N = 0, N = 1; N < size; log_N++, N *= 2) {
|
||||
float strata_count = (float)(N * 2);
|
||||
for (int i = 0; i < N && (N + i) < size; i++) {
|
||||
/* Find the strata that are already occupied in this cell. */
|
||||
uint occupied_x_stratum = (uint)(points[i ^ xors[0][log_N]].x * strata_count);
|
||||
uint occupied_y_stratum = (uint)(points[i ^ xors[1][log_N]].y * strata_count);
|
||||
|
||||
/* Generate a new point in the unoccupied strata. */
|
||||
points[N + i].x = ((float)(occupied_x_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
points[N + i].y = ((float)(occupied_y_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -1,15 +0,0 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2019-2022 Blender Foundation */
|
||||
|
||||
#ifndef __JITTER_H__
|
||||
#define __JITTER_H__
|
||||
|
||||
#include "util/types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void progressive_multi_jitter_02_generate_2D(float2 points[], int size, int rng_seed);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __JITTER_H__ */
|
|
@ -257,6 +257,9 @@ void Scene::device_update(Device *device_, Progress &progress)
|
|||
light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED);
|
||||
object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED);
|
||||
}
|
||||
if (film->exposure_is_modified()) {
|
||||
integrator->tag_modified();
|
||||
}
|
||||
|
||||
progress.set_status("Updating Shaders");
|
||||
shader_manager->device_update(device, &dscene, this, progress);
|
||||
|
|
|
@ -226,6 +226,7 @@ NODE_DEFINE(ImageTextureNode)
|
|||
extension_enum.insert("periodic", EXTENSION_REPEAT);
|
||||
extension_enum.insert("clamp", EXTENSION_EXTEND);
|
||||
extension_enum.insert("black", EXTENSION_CLIP);
|
||||
extension_enum.insert("mirror", EXTENSION_MIRROR);
|
||||
SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT);
|
||||
|
||||
static NodeEnum projection_enum;
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2019-2022 Blender Foundation */
|
||||
|
||||
/* This file is based on the paper "Stochastic Generation of (t, s)
|
||||
* Sample Sequences" by Helmer, Christensen, and Kensler.
|
||||
*/
|
||||
|
||||
#include "scene/tabulated_sobol.h"
|
||||
#include "util/hash.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void tabulated_sobol_generate_4D(float4 points[], int size, int rng_seed)
|
||||
{
|
||||
/* Xor values for generating the (4D) Owen-scrambled Sobol sequence.
|
||||
* These permute the order we visit the strata in, which is what
|
||||
* makes the code below produce the scrambled Sobol sequence. Other
|
||||
* choices are also possible, but result in different sequences. */
|
||||
static uint xors[4][32] = {
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
{0x00000000, 0x00000001, 0x00000001, 0x00000007, 0x00000001, 0x00000013, 0x00000015,
|
||||
0x0000007f, 0x00000001, 0x00000103, 0x00000105, 0x0000070f, 0x00000111, 0x00001333,
|
||||
0x00001555, 0x00007fff, 0x00000001, 0x00010003, 0x00010005, 0x0007000f, 0x00010011,
|
||||
0x00130033, 0x00150055, 0x007f00ff, 0x00010101, 0x01030303, 0x01050505, 0x070f0f0f,
|
||||
0x01111111, 0x13333333, 0x15555555, 0x7fffffff},
|
||||
{0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x00000005, 0x0000001f, 0x0000002b,
|
||||
0x0000003d, 0x00000011, 0x00000133, 0x00000377, 0x00000199, 0x00000445, 0x00001ccf,
|
||||
0x00002ddb, 0x0000366d, 0x00000101, 0x00010303, 0x00030707, 0x00010909, 0x00051515,
|
||||
0x001f3f3f, 0x002b6b6b, 0x003dbdbd, 0x00101011, 0x01303033, 0x03707077, 0x01909099,
|
||||
0x04515145, 0x1cf3f3cf, 0x2db6b6db, 0x36dbdb6d},
|
||||
{0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x0000000d, 0x0000000c, 0x00000005,
|
||||
0x0000004f, 0x00000014, 0x000000e7, 0x00000329, 0x0000039c, 0x00000011, 0x00001033,
|
||||
0x00000044, 0x000030bb, 0x0000d1cd, 0x0000c2ec, 0x00005415, 0x0004fc3f, 0x00015054,
|
||||
0x000e5c97, 0x0032e5b9, 0x0039725c, 0x00000101, 0x01000303, 0x00000404, 0x03000b0b,
|
||||
0x0d001d1d, 0x0c002c2c, 0x05004545, 0x4f00cfcf},
|
||||
};
|
||||
|
||||
/* Randomize the seed, in case it's incrementing. The constant is just a
|
||||
* random number, and has no other significance. */
|
||||
uint rng_i = hash_hp_seeded_uint(rng_seed, 0x44605a73);
|
||||
|
||||
points[0].x = hash_hp_float(rng_i++);
|
||||
points[0].y = hash_hp_float(rng_i++);
|
||||
points[0].z = hash_hp_float(rng_i++);
|
||||
points[0].w = hash_hp_float(rng_i++);
|
||||
|
||||
/* Subdivide the domain into smaller and smaller strata, filling in new
|
||||
* points as we go. */
|
||||
for (int log_N = 0, N = 1; N < size; log_N++, N *= 2) {
|
||||
float strata_count = (float)(N * 2);
|
||||
for (int i = 0; i < N && (N + i) < size; i++) {
|
||||
/* Find the strata that are already occupied in this cell. */
|
||||
uint occupied_x_stratum = (uint)(points[i ^ xors[0][log_N]].x * strata_count);
|
||||
uint occupied_y_stratum = (uint)(points[i ^ xors[1][log_N]].y * strata_count);
|
||||
uint occupied_z_stratum = (uint)(points[i ^ xors[2][log_N]].z * strata_count);
|
||||
uint occupied_w_stratum = (uint)(points[i ^ xors[3][log_N]].w * strata_count);
|
||||
|
||||
/* Generate a new point in the unoccupied strata. */
|
||||
points[N + i].x = ((float)(occupied_x_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
points[N + i].y = ((float)(occupied_y_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
points[N + i].z = ((float)(occupied_z_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
points[N + i].w = ((float)(occupied_w_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2019-2022 Blender Foundation */
|
||||
|
||||
#ifndef __TABULATED_SOBOL_H__
|
||||
#define __TABULATED_SOBOL_H__
|
||||
|
||||
#include "util/types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void tabulated_sobol_generate_4D(float4 points[], int size, int rng_seed);
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __TABULATED_SOBOL_H__ */
|
|
@ -22,13 +22,26 @@ static bool validate_cpu_capabilities()
|
|||
#endif
|
||||
}
|
||||
|
||||
/* These are not just static variables because we don't want to run the
|
||||
* constructor until we know the instructions are supported. */
|
||||
static vfloat8 float8_a()
|
||||
{
|
||||
return make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f);
|
||||
}
|
||||
|
||||
static vfloat8 float8_b()
|
||||
{
|
||||
return make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f);
|
||||
}
|
||||
|
||||
static vfloat8 float8_c()
|
||||
{
|
||||
return make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f);
|
||||
}
|
||||
|
||||
#define INIT_FLOAT8_TEST \
|
||||
if (!validate_cpu_capabilities()) \
|
||||
return; \
|
||||
\
|
||||
const vfloat8 float8_a = make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f); \
|
||||
const vfloat8 float8_b = make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); \
|
||||
const vfloat8 float8_c = make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f);
|
||||
return;
|
||||
|
||||
#define compare_vector_scalar(a, b) \
|
||||
for (size_t index = 0; index < 8; index++) \
|
||||
|
@ -57,15 +70,15 @@ static bool validate_cpu_capabilities()
|
|||
|
||||
static const float float_b = 1.5f;
|
||||
|
||||
TEST(TEST_CATEGORY_NAME,
|
||||
float8_add_vv){basic_test_vv(float8_a, float8_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vv){
|
||||
basic_test_vv(float8_a, float8_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vv){
|
||||
basic_test_vv(float8_a, float8_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vv){
|
||||
basic_test_vv(float8_a, float8_b, /)} TEST(TEST_CATEGORY_NAME, float8_add_vf){
|
||||
basic_test_vf(float8_a, float_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vf){
|
||||
basic_test_vf(float8_a, float_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vf){
|
||||
basic_test_vf(float8_a, float_b, *)} TEST(TEST_CATEGORY_NAME,
|
||||
float8_div_vf){basic_test_vf(float8_a, float_b, /)}
|
||||
TEST(TEST_CATEGORY_NAME, float8_add_vv){
|
||||
basic_test_vv(float8_a(), float8_b(), +)} TEST(TEST_CATEGORY_NAME, float8_sub_vv){
|
||||
basic_test_vv(float8_a(), float8_b(), -)} TEST(TEST_CATEGORY_NAME, float8_mul_vv){
|
||||
basic_test_vv(float8_a(), float8_b(), *)} TEST(TEST_CATEGORY_NAME, float8_div_vv){
|
||||
basic_test_vv(float8_a(), float8_b(), /)} TEST(TEST_CATEGORY_NAME, float8_add_vf){
|
||||
basic_test_vf(float8_a(), float_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vf){
|
||||
basic_test_vf(float8_a(), float_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vf){
|
||||
basic_test_vf(float8_a(), float_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vf){
|
||||
basic_test_vf(float8_a(), float_b, /)}
|
||||
|
||||
TEST(TEST_CATEGORY_NAME, float8_ctor)
|
||||
{
|
||||
|
@ -85,18 +98,18 @@ TEST(TEST_CATEGORY_NAME, float8_sqrt)
|
|||
TEST(TEST_CATEGORY_NAME, float8_min_max)
|
||||
{
|
||||
INIT_FLOAT8_TEST
|
||||
compare_vector_vector(min(float8_a, float8_b), float8_a);
|
||||
compare_vector_vector(max(float8_a, float8_b), float8_b);
|
||||
compare_vector_vector(min(float8_a(), float8_b()), float8_a());
|
||||
compare_vector_vector(max(float8_a(), float8_b()), float8_b());
|
||||
}
|
||||
|
||||
TEST(TEST_CATEGORY_NAME, float8_shuffle)
|
||||
{
|
||||
INIT_FLOAT8_TEST
|
||||
vfloat8 res0 = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(float8_a);
|
||||
vfloat8 res0 = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(float8_a());
|
||||
compare_vector_vector(res0, make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f, 0.7f, 0.5f));
|
||||
vfloat8 res1 = shuffle<3>(float8_a);
|
||||
vfloat8 res1 = shuffle<3>(float8_a());
|
||||
compare_vector_vector(res1, make_vfloat8(0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f));
|
||||
vfloat8 res2 = shuffle<3, 2, 1, 0>(float8_a, float8_b);
|
||||
vfloat8 res2 = shuffle<3, 2, 1, 0>(float8_a(), float8_b());
|
||||
compare_vector_vector(res2, make_vfloat8(0.4f, 0.3f, 2.0f, 1.0f, 0.8f, 0.7f, 6.0f, 5.0f));
|
||||
}
|
||||
|
||||
|
|
|
@ -65,6 +65,8 @@ typedef enum ExtensionType {
|
|||
EXTENSION_EXTEND = 1,
|
||||
/* Clip to image size and set exterior pixels as transparent. */
|
||||
EXTENSION_CLIP = 2,
|
||||
/* Repeatedly flip the image horizontally and vertically. */
|
||||
EXTENSION_MIRROR = 3,
|
||||
|
||||
EXTENSION_NUM_TYPES,
|
||||
} ExtensionType;
|
||||
|
|
|
@ -274,7 +274,7 @@ class GHOST_IWindow {
|
|||
*/
|
||||
virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0;
|
||||
|
||||
virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) = 0;
|
||||
virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const = 0;
|
||||
|
||||
virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode,
|
||||
GHOST_TAxisFlag &axis_flag,
|
||||
|
|
|
@ -5316,7 +5316,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background)
|
|||
/* Connect to the Wayland server. */
|
||||
display_->wl_display = wl_display_connect(nullptr);
|
||||
if (!display_->wl_display) {
|
||||
gwl_display_destroy(display_);
|
||||
this->~GHOST_SystemWayland();
|
||||
throw std::runtime_error("Wayland: unable to connect to display!");
|
||||
}
|
||||
|
||||
|
@ -5360,7 +5360,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background)
|
|||
"WAYLAND found but libdecor was not, install libdecor for Wayland support, "
|
||||
"falling back to X11\n");
|
||||
# endif
|
||||
gwl_display_destroy(display_);
|
||||
this->~GHOST_SystemWayland();
|
||||
throw std::runtime_error("Wayland: unable to find libdecor!");
|
||||
|
||||
use_libdecor = true;
|
||||
|
@ -5377,7 +5377,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background)
|
|||
GWL_LibDecor_System &decor = *display_->libdecor;
|
||||
decor.context = libdecor_new(display_->wl_display, &libdecor_interface);
|
||||
if (!decor.context) {
|
||||
gwl_display_destroy(display_);
|
||||
this->~GHOST_SystemWayland();
|
||||
throw std::runtime_error("Wayland: unable to create window decorations!");
|
||||
}
|
||||
}
|
||||
|
@ -5388,7 +5388,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background)
|
|||
{
|
||||
GWL_XDG_Decor_System &decor = *display_->xdg_decor;
|
||||
if (!decor.shell) {
|
||||
gwl_display_destroy(display_);
|
||||
this->~GHOST_SystemWayland();
|
||||
throw std::runtime_error("Wayland: unable to access xdg_shell!");
|
||||
}
|
||||
}
|
||||
|
@ -5830,8 +5830,36 @@ static GHOST_TSuccess getCursorPositionClientRelative_impl(
|
|||
int32_t &y)
|
||||
{
|
||||
const wl_fixed_t scale = win->scale();
|
||||
x = wl_fixed_to_int(scale * seat_state_pointer->xy[0]);
|
||||
y = wl_fixed_to_int(scale * seat_state_pointer->xy[1]);
|
||||
|
||||
if (win->getCursorGrabModeIsWarp()) {
|
||||
/* As the cursor is restored at the warped location,
|
||||
* apply warping when requesting the cursor location. */
|
||||
GHOST_Rect wrap_bounds{};
|
||||
if (win->getCursorGrabModeIsWarp()) {
|
||||
if (win->getCursorGrabBounds(wrap_bounds) == GHOST_kFailure) {
|
||||
win->getClientBounds(wrap_bounds);
|
||||
}
|
||||
}
|
||||
int xy_wrap[2] = {
|
||||
seat_state_pointer->xy[0],
|
||||
seat_state_pointer->xy[1],
|
||||
};
|
||||
|
||||
GHOST_Rect wrap_bounds_scale;
|
||||
wrap_bounds_scale.m_l = wl_fixed_from_int(wrap_bounds.m_l) / scale;
|
||||
wrap_bounds_scale.m_t = wl_fixed_from_int(wrap_bounds.m_t) / scale;
|
||||
wrap_bounds_scale.m_r = wl_fixed_from_int(wrap_bounds.m_r) / scale;
|
||||
wrap_bounds_scale.m_b = wl_fixed_from_int(wrap_bounds.m_b) / scale;
|
||||
wrap_bounds_scale.wrapPoint(UNPACK2(xy_wrap), 0, win->getCursorGrabAxis());
|
||||
|
||||
x = wl_fixed_to_int(scale * xy_wrap[0]);
|
||||
y = wl_fixed_to_int(scale * xy_wrap[1]);
|
||||
}
|
||||
else {
|
||||
x = wl_fixed_to_int(scale * seat_state_pointer->xy[0]);
|
||||
y = wl_fixed_to_int(scale * seat_state_pointer->xy[1]);
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
|
|
|
@ -1061,82 +1061,62 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
|||
|
||||
int32_t x_screen = screen_co[0], y_screen = screen_co[1];
|
||||
if (window->getCursorGrabModeIsWarp()) {
|
||||
/* WORKAROUND:
|
||||
* Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is
|
||||
* outdated. Identify these cases by checking if the cursor is not yet within bounds. */
|
||||
static bool is_warping_x = false;
|
||||
static bool is_warping_y = false;
|
||||
static uint64_t last_warp_time = 0;
|
||||
{
|
||||
/* WORKAROUND: Check the mouse event timestamp so we can ignore mousemove events that were
|
||||
* already in the queue before we changed the cursor position. */
|
||||
MOUSEMOVEPOINT mp = {x_screen, y_screen};
|
||||
::GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &mp, &mp, 1, GMMP_USE_DISPLAY_POINTS);
|
||||
if (mp.time <= last_warp_time) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t x_new = x_screen;
|
||||
int32_t y_new = y_screen;
|
||||
int32_t x_accum, y_accum;
|
||||
GHOST_Rect bounds;
|
||||
|
||||
/* Warp within bounds. */
|
||||
{
|
||||
GHOST_Rect bounds;
|
||||
int32_t bounds_margin = 0;
|
||||
GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone;
|
||||
|
||||
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
||||
window->getClientBounds(bounds);
|
||||
|
||||
/* WARNING(@campbellbarton): The current warping logic fails to warp on every event,
|
||||
* so the box needs to small enough not to let the cursor escape the window but large
|
||||
* enough that the cursor isn't being warped every time.
|
||||
* If this was not the case it would be less trouble to simply warp the cursor to the
|
||||
* center of the screen on every motion, see: D16558 (alternative fix for T102346). */
|
||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
||||
/* Shrink the box to prevent the cursor escaping. */
|
||||
bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
|
||||
bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
|
||||
bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
|
||||
bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
|
||||
bounds_margin = 0;
|
||||
bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY);
|
||||
}
|
||||
else {
|
||||
/* Fallback to window bounds. */
|
||||
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
|
||||
window->getClientBounds(bounds);
|
||||
}
|
||||
bounds_margin = 2;
|
||||
bounds_axis = window->getCursorGrabAxis();
|
||||
}
|
||||
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will
|
||||
* fail at the moment. Use inset in case the window is at screen bounds. */
|
||||
bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis);
|
||||
/* Fallback to window bounds. */
|
||||
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
|
||||
window->getClientBounds(bounds);
|
||||
}
|
||||
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will
|
||||
* fail at the moment. Use inset in case the window is at screen bounds. */
|
||||
bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis());
|
||||
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
if (x_new != x_screen || y_new != y_screen) {
|
||||
system->setCursorPosition(x_new, y_new); /* wrap */
|
||||
/* WORKAROUND: Store the current time so that we ignore outdated mousemove events. */
|
||||
last_warp_time = ::GetTickCount64();
|
||||
|
||||
/* Do not update the accum values if we are an outdated or failed pos-warp event. */
|
||||
if (!is_warping_x) {
|
||||
is_warping_x = x_new != x_screen;
|
||||
if (is_warping_x) {
|
||||
x_accum += (x_screen - x_new);
|
||||
}
|
||||
}
|
||||
/* For more control over which timestamp to store in the event, we use `SendInput` instead of
|
||||
* `SetCursorPos` here.
|
||||
* It is quite unlikely to happen, but still possible that some event between
|
||||
* `last_warp_time` and `GHOST_SystemWin32::setCursorPosition` is sent. */
|
||||
INPUT input[3] = {0};
|
||||
input[0].type = INPUT_MOUSE;
|
||||
input[0].mi.dx = (LONG)(x_new * (65535.0f / GetSystemMetrics(SM_CXSCREEN)));
|
||||
input[0].mi.dy = (LONG)(y_new * (65535.0f / GetSystemMetrics(SM_CYSCREEN)));
|
||||
input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
|
||||
input[0].mi.time = last_warp_time;
|
||||
|
||||
if (!is_warping_y) {
|
||||
is_warping_y = y_new != y_screen;
|
||||
if (is_warping_y) {
|
||||
y_accum += (y_screen - y_new);
|
||||
}
|
||||
}
|
||||
/* Send 3 events with a jitter to make sure Windows does not occasionally and
|
||||
* inexplicably ignore `SetCursorPos` or `SendInput`. */
|
||||
input[2] = input[1] = input[0];
|
||||
input[1].mi.dx += 1;
|
||||
::SendInput(3, input, sizeof(INPUT));
|
||||
|
||||
x_accum += (x_screen - x_new);
|
||||
y_accum += (y_screen - y_new);
|
||||
window->setCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
/* When wrapping we don't need to add an event because the setCursorPosition call will cause
|
||||
* a new event after. */
|
||||
/* When wrapping we don't need to add an event because the `SendInput` call will cause new
|
||||
* events after. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
is_warping_x = false;
|
||||
is_warping_y = false;
|
||||
x_screen += x_accum;
|
||||
y_screen += y_accum;
|
||||
}
|
||||
|
@ -1210,16 +1190,16 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
||||
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
||||
|
||||
if (!key_down) {
|
||||
/* Pass. */
|
||||
}
|
||||
/* We can be here with !key_down if processing dead keys (diacritics). See T103119. */
|
||||
|
||||
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
||||
else if (ctrl_pressed && !alt_pressed) {
|
||||
if (ctrl_pressed && !alt_pressed) {
|
||||
/* Pass. */
|
||||
}
|
||||
/* Don't call #ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical
|
||||
* composition. */
|
||||
else if (MapVirtualKeyW(vk, 2) != 0) {
|
||||
* composition. XXX: we are not checking return of MapVirtualKeyW for high bit set, which is
|
||||
* what is supposed to indicate dead keys. But this is working now so approach cautiously. */
|
||||
else if (MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) != 0) {
|
||||
wchar_t utf16[3] = {0};
|
||||
int r;
|
||||
/* TODO: #ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here).
|
||||
|
@ -1234,6 +1214,10 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||
utf8_char[0] = '\0';
|
||||
}
|
||||
}
|
||||
if (!key_down) {
|
||||
/* Clear or wm_event_add_ghostevent will warn of unexpected data on key up. */
|
||||
utf8_char[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
|
|
@ -275,10 +275,6 @@ uint8_t GHOST_SystemX11::getNumDisplays() const
|
|||
return uint8_t(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the main display on this system.
|
||||
* \return The dimension of the main display.
|
||||
*/
|
||||
void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const
|
||||
{
|
||||
if (m_display) {
|
||||
|
@ -289,10 +285,6 @@ void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the dimensions of the main display on this system.
|
||||
* \return The dimension of the main display.
|
||||
*/
|
||||
void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const
|
||||
{
|
||||
if (m_display) {
|
||||
|
@ -301,22 +293,6 @@ void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new window.
|
||||
* The new window is added to the list of windows managed.
|
||||
* Never explicitly delete the window, use #disposeWindow() instead.
|
||||
* \param title: The name of the window
|
||||
* (displayed in the title bar of the window if the OS supports it).
|
||||
* \param left: The coordinate of the left edge of the window.
|
||||
* \param top: The coordinate of the top edge of the window.
|
||||
* \param width: The width the window.
|
||||
* \param height: The height the window.
|
||||
* \param state: The state of the window when opened.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title,
|
||||
int32_t left,
|
||||
int32_t top,
|
||||
|
@ -417,11 +393,7 @@ static GHOST_Context *create_glx_context(Display *display,
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
/**
|
||||
* Create a new off-screen context.
|
||||
* Never explicitly delete the context, use #disposeContext() instead.
|
||||
* \return The new context (or 0 if creation failed).
|
||||
*/
|
||||
|
||||
GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings)
|
||||
{
|
||||
/* During development:
|
||||
|
@ -479,11 +451,6 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of a context.
|
||||
* \param context: Pointer to the context to be disposed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess GHOST_SystemX11::disposeContext(GHOST_IContext *context)
|
||||
{
|
||||
delete context;
|
||||
|
@ -950,48 +917,17 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
int32_t x_new = xme.x_root;
|
||||
int32_t y_new = xme.y_root;
|
||||
int32_t x_accum, y_accum;
|
||||
GHOST_Rect bounds;
|
||||
|
||||
/* Warp within bounds. */
|
||||
{
|
||||
GHOST_Rect bounds;
|
||||
int32_t bounds_margin = 0;
|
||||
GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone;
|
||||
|
||||
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
||||
window->getClientBounds(bounds);
|
||||
|
||||
/* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`,
|
||||
* on every motion event, see: D16557 (alternative fix for T102346). */
|
||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||
const int32_t center[2] = {
|
||||
(bounds.m_l + bounds.m_r) / 2,
|
||||
(bounds.m_t + bounds.m_b) / 2,
|
||||
};
|
||||
/* Shrink the box to prevent the cursor escaping. */
|
||||
bounds.m_l = center[0] - (size[0] / (subregion_div * 2));
|
||||
bounds.m_r = center[0] + (size[0] / (subregion_div * 2));
|
||||
bounds.m_t = center[1] - (size[1] / (subregion_div * 2));
|
||||
bounds.m_b = center[1] + (size[1] / (subregion_div * 2));
|
||||
bounds_margin = 0;
|
||||
bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY);
|
||||
}
|
||||
else {
|
||||
/* Fallback to window bounds. */
|
||||
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
|
||||
window->getClientBounds(bounds);
|
||||
}
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will
|
||||
* fail at the moment. Use offset of 8 in case the window is at screen bounds. */
|
||||
bounds_margin = 8;
|
||||
bounds_axis = window->getCursorGrabAxis();
|
||||
}
|
||||
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will
|
||||
* fail at the moment. Use inset in case the window is at screen bounds. */
|
||||
bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis);
|
||||
/* fallback to window bounds */
|
||||
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
|
||||
window->getClientBounds(bounds);
|
||||
}
|
||||
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will
|
||||
* fail at the moment. Use offset of 8 in case the window is at screen bounds. */
|
||||
bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
|
||||
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
if (x_new != xme.x_root || y_new != xme.y_root) {
|
||||
|
|
|
@ -175,7 +175,7 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode,
|
|||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds)
|
||||
GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) const
|
||||
{
|
||||
if (m_cursorGrab != GHOST_kGrabWrap) {
|
||||
return GHOST_kFailure;
|
||||
|
|
|
@ -152,7 +152,7 @@ class GHOST_Window : public GHOST_IWindow {
|
|||
* Gets the cursor grab region, if unset the window is used.
|
||||
* reset when grab is disabled.
|
||||
*/
|
||||
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) override;
|
||||
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override;
|
||||
|
||||
void getCursorGrabState(GHOST_TGrabCursorMode &mode,
|
||||
GHOST_TAxisFlag &axis_flag,
|
||||
|
|
|
@ -1203,10 +1203,6 @@ void GHOST_WindowWayland::setOpaque() const
|
|||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \param type: The type of rendering context create.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType type)
|
||||
{
|
||||
GHOST_Context *context;
|
||||
|
|
|
@ -1112,11 +1112,6 @@ void GHOST_WindowX11::validate()
|
|||
m_invalid_window = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
* Closes the window and disposes resources allocated.
|
||||
*/
|
||||
|
||||
GHOST_WindowX11::~GHOST_WindowX11()
|
||||
{
|
||||
std::map<uint, Cursor>::iterator it = m_standard_cursors.begin();
|
||||
|
|
|
@ -9,13 +9,24 @@ __all__ = (
|
|||
)
|
||||
|
||||
import bpy
|
||||
from typing import Mapping, List, Tuple, Sequence
|
||||
from bpy.types import Action
|
||||
|
||||
# (fcurve.data_path, fcurve.array_index)
|
||||
FCurveKey = Tuple[str, int]
|
||||
# [frame0, value0, frame1, value1, ...]
|
||||
from typing import (
|
||||
List,
|
||||
Mapping,
|
||||
Sequence,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
FCurveKey = Tuple[
|
||||
# `fcurve.data_path`.
|
||||
str,
|
||||
# `fcurve.array_index`.
|
||||
int,
|
||||
]
|
||||
|
||||
# List of `[frame0, value0, frame1, value1, ...]` pairs.
|
||||
ListKeyframes = List[float]
|
||||
Action = bpy.types.Action
|
||||
|
||||
|
||||
def bake_action(
|
||||
|
@ -144,11 +155,11 @@ def bake_action_iter(
|
|||
|
||||
# Note: BBONE_PROPS is a list so we can preserve the ordering
|
||||
BBONE_PROPS = [
|
||||
'bbone_curveinx', 'bbone_curveoutx',
|
||||
'bbone_curveinz', 'bbone_curveoutz',
|
||||
'bbone_rollin', 'bbone_rollout',
|
||||
'bbone_scalein', 'bbone_scaleout',
|
||||
'bbone_easein', 'bbone_easeout'
|
||||
"bbone_curveinx", "bbone_curveoutx",
|
||||
"bbone_curveinz", "bbone_curveoutz",
|
||||
"bbone_rollin", "bbone_rollout",
|
||||
"bbone_scalein", "bbone_scaleout",
|
||||
"bbone_easein", "bbone_easeout",
|
||||
]
|
||||
BBONE_PROPS_LENGTHS = {
|
||||
"bbone_curveinx": 1,
|
||||
|
@ -433,14 +444,18 @@ def bake_action_iter(
|
|||
|
||||
|
||||
class KeyframesCo:
|
||||
"""A buffer for keyframe Co unpacked values per FCurveKey. FCurveKeys are added using
|
||||
add_paths(), Co values stored using extend_co_values(), then finally use
|
||||
insert_keyframes_into_*_action() for efficiently inserting keys into the fcurves.
|
||||
"""
|
||||
A buffer for keyframe Co unpacked values per ``FCurveKey``. ``FCurveKeys`` are added using
|
||||
``add_paths()``, Co values stored using extend_co_values(), then finally use
|
||||
``insert_keyframes_into_*_action()`` for efficiently inserting keys into the F-curves.
|
||||
|
||||
Users are limited to one Action Group per instance.
|
||||
"""
|
||||
__slots__ = (
|
||||
"keyframes_from_fcurve",
|
||||
)
|
||||
|
||||
# keyframes[(rna_path, array_index)] = list(time0,value0, time1,value1,...)
|
||||
# `keyframes[(rna_path, array_index)] = list(time0,value0, time1,value1,...)`.
|
||||
keyframes_from_fcurve: Mapping[FCurveKey, ListKeyframes]
|
||||
|
||||
def __init__(self):
|
||||
|
@ -480,11 +495,12 @@ class KeyframesCo:
|
|||
action: Action,
|
||||
action_group_name: str,
|
||||
) -> None:
|
||||
"""Assumes the action is new, that it has no fcurves. Otherwise, the only difference between versions is
|
||||
"""
|
||||
Assumes the action is new, that it has no F-curves. Otherwise, the only difference between versions is
|
||||
performance and implementation simplicity.
|
||||
|
||||
Args:
|
||||
action_group_name (str): Name of Action Group that fcurves are added to.
|
||||
:arg action_group_name: Name of Action Group that F-curves are added to.
|
||||
:type action_group_name: str
|
||||
"""
|
||||
linear_enum_values = [
|
||||
bpy.types.Keyframe.bl_rna.properties["interpolation"].enum_items["LINEAR"].value
|
||||
|
@ -513,14 +529,15 @@ class KeyframesCo:
|
|||
action: Action,
|
||||
action_group_name: str,
|
||||
) -> None:
|
||||
"""Assumes the action already exists, that it might already have fcurves. Otherwise, the
|
||||
"""
|
||||
Assumes the action already exists, that it might already have F-curves. Otherwise, the
|
||||
only difference between versions is performance and implementation simplicity.
|
||||
|
||||
Args:
|
||||
lookup_fcurves (Mapping[FCurveKey, bpy.types.FCurve]): This is only used for efficiency.
|
||||
It's a substitute for action.fcurves.find() which is a potentially expensive linear
|
||||
search.
|
||||
action_group_name (str): Name of Action Group that fcurves are added to.
|
||||
:arg lookup_fcurves: : This is only used for efficiency.
|
||||
It's a substitute for ``action.fcurves.find()`` which is a potentially expensive linear search.
|
||||
:type lookup_fcurves: ``Mapping[FCurveKey, bpy.types.FCurve]``
|
||||
:arg action_group_name: Name of Action Group that F-curves are added to.
|
||||
:type action_group_name: str
|
||||
"""
|
||||
linear_enum_values = [
|
||||
bpy.types.Keyframe.bl_rna.properties["interpolation"].enum_items["LINEAR"].value
|
||||
|
@ -539,7 +556,7 @@ class KeyframesCo:
|
|||
|
||||
keyframe_points = fcurve.keyframe_points
|
||||
|
||||
co_buffer = [0] * 2 * len(keyframe_points)
|
||||
co_buffer = [0] * (2 * len(keyframe_points))
|
||||
keyframe_points.foreach_get("co", co_buffer)
|
||||
co_buffer.extend(key_values)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ __all__ = (
|
|||
"path_reference",
|
||||
"path_reference_copy",
|
||||
"path_reference_mode",
|
||||
"unique_name"
|
||||
"unique_name",
|
||||
)
|
||||
|
||||
import bpy
|
||||
|
|
|
@ -5779,6 +5779,8 @@ def km_transform_modal_map(_params):
|
|||
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
|
||||
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
|
||||
("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
|
||||
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
|
||||
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
|
||||
("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
|
||||
|
|
|
@ -3996,6 +3996,8 @@ def km_transform_modal_map(_params):
|
|||
("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None),
|
||||
("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None),
|
||||
("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None),
|
||||
("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None),
|
||||
("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None),
|
||||
("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None),
|
||||
("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None),
|
||||
|
|
|
@ -1028,7 +1028,7 @@ class CLIP_OT_track_settings_to_track(Operator):
|
|||
"use_red_channel",
|
||||
"use_green_channel",
|
||||
"use_blue_channel",
|
||||
"weight"
|
||||
"weight",
|
||||
)
|
||||
|
||||
_attrs_marker = (
|
||||
|
|
|
@ -776,7 +776,7 @@ class TransformsToDeltasAnim(Operator):
|
|||
"rotation_euler": "delta_rotation_euler",
|
||||
"rotation_quaternion": "delta_rotation_quaternion",
|
||||
# "rotation_axis_angle" : "delta_rotation_axis_angle",
|
||||
"scale": "delta_scale"
|
||||
"scale": "delta_scale",
|
||||
}
|
||||
DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values()
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ class QuickFur(ObjectModeOperator, Operator):
|
|||
items=(
|
||||
('LIGHT', "Light", ""),
|
||||
('MEDIUM', "Medium", ""),
|
||||
('HEAVY', "Heavy", "")
|
||||
('HEAVY', "Heavy", ""),
|
||||
),
|
||||
default='MEDIUM',
|
||||
)
|
||||
|
|
|
@ -20,7 +20,7 @@ from bpy.app.translations import (
|
|||
WindowManager.preset_name = StringProperty(
|
||||
name="Preset Name",
|
||||
description="Name for new preset",
|
||||
default=data_("New Preset")
|
||||
default=data_("New Preset"),
|
||||
)
|
||||
|
||||
|
||||
|
@ -309,7 +309,7 @@ class AddPresetCamera(AddPresetBase, Operator):
|
|||
preset_values = [
|
||||
"cam.sensor_width",
|
||||
"cam.sensor_height",
|
||||
"cam.sensor_fit"
|
||||
"cam.sensor_fit",
|
||||
]
|
||||
if self.use_focal_length:
|
||||
preset_values.append("cam.lens")
|
||||
|
@ -439,7 +439,7 @@ class AddPresetTrackingCamera(AddPresetBase, Operator):
|
|||
"camera.pixel_aspect",
|
||||
"camera.k1",
|
||||
"camera.k2",
|
||||
"camera.k3"
|
||||
"camera.k3",
|
||||
]
|
||||
if self.use_focal_length:
|
||||
preset_values.append("camera.units")
|
||||
|
@ -459,7 +459,7 @@ class AddPresetTrackingTrackColor(AddPresetBase, Operator):
|
|||
|
||||
preset_values = [
|
||||
"track.color",
|
||||
"track.use_custom_color"
|
||||
"track.use_custom_color",
|
||||
]
|
||||
|
||||
preset_subdir = "tracking_track_color"
|
||||
|
@ -489,7 +489,7 @@ class AddPresetTrackingSettings(AddPresetBase, Operator):
|
|||
"settings.use_default_red_channel",
|
||||
"settings.use_default_green_channel",
|
||||
"settings.use_default_blue_channel",
|
||||
"settings.default_weight"
|
||||
"settings.default_weight",
|
||||
]
|
||||
|
||||
preset_subdir = "tracking_settings"
|
||||
|
@ -507,7 +507,7 @@ class AddPresetNodeColor(AddPresetBase, Operator):
|
|||
|
||||
preset_values = [
|
||||
"node.color",
|
||||
"node.use_custom_color"
|
||||
"node.use_custom_color",
|
||||
]
|
||||
|
||||
preset_subdir = "node_color"
|
||||
|
@ -616,7 +616,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator):
|
|||
|
||||
preset_defines = [
|
||||
"brush = bpy.context.tool_settings.gpencil_paint.brush",
|
||||
"settings = brush.gpencil_settings"
|
||||
"settings = brush.gpencil_settings",
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
|
@ -650,7 +650,7 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator):
|
|||
|
||||
preset_defines = [
|
||||
"material = bpy.context.object.active_material",
|
||||
"gpcolor = material.grease_pencil"
|
||||
"gpcolor = material.grease_pencil",
|
||||
]
|
||||
|
||||
preset_values = [
|
||||
|
|
|
@ -133,7 +133,7 @@ class PlayRenderedAnim(Operator):
|
|||
"-speed", str(fps_final),
|
||||
"-in_out", str(frame_start), str(frame_end),
|
||||
"-frame", str(scene.frame_current),
|
||||
"-time_units", "Frames"
|
||||
"-time_units", "Frames",
|
||||
]
|
||||
cmd.extend(opts)
|
||||
elif preset == 'FRAMECYCLER':
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import bpy
|
||||
from bpy.types import (
|
||||
Operator,
|
||||
OperatorFileListElement
|
||||
OperatorFileListElement,
|
||||
)
|
||||
from bpy.props import (
|
||||
BoolProperty,
|
||||
|
@ -981,7 +981,7 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
|||
('MATCAP', "MatCap", "Install custom MatCaps"),
|
||||
('WORLD', "World", "Install custom HDRIs"),
|
||||
('STUDIO', "Studio", "Install custom Studio Lights"),
|
||||
)
|
||||
),
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
|
|
|
@ -32,7 +32,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||
TRANSFORM_OT_translate={
|
||||
"orient_type": 'NORMAL',
|
||||
"constraint_axis": (False, False, True),
|
||||
}
|
||||
},
|
||||
)
|
||||
elif select_mode[2] and totface > 1:
|
||||
bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN')
|
||||
|
@ -57,7 +57,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
dissolve_and_intersect: BoolProperty(
|
||||
name="dissolve_and_intersect",
|
||||
default=False,
|
||||
description="Dissolves adjacent faces and intersects new geometry"
|
||||
description="Dissolves adjacent faces and intersects new geometry",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -1377,7 +1377,8 @@ class WM_OT_properties_edit(Operator):
|
|||
name="Array Length",
|
||||
default=3,
|
||||
min=1,
|
||||
max=32, # 32 is the maximum size for RNA array properties.
|
||||
# 32 is the maximum size for RNA array properties.
|
||||
max=32,
|
||||
)
|
||||
|
||||
# Integer properties.
|
||||
|
@ -1458,7 +1459,7 @@ class WM_OT_properties_edit(Operator):
|
|||
# Store the value converted to a string as a fallback for otherwise unsupported types.
|
||||
eval_string: StringProperty(
|
||||
name="Value",
|
||||
description="Python value for unsupported custom property types"
|
||||
description="Python value for unsupported custom property types",
|
||||
)
|
||||
|
||||
type_items = rna_custom_property_type_items
|
||||
|
@ -1904,7 +1905,7 @@ class WM_OT_properties_edit_value(Operator):
|
|||
# Store the value converted to a string as a fallback for otherwise unsupported types.
|
||||
eval_string: StringProperty(
|
||||
name="Value",
|
||||
description="Value for custom property types that can only be edited as a Python expression"
|
||||
description="Value for custom property types that can only be edited as a Python expression",
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
|
@ -2470,11 +2471,11 @@ class BatchRenameAction(bpy.types.PropertyGroup):
|
|||
replace_match_case: BoolProperty(name="Case Sensitive")
|
||||
use_replace_regex_src: BoolProperty(
|
||||
name="Regular Expression Find",
|
||||
description="Use regular expressions to match text in the 'Find' field"
|
||||
description="Use regular expressions to match text in the 'Find' field",
|
||||
)
|
||||
use_replace_regex_dst: BoolProperty(
|
||||
name="Regular Expression Replace",
|
||||
description="Use regular expression for the replacement text (supporting groups)"
|
||||
description="Use regular expression for the replacement text (supporting groups)",
|
||||
)
|
||||
|
||||
# type: 'CASE'.
|
||||
|
|
|
@ -94,16 +94,6 @@ _namespace = globals()
|
|||
_modules_loaded = [_namespace[name] for name in _modules]
|
||||
del _namespace
|
||||
|
||||
def _addon_support_items():
|
||||
"""Return the addon support levels suitable for this Blender build."""
|
||||
|
||||
items = [
|
||||
('OFFICIAL', "Official", "Officially supported"),
|
||||
('COMMUNITY', "Community", "Maintained by community developers"),
|
||||
]
|
||||
if bpy.app.version_cycle == 'alpha':
|
||||
items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"))
|
||||
return items
|
||||
|
||||
def register():
|
||||
from bpy.utils import register_class
|
||||
|
@ -150,13 +140,23 @@ def register():
|
|||
description="Filter add-ons by category",
|
||||
)
|
||||
|
||||
# These items are static but depend on the version cycle.
|
||||
items = [
|
||||
('OFFICIAL', "Official", "Officially supported"),
|
||||
('COMMUNITY', "Community", "Maintained by community developers"),
|
||||
]
|
||||
if bpy.app.version_cycle == "alpha":
|
||||
items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)"))
|
||||
|
||||
WindowManager.addon_support = EnumProperty(
|
||||
items=_addon_support_items(),
|
||||
items=items,
|
||||
name="Support",
|
||||
description="Display support level",
|
||||
default={'OFFICIAL', 'COMMUNITY'},
|
||||
options={'ENUM_FLAG'},
|
||||
)
|
||||
del items
|
||||
|
||||
# done...
|
||||
|
||||
|
||||
|
|
|
@ -210,12 +210,12 @@ class GPENCIL_MT_snap_pie(Menu):
|
|||
pie.operator(
|
||||
"gpencil.snap_to_cursor",
|
||||
text="Selection to Cursor",
|
||||
icon='RESTRICT_SELECT_OFF'
|
||||
icon='RESTRICT_SELECT_OFF',
|
||||
).use_offset = False
|
||||
pie.operator(
|
||||
"gpencil.snap_to_cursor",
|
||||
text="Selection to Cursor (Keep Offset)",
|
||||
icon='RESTRICT_SELECT_OFF'
|
||||
icon='RESTRICT_SELECT_OFF',
|
||||
).use_offset = True
|
||||
pie.separator()
|
||||
pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR')
|
||||
|
|
|
@ -386,7 +386,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
|
|||
'MKV',
|
||||
'OGG',
|
||||
'MPEG4',
|
||||
'WEBM'
|
||||
'WEBM',
|
||||
}
|
||||
if needs_codec:
|
||||
layout.prop(ffmpeg, "codec")
|
||||
|
@ -402,7 +402,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel):
|
|||
'H264',
|
||||
'MPEG4',
|
||||
'WEBM',
|
||||
'AV1'
|
||||
'AV1',
|
||||
}
|
||||
if use_crf:
|
||||
layout.prop(ffmpeg, "constant_rate_factor")
|
||||
|
|
|
@ -1196,7 +1196,7 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False):
|
|||
unified_name="use_unified_size",
|
||||
slider=True,
|
||||
text="Radius",
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
|
@ -1205,7 +1205,7 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False):
|
|||
"strength",
|
||||
pressure_name="use_pressure_strength",
|
||||
unified_name="use_unified_strength",
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -1345,7 +1345,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False)
|
|||
"builtin.line",
|
||||
"builtin.box",
|
||||
"builtin.circle",
|
||||
"builtin.polyline"
|
||||
"builtin.polyline",
|
||||
}:
|
||||
settings = context.tool_settings.gpencil_sculpt
|
||||
if compact:
|
||||
|
|
|
@ -422,7 +422,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel):
|
|||
col = flow.column()
|
||||
col.prop_search(
|
||||
cloth, "vertex_group_bending", ob, "vertex_groups",
|
||||
text="Bending Group"
|
||||
text="Bending Group",
|
||||
)
|
||||
col.prop(cloth, "bending_stiffness_max", text="Max Bending")
|
||||
|
||||
|
@ -431,7 +431,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel):
|
|||
col = flow.column()
|
||||
col.prop_search(
|
||||
cloth, "vertex_group_shrink", ob, "vertex_groups",
|
||||
text="Shrinking Group"
|
||||
text="Shrinking Group",
|
||||
)
|
||||
col.prop(cloth, "shrink_max", text="Max Shrinking")
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
|||
col, obj.rigid_body, "Rigid Body",
|
||||
"rigidbody.object_add",
|
||||
"rigidbody.object_remove",
|
||||
'RIGID_BODY'
|
||||
'RIGID_BODY',
|
||||
)
|
||||
|
||||
# all types of objects can have rigid body constraint.
|
||||
|
@ -94,7 +94,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
|
|||
col, obj.rigid_body_constraint, "Rigid Body Constraint",
|
||||
"rigidbody.constraint_add",
|
||||
"rigidbody.constraint_remove",
|
||||
'RIGID_BODY_CONSTRAINT'
|
||||
'RIGID_BODY_CONSTRAINT',
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1166,7 +1166,7 @@ from bl_ui.properties_mask_common import (
|
|||
MASK_PT_point,
|
||||
MASK_PT_display,
|
||||
MASK_PT_transforms,
|
||||
MASK_PT_tools
|
||||
MASK_PT_tools,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -41,14 +41,14 @@ class FILEBROWSER_HT_header(Header):
|
|||
layout.popover(
|
||||
panel="ASSETBROWSER_PT_filter",
|
||||
text="",
|
||||
icon='FILTER'
|
||||
icon='FILTER',
|
||||
)
|
||||
|
||||
layout.operator(
|
||||
"screen.region_toggle",
|
||||
text="",
|
||||
icon='PREFERENCES',
|
||||
depress=is_option_region_visible(context, space_data)
|
||||
depress=is_option_region_visible(context, space_data),
|
||||
).region_type = 'TOOL_PROPS'
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -464,7 +464,7 @@ class FILEBROWSER_PT_directory_path(Panel):
|
|||
"screen.region_toggle",
|
||||
text="",
|
||||
icon='PREFERENCES',
|
||||
depress=is_option_region_visible(context, space)
|
||||
depress=is_option_region_visible(context, space),
|
||||
).region_type = 'TOOL_PROPS'
|
||||
|
||||
|
||||
|
|
|
@ -697,7 +697,7 @@ class _draw_tool_settings_context_mode:
|
|||
pressure_name="use_pressure_size",
|
||||
unified_name="use_unified_size",
|
||||
slider=True,
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
|
@ -707,7 +707,7 @@ class _draw_tool_settings_context_mode:
|
|||
pressure_name="use_pressure_strength",
|
||||
unified_name="use_unified_strength",
|
||||
slider=True,
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -14,7 +14,7 @@ from bl_ui.space_toolsystem_common import (
|
|||
)
|
||||
from bl_ui.properties_material import (
|
||||
EEVEE_MATERIAL_PT_settings,
|
||||
MATERIAL_PT_viewport
|
||||
MATERIAL_PT_viewport,
|
||||
)
|
||||
from bl_ui.properties_world import (
|
||||
WORLD_PT_viewport_display
|
||||
|
@ -496,18 +496,18 @@ class NODE_MT_context_menu(Menu):
|
|||
# If no nodes are selected.
|
||||
if selected_nodes_len == 0:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.menu("NODE_MT_add", icon="ADD")
|
||||
layout.operator("node.clipboard_paste", text="Paste", icon="PASTEDOWN")
|
||||
layout.menu("NODE_MT_add", icon='ADD')
|
||||
layout.operator("node.clipboard_paste", text="Paste", icon='PASTEDOWN')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("node.find_node", text="Find...", icon="VIEWZOOM")
|
||||
layout.operator("node.find_node", text="Find...", icon='VIEWZOOM')
|
||||
|
||||
layout.separator()
|
||||
|
||||
if is_geometrynodes:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("node.select", text="Clear Viewer", icon="HIDE_ON").clear_viewer = True
|
||||
layout.operator("node.select", text="Clear Viewer", icon='HIDE_ON').clear_viewer = True
|
||||
|
||||
layout.operator("node.links_cut")
|
||||
layout.operator("node.links_mute")
|
||||
|
@ -521,19 +521,19 @@ class NODE_MT_context_menu(Menu):
|
|||
|
||||
if is_geometrynodes:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("node.link_viewer", text="Link to Viewer", icon="HIDE_OFF")
|
||||
layout.operator("node.link_viewer", text="Link to Viewer", icon='HIDE_OFF')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("node.clipboard_copy", text="Copy", icon="COPYDOWN")
|
||||
layout.operator("node.clipboard_paste", text="Paste", icon="PASTEDOWN")
|
||||
layout.operator("node.clipboard_copy", text="Copy", icon='COPYDOWN')
|
||||
layout.operator("node.clipboard_paste", text="Paste", icon='PASTEDOWN')
|
||||
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("node.duplicate_move", icon="DUPLICATE")
|
||||
layout.operator("node.duplicate_move", icon='DUPLICATE')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("node.delete", icon="X")
|
||||
layout.operator("node.delete", icon='X')
|
||||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
layout.operator("node.delete_reconnect", text="Dissolve")
|
||||
|
||||
|
@ -546,7 +546,7 @@ class NODE_MT_context_menu(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("node.group_make", text="Make Group", icon="NODETREE")
|
||||
layout.operator("node.group_make", text="Make Group", icon='NODETREE')
|
||||
layout.operator("node.group_insert", text="Insert Into Group")
|
||||
|
||||
if active_node and active_node.type == 'GROUP':
|
||||
|
@ -878,7 +878,7 @@ class NodeTreeInterfacePanel(Panel):
|
|||
props = property_row.operator_menu_enum(
|
||||
"node.tree_socket_change_type",
|
||||
"socket_type",
|
||||
text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname
|
||||
text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname,
|
||||
)
|
||||
props.in_out = in_out
|
||||
|
||||
|
|
|
@ -732,7 +732,7 @@ class SEQUENCER_MT_add_scene(Menu):
|
|||
|
||||
layout = self.layout
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
layout.operator("sequencer.scene_strip_add_new", text="New Scene", icon="ADD").type = 'NEW'
|
||||
layout.operator("sequencer.scene_strip_add_new", text="New Scene", icon='ADD').type = 'NEW'
|
||||
|
||||
bpy_data_scenes_len = len(bpy.data.scenes)
|
||||
if bpy_data_scenes_len > 10:
|
||||
|
@ -1378,7 +1378,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
|
|||
'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
|
||||
'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
|
||||
'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
|
||||
'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX'
|
||||
'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX',
|
||||
}
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -2112,7 +2112,7 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel):
|
|||
'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
|
||||
'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
|
||||
'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
|
||||
'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
|
||||
'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX',
|
||||
}
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -2160,7 +2160,7 @@ class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel):
|
|||
'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
|
||||
'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
|
||||
'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
|
||||
'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
|
||||
'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX',
|
||||
}
|
||||
|
||||
def draw(self, context):
|
||||
|
|
|
@ -272,7 +272,7 @@ class TEXT_MT_templates_py(Menu):
|
|||
bpy.utils.script_paths(subdir="templates_py"),
|
||||
"text.open",
|
||||
props_default={"internal": True},
|
||||
filter_ext=lambda ext: (ext.lower() == ".py")
|
||||
filter_ext=lambda ext: (ext.lower() == ".py"),
|
||||
)
|
||||
|
||||
|
||||
|
@ -284,7 +284,7 @@ class TEXT_MT_templates_osl(Menu):
|
|||
bpy.utils.script_paths(subdir="templates_osl"),
|
||||
"text.open",
|
||||
props_default={"internal": True},
|
||||
filter_ext=lambda ext: (ext.lower() == ".osl")
|
||||
filter_ext=lambda ext: (ext.lower() == ".osl"),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ class ToolSelectPanelHelper:
|
|||
return next(
|
||||
(cls for cls in ToolSelectPanelHelper.__subclasses__()
|
||||
if cls.bl_space_type == space_type),
|
||||
None
|
||||
None,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
@ -904,7 +904,8 @@ class ToolSelectPanelHelper:
|
|||
"workspace_tool_type",
|
||||
value='DEFAULT',
|
||||
text="Active Tool",
|
||||
icon='TOOL_SETTINGS', # Could use a less generic icon.
|
||||
# Could use a less generic icon.
|
||||
icon='TOOL_SETTINGS',
|
||||
)
|
||||
is_active_tool = (tool_settings.workspace_tool_type == 'DEFAULT')
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ def generate_from_enum_ex(
|
|||
attr,
|
||||
cursor='DEFAULT',
|
||||
tooldef_keywords={},
|
||||
exclude_filter={}
|
||||
exclude_filter={},
|
||||
):
|
||||
tool_defs = []
|
||||
for enum in type.bl_rna.properties[attr].enum_items_static:
|
||||
|
@ -49,8 +49,8 @@ def generate_from_enum_ex(
|
|||
cursor=cursor,
|
||||
data_block=idname,
|
||||
**tooldef_keywords,
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
return tuple(tool_defs)
|
||||
|
||||
|
@ -1633,7 +1633,7 @@ class _defs_weight_paint:
|
|||
cursor='EYEDROPPER',
|
||||
widget=None,
|
||||
keymap=(),
|
||||
draw_settings=draw_settings
|
||||
draw_settings=draw_settings,
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -1660,7 +1660,7 @@ class _defs_weight_paint:
|
|||
"weight",
|
||||
unified_name="use_unified_weight",
|
||||
slider=True,
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
UnifiedPaintPanel.prop_unified(
|
||||
layout,
|
||||
|
@ -1668,7 +1668,7 @@ class _defs_weight_paint:
|
|||
brush,
|
||||
"strength",
|
||||
unified_name="use_unified_strength",
|
||||
header=True
|
||||
header=True,
|
||||
)
|
||||
|
||||
props = tool.operator_properties("paint.weight_gradient")
|
||||
|
@ -2323,7 +2323,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.selection_paint",
|
||||
label="Selection Paint",
|
||||
icon="ops.generic.select_paint",
|
||||
data_block="SELECTION_PAINT"
|
||||
data_block="SELECTION_PAINT",
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2332,7 +2332,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.comb",
|
||||
label="Comb",
|
||||
icon="ops.curves.sculpt_comb",
|
||||
data_block='COMB'
|
||||
data_block='COMB',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2341,7 +2341,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.add",
|
||||
label="Add",
|
||||
icon="ops.curves.sculpt_add",
|
||||
data_block='ADD'
|
||||
data_block='ADD',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2350,7 +2350,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.delete",
|
||||
label="Delete",
|
||||
icon="ops.curves.sculpt_delete",
|
||||
data_block='DELETE'
|
||||
data_block='DELETE',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2359,7 +2359,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.snake_hook",
|
||||
label="Snake Hook",
|
||||
icon="ops.curves.sculpt_snake_hook",
|
||||
data_block='SNAKE_HOOK'
|
||||
data_block='SNAKE_HOOK',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2368,7 +2368,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.grow_shrink",
|
||||
label="Grow/Shrink",
|
||||
icon="ops.curves.sculpt_grow_shrink",
|
||||
data_block='GROW_SHRINK'
|
||||
data_block='GROW_SHRINK',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2377,7 +2377,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.pinch",
|
||||
label="Pinch",
|
||||
icon="ops.curves.sculpt_pinch",
|
||||
data_block='PINCH'
|
||||
data_block='PINCH',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2386,7 +2386,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.smooth",
|
||||
label="Smooth",
|
||||
icon="ops.curves.sculpt_smooth",
|
||||
data_block='SMOOTH'
|
||||
data_block='SMOOTH',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2395,7 +2395,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.puff",
|
||||
label="Puff",
|
||||
icon="ops.curves.sculpt_puff",
|
||||
data_block='PUFF'
|
||||
data_block='PUFF',
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2404,7 +2404,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.density",
|
||||
label="Density",
|
||||
icon="ops.curves.sculpt_density",
|
||||
data_block="DENSITY"
|
||||
data_block="DENSITY",
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
|
@ -2413,7 +2413,7 @@ class _defs_curves_sculpt:
|
|||
idname="builtin_brush.slide",
|
||||
label="Slide",
|
||||
icon="ops.curves.sculpt_slide",
|
||||
data_block="SLIDE"
|
||||
data_block="SLIDE",
|
||||
)
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue