Merge branch 'master' into refactor-mesh-position-generic

This commit is contained in:
Hans Goudey 2022-12-15 17:47:51 -06:00
commit fd395c9a0a
225 changed files with 3531 additions and 2300 deletions

View File

@ -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)

View File

@ -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

View File

@ -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} &&)

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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}*")

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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()

View File

@ -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
)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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]

View File

@ -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

View File

@ -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()); }

View File

@ -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

View File

@ -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 = [

View File

@ -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(

View File

@ -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,

View File

@ -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:

View File

@ -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"

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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 */

View File

@ -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
)

View File

@ -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);

View File

@ -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;

View File

@ -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(

View File

@ -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();
}

View File

@ -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 */

View File

@ -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. */

View File

@ -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();

View File

@ -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),
};

View File

@ -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

View File

@ -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);

View File

@ -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.

View File

@ -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.
*/

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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

View File

@ -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;
}

View File

@ -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),

View File

@ -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

View File

@ -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.
*

View File

@ -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
)

View File

@ -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();

View File

@ -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

View File

@ -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__ */

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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__ */

View File

@ -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));
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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();

View File

@ -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)

View File

@ -12,7 +12,7 @@ __all__ = (
"path_reference",
"path_reference_copy",
"path_reference_mode",
"unique_name"
"unique_name",
)
import bpy

View File

@ -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),

View File

@ -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),

View File

@ -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 = (

View File

@ -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()

View File

@ -46,7 +46,7 @@ class QuickFur(ObjectModeOperator, Operator):
items=(
('LIGHT', "Light", ""),
('MEDIUM', "Medium", ""),
('HEAVY', "Heavy", "")
('HEAVY', "Heavy", ""),
),
default='MEDIUM',
)

View File

@ -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 = [

View File

@ -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':

View File

@ -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):

View File

@ -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

View File

@ -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'.

View File

@ -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...

View File

@ -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')

View File

@ -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")

View File

@ -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:

View File

@ -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")

View File

@ -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',
)

View File

@ -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,
)

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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):

View File

@ -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"),
)

View File

@ -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')

View File

@ -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