Merge branch 'master' into blender2.8

This commit is contained in:
Sergey Sharybin 2017-09-22 13:26:49 +05:00
commit 128c7c3ba1
59 changed files with 688 additions and 626 deletions

@ -76,7 +76,7 @@ include(cmake/osl.cmake)
include(cmake/tbb.cmake)
include(cmake/openvdb.cmake)
include(cmake/python.cmake)
include(cmake/requests.cmake)
include(cmake/python_site_packages.cmake)
include(cmake/numpy.cmake)
include(cmake/webp.cmake)
if(WIN32)

@ -40,19 +40,27 @@ if(WIN32)
set(semi_path "${PATCH_DIR}/semi.txt")
FILE(TO_NATIVE_PATH ${semi_path} semi_path)
set(BOOST_CONFIGURE_COMMAND bootstrap.bat &&
echo using python : 3.5 : ${PYTHON_OUTPUTDIR}\\python.exe > "${JAM_FILE}" &&
echo using python : ${PYTHON_OUTPUTDIR}\\python.exe > "${JAM_FILE}" &&
echo. : ${BUILD_DIR}/python/src/external_python/include ${BUILD_DIR}/python/src/external_python/pc >> "${JAM_FILE}" &&
echo. : ${BUILD_DIR}/python/src/external_python/pcbuild >> "${JAM_FILE}" &&
type ${semi_path} >> "${JAM_FILE}"
)
set(BOOST_BUILD_COMMAND bjam)
set(BOOST_BUILD_OPTIONS runtime-link=static --user-config=user-config.jam)
set(BOOST_WITH_PYTHON --with-python)
#--user-config=user-config.jam
set(BOOST_BUILD_OPTIONS runtime-link=static )
#set(BOOST_WITH_PYTHON --with-python)
set(BOOST_HARVEST_CMD ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/lib/ ${HARVEST_TARGET}/boost/lib/ )
if(BUILD_MODE STREQUAL Release)
set(BOOST_HARVEST_CMD ${BOOST_HARVEST_CMD} && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/include/boost-1_60/ ${HARVEST_TARGET}/boost/include/)
endif()
elseif(APPLE)
set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh)
set(BOOST_BUILD_COMMAND ./bjam)
set(BOOST_BUILD_OPTIONS toolset=clang cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} --disable-icu boost.locale.icu=off)
set(BOOST_HARVEST_CMD echo .)
else()
set(BOOST_HARVEST_CMD echo .)
set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh)
set(BOOST_BUILD_COMMAND ./bjam)
set(BOOST_BUILD_OPTIONS cxxflags=${PLATFORM_CXXFLAGS} --disable-icu boost.locale.icu=off)
@ -91,7 +99,7 @@ ExternalProject_Add(external_boost
CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND}
BUILD_COMMAND ${BOOST_BUILD_COMMAND} ${BOOST_BUILD_OPTIONS} -j${MAKE_THREADS} architecture=x86 address-model=${BOOST_ADDRESS_MODEL} variant=${BOOST_BUILD_TYPE} link=static threading=multi ${BOOST_OPTIONS} --prefix=${LIBDIR}/boost install
BUILD_IN_SOURCE 1
INSTALL_COMMAND ""
INSTALL_COMMAND "${BOOST_HARVEST_CMD}"
)
if(WIN32)

@ -28,8 +28,24 @@ ExternalProject_Add(external_clang
URL_HASH MD5=${CLANG_HASH}
PATCH_COMMAND ${PATCH_CMD} -p 2 -N -R -d ${BUILD_DIR}/clang/src/external_clang < ${PATCH_DIR}/clang.diff
PREFIX ${BUILD_DIR}/clang
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/llvm ${DEFAULT_CMAKE_FLAGS} ${CLANG_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/llvm
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/clang ${DEFAULT_CMAKE_FLAGS} ${CLANG_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/clang
)
if (MSVC)
if (BUILD_MODE STREQUAL Release)
set(CLANG_HARVEST_COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/clang/ ${HARVEST_TARGET}/llvm/ )
else()
set(CLANG_HARVEST_COMMAND
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/clang/lib/ ${HARVEST_TARGET}/llvm/debug/lib/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/clang/bin/ ${HARVEST_TARGET}/llvm/debug/bin/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/clang/include/ ${HARVEST_TARGET}/llvm/debug/include/
)
endif()
ExternalProject_Add_Step(external_clang after_install
COMMAND ${CLANG_HARVEST_COMMAND}
DEPENDEES mkdir update patch download configure build install
)
endif()
add_dependencies(external_clang ll)

@ -33,9 +33,6 @@ if(BUILD_MODE STREQUAL Release)
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/zlib/lib/zlibstatic.lib ${HARVEST_TARGET}/zlib/lib/libz_st.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/zlib/include/ ${HARVEST_TARGET}/zlib/include/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/zlib/bin/ ${HARVEST_TARGET}/zlib/bin/ &&
# Boost copy lib + rename boost_1_60 to boost
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/lib/ ${HARVEST_TARGET}/boost/lib/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/include/boost-1_60/ ${HARVEST_TARGET}/boost/include/ &&
# jpeg rename libfile + copy include
${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpg/include/ ${HARVEST_TARGET}/jpeg/include/ &&
@ -98,8 +95,6 @@ if(BUILD_MODE STREQUAL Release)
# tbb
${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb_static.lib ${HARVEST_TARGET}/tbb/lib/tbb.lib &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tbb/include/ ${HARVEST_TARGET}/tbb/include/ &&
# llvm
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/ ${HARVEST_TARGET}/llvm/ &&
# opencollada
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencollada/ ${HARVEST_TARGET}/opencollada/ &&
# opensubdiv
@ -114,11 +109,9 @@ if(BUILD_MODE STREQUAL Release)
${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb64/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb64.dll &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb32/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb.dll &&
# python
${CMAKE_COMMAND} -E copy ${LIBDIR}/python35.tar.gz ${HARVEST_TARGET}/Release/python35.tar.gz &&
# requests
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/requests ${HARVEST_TARGET}/Release/site-packages/requests &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}.tar.gz &&
# numpy
${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_numpy${PYTHON_POSTFIX}_1.10.tar.gz ${HARVEST_TARGET}/Release/python35_numpy_1.10.tar.gz &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}.tar.gz &&
# hidapi
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hidapi/ ${HARVEST_TARGET}/hidapi/ &&
# webp, straight up copy
@ -154,12 +147,6 @@ if(BUILD_MODE STREQUAL Debug)
${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/xml.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/xml_d.lib &&
# blosc
${CMAKE_COMMAND} -E copy ${LIBDIR}/blosc/lib/libblosc_d.lib ${HARVEST_TARGET}/blosc/lib/libblosc_d.lib &&
# boost
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/lib/ ${HARVEST_TARGET}/boost/lib/ &&
# llvm
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/lib/ ${HARVEST_TARGET}/llvm/debug/lib/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/bin/ ${HARVEST_TARGET}/llvm/debug/bin/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/include/ ${HARVEST_TARGET}/llvm/debug/include/ &&
# osl
${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslcomp.lib ${HARVEST_TARGET}/osl/lib/oslcomp_d.lib &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslexec.lib ${HARVEST_TARGET}/osl/lib/oslexec_d.lib &&
@ -178,9 +165,9 @@ if(BUILD_MODE STREQUAL Debug)
# hdf5
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hdf5/lib ${HARVEST_TARGET}/hdf5/lib &&
# numpy
${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_numpy_1.10d.tar.gz ${HARVEST_TARGET}/Release/python35_numpy_1.10d.tar.gz &&
${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}d.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}d.tar.gz &&
# python
${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_d.tar.gz ${HARVEST_TARGET}/Release/python35_d.tar.gz
${CMAKE_COMMAND} -E copy ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_d.tar.gz ${HARVEST_TARGET}/Release/python${PYTHON_SHORT_VERSION_NO_DOTS}_d.tar.gz
DEPENDS Package_Python
)
endif(BUILD_MODE STREQUAL Debug)

@ -42,3 +42,20 @@ ExternalProject_Add(ll
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/llvm ${DEFAULT_CMAKE_FLAGS} ${LLVM_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/llvm
)
if (MSVC)
if (BUILD_MODE STREQUAL Release)
set(LLVM_HARVEST_COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/ ${HARVEST_TARGET}/llvm/ )
else()
set(LLVM_HARVEST_COMMAND
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/lib/ ${HARVEST_TARGET}/llvm/debug/lib/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/bin/ ${HARVEST_TARGET}/llvm/debug/bin/ &&
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/include/ ${HARVEST_TARGET}/llvm/debug/include/
)
endif()
ExternalProject_Add_Step(ll after_install
COMMAND ${LLVM_HARVEST_COMMAND}
DEPENDEES mkdir update patch download configure build install
)
endif()

@ -1,40 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
if(MSVC)
if(BUILD_MODE STREQUAL Release)
set(NUMPY_POSTFIX)
message("Python_binary = ${PYTHON_BINARY}")
message("Python_post = ${PYTHON_POSTFIX}")
ExternalProject_Add(external_numpy
URL ${NUMPY_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${NUMPY_HASH}
PREFIX ${BUILD_DIR}/numpy
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
CONFIGURE_COMMAND ""
LOG_BUILD 1
BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build
INSTALL_COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-3.5"
${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35_numpy${PYTHON_POSTFIX}_1.11.tar.gz" "."
)
add_dependencies(external_numpy Make_Python_Environment)
endif()
endif()

@ -32,12 +32,14 @@ set(NUMPY_POSTFIX)
if(WIN32)
set(NUMPY_INSTALL
${CMAKE_COMMAND} -E copy_directory "${BUILD_DIR}/python/src/external_python/run/lib/site-packages/numpy/core/include/numpy" "${LIBDIR}/python/include/python3.5/numpy" &&
${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-3.5${NUMPY_DIR_POSTFIX}"
${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35_numpy_${NUMPY_SHORT_VERSION}${NUMPY_ARCHIVE_POSTFIX}.tar.gz" "."
${CMAKE_COMMAND} -E copy_directory "${BUILD_DIR}/python/src/external_python/run/lib/site-packages/numpy/core/include/numpy" "${LIBDIR}/python/include/python${PYTHON_SHORT_VERSION}/numpy" &&
${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-${PYTHON_SHORT_VERSION}${NUMPY_DIR_POSTFIX}"
${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}_numpy_${NUMPY_SHORT_VERSION}${NUMPY_ARCHIVE_POSTFIX}.tar.gz" "."
)
set(NUMPY_PATCH ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff )
else()
set(NUMPY_INSTALL echo .)
set(NUMPY_PATCH echo .)
endif()
ExternalProject_Add(external_numpy
@ -45,6 +47,7 @@ ExternalProject_Add(external_numpy
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${NUMPY_HASH}
PREFIX ${BUILD_DIR}/numpy
PATCH_COMMAND ${NUMPY_PATCH}
CONFIGURE_COMMAND ""
LOG_BUILD 1
BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build ${NUMPY_BUILD_OPTION} install --old-and-unmanageable

@ -59,7 +59,7 @@ set(OPENIMAGEIO_EXTRA_ARGS
-DUSE_GIF=OFF
-DUSE_OPENCV=OFF
-DUSE_OPENSSL=OFF
-DUSE_OPENJPEG=OFF
-DUSE_OPENJPEG=ON
-DUSE_FFMPEG=OFF
-DUSE_PTEX=OFF
-DUSE_FREETYPE=OFF
@ -78,6 +78,8 @@ set(OPENIMAGEIO_EXTRA_ARGS
-DTIFF_INCLUDE_DIR=${LIBDIR}/tiff/include
-DJPEG_LIBRARY=${LIBDIR}/jpg/lib/${JPEG_LIBRARY}
-DJPEG_INCLUDE_DIR=${LIBDIR}/jpg/include
-DOPENJPEG_INCLUDE_DIR=${LIBDIR}/openjpeg/include/openjpeg-${OPENJPEG_VERSION}
-DOPENJPEG_LIBRARY=${LIBDIR}/openjpeg/lib/${OPENJPEG_LIBRARY}
-DOCIO_PATH=${LIBDIR}/opencolorio/
-DOpenEXR_USE_STATIC_LIBS=On
-DOPENEXR_HOME=${LIBDIR}/openexr/
@ -107,7 +109,7 @@ ExternalProject_Add(external_openimageio
INSTALL_DIR ${LIBDIR}/openimageio
)
add_dependencies(external_openimageio external_png external_zlib external_ilmbase external_openexr external_jpeg external_boost external_tiff external_webp external_opencolorio)
add_dependencies(external_openimageio external_png external_zlib external_ilmbase external_openexr external_jpeg external_boost external_tiff external_webp external_opencolorio external_openjpeg)
if(NOT WIN32)
add_dependencies(external_openimageio external_opencolorio_extra)
endif()

@ -38,6 +38,7 @@ ExternalProject_Add(external_openjpeg
INSTALL_DIR ${LIBDIR}/openjpeg
)
set(OPENJPEG_LIBRARY libopenjpeg${LIBEXT})
if(MSVC)
set_target_properties(external_openjpeg PROPERTIES FOLDER Mingw)
endif(MSVC)

@ -115,10 +115,14 @@ else()
set(LIBPREFIX "lib")
if(APPLE)
# Let's get the current Xcode dir, to support xcode-select
execute_process(
COMMAND xcode-select --print-path
OUTPUT_VARIABLE XCODE_DEV_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
set(OSX_ARCHITECTURES x86_64)
set(OSX_DEPLOYMENT_TARGET 10.9)
set(OSX_SDK_VERSION 10.12)
set(OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk)
set(OSX_SYSROOT ${XCODE_DEV_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk)
set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}")
set(PLATFORM_CXXFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++")

@ -50,11 +50,11 @@ if(WIN32)
${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/pc < ${PATCH_DIR}/pyshell.diff
CONFIGURE_COMMAND ""
BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p ${PYTHON_ARCH} -c ${BUILD_MODE} -k ${PYTHON_COMPILER_STRING}
INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.dll ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.dll &&
${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.lib &&
${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.exp ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.exp &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${LIBDIR}/python/include/Python3.5 &&
${CMAKE_COMMAND} -E copy "${BUILD_DIR}/python/src/external_python/PC/pyconfig.h" ${LIBDIR}/python/include/Python3.5/pyconfig.h
INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll &&
${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib &&
${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.exp ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.exp &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${LIBDIR}/python/include/Python${PYTHON_SHORT_VERSION} &&
${CMAKE_COMMAND} -E copy "${BUILD_DIR}/python/src/external_python/PC/pyconfig.h" ${LIBDIR}/python/include/Python${PYTHON_SHORT_VERSION}/pyconfig.h
)
Message("PythinRedist = ${BUILD_DIR}/python/src/external_python/redist")
Message("POutput = ${PYTHON_OUTPUTDIR}")
@ -87,7 +87,7 @@ endif()
if(MSVC)
add_custom_command(
OUTPUT ${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz
OUTPUT ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz
OUTPUT ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe
COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/lib ${BUILD_DIR}/python/src/external_python/redist/lib
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe
@ -112,10 +112,10 @@ if(MSVC)
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testcapi${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testcapi${PYTHON_POSTFIX}.pyd
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testimportmultiple${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testimportmultiple${PYTHON_POSTFIX}.pyd
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testmultiphase${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testmultiphase${PYTHON_POSTFIX}.pyd
COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/python/src/external_python/redist" ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz" "."
COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/python/src/external_python/redist" ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz" "."
)
add_custom_target(Package_Python ALL DEPENDS external_python ${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe)
add_custom_target(Package_Python ALL DEPENDS external_python ${LIBDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.tar.gz ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe)
if(MSVC12)
set(PYTHON_DISTUTIL_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/run/lib/distutils < ${PATCH_DIR}/python_runtime_vc2013.diff)
@ -127,9 +127,9 @@ if(MSVC)
COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/redist ${BUILD_DIR}/python/src/external_python/run
COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${BUILD_DIR}/python/src/external_python/run/include
COMMAND ${CMAKE_COMMAND} -E copy "${BUILD_DIR}/python/src/external_python/PC/pyconfig.h" ${BUILD_DIR}/python/src/external_python/run/include/pyconfig.h
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.dll" ${BUILD_DIR}/python/src/external_python/run/python35${PYTHON_POSTFIX}.dll
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python35.lib #missing postfix on purpose, distutils is not expecting it
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python35${PYTHON_POSTFIX}.lib #other things like numpy still want it though.
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll" ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.dll
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib #missing postfix on purpose, distutils is not expecting it
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}${PYTHON_POSTFIX}.lib #other things like numpy still want it though.
COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe
COMMAND ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe -m ensurepip --upgrade
COMMAND ${PYTHON_DISTUTIL_PATCH}

@ -0,0 +1,38 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
if(WIN32)
set(HARVEST_CMD cmd /C FOR /d /r ${BUILD_DIR}/python/src/external_python/run/lib/site-packages %d IN (__pycache__) DO @IF EXIST "%d" rd /s /q "%d" &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/run/lib/site-packages/idna ${HARVEST_TARGET}/Release/site-packages/idna &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/run/lib/site-packages/chardet ${HARVEST_TARGET}/Release/site-packages/chardet &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/run/lib/site-packages/urllib3 ${HARVEST_TARGET}/Release/site-packages/urllib3 &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/run/lib/site-packages/certifi ${HARVEST_TARGET}/Release/site-packages/certifi &&
${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/run/lib/site-packages/requests ${HARVEST_TARGET}/Release/site-packages/requests
)
else()
set(HARVEST_CMD echo .)
endif()
ExternalProject_Add(external_python_site_packages
DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
PREFIX ${BUILD_DIR}/site_packages
INSTALL_COMMAND ${PYTHON_BINARY} -m pip install idna==${IDNA_VERSION} chardet==${CHARDET_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} --no-binary :all: && ${HARVEST_CMD}
)
add_dependencies(external_python_site_packages Make_Python_Environment)

@ -1,37 +0,0 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ***** END GPL LICENSE BLOCK *****
if(BUILD_MODE STREQUAL Release)
if(WIN32)
set(REQUESTS_INSTALL_DIR ${LIBDIR}/requests)
else()
set(REQUESTS_INSTALL_DIR ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION}/site-packages/requests)
endif()
ExternalProject_Add(external_requests
URL ${REQUESTS_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${REQUESTS_HASH}
PREFIX ${BUILD_DIR}/requests
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/requests/src/external_requests/requests ${REQUESTS_INSTALL_DIR}
)
add_dependencies(external_requests Make_Python_Environment)
endif(BUILD_MODE STREQUAL Release)

@ -27,12 +27,18 @@ else()
set(SNDFILE_OPTIONS --enable-static --disable-shared )
endif()
if(APPLE)
set(SNDFILE_CONFIGURE_ENV echo .)
else()
set(SNDFILE_CONFIGURE_ENV ${CONFIGURE_ENV})
endif()
ExternalProject_Add(external_sndfile
URL ${SNDFILE_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${SNDFILE_HASH}
PREFIX ${BUILD_DIR}/sndfile
CONFIGURE_COMMAND cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${SNDFILE_ENV} ${CONFIGURE_COMMAND} ${SNDFILE_OPTIONS} --prefix=${mingw_LIBDIR}/sndfile
CONFIGURE_COMMAND ${SNDFILE_CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${SNDFILE_ENV} ${CONFIGURE_COMMAND} ${SNDFILE_OPTIONS} --prefix=${mingw_LIBDIR}/sndfile
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make install
INSTALL_DIR ${LIBDIR}/sndfile

@ -133,6 +133,7 @@ set(OSL_HASH 6924dd5d453159e7b6eb106a08c358cf)
set(PYTHON_VERSION 3.6.2)
set(PYTHON_SHORT_VERSION 3.6)
set(PYTHON_SHORT_VERSION_NO_DOTS 36)
set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
set(PYTHON_HASH 2c68846471994897278364fc18730dd9)
@ -144,9 +145,11 @@ set(OPENVDB_VERSION 3.1.0)
set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
set(OPENVDB_HASH 30a7e9571a03ab7bcf1a39fb62aa436f)
set(REQUESTS_VERSION v2.10.0)
set(REQUESTS_URI https://github.com/kennethreitz/requests/archive/${REQUESTS_VERSION}.zip)
set(REQUESTS_HASH 6ebefdf0210c7f0933f61501334e46c3)
set(IDNA_VERSION 2.6)
set(CHARDET_VERSION 3.0.2)
set(URLLIB3_VERSION 1.22)
set(CERTIFI_VERSION 2017.7.27.1)
set(REQUESTS_VERSION 2.18.4)
set(NUMPY_VERSION v1.13.1)
set(NUMPY_SHORT_VERSION 1.13)

@ -287,13 +287,13 @@ NO_BUILD=false
NO_CONFIRM=false
USE_CXX11=true # Mandatory in blender2.8
PYTHON_VERSION="3.5.3"
PYTHON_VERSION_MIN="3.5"
PYTHON_VERSION="3.6.2"
PYTHON_VERSION_MIN="3.6"
PYTHON_FORCE_BUILD=false
PYTHON_FORCE_REBUILD=false
PYTHON_SKIP=false
NUMPY_VERSION="1.10.1"
NUMPY_VERSION="1.13.1"
NUMPY_VERSION_MIN="1.8"
NUMPY_FORCE_BUILD=false
NUMPY_FORCE_REBUILD=false

@ -1,3 +1,45 @@
--- Include/Python.h 2017-07-07 21:33:27 -0600
+++ Include/Python.h 2017-09-19 10:36:10 -0600
@@ -2,6 +2,10 @@
#define Py_PYTHON_H
/* Since this is a "meta-include" file, no #ifdef __cplusplus / extern "C" { */
+#if _MSC_VER < 1900
+#define inline __inline
+#endif
+
/* Include nearly all Python header files */
#include "patchlevel.h"
--- Include/pydtrace.h 2017-07-07 21:33:27 -0600
+++ Include/pydtrace.h 2017-09-19 10:32:31 -0600
@@ -2,6 +2,11 @@
#ifndef Py_DTRACE_H
#define Py_DTRACE_H
+
+#if _MSC_VER < 1900
+#define inline __inline
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
--- Modules/_blake2/impl/blake2.h 2017-07-07 21:33:27 -0600
+++ Modules/_blake2/impl/blake2.h 2017-09-19 10:22:41 -0600
@@ -19,6 +19,10 @@
#include <stddef.h>
#include <stdint.h>
+#if _MSC_VER < 1900
+#define inline __inline
+#endif
+
#ifdef BLAKE2_NO_INLINE
#define BLAKE2_LOCAL_INLINE(type) static type
#endif
--- pcbuild/build.bat 2016-05-21 09:53:55 -0600
+++ pcbuild/build.bat 2016-05-21 09:56:16 -0600
@@ -59,6 +59,7 @@
@ -8,19 +50,19 @@
if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts
if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts
if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts
@@ -126,7 +126,7 @@
@@ -120,7 +120,7 @@
:Kill
echo on
-msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
+msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose% /p:PlatformToolset=%vs_toolset%^
-%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
+%MSBUILD% "%dir%\pythoncore.vcxproj" /t:KillPython %verbose% /p:PlatformToolset=%vs_toolset%^
/p:Configuration=%conf% /p:Platform=%platf%^
/p:KillPython=true
@@ -95,7 +96,7 @@
@@ -130,7 +130,7 @@
rem batch is, shall we say, "lackluster"
echo on
msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
%MSBUILD% "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
- /p:Configuration=%conf% /p:Platform=%platf%^
+ /p:Configuration=%conf% /p:Platform=%platf% /p:PlatformToolset=%vs_toolset%^
/p:IncludeExternals=%IncludeExternals%^

@ -302,7 +302,7 @@ if(WITH_JACK)
endif()
if(WITH_PYTHON)
set(PYTHON_VERSION 3.5) # CACHE STRING)
set(PYTHON_VERSION 3.6) # CACHE STRING)
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
# Use shared libs for vc2008 and vc2010 until we actually have vc2010 libs

@ -63,9 +63,8 @@ inline void face_split_tri_indices(const int face_flag,
tri_b[1] = 3;
tri_b[2] = 1;
}
else /*if(face_flag & FACE_FLAG_DIVIDE_13)*/ {
assert(face_flag & FACE_FLAG_DIVIDE_13);
else {
/* Quad with FACE_FLAG_DIVIDE_13 or single triangle. */
tri_a[0] = 0;
tri_a[1] = 1;
tri_a[2] = 2;

@ -400,7 +400,7 @@ ccl_device int bssrdf_setup(Bssrdf *bssrdf, ClosureType type)
bssrdf_burley_setup(bssrdf);
}
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF;
return SD_BSSRDF;
}
}

@ -51,8 +51,7 @@ ccl_device_inline void compute_light_pass(KernelGlobals *kg,
path_state_init(kg, &emission_sd, &state, rng_hash, sample, NULL);
/* evaluate surface shader */
float rbsdf = path_state_rng_1D(kg, &state, PRNG_BSDF);
shader_eval_surface(kg, sd, &state, rbsdf, state.flag);
shader_eval_surface(kg, sd, &state, state.flag);
/* TODO, disable more closures we don't need besides transparent */
shader_bsdf_disable_transparency(kg, sd);
@ -241,12 +240,12 @@ ccl_device float3 kernel_bake_evaluate_direct_indirect(KernelGlobals *kg,
}
else {
/* surface color of the pass only */
shader_eval_surface(kg, sd, state, 0.0f, 0);
shader_eval_surface(kg, sd, state, 0);
return kernel_bake_shader_bsdf(kg, sd, type);
}
}
else {
shader_eval_surface(kg, sd, state, 0.0f, 0);
shader_eval_surface(kg, sd, state, 0);
color = kernel_bake_shader_bsdf(kg, sd, type);
}
@ -338,7 +337,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
case SHADER_EVAL_NORMAL:
{
if((sd.flag & SD_HAS_BUMP)) {
shader_eval_surface(kg, &sd, &state, 0.f, 0);
shader_eval_surface(kg, &sd, &state, 0);
}
/* encoding: normal = (2 * color) - 1 */
@ -352,7 +351,7 @@ ccl_device void kernel_bake_evaluate(KernelGlobals *kg, ccl_global uint4 *input,
}
case SHADER_EVAL_EMISSION:
{
shader_eval_surface(kg, &sd, &state, 0.f, 0);
shader_eval_surface(kg, &sd, &state, 0);
out = shader_emissive_eval(kg, &sd);
break;
}

@ -70,7 +70,7 @@ ccl_device_noinline float3 direct_emissive_eval(KernelGlobals *kg,
/* no path flag, we're evaluating this for all closures. that's weak but
* we'd have to do multiple evaluations otherwise */
path_state_modify_bounce(state, true);
shader_eval_surface(kg, emission_sd, state, 0.0f, 0);
shader_eval_surface(kg, emission_sd, state, 0);
path_state_modify_bounce(state, false);
/* evaluate emissive closure */

@ -210,8 +210,8 @@ ccl_device_forceinline VolumeIntegrateResult kernel_path_volume(
/* indirect sample. if we use distance sampling and take just
* one sample for direct and indirect light, we could share
* this computation, but makes code a bit complex */
float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
result = kernel_volume_decoupled_scatter(kg,
state, &volume_ray, sd, throughput,
@ -434,11 +434,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
sd,
&isect,
ray);
float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, sd, state, rbsdf, state->flag);
#ifdef __BRANCHED_PATH__
shader_merge_closures(sd);
#endif /* __BRANCHED_PATH__ */
shader_eval_surface(kg, sd, state, state->flag);
shader_prepare_closures(sd, state);
/* Apply shadow catcher, holdout, emission. */
if(!kernel_path_shader_apply(kg,
@ -462,7 +459,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
break;
}
else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
if(terminate >= probability)
break;
@ -483,21 +480,18 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
/* bssrdf scatter to a different location on the same object, replacing
* the closures with a diffuse BSDF */
if(sd->flag & SD_BSSRDF) {
float bssrdf_probability;
ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability);
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg,
state,
PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v);
/* modify throughput for picking bssrdf or bsdf */
throughput *= bssrdf_probability;
const ShaderClosure *sc = shader_bssrdf_pick(sd, &throughput, &bssrdf_u);
/* do bssrdf scatter step if we picked a bssrdf closure */
if(sc) {
uint lcg_state = lcg_state_init(state, 0x68bc21eb);
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg,
state,
PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v);
subsurface_scatter_step(kg,
sd,
state,
@ -591,8 +585,8 @@ ccl_device_forceinline void kernel_path_integrate(
/* Setup and evaluate shader. */
shader_setup_from_ray(kg, &sd, &isect, ray);
float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, &sd, state, rbsdf, state->flag);
shader_eval_surface(kg, &sd, state, state->flag);
shader_prepare_closures(&sd, state);
/* Apply shadow catcher, holdout, emission. */
if(!kernel_path_shader_apply(kg,
@ -616,7 +610,7 @@ ccl_device_forceinline void kernel_path_integrate(
break;
}
else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
if(terminate >= probability)
break;

@ -339,8 +339,8 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* scatter sample. if we use distance sampling and take just one
* sample for direct and indirect light, we could share this
* computation, but makes code a bit complex */
float rphase = path_state_rng_1D_for_decision(kg, &ps, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, &ps, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D(kg, &ps, PRNG_PHASE_CHANNEL);
float rscatter = path_state_rng_1D(kg, &ps, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
&ps, &pray, &sd, &tp, rphase, rscatter, &volume_segment, NULL, false);
@ -439,7 +439,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
/* Setup and evaluate shader. */
shader_setup_from_ray(kg, &sd, &isect, &ray);
shader_eval_surface(kg, &sd, &state, 0.0f, state.flag);
shader_eval_surface(kg, &sd, &state, state.flag);
shader_merge_closures(&sd);
/* Apply shadow catcher, holdout, emission. */
@ -466,7 +466,7 @@ ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
break;
}
else if(probability != 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, &state, PRNG_TERMINATE);
float terminate = path_state_rng_1D(kg, &state, PRNG_TERMINATE);
if(terminate >= probability)
break;

@ -76,12 +76,12 @@ ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathSta
state->flag |= PATH_RAY_TRANSPARENT;
state->transparent_bounce++;
/* don't increase random number generator offset here, to avoid some
* unwanted patterns, see path_state_rng_1D_for_decision */
if(!kernel_data.integrator.transparent_shadows)
state->flag |= PATH_RAY_MIS_SKIP;
/* random number generator next bounce */
state->rng_offset += PRNG_BOUNCE_NUM;
return;
}

@ -32,11 +32,10 @@ bool kernel_path_subsurface_scatter(
ccl_addr_space float3 *throughput,
ccl_addr_space SubsurfaceIndirectRays *ss_indirect)
{
float bssrdf_probability;
ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability);
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
/* modify throughput for picking bssrdf or bsdf */
*throughput *= bssrdf_probability;
const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
/* do bssrdf scatter step if we picked a bssrdf closure */
if(sc) {
@ -49,8 +48,6 @@ bool kernel_path_subsurface_scatter(
uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
SubsurfaceIntersection ss_isect;
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_intersect(kg,
&ss_isect,
sd,

@ -77,7 +77,7 @@ bool kernel_path_volume_bounce(
float3 phase_omega_in;
differential3 phase_domega_in;
float phase_u, phase_v;
path_state_rng_2D(kg, state, PRNG_PHASE_U, &phase_u, &phase_v);
path_state_rng_2D(kg, state, PRNG_BSDF_U, &phase_u, &phase_v);
int label;
label = shader_volume_phase_sample(kg, sd, phase_u, phase_v, &phase_eval,
@ -155,8 +155,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput;
/* sample position on volume segment */
float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@ -201,8 +201,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput;
/* sample position on volume segment */
float rphase = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE);
float rscatter = path_branched_rng_1D_for_decision(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
float rphase = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_PHASE_CHANNEL);
float rscatter = path_branched_rng_1D(kg, state->rng_hash, state, j, num_samples, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);
@ -238,8 +238,8 @@ ccl_device void kernel_branched_path_volume_connect_light(
float3 tp = throughput;
/* sample position on volume segment */
float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float rscatter = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
float rscatter = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
VolumeIntegrateResult result = kernel_volume_decoupled_scatter(kg,
state, ray, sd, &tp, rphase, rscatter, segment, (ls.t != FLT_MAX)? &ls.P: NULL, false);

@ -30,12 +30,6 @@ CCL_NAMESPACE_BEGIN
#ifdef __SOBOL__
/* Skip initial numbers that are not as well distributed, especially the
* first sequence is just 0 everywhere, which can be problematic for e.g.
* path termination.
*/
#define SOBOL_SKIP 64
ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
{
uint result = 0;
@ -73,7 +67,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
#ifdef __SOBOL__
/* Sobol sequence value using direction vectors. */
uint result = sobol_dimension(kg, sample + SOBOL_SKIP, dimension);
uint result = sobol_dimension(kg, sample, dimension);
float r = (float)result * (1.0f/(float)0xFFFFFFFF);
/* Cranly-Patterson rotation using rng seed */
@ -186,25 +180,6 @@ ccl_device_inline float path_state_rng_1D(KernelGlobals *kg,
state->rng_offset + dimension);
}
ccl_device_inline float path_state_rng_1D_for_decision(
KernelGlobals *kg,
const ccl_addr_space PathState *state,
int dimension)
{
/* The rng_offset is not increased for transparent bounces. if we do then
* fully transparent objects can become subtly visible by the different
* sampling patterns used where the transparent object is.
*
* however for some random numbers that will determine if we next bounce
* is transparent we do need to increase the offset to avoid always making
* the same decision. */
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
return path_rng_1D(kg,
state->rng_hash,
state->sample, state->num_samples,
rng_offset + dimension);
}
ccl_device_inline void path_state_rng_2D(KernelGlobals *kg,
const ccl_addr_space PathState *state,
int dimension,
@ -232,22 +207,6 @@ ccl_device_inline float path_branched_rng_1D(
state->rng_offset + dimension);
}
ccl_device_inline float path_branched_rng_1D_for_decision(
KernelGlobals *kg,
uint rng_hash,
const ccl_addr_space PathState *state,
int branch,
int num_branches,
int dimension)
{
const int rng_offset = state->rng_offset + state->transparent_bounce * PRNG_BOUNCE_NUM;
return path_rng_1D(kg,
rng_hash,
state->sample * num_branches + branch,
state->num_samples * num_branches,
rng_offset + dimension);
}
ccl_device_inline void path_branched_rng_2D(
KernelGlobals *kg,
uint rng_hash,
@ -273,7 +232,7 @@ ccl_device_inline float path_state_rng_light_termination(
const ccl_addr_space PathState *state)
{
if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
return path_state_rng_1D_for_decision(kg, state, PRNG_LIGHT_TERMINATE);
return path_state_rng_1D(kg, state, PRNG_LIGHT_TERMINATE);
}
return 0.0f;
}
@ -286,12 +245,12 @@ ccl_device_inline float path_branched_rng_light_termination(
int num_branches)
{
if(kernel_data.integrator.light_inv_rr_threshold > 0.0f) {
return path_branched_rng_1D_for_decision(kg,
rng_hash,
state,
branch,
num_branches,
PRNG_LIGHT_TERMINATE);
return path_branched_rng_1D(kg,
rng_hash,
state,
branch,
num_branches,
PRNG_LIGHT_TERMINATE);
}
return 0.0f;
}

@ -494,20 +494,45 @@ ccl_device_inline void shader_merge_closures(ShaderData *sd)
}
#endif
/* Defensive sampling. */
ccl_device_inline void shader_prepare_closures(ShaderData *sd,
ccl_addr_space PathState *state)
{
/* We can likely also do defensive sampling at deeper bounces, particularly
* for cases like a perfect mirror but possibly also others. This will need
* a good heuristic. */
if(state->bounce + state->transparent_bounce == 0 && sd->num_closure > 1) {
float sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
sum += sc->sample_weight;
}
}
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
sc->sample_weight = max(sc->sample_weight, 0.125f * sum);
}
}
}
}
/* BSDF */
ccl_device_inline void _shader_bsdf_multi_eval(KernelGlobals *kg, ShaderData *sd, const float3 omega_in, float *pdf,
int skip_bsdf, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
const ShaderClosure *skip_sc, BsdfEval *result_eval, float sum_pdf, float sum_sample_weight)
{
/* this is the veach one-sample model with balance heuristic, some pdf
* factors drop out when using balance heuristic weighting */
for(int i = 0; i < sd->num_closure; i++) {
if(i == skip_bsdf)
continue;
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) {
if(sc != skip_sc && CLOSURE_IS_BSDF(sc->type)) {
float bsdf_pdf = 0.0f;
float3 eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf);
@ -570,7 +595,7 @@ void shader_bsdf_eval(KernelGlobals *kg,
#endif
{
float pdf;
_shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, -1, eval, 0.0f, 0.0f);
_shader_bsdf_multi_eval(kg, sd, omega_in, &pdf, NULL, eval, 0.0f, 0.0f);
if(use_mis) {
float weight = power_heuristic(light_pdf, pdf);
bsdf_eval_mis(eval, weight);
@ -578,6 +603,104 @@ void shader_bsdf_eval(KernelGlobals *kg,
}
}
ccl_device_inline const ShaderClosure *shader_bsdf_pick(ShaderData *sd,
float *randu)
{
int sampled = 0;
if(sd->num_closure > 1) {
/* Pick a BSDF or based on sample weights. */
float sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) {
sum += sc->sample_weight;
}
}
float r = (*randu)*sum;
float partial_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) {
float next_sum = partial_sum + sc->sample_weight;
if(r < next_sum) {
sampled = i;
/* Rescale to reuse for direction sample, to better
* preserve stratifaction. */
*randu = (r - partial_sum) / sc->sample_weight;
break;
}
partial_sum = next_sum;
}
}
}
return &sd->closure[sampled];
}
ccl_device_inline const ShaderClosure *shader_bssrdf_pick(ShaderData *sd,
ccl_addr_space float3 *throughput,
float *randu)
{
int sampled = 0;
if(sd->num_closure > 1) {
/* Pick a BSDF or BSSRDF or based on sample weights. */
float sum_bsdf = 0.0f;
float sum_bssrdf = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type)) {
sum_bsdf += sc->sample_weight;
}
else if(CLOSURE_IS_BSSRDF(sc->type)) {
sum_bssrdf += sc->sample_weight;
}
}
float r = (*randu)*(sum_bsdf + sum_bssrdf);
float partial_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
const ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) {
float next_sum = partial_sum + sc->sample_weight;
if(r < next_sum) {
if(CLOSURE_IS_BSDF(sc->type)) {
*throughput *= (sum_bsdf + sum_bssrdf) / sum_bsdf;
return NULL;
}
else {
*throughput *= (sum_bsdf + sum_bssrdf) / sum_bssrdf;
sampled = i;
/* Rescale to reuse for direction sample, to better
* preserve stratifaction. */
*randu = (r - partial_sum) / sc->sample_weight;
break;
}
}
partial_sum = next_sum;
}
}
}
return &sd->closure[sampled];
}
ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
ShaderData *sd,
float randu, float randv,
@ -586,40 +709,14 @@ ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
differential3 *domega_in,
float *pdf)
{
int sampled = 0;
if(sd->num_closure > 1) {
/* pick a BSDF closure based on sample weights */
float sum = 0.0f;
for(sampled = 0; sampled < sd->num_closure; sampled++) {
const ShaderClosure *sc = &sd->closure[sampled];
if(CLOSURE_IS_BSDF(sc->type))
sum += sc->sample_weight;
}
float r = sd->randb_closure*sum;
sum = 0.0f;
for(sampled = 0; sampled < sd->num_closure; sampled++) {
const ShaderClosure *sc = &sd->closure[sampled];
if(CLOSURE_IS_BSDF(sc->type)) {
sum += sc->sample_weight;
if(r <= sum)
break;
}
}
if(sampled == sd->num_closure) {
*pdf = 0.0f;
return LABEL_NONE;
}
const ShaderClosure *sc = shader_bsdf_pick(sd, &randu);
if(!sc) {
*pdf = 0.0f;
return LABEL_NONE;
}
const ShaderClosure *sc = &sd->closure[sampled];
/* BSSRDF should already have been handled elsewhere. */
kernel_assert(CLOSURE_IS_BSDF(sc->type));
int label;
float3 eval;
@ -632,7 +729,7 @@ ccl_device_inline int shader_bsdf_sample(KernelGlobals *kg,
if(sd->num_closure > 1) {
float sweight = sc->sample_weight;
_shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sampled, bsdf_eval, *pdf*sweight, sweight);
_shader_bsdf_multi_eval(kg, sd, *omega_in, pdf, sc, bsdf_eval, *pdf*sweight, sweight);
}
}
@ -868,11 +965,10 @@ ccl_device float3 shader_holdout_eval(KernelGlobals *kg, ShaderData *sd)
/* Surface Evaluation */
ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
ccl_addr_space PathState *state, float randb, int path_flag)
ccl_addr_space PathState *state, int path_flag)
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
sd->randb_closure = randb;
#ifdef __OSL__
if(kg->osl)
@ -903,7 +999,6 @@ ccl_device float3 shader_eval_background(KernelGlobals *kg, ShaderData *sd,
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
sd->randb_closure = 0.0f;
#ifdef __SVM__
#ifdef __OSL__
@ -985,17 +1080,22 @@ ccl_device int shader_volume_phase_sample(KernelGlobals *kg, const ShaderData *s
sum += sc->sample_weight;
}
float r = sd->randb_closure*sum;
sum = 0.0f;
float r = randu*sum;
float partial_sum = 0.0f;
for(sampled = 0; sampled < sd->num_closure; sampled++) {
const ShaderClosure *sc = &sd->closure[sampled];
if(CLOSURE_IS_PHASE(sc->type)) {
sum += sc->sample_weight;
float next_sum = partial_sum + sc->sample_weight;
if(r <= sum)
if(r <= next_sum) {
/* Rescale to reuse for BSDF direction sample. */
randu = (r - partial_sum) / sc->sample_weight;
break;
}
partial_sum = next_sum;
}
}
@ -1099,7 +1199,6 @@ ccl_device void shader_eval_displacement(KernelGlobals *kg, ShaderData *sd, ccl_
{
sd->num_closure = 0;
sd->num_closure_extra = 0;
sd->randb_closure = 0.0f;
/* this will modify sd->P */
#ifdef __SVM__

@ -86,7 +86,6 @@ ccl_device_forceinline bool shadow_handle_transparent_isect(
shader_eval_surface(kg,
shadow_sd,
state,
0.0f,
PATH_RAY_SHADOW);
path_state_modify_bounce(state, false);
*throughput *= shader_bsdf_transparency(kg, shadow_sd);

@ -28,87 +28,31 @@ CCL_NAMESPACE_BEGIN
* - try to reduce one sample model variance
*/
#define BSSRDF_MULTI_EVAL
ccl_device ShaderClosure *subsurface_scatter_pick_closure(KernelGlobals *kg, ShaderData *sd, float *probability)
{
/* sum sample weights of bssrdf and bsdf */
float bsdf_sum = 0.0f;
float bssrdf_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSDF(sc->type))
bsdf_sum += sc->sample_weight;
else if(CLOSURE_IS_BSSRDF(sc->type))
bssrdf_sum += sc->sample_weight;
}
/* use bsdf or bssrdf? */
float r = sd->randb_closure*(bsdf_sum + bssrdf_sum);
if(r < bsdf_sum) {
/* use bsdf, and adjust randb so we can reuse it for picking a bsdf */
sd->randb_closure = r/bsdf_sum;
*probability = (bsdf_sum > 0.0f)? (bsdf_sum + bssrdf_sum)/bsdf_sum: 1.0f;
return NULL;
}
/* use bssrdf */
r -= bsdf_sum;
float sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
if(CLOSURE_IS_BSSRDF(sc->type)) {
sum += sc->sample_weight;
if(r <= sum) {
sd->randb_closure = (r - (sum - sc->sample_weight))/sc->sample_weight;
#ifdef BSSRDF_MULTI_EVAL
*probability = (bssrdf_sum > 0.0f)? (bsdf_sum + bssrdf_sum)/bssrdf_sum: 1.0f;
#else
*probability = (bssrdf_sum > 0.0f)? (bsdf_sum + bssrdf_sum)/sc->sample_weight: 1.0f;
#endif
return sc;
}
}
}
/* should never happen */
sd->randb_closure = 0.0f;
*probability = 1.0f;
return NULL;
}
ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd,
ShaderClosure *sc,
const ShaderClosure *sc,
float disk_r,
float r,
bool all)
{
#ifdef BSSRDF_MULTI_EVAL
/* this is the veach one-sample model with balance heuristic, some pdf
* factors drop out when using balance heuristic weighting */
float3 eval_sum = make_float3(0.0f, 0.0f, 0.0f);
float pdf_sum = 0.0f;
float sample_weight_sum = 0.0f;
int num_bssrdf = 0;
float sample_weight_inv = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
sc = &sd->closure[i];
if(CLOSURE_IS_BSSRDF(sc->type)) {
float sample_weight = (all)? 1.0f: sc->sample_weight;
sample_weight_sum += sample_weight;
if(!all) {
float sample_weight_sum = 0.0f;
for(int i = 0; i < sd->num_closure; i++) {
sc = &sd->closure[i];
if(CLOSURE_IS_BSSRDF(sc->type)) {
sample_weight_sum += sc->sample_weight;
}
}
}
float sample_weight_inv = 1.0f/sample_weight_sum;
sample_weight_inv = 1.0f/sample_weight_sum;
}
for(int i = 0; i < sd->num_closure; i++) {
sc = &sd->closure[i];
@ -125,25 +69,16 @@ ccl_device_inline float3 subsurface_scatter_eval(ShaderData *sd,
/* TODO power heuristic is not working correct here */
eval_sum += sc->weight*pdf; //*sample_weight*disk_pdf;
pdf_sum += sample_weight*disk_pdf; //*sample_weight*disk_pdf;
num_bssrdf++;
}
}
return (pdf_sum > 0.0f)? eval_sum / pdf_sum : make_float3(0.0f, 0.0f, 0.0f);
#else
float pdf = bssrdf_pdf(pick_sc, r);
float disk_pdf = bssrdf_pdf(pick_sc, disk_r);
return pick_sc->weight * pdf / disk_pdf;
#endif
}
/* replace closures with a single diffuse bsdf closure after scatter step */
ccl_device void subsurface_scatter_setup_diffuse_bsdf(ShaderData *sd, ShaderClosure *sc, float3 weight, bool hit, float3 N)
ccl_device void subsurface_scatter_setup_diffuse_bsdf(ShaderData *sd, const ShaderClosure *sc, float3 weight, bool hit, float3 N)
{
sd->flag &= ~SD_CLOSURE_FLAGS;
sd->randb_closure = 0.0f;
sd->num_closure = 0;
sd->num_closure_extra = 0;
@ -219,7 +154,7 @@ ccl_device void subsurface_color_bump_blur(KernelGlobals *kg,
if(bump || texture_blur > 0.0f) {
/* average color and normal at incoming point */
shader_eval_surface(kg, sd, state, 0.0f, state_flag);
shader_eval_surface(kg, sd, state, state_flag);
float3 in_color = shader_bssrdf_sum(sd, (bump)? N: NULL, NULL);
/* we simply divide out the average color and multiply with the average
@ -242,7 +177,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
KernelGlobals *kg,
SubsurfaceIntersection *ss_isect,
ShaderData *sd,
ShaderClosure *sc,
const ShaderClosure *sc,
uint *lcg_state,
float disk_u,
float disk_v,
@ -255,26 +190,20 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
disk_N = sd->Ng;
make_orthonormals(disk_N, &disk_T, &disk_B);
/* reusing variable for picking the closure gives a bit nicer stratification
* for path tracer, for branched we do all closures so it doesn't help */
float axisu = (all)? disk_u: sd->randb_closure;
if(axisu < 0.5f) {
if(disk_u < 0.5f) {
pick_pdf_N = 0.5f;
pick_pdf_T = 0.25f;
pick_pdf_B = 0.25f;
if(all)
disk_u *= 2.0f;
disk_u *= 2.0f;
}
else if(axisu < 0.75f) {
else if(disk_u < 0.75f) {
float3 tmp = disk_N;
disk_N = disk_T;
disk_T = tmp;
pick_pdf_N = 0.25f;
pick_pdf_T = 0.5f;
pick_pdf_B = 0.25f;
if(all)
disk_u = (disk_u - 0.5f)*4.0f;
disk_u = (disk_u - 0.5f)*4.0f;
}
else {
float3 tmp = disk_N;
@ -283,8 +212,7 @@ ccl_device_inline int subsurface_scatter_multi_intersect(
pick_pdf_N = 0.25f;
pick_pdf_T = 0.25f;
pick_pdf_B = 0.5f;
if(all)
disk_u = (disk_u - 0.75f)*4.0f;
disk_u = (disk_u - 0.75f)*4.0f;
}
/* sample point on disk */
@ -390,7 +318,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
ShaderData *sd,
ccl_addr_space PathState *state,
int state_flag,
ShaderClosure *sc,
const ShaderClosure *sc,
bool all)
{
#ifdef __SPLIT_KERNEL__
@ -419,7 +347,7 @@ ccl_device_noinline void subsurface_scatter_multi_setup(
/* subsurface scattering step, from a point on the surface to another nearby point on the same object */
ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_addr_space PathState *state,
int state_flag, ShaderClosure *sc, uint *lcg_state, float disk_u, float disk_v, bool all)
int state_flag, const ShaderClosure *sc, uint *lcg_state, float disk_u, float disk_v, bool all)
{
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
@ -430,18 +358,20 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a
disk_N = sd->Ng;
make_orthonormals(disk_N, &disk_T, &disk_B);
if(sd->randb_closure < 0.5f) {
if(disk_u < 0.5f) {
pick_pdf_N = 0.5f;
pick_pdf_T = 0.25f;
pick_pdf_B = 0.25f;
disk_u *= 2.0f;
}
else if(sd->randb_closure < 0.75f) {
else if(disk_u < 0.75f) {
float3 tmp = disk_N;
disk_N = disk_T;
disk_T = tmp;
pick_pdf_N = 0.25f;
pick_pdf_T = 0.5f;
pick_pdf_B = 0.25f;
disk_u = (disk_u - 0.5f)*4.0f;
}
else {
float3 tmp = disk_N;
@ -450,6 +380,7 @@ ccl_device void subsurface_scatter_step(KernelGlobals *kg, ShaderData *sd, ccl_a
pick_pdf_N = 0.25f;
pick_pdf_T = 0.25f;
pick_pdf_B = 0.5f;
disk_u = (disk_u - 0.75f)*4.0f;
}
/* sample point on disk */

@ -281,31 +281,21 @@ enum PathTraceDimension {
PRNG_FILTER_V = 1,
PRNG_LENS_U = 2,
PRNG_LENS_V = 3,
#ifdef __CAMERA_MOTION__
PRNG_TIME = 4,
PRNG_UNUSED_0 = 5,
PRNG_UNUSED_1 = 6, /* for some reason (6, 7) is a bad sobol pattern */
PRNG_UNUSED_2 = 7, /* with a low number of samples (< 64) */
#endif
PRNG_BASE_NUM = 8,
PRNG_BASE_NUM = 10,
PRNG_BSDF_U = 0,
PRNG_BSDF_V = 1,
PRNG_BSDF = 2,
PRNG_UNUSED3 = 3,
PRNG_LIGHT_U = 4,
PRNG_LIGHT_V = 5,
PRNG_LIGHT_TERMINATE = 6,
PRNG_TERMINATE = 7,
#ifdef __VOLUME__
PRNG_PHASE_U = 8,
PRNG_PHASE_V = 9,
PRNG_PHASE = 10,
PRNG_SCATTER_DISTANCE = 11,
#endif
PRNG_BOUNCE_NUM = 12,
PRNG_LIGHT_U = 2,
PRNG_LIGHT_V = 3,
PRNG_LIGHT_TERMINATE = 4,
PRNG_TERMINATE = 5,
PRNG_PHASE_CHANNEL = 6,
PRNG_SCATTER_DISTANCE = 7,
PRNG_BOUNCE_NUM = 8,
};
enum SamplingPattern {

@ -379,13 +379,12 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_homogeneous(
/* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */
float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel;
/* decide if we will hit or miss */
bool scatter = true;
float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
if(probalistic_scatter) {
float sample_sigma_t = kernel_volume_channel_get(sigma_t, channel);
@ -483,10 +482,9 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
/* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */
float xi = path_state_rng_1D_for_decision(kg, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D_for_decision(kg, state, PRNG_PHASE);
float xi = path_state_rng_1D(kg, state, PRNG_SCATTER_DISTANCE);
float rphase = path_state_rng_1D(kg, state, PRNG_PHASE_CHANNEL);
int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel;
bool has_scatter = false;
for(int i = 0; i < max_steps; i++) {
@ -843,7 +841,6 @@ ccl_device VolumeIntegrateResult kernel_volume_decoupled_scatter(
/* pick random color channel, we use the Veach one-sample
* model with balance heuristic for the channels */
int channel = (int)(rphase*3.0f);
sd->randb_closure = rphase*3.0f - channel;
float xi = rscatter;
/* probabilistic scattering decision based on transmittance */

@ -27,90 +27,54 @@ CCL_NAMESPACE_BEGIN
# pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable
#endif
ccl_device_inline uint kernel_total_work_size(KernelGlobals *kg)
{
return kernel_split_params.w * kernel_split_params.h * kernel_split_params.num_samples;
}
ccl_device_inline uint kernel_num_work_pools(KernelGlobals *kg)
{
return ccl_global_size(0) * ccl_global_size(1) / WORK_POOL_SIZE;
}
ccl_device_inline uint work_pool_from_ray_index(KernelGlobals *kg, uint ray_index)
{
return ray_index / WORK_POOL_SIZE;
}
ccl_device_inline uint work_pool_work_size(KernelGlobals *kg, uint work_pool)
{
uint total_work_size = kernel_total_work_size(kg);
uint num_pools = kernel_num_work_pools(kg);
if(work_pool >= num_pools || work_pool * WORK_POOL_SIZE >= total_work_size) {
return 0;
}
uint work_size = (total_work_size / (num_pools * WORK_POOL_SIZE)) * WORK_POOL_SIZE;
uint remainder = (total_work_size % (num_pools * WORK_POOL_SIZE));
if(work_pool < remainder / WORK_POOL_SIZE) {
work_size += WORK_POOL_SIZE;
}
else if(work_pool == remainder / WORK_POOL_SIZE) {
work_size += remainder % WORK_POOL_SIZE;
}
return work_size;
}
ccl_device_inline uint get_global_work_index(KernelGlobals *kg, uint work_index, uint ray_index)
{
uint num_pools = kernel_num_work_pools(kg);
uint pool = work_pool_from_ray_index(kg, ray_index);
return (work_index / WORK_POOL_SIZE) * (num_pools * WORK_POOL_SIZE)
+ (pool * WORK_POOL_SIZE)
+ (work_index % WORK_POOL_SIZE);
}
/* Returns true if there is work */
ccl_device bool get_next_work(KernelGlobals *kg, ccl_private uint *work_index, uint ray_index)
ccl_device bool get_next_work(KernelGlobals *kg,
uint thread_index,
ccl_private uint *global_work_index)
{
uint work_pool = work_pool_from_ray_index(kg, ray_index);
uint pool_size = work_pool_work_size(kg, work_pool);
uint total_work_size = kernel_split_params.w
* kernel_split_params.h
* kernel_split_params.num_samples;
if(pool_size == 0) {
/* With a small amount of work there may be more threads than work due to
* rounding up of global size, stop such threads immediately. */
if(thread_index >= total_work_size) {
return false;
}
*work_index = atomic_fetch_and_inc_uint32(&kernel_split_params.work_pools[work_pool]);
return (*work_index < pool_size);
/* Increase atomic work index counter in pool. */
uint pool = thread_index / WORK_POOL_SIZE;
uint work_index = atomic_fetch_and_inc_uint32(&kernel_split_params.work_pools[pool]);
/* Map per-pool work index to a global work index. */
uint global_size = ccl_global_size(0) * ccl_global_size(1);
kernel_assert(global_size % WORK_POOL_SIZE == 0);
kernel_assert(thread_index < global_size);
*global_work_index = (work_index / WORK_POOL_SIZE) * global_size
+ (pool * WORK_POOL_SIZE)
+ (work_index % WORK_POOL_SIZE);
/* Test if all work for this pool is done. */
return (*global_work_index < total_work_size);
}
/* This function assumes that the passed `work` is valid. */
/* Decode sample number w.r.t. assigned `work`. */
ccl_device uint get_work_sample(KernelGlobals *kg, uint work_index, uint ray_index)
/* Map global work index to pixel X/Y and sample. */
ccl_device_inline void get_work_pixel(KernelGlobals *kg,
uint global_work_index,
ccl_private uint *x,
ccl_private uint *y,
ccl_private uint *sample)
{
return get_global_work_index(kg, work_index, ray_index) / (kernel_split_params.w * kernel_split_params.h);
}
uint tile_pixels = kernel_split_params.w * kernel_split_params.h;
uint sample_offset = global_work_index / tile_pixels;
uint pixel_offset = global_work_index - sample_offset * tile_pixels;
uint y_offset = pixel_offset / kernel_split_params.w;
uint x_offset = pixel_offset - y_offset * kernel_split_params.w;
/* Decode pixel and tile position w.r.t. assigned `work`. */
ccl_device void get_work_pixel_tile_position(KernelGlobals *kg,
ccl_private uint *pixel_x,
ccl_private uint *pixel_y,
ccl_private uint *tile_x,
ccl_private uint *tile_y,
uint work_index,
uint ray_index)
{
uint pixel_index = get_global_work_index(kg, work_index, ray_index) % (kernel_split_params.w*kernel_split_params.h);
*tile_x = pixel_index % kernel_split_params.w;
*tile_y = pixel_index / kernel_split_params.w;
*pixel_x = *tile_x + kernel_split_params.x;
*pixel_y = *tile_y + kernel_split_params.y;
*x = kernel_split_params.x + x_offset;
*y = kernel_split_params.y + y_offset;
*sample = kernel_split_params.start_sample + sample_offset;
}
CCL_NAMESPACE_END

@ -84,14 +84,9 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
uint work_index = kernel_split_state.work_array[ray_index];
uint sample = get_work_sample(kg, work_index, ray_index) + kernel_split_params.start_sample;
uint tile_x, tile_y, pixel_x, pixel_y;
get_work_pixel_tile_position(kg, &pixel_x, &pixel_y, &tile_x, &tile_y, work_index, ray_index);
ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride;
uint sample = state->sample;
uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
ccl_global float *buffer = kernel_split_params.buffer + buffer_offset;
/* accumulate result in output buffer */
kernel_write_result(kg, buffer, sample, L);
@ -102,31 +97,26 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
if(IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
/* We have completed current work; So get next work */
uint work_index;
int valid_work = get_next_work(kg, &work_index, ray_index);
if(!valid_work) {
if(!get_next_work(kg, ray_index, &work_index)) {
/* If work is invalid, this means no more work is available and the thread may exit */
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_INACTIVE);
}
if(IS_STATE(ray_state, ray_index, RAY_TO_REGENERATE)) {
kernel_split_state.work_array[ray_index] = work_index;
/* Get the sample associated with the current work */
uint sample = get_work_sample(kg, work_index, ray_index) + kernel_split_params.start_sample;
/* Get pixel and tile position associated with current work */
uint tile_x, tile_y, pixel_x, pixel_y;
get_work_pixel_tile_position(kg, &pixel_x, &pixel_y, &tile_x, &tile_y, work_index, ray_index);
uint x, y, sample;
get_work_pixel(kg, work_index, &x, &y, &sample);
/* Remap rng_state according to the current work */
/* Remap rng_state to current pixel. */
ccl_global uint *rng_state = kernel_split_params.rng_state;
rng_state += kernel_split_params.offset + pixel_x + pixel_y*stride;
rng_state += kernel_split_params.offset + x + y*stride;
/* Remap buffer according to the current work */
ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride;
/* Store buffer offset for writing to passes. */
uint buffer_offset = (kernel_split_params.offset + x + y*stride) * kernel_data.film.pass_stride;
kernel_split_state.buffer_offset[ray_index] = buffer_offset;
/* Initialize random numbers and ray. */
uint rng_hash;
kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng_hash, ray);
kernel_path_trace_setup(kg, rng_state, sample, x, y, &rng_hash, ray);
if(ray->t != 0.0f) {
/* Initialize throughput, path radiance, Ray, PathState;
@ -145,6 +135,7 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
/* These rays do not participate in path-iteration. */
float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
/* Accumulate result in output buffer. */
ccl_global float *buffer = kernel_split_params.buffer + buffer_offset;
kernel_write_pass_float4(buffer, sample, L_rad);
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);

@ -90,8 +90,6 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
if(ray_index != QUEUE_EMPTY_SLOT) {
#endif
int stride = kernel_split_params.stride;
ccl_global PathState *state = 0x0;
float3 throughput;
@ -99,15 +97,8 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
ShaderData *sd = &kernel_split_state.sd[ray_index];
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
uint work_index = kernel_split_state.work_array[ray_index];
uint pixel_x, pixel_y, tile_x, tile_y;
get_work_pixel_tile_position(kg, &pixel_x, &pixel_y,
&tile_x, &tile_y,
work_index,
ray_index);
ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y * stride) * kernel_data.film.pass_stride;
uint buffer_offset = kernel_split_state.buffer_offset[ray_index];
ccl_global float *buffer = kernel_split_params.buffer + buffer_offset;
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
ShaderData *emission_sd = &kernel_split_state.sd_DL_shadow[ray_index];
@ -140,7 +131,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
kernel_split_path_end(kg, ray_index);
}
else if(probability < 1.0f) {
float terminate = path_state_rng_1D_for_decision(kg, state, PRNG_TERMINATE);
float terminate = path_state_rng_1D(kg, state, PRNG_TERMINATE);
if(terminate >= probability) {
kernel_split_path_end(kg, ray_index);
}

@ -29,38 +29,32 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
*/
kernel_split_state.ray_state[ray_index] = RAY_ACTIVE;
uint work_index = 0;
/* Get work. */
if(!get_next_work(kg, &work_index, ray_index)) {
uint work_index;
if(!get_next_work(kg, ray_index, &work_index)) {
/* No more work, mark ray as inactive */
kernel_split_state.ray_state[ray_index] = RAY_INACTIVE;
return;
}
/* Get the sample associated with the work. */
uint sample = get_work_sample(kg, work_index, ray_index) + kernel_split_params.start_sample;
/* Get pixel and tile position associated with the work. */
uint pixel_x, pixel_y, tile_x, tile_y;
get_work_pixel_tile_position(kg, &pixel_x, &pixel_y,
&tile_x, &tile_y,
work_index,
ray_index);
kernel_split_state.work_array[ray_index] = work_index;
uint x, y, sample;
get_work_pixel(kg, work_index, &x, &y, &sample);
/* Remap rng_state and buffer to current pixel. */
ccl_global uint *rng_state = kernel_split_params.rng_state;
rng_state += kernel_split_params.offset + pixel_x + pixel_y*kernel_split_params.stride;
rng_state += kernel_split_params.offset + x + y*kernel_split_params.stride;
ccl_global float *buffer = kernel_split_params.buffer;
buffer += (kernel_split_params.offset + pixel_x + pixel_y * kernel_split_params.stride) * kernel_data.film.pass_stride;
/* Store buffer offset for writing to passes. */
uint buffer_offset = (kernel_split_params.offset + x + y*kernel_split_params.stride) * kernel_data.film.pass_stride;
kernel_split_state.buffer_offset[ray_index] = buffer_offset;
/* Initialize random numbers and ray. */
uint rng_hash;
kernel_path_trace_setup(kg,
rng_state,
sample,
pixel_x, pixel_y,
x, y,
&rng_hash,
&kernel_split_state.ray[ray_index]);
@ -84,6 +78,7 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
/* These rays do not participate in path-iteration. */
float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
/* Accumulate result in output buffer. */
ccl_global float *buffer = kernel_split_params.buffer + buffer_offset;
kernel_write_pass_float4(buffer, sample, L_rad);
ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE);
}

@ -50,20 +50,16 @@ ccl_device void kernel_shader_eval(KernelGlobals *kg)
if(IS_STATE(ray_state, ray_index, RAY_ACTIVE)) {
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
#ifndef __BRANCHED_PATH__
float rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag);
#else
float rbsdf = 0.0f;
if(!kernel_data.integrator.branched || IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
rbsdf = path_state_rng_1D_for_decision(kg, state, PRNG_BSDF);
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, state->flag);
#ifdef __BRANCHED_PATH__
if(kernel_data.integrator.branched) {
shader_merge_closures(&kernel_split_state.sd[ray_index]);
}
else
#endif
{
shader_prepare_closures(&kernel_split_state.sd[ray_index], state);
}
shader_eval_surface(kg, &kernel_split_state.sd[ray_index], state, rbsdf, state->flag);
shader_merge_closures(&kernel_split_state.sd[ray_index]);
#endif /* __BRANCHED_PATH__ */
}
}

@ -122,7 +122,7 @@ typedef ccl_global struct SplitBranchedState {
SPLIT_DATA_ENTRY(ccl_global int, is_lamp, 1) \
SPLIT_DATA_ENTRY(ccl_global Ray, light_ray, 1) \
SPLIT_DATA_ENTRY(ccl_global int, queue_data, (NUM_QUEUES*2)) /* TODO(mai): this is too large? */ \
SPLIT_DATA_ENTRY(ccl_global uint, work_array, 1) \
SPLIT_DATA_ENTRY(ccl_global uint, buffer_offset, 1) \
SPLIT_DATA_ENTRY(ShaderData, sd, 1) \
SPLIT_DATA_ENTRY(ShaderData, sd_DL_shadow, 1) \
SPLIT_DATA_SUBSURFACE_ENTRIES \

@ -250,20 +250,17 @@ ccl_device void kernel_subsurface_scatter(KernelGlobals *kg)
#ifdef __BRANCHED_PATH__
}
else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
float bssrdf_probability;
ShaderClosure *sc = subsurface_scatter_pick_closure(kg, sd, &bssrdf_probability);
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg,
state,
PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v);
/* modify throughput for picking bssrdf or bsdf */
*throughput *= bssrdf_probability;
const ShaderClosure *sc = shader_bssrdf_pick(sd, throughput, &bssrdf_u);
/* do bssrdf scatter step if we picked a bssrdf closure */
if(sc) {
uint lcg_state = lcg_state_init_addrspace(state, 0x68bc21eb);
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg,
state,
PRNG_BSDF_U,
&bssrdf_u, &bssrdf_v);
subsurface_scatter_step(kg,
sd,
state,

@ -25,6 +25,9 @@
#if defined(i386) || defined(_M_IX86)
/* We require minimum SSE2 support on x86, so auto enable. */
# define __KERNEL_SSE2__
# ifdef WITH_KERNEL_SSE2
# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
# endif

@ -237,6 +237,7 @@ class InfoPropertyRNA:
"min",
"max",
"array_length",
"array_dimensions",
"collection_type",
"type",
"fixed_type",
@ -262,6 +263,7 @@ class InfoPropertyRNA:
self.min = getattr(rna_prop, "hard_min", -1)
self.max = getattr(rna_prop, "hard_max", -1)
self.array_length = getattr(rna_prop, "array_length", 0)
self.array_dimensions = getattr(rna_prop, "array_dimensions", ())[:]
self.collection_type = GetInfoStructRNA(rna_prop.srna)
self.is_required = rna_prop.is_required
self.is_readonly = rna_prop.is_readonly
@ -281,13 +283,21 @@ class InfoPropertyRNA:
else:
self.is_enum_flag = False
self.default_str = "" # fallback
if self.array_length:
self.default = tuple(getattr(rna_prop, "default_array", ()))
if self.array_dimensions[1] != 0: # Multi-dimensional array, convert default flat one accordingly.
self.default_str = tuple(float_as_string(v) if self.type == "float" else str(v) for v in self.default)
for dim in self.array_dimensions[::-1]:
if dim != 0:
self.default = tuple(zip(*((iter(self.default),) * dim)))
self.default_str = tuple("(%s)" % ", ".join(s for s in b) for b in zip(*((iter(self.default_str),) * dim)))
self.default_str = self.default_str[0]
elif self.type == "enum" and self.is_enum_flag:
self.default = getattr(rna_prop, "default_flag", set())
else:
self.default = getattr(rna_prop, "default", None)
self.default_str = "" # fallback
if self.type == "pointer":
# pointer has no default, just set as None
@ -302,13 +312,12 @@ class InfoPropertyRNA:
else:
self.default_str = "'%s'" % self.default
elif self.array_length:
self.default_str = ''
# special case for floats
if len(self.default) > 0:
if self.type == "float":
if self.array_dimensions[1] == 0: # single dimension array, we already took care of multi-dimensions ones.
# special case for floats
if self.type == "float" and len(self.default) > 0:
self.default_str = "(%s)" % ", ".join(float_as_string(f) for f in self.default)
if not self.default_str:
self.default_str = str(self.default)
else:
self.default_str = str(self.default)
else:
if self.type == "float":
self.default_str = float_as_string(self.default)
@ -328,7 +337,10 @@ class InfoPropertyRNA:
if self.fixed_type is None:
type_str += self.type
if self.array_length:
type_str += " array of %d items" % (self.array_length)
if self.array_dimensions[1] != 0:
type_str += " multi-dimensional array of %s items" % (" * ".join(str(d) for d in self.array_dimensions if d != 0))
else:
type_str += " array of %d items" % (self.array_length)
if self.type in {"float", "int"}:
type_str += " in [%s, %s]" % (range_str(self.min), range_str(self.max))
@ -632,7 +644,7 @@ def BuildRNAInfo():
for rna_prop_ptr in (getattr(rna_prop, "fixed_type", None), getattr(rna_prop, "srna", None)):
# Does this property point to me?
if rna_prop_ptr:
if rna_prop_ptr and rna_prop_ptr.identifier in rna_references_dict:
rna_references_dict[rna_prop_ptr.identifier].append(
"%s.%s" % (rna_struct_path, rna_prop_identifier))
@ -645,7 +657,7 @@ def BuildRNAInfo():
rna_prop_ptr = getattr(rna_prop, "fixed_type", None)
# Does this property point to me?
if rna_prop_ptr:
if rna_prop_ptr and rna_prop_ptr.identifier in rna_references_dict:
rna_references_dict[rna_prop_ptr.identifier].append(
"%s.%s" % (rna_struct_path, rna_func.identifier))
@ -680,16 +692,22 @@ def BuildRNAInfo():
for rna_info_prop in InfoFunctionRNA.global_lookup.values():
rna_info_prop.build()
for rna_info in InfoStructRNA.global_lookup.values():
rna_info.build()
for prop in rna_info.properties:
prop.build()
for func in rna_info.functions:
func.build()
for prop in func.args:
prop.build()
for prop in func.return_values:
done_keys = set()
new_keys = set(InfoStructRNA.global_lookup.keys())
while new_keys:
for rna_key in new_keys:
rna_info = InfoStructRNA.global_lookup[rna_key]
rna_info.build()
for prop in rna_info.properties:
prop.build()
for func in rna_info.functions:
func.build()
for prop in func.args:
prop.build()
for prop in func.return_values:
prop.build()
done_keys |= new_keys
new_keys = set(InfoStructRNA.global_lookup.keys()) - done_keys
# there are too many invalid defaults, unless we intend to fix, leave this off
if 0:

@ -230,6 +230,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
"`": 'ACCENT_GRAVE',
"*": 'NUMPAD_ASTERIX',
"/": 'NUMPAD_SLASH',
'+': 'NUMPAD_PLUS',
"RMB": 'RIGHTMOUSE',
"LMB": 'LEFTMOUSE',
"MMB": 'MIDDLEMOUSE',

@ -1799,7 +1799,7 @@ void CDDM_recalc_looptri(DerivedMesh *dm)
const unsigned int totloop = dm->numLoopData;
DM_ensure_looptri_data(dm);
BLI_assert(cddm->dm.looptris.array_wip != NULL);
BLI_assert(totpoly == 0 || cddm->dm.looptris.array_wip != NULL);
BKE_mesh_recalc_looptri(
cddm->mloop, cddm->mpoly,

@ -281,7 +281,7 @@ static void emDM_recalcLoopTri(DerivedMesh *dm)
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array_wip;
BLI_assert(mlooptri != NULL);
BLI_assert(tottri == 0 || mlooptri != NULL);
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);

@ -61,6 +61,8 @@
#include "BKE_movieclip.h"
#include "BKE_image.h"
#include "DEG_depsgraph_build.h"
static struct {
ListBase splines;
struct GHash *id_hash;
@ -817,6 +819,8 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
mask->sfra = 1;
mask->efra = 100;
DEG_relations_tag_update(bmain);
return mask;
}

@ -4230,7 +4230,7 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm)
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array_wip;
BLI_assert(mlooptri != NULL);
BLI_assert(tottri == 0 || mlooptri != NULL);
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);

@ -303,7 +303,10 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen
// <library_visual_scenes>
SceneExporter se(writer, &arm_exporter, this->export_settings);
#if 0
/* The following code seems to be an obsolete workaround
Comment out until it proofs correct that we no longer need it.
*/
if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
// channels adressing <matrix> objects is not (yet) supported
// So we force usage of <location>, <translation> and <scale>
@ -315,7 +318,9 @@ int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scen
else {
se.setExportTransformationType(this->export_settings->export_transformation_type);
}
#else
se.setExportTransformationType(this->export_settings->export_transformation_type);
#endif
se.exportScene(eval_ctx, sce);
// <scene>

@ -39,6 +39,7 @@
#include "DNA_scene_types.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_context.h"
#include "BKE_object.h"
@ -94,9 +95,13 @@ typedef struct tPoseSlideOp {
ListBase pfLinks; /* links between posechannels and f-curves */
DLRBT_Tree keys; /* binary tree for quicker searching for keyframes (when applicable) */
int cframe; /* current frame number */
int prevFrame; /* frame before current frame (blend-from) */
int nextFrame; /* frame after current frame (blend-to) */
int cframe; /* current frame number - global time */
int prevFrame; /* frame before current frame (blend-from) - global time */
int nextFrame; /* frame after current frame (blend-to) - global time */
float prevFrameF; /* prevFrame, but in local action time (for F-Curve lookups to work) */
float nextFrameF; /* nextFrame, but in local action time (for F-Curve lookups to work) */
short mode; /* sliding mode (ePoseSlide_Modes) */
short flag; /* unused for now, but can later get used for storing runtime settings.... */
@ -189,11 +194,15 @@ static int pose_slide_init(bContext *C, wmOperator *op, short mode)
pso->channels = RNA_enum_get(op->ptr, "channels");
pso->axislock = RNA_enum_get(op->ptr, "axis_lock");
/* check the settings from the context */
/* ensure validity of the settings from the context */
if (ELEM(NULL, pso->ob, pso->arm, pso->ob->adt, pso->ob->adt->action))
return 0;
else
act = pso->ob->adt->action;
act = pso->ob->adt->action;
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
/* for each Pose-Channel which gets affected, get the F-Curves for that channel
* and set the relevant transform flags...
@ -259,9 +268,9 @@ static void pose_slide_apply_val(tPoseSlideOp *pso, FCurve *fcu, float *val)
/* get keyframe values for endpoint poses to blend with */
/* previous/start */
sVal = evaluate_fcurve(fcu, (float)pso->prevFrame);
sVal = evaluate_fcurve(fcu, pso->prevFrameF);
/* next/end */
eVal = evaluate_fcurve(fcu, (float)pso->nextFrame);
eVal = evaluate_fcurve(fcu, pso->nextFrameF);
/* if both values are equal, don't do anything */
if (IS_EQF(sVal, eVal)) {
@ -483,15 +492,15 @@ static void pose_slide_apply_quat(tPoseSlideOp *pso, tPChanFCurveLink *pfl)
float quat_prev[4], quat_next[4];
/* get 2 quats */
quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrame);
quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrame);
quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrame);
quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrame);
quat_prev[0] = evaluate_fcurve(fcu_w, pso->prevFrameF);
quat_prev[1] = evaluate_fcurve(fcu_x, pso->prevFrameF);
quat_prev[2] = evaluate_fcurve(fcu_y, pso->prevFrameF);
quat_prev[3] = evaluate_fcurve(fcu_z, pso->prevFrameF);
quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrame);
quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrame);
quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrame);
quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrame);
quat_next[0] = evaluate_fcurve(fcu_w, pso->nextFrameF);
quat_next[1] = evaluate_fcurve(fcu_x, pso->nextFrameF);
quat_next[2] = evaluate_fcurve(fcu_y, pso->nextFrameF);
quat_next[3] = evaluate_fcurve(fcu_z, pso->nextFrameF);
/* perform blending */
if (pso->mode == POSESLIDE_BREAKDOWN) {
@ -543,6 +552,10 @@ static void pose_slide_apply(bContext *C, tPoseSlideOp *pso)
/* move out one step either side */
pso->prevFrame--;
pso->nextFrame++;
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
}
/* for each link, handle each set of transforms */
@ -746,6 +759,10 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
pso->nextFrame = (ak->next) ? (ak->next->cfra) : (pso->cframe + 1);
RNA_int_set(op->ptr, "next_frame", pso->nextFrame);
}
/* apply NLA mapping corrections so the frame lookups work */
pso->prevFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->prevFrame, NLATIME_CONVERT_UNMAP);
pso->nextFrameF = BKE_nla_tweakedit_remap(pso->ob->adt, pso->nextFrame, NLATIME_CONVERT_UNMAP);
}
else {
BKE_report(op->reports, RPT_ERROR, "No keyframes to slide between");

@ -40,7 +40,7 @@ struct wmOperatorType;
struct ViewContext;
/* editfont.c */
enum { DEL_ALL, DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL };
enum { DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_NEXT_WORD, DEL_PREV_WORD, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL };
enum { CASE_LOWER, CASE_UPPER };
enum { LINE_BEGIN, LINE_END, PREV_CHAR, NEXT_CHAR, PREV_WORD, NEXT_WORD,
PREV_LINE, NEXT_LINE, PREV_PAGE, NEXT_PAGE };

@ -178,9 +178,10 @@ void ED_keymap_curve(wmKeyConfig *keyconf)
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_style_toggle", PKEY, KM_PRESS, KM_CTRL, 0)->ptr, "style", CU_CHINFO_SMALLCAPS);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", DELKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_NEXT_SEL);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", DELKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_NEXT_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", BACKSPACEKEY, KM_PRESS, 0, 0)->ptr, "type", DEL_PREV_SEL);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", DEL_PREV_SEL); /* same as above [#26623] */
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_ALL);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_delete", BACKSPACEKEY, KM_PRESS, KM_CTRL, 0)->ptr, "type", DEL_PREV_WORD);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move", HOMEKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_BEGIN);
RNA_enum_set(WM_keymap_add_item(keymap, "FONT_OT_move", ENDKEY, KM_PRESS, 0, 0)->ptr, "type", LINE_END);

@ -1177,9 +1177,10 @@ void FONT_OT_line_break(wmOperatorType *ot)
/******************* delete operator **********************/
static EnumPropertyItem delete_type_items[] = {
{DEL_ALL, "ALL", 0, "All", ""},
{DEL_NEXT_CHAR, "NEXT_CHARACTER", 0, "Next Character", ""},
{DEL_PREV_CHAR, "PREVIOUS_CHARACTER", 0, "Previous Character", ""},
{DEL_NEXT_WORD, "NEXT_WORD", 0, "Next Word", ""},
{DEL_PREV_WORD, "PREVIOUS_WORD", 0, "Previous Word", ""},
{DEL_SELECTION, "SELECTION", 0, "Selection", ""},
{DEL_NEXT_SEL, "NEXT_OR_SELECTION", 0, "Next or Selection", ""},
{DEL_PREV_SEL, "PREVIOUS_OR_SELECTION", 0, "Previous or Selection", ""},
@ -1190,7 +1191,9 @@ static int delete_exec(bContext *C, wmOperator *op)
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
int x, selstart, selend, type = RNA_enum_get(op->ptr, "type");
int selstart, selend, type = RNA_enum_get(op->ptr, "type");
int range[2] = {0, 0};
bool has_select = false;
if (ef->len == 0)
return OPERATOR_CANCELLED;
@ -1198,6 +1201,7 @@ static int delete_exec(bContext *C, wmOperator *op)
if (BKE_vfont_select_get(obedit, &selstart, &selend)) {
if (type == DEL_NEXT_SEL) type = DEL_SELECTION;
else if (type == DEL_PREV_SEL) type = DEL_SELECTION;
has_select = true;
}
else {
if (type == DEL_NEXT_SEL) type = DEL_NEXT_CHAR;
@ -1205,10 +1209,6 @@ static int delete_exec(bContext *C, wmOperator *op)
}
switch (type) {
case DEL_ALL:
ef->len = ef->pos = 0;
ef->textbuf[0] = 0;
break;
case DEL_SELECTION:
if (!kill_selection(obedit, 0))
return OPERATOR_CANCELLED;
@ -1217,29 +1217,69 @@ static int delete_exec(bContext *C, wmOperator *op)
if (ef->pos <= 0)
return OPERATOR_CANCELLED;
for (x = ef->pos; x <= ef->len; x++)
ef->textbuf[x - 1] = ef->textbuf[x];
for (x = ef->pos; x <= ef->len; x++)
ef->textbufinfo[x - 1] = ef->textbufinfo[x];
range[0] = ef->pos - 1;
range[1] = ef->pos;
ef->pos--;
ef->textbuf[--ef->len] = '\0';
break;
case DEL_NEXT_CHAR:
if (ef->pos >= ef->len)
return OPERATOR_CANCELLED;
for (x = ef->pos; x < ef->len; x++)
ef->textbuf[x] = ef->textbuf[x + 1];
for (x = ef->pos; x < ef->len; x++)
ef->textbufinfo[x] = ef->textbufinfo[x + 1];
ef->textbuf[--ef->len] = '\0';
range[0] = ef->pos;
range[1] = ef->pos + 1;
break;
case DEL_NEXT_WORD:
{
int pos = ef->pos;
BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
range[0] = ef->pos;
range[1] = pos;
break;
}
case DEL_PREV_WORD:
{
int pos = ef->pos;
BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
range[0] = pos;
range[1] = ef->pos;
ef->pos = pos;
break;
}
default:
return OPERATOR_CANCELLED;
}
if (range[0] != range[1]) {
BLI_assert(range[0] < range[1]);
int len_remove = range[1] - range[0];
int len_tail = ef->len - range[1];
if (has_select) {
for (int i = 0; i < 2; i++) {
int *sel = i ? &ef->selend : &ef->selstart;
if (*sel <= range[0]) {
/* pass */
}
else if (*sel >= range[1]) {
*sel -= len_remove;
}
else if (*sel < range[1]) {
/* pass */
*sel = range[0];
}
}
}
memmove(&ef->textbuf[range[0]], &ef->textbuf[range[1]], sizeof(*ef->textbuf) * len_tail);
memmove(&ef->textbufinfo[range[0]], &ef->textbufinfo[range[1]], sizeof(*ef->textbufinfo) * len_tail);
ef->len -= len_remove;
ef->textbuf[ef->len] = '\0';
BKE_vfont_select_clamp(obedit);
}
text_update_edited(C, obedit, FO_EDIT);
return OPERATOR_FINISHED;
@ -1260,7 +1300,7 @@ void FONT_OT_delete(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_enum(ot->srna, "type", delete_type_items, DEL_ALL, "Type", "Which part of the text to delete");
RNA_def_enum(ot->srna, "type", delete_type_items, DEL_PREV_CHAR, "Type", "Which part of the text to delete");
}
/*********************** insert text operator *************************/

@ -347,11 +347,13 @@ static uiTooltipData *ui_tooltip_data_from_button(bContext *C, uiBut *but)
/* Tip */
if (but_tip.strinfo) {
BLI_strncpy(data->header, but_tip.strinfo, sizeof(data->lines[0]));
if (enum_label.strinfo) {
BLI_snprintf(data->header, sizeof(data->header), "%s: ", but_tip.strinfo);
BLI_strncpy(data->active_info, enum_label.strinfo, sizeof(data->lines[0]));
}
else {
BLI_snprintf(data->header, sizeof(data->header), "%s.", but_tip.strinfo);
}
data->format[data->totline].style = UI_TIP_STYLE_HEADER;
data->totline++;

@ -637,13 +637,17 @@ static void action_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, I
{
SpaceAction *sact = (SpaceAction *)slink;
if (!ELEM(GS(old_id->name), ID_GR)) {
return;
if ((ID *)sact->action == old_id) {
sact->action = (bAction *)new_id;
}
if ((ID *)sact->ads.filter_grp == old_id) {
sact->ads.filter_grp = (Group *)new_id;
}
if ((ID *)sact->ads.source == old_id) {
sact->ads.source = new_id;
}
}
/* only called once, from space/spacetypes.c */

@ -70,6 +70,6 @@ void CONSOLE_OT_select_set(struct wmOperatorType *ot);
void CONSOLE_OT_select_word(struct wmOperatorType *ot);
enum { LINE_BEGIN, LINE_END, PREV_CHAR, NEXT_CHAR, PREV_WORD, NEXT_WORD };
enum { DEL_ALL, DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_NEXT_WORD, DEL_PREV_WORD, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL };
enum { DEL_NEXT_CHAR, DEL_PREV_CHAR, DEL_NEXT_WORD, DEL_PREV_WORD, DEL_SELECTION, DEL_NEXT_SEL, DEL_PREV_SEL };
#endif /* __CONSOLE_INTERN_H__ */

@ -610,6 +610,22 @@ static int rna_Property_array_length_get(PointerRNA *ptr)
return prop->totarraylength;
}
static void rna_Property_array_dimensions_get(PointerRNA *ptr, int dimensions[RNA_MAX_ARRAY_DIMENSION])
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
rna_idproperty_check(&prop, ptr);
if (prop->arraydimension > 1) {
for (int i = RNA_MAX_ARRAY_DIMENSION; i--; ) {
dimensions[i] = (i >= prop->arraydimension) ? 0 : prop->arraylength[i];
}
}
else {
memset(dimensions, 0, sizeof(*dimensions) * RNA_MAX_ARRAY_DIMENSION);
dimensions[0] = prop->totarraylength;
}
}
static int rna_Property_is_registered_get(PointerRNA *ptr)
{
PropertyRNA *prop = (PropertyRNA *)ptr->data;
@ -1354,6 +1370,12 @@ static void rna_def_number_property(StructRNA *srna, PropertyType type)
RNA_def_property_int_funcs(prop, "rna_Property_array_length_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Array Length", "Maximum length of the array, 0 means unlimited");
prop = RNA_def_property(srna, "array_dimensions", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_array(prop, RNA_MAX_ARRAY_DIMENSION);
RNA_def_property_int_funcs(prop, "rna_Property_array_dimensions_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Array Dimensions", "Length of each dimension of the array");
prop = RNA_def_property(srna, "is_array", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_boolean_funcs(prop, "rna_NumberProperty_is_array_get", NULL);

@ -2401,7 +2401,6 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure
#define _SWIZZLE3(a, b, c) (_SWIZZLE2(a, b) | (((c) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 2)))
#define _SWIZZLE4(a, b, c, d) (_SWIZZLE3(a, b, c) | (((d) | SWIZZLE_VALID_AXIS) << (SWIZZLE_BITS_PER_AXIS * 3)))
#define SWIZZLE1(a) SET_INT_IN_POINTER(_SWIZZLE1(a))
#define SWIZZLE2(a, b) SET_INT_IN_POINTER(_SWIZZLE2(a, b))
#define SWIZZLE3(a, b, c) SET_INT_IN_POINTER(_SWIZZLE3(a, b, c))
#define SWIZZLE4(a, b, c, d) SET_INT_IN_POINTER(_SWIZZLE4(a, b, c, d))

@ -613,7 +613,7 @@ if(UNIX AND NOT APPLE)
PATTERN "*.pyo" EXCLUDE # * any cache *
)
# On some platforms requests does have extra dependencies.
set(_requests_deps "chardet" "urllib3")
set(_requests_deps "certifi" "chardet" "idna" "urllib3")
foreach(_requests_dep ${_requests_deps})
if(EXISTS ${PYTHON_REQUESTS_PATH}/${_requests_dep})
install(
@ -707,7 +707,7 @@ elseif(WIN32)
)
if(WITH_PYTHON_INSTALL_NUMPY)
set(PYTHON_NUMPY_VERSION 1.10)
set(PYTHON_NUMPY_VERSION 1.13)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages
COMMAND ${CMAKE_COMMAND} -E
make_directory ${CMAKE_CURRENT_BINARY_DIR}/${BLENDER_VERSION}/python/lib/site-packages)

@ -173,13 +173,11 @@ class Report:
if not os.path.exists(outdir):
os.makedirs(outdir)
f = open(os.path.join(outdir, "failed.data"), "w")
f.write(self.failed_tests)
f.close()
filepath = os.path.join(outdir, "failed.data")
pathlib.Path(filepath).write_text(self.failed_tests)
f = open(os.path.join(outdir, "passed.data"), "w")
f.write(self.passed_tests)
f.close()
filepath = os.path.join(outdir, "passed.data")
pathlib.Path(filepath).write_text(self.passed_tests)
# gather intermediate data for all tests
failed_data = sorted(glob.glob(os.path.join(OUTDIR, "*/failed.data")))
@ -189,9 +187,11 @@ class Report:
passed_tests = ""
for filename in failed_data:
failed_tests += open(os.path.join(OUTDIR, filename), "r").read()
filepath = os.path.join(OUTDIR, filename)
failed_tests += pathlib.Path(filepath).read_text()
for filename in passed_data:
passed_tests += open(os.path.join(OUTDIR, filename), "r").read()
filepath = os.path.join(OUTDIR, filename)
passed_tests += pathlib.Path(filepath).read_text()
# write html for all tests
self.html = """
@ -241,9 +241,7 @@ class Report:
""" . format(failed_tests, passed_tests)
filepath = os.path.join(OUTDIR, "report.html")
f = open(filepath, "w")
f.write(self.html)
f.close()
pathlib.Path(filepath).write_text(self.html)
print_message("Report saved to: " + pathlib.Path(filepath).as_uri())