Compare commits

..

11 Commits

Author SHA1 Message Date
1339e7c44f Merge branch 'master' into experiment-point-distribution 2021-01-12 21:22:32 +01:00
b66fcd83f6 rename back 2021-01-12 21:21:55 +01:00
e583e236f3 cleanup 2021-01-12 21:21:37 +01:00
2809419eff cleanup 2021-01-12 21:17:59 +01:00
b4c5729726 cleanup 2021-01-12 21:13:20 +01:00
cb55872cda cleanup 2021-01-12 20:57:39 +01:00
3e59cd213e cleanup 2021-01-12 20:56:19 +01:00
d0cf25259d take density factors into account 2021-01-12 20:49:11 +01:00
225039ff92 cleanup 2021-01-12 20:29:36 +01:00
e3f14564a4 initial new implementation 2021-01-12 20:11:00 +01:00
8d34b73df2 remove poisson distribution code 2021-01-12 16:54:43 +01:00
826 changed files with 10818 additions and 17921 deletions

View File

@@ -10,9 +10,8 @@
# Changes that belong here:
# - Massive comment, doxy-sections, or spelling corrections.
# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change".
# - Several commits should be added to this list at once, because adding
# one extra commit (to edit this file) after every cleanup is noisy.
# - No clang-tidy changes.
# - Several smaller commits should be added to this list at once, because adding
# one extra commit (to edit this file) after every small cleanup is noisy.
#
# Note:
# - The comment above the SHA should be the first line of the commit.
@@ -93,12 +92,78 @@ c42a6b77b52560d257279de2cb624b4ef2c0d24c
# Cleanup: use doxy sections for imbuf
c207f7c22e1439e0b285fba5d2c072bdae23f981
# Cleanup: Clang-Tidy, modernize-use-bool-literals
af35ada2f3fa8da4d46b3a71de724d353d716820
# Cleanup: Use nullptr everywhere in fluid code
311031ecd03dbfbf43e1df672a395f24b2e7d4d3
# Cleanup: Clang-Tidy, modernize-redundant-void-arg
a331d5c99299c4514ca33c843b1c79b872f2728d
# Cleanup: Clang-Tidy modernize-use-nullptr
16732def37c5a66f3ea28dbe247b09cc6bca6677
# Cleanup: Clang-tidy, modernize-concat-nested-namespaces
4525049aa0cf818f6483dce589ac9791eb562338
# Cleanup: Clang-tidy else-after-return
ae342ed4511cf2e144dcd27ce2c635d3d536f9ad
# Cleanup: Clang-Tidy, readability-redundant-member-init
190170d4cc92ff34abe1744a10474ac4f1074086
# Cleanup: use 'filepath' instead of 'name' for ImBuf utilities
99f56b4c16323f96c0cbf54e392fb509fcac5bda
# Cleanup: clang-format
c4d8f6a4a8ddc29ed27311ed7578b3c8c31399d2
b5d310b569e07a937798a2d38539cfd290149f1c
8c846cccd6bdfd3e90a695fabbf05f53e5466a57
4eac03d821fa17546f562485f7d073813a5e5943
1166110a9d66af9c5a47cee2be591f50fdc445e8
# Cleanup: clang-format.
40d4a4cb1a6b4c3c2a486e8f2868f547530e0811
4eac03d821fa17546f562485f7d073813a5e5943
# Cleanup: use preprocessor version check for PyTypeObject declaration
cd9acfed4f7674b84be965d469a367aef96f8af3
# Cycles: fix compilation of OSL shaders following API change
b980cd163a9d5d77eeffc2e353333e739fa9e719
# Cleanup: clang-tidy suppress warnings for PyTypeObject.tp_print
efd71aad4f22ec0073d80b8dd296015d3f395aa8
# Cleanup: fix wrong merge, remove extra unique_ptr.
6507449e54a167c63a72229e4d0119dd2af68ae5
# Cleanup: fix some clang tidy issues
525a042c5c7513c41240b118acca002f6c60cc12
# Fix T82520: error building freestyle with Python3.8
e118426e4695a97d67e65d69677f3c4e2db50a56
# Cleanup: Clang-tidy, readability-else-after-return
7be47dadea5066ae095c644e0b4f1f10d75f5ab3
# Cleanup: Add `r_` to return parameter
45dca05b1cd2a5ead59144c93d790fdfe7c35ee6
# Cleanup: Typo in `print_default_info` function name.
41a73909dec716642f044e60b40a28335c9fdb10
# Cleanup: Reduce indentation
1cc3a0e2cf73a5ff4f9e0a7f5338eda77266b300
# Build-system: Force C linkage for all DNA type headers
ad4b7741dba45a2be210942c18af6b6e4438f129
# Cleanup: Move function to proper section
c126e27cdc8b28365a9d5f9fafc4d521d1eb83df
# Cleanup: remove break after return statements
bbdfeb751e16d939482d2e4b95c4d470f53f18a5
# Cleanup: clang-tidy
af013ff76feef7e8b8ba642279c62a5dc275d59f
# Cleanup: Make panel type flag names more clear
9d28353b525ecfbcca1501be72e4276dfb2bbc2a

View File

@@ -727,9 +727,8 @@ set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF)
# NanoVDB requires OpenVDB to convert the data structure
set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF)
# OpenVDB and OpenColorIO uses 'half' type from OpenEXR
# OpenVDB uses 'half' type from OpenEXR & fails to link without OpenEXR enabled.
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF)
set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENCOLORIO OFF)
# auto enable openimageio for cycles
if(WITH_CYCLES)
@@ -1764,20 +1763,8 @@ if(WITH_BLENDER)
# internal and external library information first, for test linking
add_subdirectory(source)
elseif(WITH_CYCLES_STANDALONE)
add_subdirectory(intern/glew-mx)
add_subdirectory(intern/guardedalloc)
add_subdirectory(intern/libc_compat)
add_subdirectory(intern/numaapi)
add_subdirectory(intern/sky)
add_subdirectory(intern/cycles)
add_subdirectory(extern/clew)
if(WITH_CYCLES_LOGGING)
if(NOT WITH_SYSTEM_GFLAGS)
add_subdirectory(extern/gflags)
endif()
add_subdirectory(extern/glog)
endif()
if(WITH_CUDA_DYNLOAD)
add_subdirectory(extern/cuew)
endif()
@@ -1858,8 +1845,6 @@ if(FIRST_RUN)
info_cfg_option(WITH_OPENCOLORIO)
info_cfg_option(WITH_OPENIMAGEDENOISE)
info_cfg_option(WITH_OPENVDB)
info_cfg_option(WITH_POTRACE)
info_cfg_option(WITH_PUGIXML)
info_cfg_option(WITH_QUADRIFLOW)
info_cfg_option(WITH_TBB)
info_cfg_option(WITH_USD)

View File

@@ -520,7 +520,7 @@ format: .FORCE
# Simple version of ./doc/python_api/sphinx_doc_gen.sh with no PDF generation.
doc_py: .FORCE
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
ASAN_OPTIONS=halt_on_error=0 \
$(BLENDER_BIN) --background -noaudio --factory-startup \
--python doc/python_api/sphinx_doc_gen.py
sphinx-build -b html -j $(NPROCS) doc/python_api/sphinx-in doc/python_api/sphinx-out

View File

@@ -70,6 +70,7 @@ include(cmake/cuew.cmake)
include(cmake/opensubdiv.cmake)
include(cmake/sdl.cmake)
include(cmake/opencollada.cmake)
include(cmake/opencolorio.cmake)
include(cmake/llvm.cmake)
include(cmake/clang.cmake)
if(APPLE)
@@ -103,15 +104,18 @@ if(NOT APPLE)
include(cmake/xr_openxr.cmake)
endif()
# OpenColorIO and dependencies.
include(cmake/expat.cmake)
include(cmake/yamlcpp.cmake)
include(cmake/opencolorio.cmake)
if(WITH_WEBP)
include(cmake/webp.cmake)
endif()
if(WIN32)
# OCIO deps
include(cmake/tinyxml.cmake)
include(cmake/yamlcpp.cmake)
# LCMS is an OCIO dep, but only if you build the apps, leaving it here for convenience
# include(cmake/lcms.cmake)
endif()
if(NOT WIN32 OR ENABLE_MINGW64)
include(cmake/gmp.cmake)
include(cmake/openjpeg.cmake)

View File

@@ -16,20 +16,16 @@
#
# ***** END GPL LICENSE BLOCK *****
set(EXPAT_EXTRA_ARGS
-DEXPAT_BUILD_DOCS=OFF
-DEXPAT_BUILD_EXAMPLES=OFF
-DEXPAT_BUILD_TESTS=OFF
-DEXPAT_BUILD_TOOLS=OFF
-DEXPAT_SHARED_LIBS=OFF
set(LCMS_EXTRA_ARGS
)
ExternalProject_Add(external_expat
URL ${EXPAT_URI}
ExternalProject_Add(external_lcms
URL ${LCMS_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${EXPAT_HASH}
PREFIX ${BUILD_DIR}/expat
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/expat ${DEFAULT_CMAKE_FLAGS} ${EXPAT_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/expat
SOURCE_SUBDIR expat
URL_HASH MD5=${LCMS_HASH}
PREFIX ${BUILD_DIR}/lcms
# Patch taken from ocio.
PATCH_COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_lcms.txt ${BUILD_DIR}/lcms/src/external_lcms/CMakeLists.txt
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/lcms ${DEFAULT_CMAKE_FLAGS} ${LCMS_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/lcms
)

View File

@@ -22,8 +22,8 @@ ExternalProject_Add(external_nasm
URL_HASH SHA256=${NASM_HASH}
PREFIX ${BUILD_DIR}/nasm
PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/nasm/src/external_nasm < ${PATCH_DIR}/nasm.diff
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && ./autogen.sh && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/nasm
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make -j${MAKE_THREADS} && make manpages
CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/nasm
BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make -j${MAKE_THREADS}
INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/nasm/src/external_nasm/ && make install
INSTALL_DIR ${LIBDIR}/nasm
)

View File

@@ -18,22 +18,16 @@
set(OPENCOLORIO_EXTRA_ARGS
-DOCIO_BUILD_APPS=OFF
-DOCIO_BUILD_PYTHON=OFF
-DOCIO_BUILD_PYGLUE=OFF
-DOCIO_BUILD_NUKE=OFF
-DOCIO_BUILD_JAVA=OFF
-DBUILD_SHARED_LIBS=OFF
-DOCIO_USE_BOOST_PTR=OFF
-DOCIO_BUILD_STATIC=ON
-DOCIO_BUILD_SHARED=OFF
-DOCIO_BUILD_TRUELIGHT=OFF
-DOCIO_BUILD_DOCS=OFF
-DOCIO_BUILD_TESTS=OFF
-DOCIO_BUILD_GPU_TESTS=OFF
-DOCIO_USE_SSE=ON
# Manually build ext packages except for pystring, which does not have
# a CMake or autotools build system that we can easily use.
-DOCIO_INSTALL_EXT_PACKAGES=MISSING
-DHalf_ROOT=${LIBDIR}/openexr
-DHalf_STATIC_LIBRARY=ON
-Dexpat_ROOT=${LIBDIR}/expat
-Dyaml-cpp_ROOT=${LIBDIR}/yamlcpp
-DOCIO_BUILD_PYGLUE=OFF
-DOCIO_BUILD_JNIGLUE=OFF
-DOCIO_STATIC_JNIGLUE=OFF
)
if(APPLE AND NOT("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "x86_64"))
@@ -47,7 +41,24 @@ if(WIN32)
set(OCIO_PATCH opencolorio_win.diff)
set(OPENCOLORIO_EXTRA_ARGS
${OPENCOLORIO_EXTRA_ARGS}
-DOCIO_BUILD_TESTS=OFF
-DOCIO_USE_SSE=ON
-DOCIO_INLINES_HIDDEN=OFF
-DOCIO_PYGLUE_LINK=OFF
-DOCIO_PYGLUE_RESPECT_ABI=OFF
-DOCIO_PYGLUE_SONAME=OFF
-DOCIO_PYGLUE_LIB_PREFIX=OFF
-DUSE_EXTERNAL_TINYXML=ON
-DTINYXML_INCLUDE_DIR=${LIBDIR}/tinyxml/include
-DTINYXML_LIBRARY=${LIBDIR}/tinyxml/lib/tinyxml${libext}
-DUSE_EXTERNAL_YAML=ON
-DYAML_CPP_FOUND=ON
-DYAML_CPP_VERSION=${YAMLCPP_VERSION}
-DUSE_EXTERNAL_LCMS=ON
-DINC_1=${LIBDIR}/tinyxml/include
-DINC_2=${LIBDIR}/yamlcpp/include
# Lie because ocio cmake is demanding boost even though it is not needed.
-DYAML_CPP_VERSION=0.5.0
)
else()
set(OCIO_PATCH opencolorio.diff)
@@ -61,42 +72,48 @@ ExternalProject_Add(external_opencolorio
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${OPENCOLORIO_HASH}
PREFIX ${BUILD_DIR}/opencolorio
PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/opencolorio/src/external_opencolorio < ${PATCH_DIR}/${OCIO_PATCH}
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opencolorio ${DEFAULT_CMAKE_FLAGS} ${OPENCOLORIO_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/opencolorio
)
if(NOT WIN32)
add_custom_command(
OUTPUT ${LIBDIR}/opencolorio/lib/libtinyxml.a
COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libtinyxml.a ${LIBDIR}/opencolorio/lib/libtinyxml.a
COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/libyaml-cpp.a
)
add_custom_target(external_opencolorio_extra ALL DEPENDS external_opencolorio ${LIBDIR}/opencolorio/lib/libtinyxml.a)
endif()
add_dependencies(
external_opencolorio
external_yamlcpp
external_expat
external_openexr
external_boost
)
if(WIN32)
add_dependencies(
external_opencolorio
external_tinyxml
external_yamlcpp
)
if(BUILD_MODE STREQUAL Release)
ExternalProject_Add_Step(external_opencolorio after_install
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/include ${HARVEST_TARGET}/opencolorio/include
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/lib ${HARVEST_TARGET}/opencolorio/lib
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencolorio/lib/static ${HARVEST_TARGET}/opencolorio/lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatMD.lib
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tinyxml/lib/tinyxml.lib ${HARVEST_TARGET}/opencolorio/lib/tinyxml.lib
DEPENDEES install
)
endif()
if(BUILD_MODE STREQUAL Debug)
ExternalProject_Add_Step(external_opencolorio after_install
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencolorio/lib/Opencolorio.lib ${HARVEST_TARGET}/opencolorio/lib/OpencolorIO_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencolorio/lib/static/Opencolorio.lib ${HARVEST_TARGET}/opencolorio/lib/OpencolorIO_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/yamlcpp/lib/libyaml-cppmdd.lib ${HARVEST_TARGET}/opencolorio/lib/libyaml-cpp_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/expat/lib/libexpatdMD.lib ${HARVEST_TARGET}/opencolorio/lib/libexpatdMD.lib
COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/pystring.lib ${HARVEST_TARGET}/opencolorio/lib/pystring_d.lib
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tinyxml/lib/tinyxml.lib ${HARVEST_TARGET}/opencolorio/lib/tinyxml_d.lib
DEPENDEES install
)
endif()
else()
ExternalProject_Add_Step(external_opencolorio after_install
COMMAND cp ${LIBDIR}/yamlcpp/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/
COMMAND cp ${LIBDIR}/expat/lib/libexpat.a ${LIBDIR}/opencolorio/lib/
COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libpystring.a ${LIBDIR}/opencolorio/lib/
DEPENDEES install
)
endif()

View File

@@ -0,0 +1,31 @@
# ***** 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 *****
set(TINYXML_EXTRA_ARGS
)
ExternalProject_Add(external_tinyxml
URL ${TINYXML_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}
URL_HASH MD5=${TINYXML_HASH}
PREFIX ${BUILD_DIR}/tinyxml
# patch taken from ocio
PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/tinyxml/src/external_tinyxml < ${PATCH_DIR}/tinyxml.diff
CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/tinyxml ${DEFAULT_CMAKE_FLAGS} ${TINYXML_EXTRA_ARGS}
INSTALL_DIR ${LIBDIR}/tinyxml
)

View File

@@ -109,9 +109,9 @@ set(OPENCOLLADA_VERSION v1.6.68)
set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
set(OPENCOLLADA_HASH ee7dae874019fea7be11613d07567493)
set(OPENCOLORIO_VERSION 2.0.0)
set(OPENCOLORIO_VERSION 1.1.1)
set(OPENCOLORIO_URI https://github.com/AcademySoftwareFoundation/OpenColorIO/archive/v${OPENCOLORIO_VERSION}.tar.gz)
set(OPENCOLORIO_HASH 1a2e3478b6cd9a1549f24e1b2205e3f0)
set(OPENCOLORIO_HASH 23d8b9ac81599305539a5a8674b94a3d)
set(LLVM_VERSION 9.0.1)
set(LLVM_URI https://github.com/llvm/llvm-project/releases/download/llvmorg-${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.xz)
@@ -256,9 +256,9 @@ set(YAMLCPP_VERSION 0.6.3)
set(YAMLCPP_URI https://codeload.github.com/jbeder/yaml-cpp/tar.gz/yaml-cpp-${YAMLCPP_VERSION})
set(YAMLCPP_HASH b45bf1089a382e81f6b661062c10d0c2)
set(EXPAT_VERSION 2_2_10)
set(EXPAT_URI https://github.com/libexpat/libexpat/archive/R_${EXPAT_VERSION}.tar.gz)
set(EXPAT_HASH 7ca5f09959fcb9a57618368deb627b9f)
set(LCMS_VERSION 2.9)
set(LCMS_URI https://nchc.dl.sourceforge.net/project/lcms/lcms/${LCMS_VERSION}/lcms2-${LCMS_VERSION}.tar.gz)
set(LCMS_HASH 8de1b7724f578d2995c8fdfa35c3ad0e)
set(PUGIXML_VERSION 1.10)
set(PUGIXML_URI https://github.com/zeux/pugixml/archive/v${PUGIXML_VERSION}.tar.gz)
@@ -313,8 +313,8 @@ set(MESA_URI ftp://ftp.freedesktop.org/pub/mesa//mesa-${MESA_VERSION}.tar.xz)
set(MESA_HASH d60828056d77bfdbae0970f9b15fb1be)
set(NASM_VERSION 2.15.02)
set(NASM_URI https://github.com/netwide-assembler/nasm/archive/nasm-${NASM_VERSION}.tar.gz)
set(NASM_HASH aded8b796c996a486a56e0515c83e414116decc3b184d88043480b32eb0a8589)
set(NASM_URI https://www.nasm.us/pub/nasm/releasebuilds/${NASM_VERSION}/nasm-${NASM_VERSION}.tar.xz)
set(NASM_HASH f4fd1329b1713e1ccd34b2fc121c4bcd278c9f91cc4cb205ae8fcd2e4728dd14)
set(XR_OPENXR_SDK_VERSION 1.0.8)
set(XR_OPENXR_SDK_URI https://github.com/KhronosGroup/OpenXR-SDK/archive/release-${XR_OPENXR_SDK_VERSION}.tar.gz)

View File

@@ -17,18 +17,13 @@
# ***** END GPL LICENSE BLOCK *****
set(YAMLCPP_EXTRA_ARGS
-DBUILD_GMOCK=OFF
-DYAML_CPP_BUILD_TESTS=OFF
-DYAML_CPP_BUILD_TOOLS=OFF
-DYAML_CPP_BUILD_CONTRIB=OFF
-DYAML_MSVC_SHARED_RT=ON
)
if(WIN32)
set(YAMLCPP_EXTRA_ARGS
${YAMLCPP_EXTRA_ARGS}
-DBUILD_GMOCK=OFF
-DYAML_MSVC_SHARED_RT=ON)
endif()
ExternalProject_Add(external_yamlcpp
URL ${YAMLCPP_URI}
DOWNLOAD_DIR ${DOWNLOAD_DIR}

View File

@@ -419,10 +419,10 @@ TBB_FORCE_BUILD=false
TBB_FORCE_REBUILD=false
TBB_SKIP=false
OCIO_VERSION="2.0.0"
OCIO_VERSION_SHORT="2.0"
OCIO_VERSION_MIN="2.0"
OCIO_VERSION_MAX="2.0"
OCIO_VERSION="1.1.1"
OCIO_VERSION_SHORT="1.1"
OCIO_VERSION_MIN="1.0"
OCIO_VERSION_MAX="1.2"
OCIO_FORCE_BUILD=false
OCIO_FORCE_REBUILD=false
OCIO_SKIP=false
@@ -1808,8 +1808,8 @@ compile_OCIO() {
cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst"
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
cmake_d="$cmake_d -D OCIO_BUILD_APPS=OFF"
cmake_d="$cmake_d -D OCIO_BUILD_PYTHON=OFF"
cmake_d="$cmake_d -D OCIO_BUILD_GPU_TESTS=OFF"
cmake_d="$cmake_d -D OCIO_BUILD_PYGLUE=OFF"
cmake_d="$cmake_d -D STOP_ON_WARNING=OFF"
if file /bin/cp | grep -q '32-bit'; then
cflags="-fPIC -m32 -march=i686"

View File

@@ -88,6 +88,7 @@ class VersionInfo:
self.short_version = "%d.%02d" % (version_numbers[0], version_numbers[1])
self.version = "%d.%02d.%d" % version_numbers
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
self.version_cycle_number = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE_NUMBER')
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
if self.version_cycle == "release":
@@ -96,7 +97,8 @@ class VersionInfo:
self.is_development_build = False
elif self.version_cycle == "rc":
# Release candidate
self.full_version = self.version + self.version_cycle
version_cycle = self.version_cycle + self.version_cycle_number
self.full_version = self.version + version_cycle
self.is_development_build = False
else:
# Development build

View File

@@ -34,8 +34,6 @@ set(_clang_tidy_SEARCH_DIRS
# TODO(sergey): Find more reliable way of finding the latest clang-tidy.
find_program(CLANG_TIDY_EXECUTABLE
NAMES
clang-tidy-12
clang-tidy-11
clang-tidy-10
clang-tidy-9
clang-tidy-8

View File

@@ -26,8 +26,7 @@ ENDIF()
SET(_opencolorio_FIND_COMPONENTS
OpenColorIO
yaml-cpp
expat
pystring
tinyxml
)
SET(_opencolorio_SEARCH_DIRS
@@ -61,23 +60,12 @@ FOREACH(COMPONENT ${_opencolorio_FIND_COMPONENTS})
ENDIF()
ENDFOREACH()
IF(EXISTS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h")
# Search twice, because this symbol changed between OCIO 1.x and 2.x
FILE(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h" _opencolorio_version
REGEX "^#define OCIO_VERSION_STR[ \t].*$")
IF(NOT _opencolorio_version)
file(STRINGS "${OPENCOLORIO_INCLUDE_DIR}/OpenColorIO/OpenColorABI.h" _opencolorio_version
REGEX "^#define OCIO_VERSION[ \t].*$")
ENDIF()
STRING(REGEX MATCHALL "[0-9]+[.0-9]+" OPENCOLORIO_VERSION ${_opencolorio_version})
ENDIF()
# handle the QUIETLY and REQUIRED arguments and set OPENCOLORIO_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenColorIO
REQUIRED_VARS _opencolorio_LIBRARIES OPENCOLORIO_INCLUDE_DIR
VERSION_VAR OPENCOLORIO_VERSION)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenColorIO DEFAULT_MSG
_opencolorio_LIBRARIES OPENCOLORIO_INCLUDE_DIR)
IF(OPENCOLORIO_FOUND)
SET(OPENCOLORIO_LIBRARIES ${_opencolorio_LIBRARIES})
@@ -90,7 +78,6 @@ MARK_AS_ADVANCED(
OPENCOLORIO_OPENCOLORIO_LIBRARY
OPENCOLORIO_TINYXML_LIBRARY
OPENCOLORIO_YAML-CPP_LIBRARY
OPENCOLORIO_VERSION
)
UNSET(COMPONENT)

View File

@@ -99,9 +99,7 @@ macro(BLENDER_SRC_GTEST_EX)
# Don't fail tests on leaks since these often happen in external libraries
# that we can't fix.
set_tests_properties(${TARGET_NAME} PROPERTIES
ENVIRONMENT LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS}
)
set_tests_properties(${TARGET_NAME} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0)
endif()
if(WIN32)
set_target_properties(${TARGET_NAME} PROPERTIES VS_GLOBAL_VcpkgEnabled "false")

View File

@@ -20,8 +20,6 @@
# <pep8 compliant>
# Note: this code should be cleaned up / refactored.
import sys
if sys.version_info.major < 3:
print("\nPython3.x needed, found %s.\nAborting!\n" %
@@ -39,23 +37,12 @@ from cmake_consistency_check_config import (
import os
from os.path import (
dirname,
join,
normpath,
splitext,
)
from os.path import join, dirname, normpath, splitext
global_h = set()
global_c = set()
global_refs = {}
# Flatten `IGNORE_SOURCE_MISSING` to avoid nested looping.
IGNORE_SOURCE_MISSING = [
(k, ignore_path) for k, ig_list in IGNORE_SOURCE_MISSING
for ignore_path in ig_list
]
# Ignore cmake file, path pairs.
global_ignore_source_missing = {}
for k, v in IGNORE_SOURCE_MISSING:
@@ -191,8 +178,6 @@ def cmake_get_src(f):
if not l:
pass
elif l in local_ignore_source_missing:
local_ignore_source_missing.remove(l)
elif l.startswith("$"):
if context_name == "SRC":
# assume if it ends with context_name we know about it
@@ -242,7 +227,10 @@ def cmake_get_src(f):
# replace_line(f, i - 1, new_path_rel)
else:
raise Exception("non existent include %s:%d -> %s" % (f, i, new_file))
if l in local_ignore_source_missing:
local_ignore_source_missing.remove(l)
else:
raise Exception("non existent include %s:%d -> %s" % (f, i, new_file))
# print(new_file)
@@ -270,16 +258,16 @@ def cmake_get_src(f):
def is_ignore_source(f, ignore_used):
for index, ignore_path in enumerate(IGNORE_SOURCE):
if ignore_path in f:
for index, ig in enumerate(IGNORE_SOURCE):
if ig in f:
ignore_used[index] = True
return True
return False
def is_ignore_cmake(f, ignore_used):
for index, ignore_path in enumerate(IGNORE_CMAKE):
if ignore_path in f:
for index, ig in enumerate(IGNORE_CMAKE):
if ig in f:
ignore_used[index] = True
return True
return False
@@ -310,7 +298,7 @@ def main():
for cf, i in refs:
errs.append((cf, i))
else:
raise Exception("CMake references missing, internal error, aborting!")
raise Exception("CMake referenecs missing, internal error, aborting!")
is_err = True
errs.sort()
@@ -321,7 +309,7 @@ def main():
# print("sed '%dd' '%s' > '%s.tmp' ; mv '%s.tmp' '%s'" % (i, cf, cf, cf, cf))
if is_err:
raise Exception("CMake references missing files, aborting!")
raise Exception("CMake referenecs missing files, aborting!")
del is_err
del errs
@@ -332,7 +320,7 @@ def main():
if cf not in global_c:
print("missing_c: ", cf)
# Check if automake builds a corresponding .o file.
# check if automake builds a corrasponding .o file.
'''
if cf in global_c:
out1 = os.path.splitext(cf)[0] + ".o"
@@ -368,21 +356,21 @@ def main():
# Check ignores aren't stale
print("\nCheck for unused 'IGNORE_SOURCE' paths...")
for index, ignore_path in enumerate(IGNORE_SOURCE):
for index, ig in enumerate(IGNORE_SOURCE):
if not ignore_used_source[index]:
print("unused ignore: %r" % ignore_path)
print("unused ignore: %r" % ig)
# Check ignores aren't stale
print("\nCheck for unused 'IGNORE_SOURCE_MISSING' paths...")
for k, v in sorted(global_ignore_source_missing.items()):
for ignore_path in v:
print("unused ignore: %r -> %r" % (ignore_path, k))
for ig in v:
print("unused ignore: %r -> %r" % (ig, k))
# Check ignores aren't stale
print("\nCheck for unused 'IGNORE_CMAKE' paths...")
for index, ignore_path in enumerate(IGNORE_CMAKE):
for index, ig in enumerate(IGNORE_CMAKE):
if not ignore_used_cmake[index]:
print("unused ignore: %r" % ignore_path)
print("unused ignore: %r" % ig)
if __name__ == "__main__":

View File

@@ -34,18 +34,8 @@ IGNORE_SOURCE = (
# Ignore cmake file, path pairs.
IGNORE_SOURCE_MISSING = (
( # Use for cycles stand-alone.
"intern/cycles/util/CMakeLists.txt", (
"../../third_party/numaapi/include",
)),
( # Use for `WITH_NANOVDB`.
"intern/cycles/kernel/CMakeLists.txt", (
"nanovdb/util/CSampleFromVoxels.h",
"nanovdb/util/SampleFromVoxels.h",
"nanovdb/NanoVDB.h",
"nanovdb/CNanoVDB.h",
),
),
# Use for cycles stand-alone.
("intern/cycles/util/CMakeLists.txt", "../../third_party/numaapi/include"),
)
IGNORE_CMAKE = (

View File

@@ -44,8 +44,6 @@ set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)

View File

@@ -51,8 +51,6 @@ set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
set(WITH_SDL OFF CACHE BOOL "" FORCE)

View File

@@ -45,8 +45,6 @@ set(WITH_OPENMP ON CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)

View File

@@ -1231,7 +1231,7 @@ function(find_python_package
set(WITH_PYTHON_INSTALL_${_upper_package} OFF PARENT_SCOPE)
else()
message(STATUS "${package} found at '${PYTHON_${_upper_package}_PATH}'")
if(NOT "${relative_include_dir}" STREQUAL "")
set(_relative_include_dir "${package}/${relative_include_dir}")
unset(PYTHON_${_upper_package}_INCLUDE_DIRS CACHE)

View File

@@ -293,12 +293,7 @@ if(WITH_OPENIMAGEIO)
endif()
if(WITH_OPENCOLORIO)
find_package(OpenColorIO 2.0.0)
if(NOT OPENCOLORIO_FOUND)
set(WITH_OPENCOLORIO OFF)
message(STATUS "OpenColorIO not found")
endif()
find_package(OpenColorIO)
endif()
if(WITH_OPENVDB)

View File

@@ -352,11 +352,6 @@ endif()
if(WITH_PUGIXML)
find_package_wrapper(PugiXML)
if (NOT PUGIXML_FOUND)
set(WITH_PUGIXML OFF)
message(STATUS "PugiXML not found, disabling WITH_PUGIXML")
endif()
endif()
if(WITH_OPENIMAGEIO)
@@ -385,7 +380,7 @@ if(WITH_OPENIMAGEIO)
endif()
if(WITH_OPENCOLORIO)
find_package_wrapper(OpenColorIO 2.0.0)
find_package_wrapper(OpenColorIO)
set(OPENCOLORIO_LIBRARIES ${OPENCOLORIO_LIBRARIES})
set(OPENCOLORIO_LIBPATH) # TODO, remove and reference the absolute path everywhere
@@ -615,13 +610,7 @@ endif()
# GNU Compiler
if(CMAKE_COMPILER_IS_GNUCC)
# ffp-contract=off:
# Automatically turned on when building with "-march=native". This is
# explicitly turned off here as it will make floating point math give a bit
# different results. This will lead to automated test failures. So disable
# this until we support it. Seems to default to off in clang and the intel
# compiler.
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -ffp-contract=off")
set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
# `maybe-uninitialized` is unreliable in release builds, but fine in debug builds.
set(GCC_EXTRA_FLAGS_RELEASE "-Wno-maybe-uninitialized")

View File

@@ -500,7 +500,7 @@ if(WITH_OPENIMAGEIO)
set(OPENIMAGEIO_LIBRARIES ${OIIO_OPTIMIZED} ${OIIO_DEBUG})
set(OPENIMAGEIO_DEFINITIONS "-DUSE_TBB=0")
set(OPENCOLORIO_DEFINITIONS "-DDOpenColorIO_SKIP_IMPORTS")
set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
add_definitions(-DOIIO_STATIC_DEFINE)
add_definitions(-DOIIO_NO_SSE=1)
@@ -538,13 +538,11 @@ if(WITH_OPENCOLORIO)
set(OPENCOLORIO_LIBPATH ${OPENCOLORIO}/lib)
set(OPENCOLORIO_LIBRARIES
optimized ${OPENCOLORIO_LIBPATH}/OpenColorIO.lib
optimized ${OPENCOLORIO_LIBPATH}/tinyxml.lib
optimized ${OPENCOLORIO_LIBPATH}/libyaml-cpp.lib
optimized ${OPENCOLORIO_LIBPATH}/libexpatMD.lib
optimized ${OPENCOLORIO_LIBPATH}/pystring.lib
debug ${OPENCOLORIO_LIBPATH}/OpencolorIO_d.lib
debug ${OPENCOLORIO_LIBPATH}/tinyxml_d.lib
debug ${OPENCOLORIO_LIBPATH}/libyaml-cpp_d.lib
debug ${OPENCOLORIO_LIBPATH}/libexpatdMD.lib
debug ${OPENCOLORIO_LIBPATH}/pystring_d.lib
)
set(OPENCOLORIO_DEFINITIONS)
endif()

View File

@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = "V2.93"
PROJECT_NUMBER = "V2.92"
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@@ -52,11 +52,10 @@ outfilename = sys.argv[2]
cmd = [blender_bin, "--help"]
print(" executing:", " ".join(cmd))
ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
blender_help = subprocess.run(
cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
cmd, env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
blender_version = subprocess.run(
[blender_bin, "--version"], env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
[blender_bin, "--version"], env={"ASAN_OPTIONS": "exitcode=0"}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8").strip()
blender_version, blender_date = (blender_version.split("build") + [None, None])[0:2]
blender_version = blender_version.rstrip().partition(" ")[2] # remove 'Blender' prefix.
if blender_date is None:

View File

@@ -55,7 +55,7 @@ if $DO_EXE_BLENDER ; then
# Don't delete existing docs, now partial updates are used for quick builds.
#
# Disable ASAN error halt since it results in nonzero exit code on any minor issue.
ASAN_OPTIONS=halt_on_error=0:${ASAN_OPTIONS} \
ASAN_OPTIONS=halt_on_error=0 \
$BLENDER_BIN \
--background \
-noaudio \

View File

@@ -170,7 +170,7 @@ struct ApplyMatrix : public KernelBase {
unusedParameter(vecRhs); // Not needed in this matrix application
if (matrixA.size() != 4)
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
Grid<Real> &A0 = *matrixA[0];
Grid<Real> &Ai = *matrixA[1];
Grid<Real> &Aj = *matrixA[2];
@@ -256,7 +256,7 @@ struct ApplyMatrix2D : public KernelBase {
unusedParameter(vecRhs); // Not needed in this matrix application
if (matrixA.size() != 3)
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
Grid<Real> &A0 = *matrixA[0];
Grid<Real> &Ai = *matrixA[1];
Grid<Real> &Aj = *matrixA[2];
@@ -338,7 +338,7 @@ struct ApplyMatrixViscosityU : public KernelBase {
const std::vector<Grid<Real> *> vecRhs) const
{
if (matrixA.size() != 15)
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
Grid<Real> &A0 = *matrixA[0];
Grid<Real> &Aplusi = *matrixA[1];
Grid<Real> &Aplusj = *matrixA[2];
@@ -348,7 +348,7 @@ struct ApplyMatrixViscosityU : public KernelBase {
Grid<Real> &Aminusk = *matrixA[6];
if (vecRhs.size() != 2)
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
Grid<Real> &srcV = *vecRhs[0];
Grid<Real> &srcW = *vecRhs[1];
@@ -450,7 +450,7 @@ struct ApplyMatrixViscosityV : public KernelBase {
const std::vector<Grid<Real> *> vecRhs) const
{
if (matrixA.size() != 15)
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
Grid<Real> &A0 = *matrixA[0];
Grid<Real> &Aplusi = *matrixA[1];
Grid<Real> &Aplusj = *matrixA[2];
@@ -460,7 +460,7 @@ struct ApplyMatrixViscosityV : public KernelBase {
Grid<Real> &Aminusk = *matrixA[6];
if (vecRhs.size() != 2)
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
Grid<Real> &srcU = *vecRhs[0];
Grid<Real> &srcW = *vecRhs[1];
@@ -562,7 +562,7 @@ struct ApplyMatrixViscosityW : public KernelBase {
const std::vector<Grid<Real> *> vecRhs) const
{
if (matrixA.size() != 15)
errMsg("ConjugateGrad: Invalid A matrix in apply matrix step");
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
Grid<Real> &A0 = *matrixA[0];
Grid<Real> &Aplusi = *matrixA[1];
Grid<Real> &Aplusj = *matrixA[2];
@@ -572,7 +572,7 @@ struct ApplyMatrixViscosityW : public KernelBase {
Grid<Real> &Aminusk = *matrixA[6];
if (vecRhs.size() != 2)
errMsg("ConjugateGrad: Invalid rhs vector in apply matrix step");
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
Grid<Real> &srcU = *vecRhs[0];
Grid<Real> &srcV = *vecRhs[1];

View File

@@ -139,7 +139,7 @@ struct KnEstimateVolumeFraction : public KernelBase {
{
const Vec3 centre = startCentre + Vec3(i, j, k) * 0.5;
const Real offset = 0.5 * dx;
const int order = 1; // is sufficient
const int order = 2;
Real phi000 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, -offset), order);
Real phi001 = phi.getInterpolatedHi(centre + Vec3(-offset, -offset, +offset), order);
@@ -1067,8 +1067,10 @@ void solveViscosity(const FlagGrid &flags,
Real viscTop = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) + viscosity(i, j + 1, k) +
viscosity(i, j + 1, k - 1));
;
Real viscBottom = 0.25 * (viscosity(i, j, k) + viscosity(i, j, k - 1) +
viscosity(i, j - 1, k) + viscosity(i, j - 1, k - 1));
;
Real volTop = exVolLiquid(i, j + 1, k);
Real volBottom = exVolLiquid(i, j, k);
@@ -1222,7 +1224,7 @@ void solveViscosity(const FlagGrid &flags,
uSolution, uRhs, uResidual, uSearch, flags, uTmp, uMatA, uVecRhs);
}
else {
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
errMsg("2D Matrix application not yet supported in viscosity solver");
}
// CG solver for V
@@ -1247,7 +1249,7 @@ void solveViscosity(const FlagGrid &flags,
vSolution, vRhs, vResidual, vSearch, flags, vTmp, vMatA, vVecRhs);
}
else {
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
errMsg("2D Matrix application not yet supported in viscosity solver");
}
// CG solver for W
@@ -1272,7 +1274,7 @@ void solveViscosity(const FlagGrid &flags,
wSolution, wRhs, wResidual, wSearch, flags, wTmp, wMatA, wVecRhs);
}
else {
errMsg("Viscosity: 2D Matrix application not yet supported in viscosity solver");
errMsg("2D Matrix application not yet supported in viscosity solver");
}
// Same accuracy for all dimensions
@@ -1306,7 +1308,7 @@ void solveViscosity(const FlagGrid &flags,
wRhs.copyFrom(wSearch);
}
debMsg(
"Viscosity: solveViscosity() done. "
"Viscosity::solveViscosity done. "
"Iterations (u,v,w): ("
<< uGcg->getIterations() << "," << vGcg->getIterations() << "," << wGcg->getIterations()
<< "), "

View File

@@ -14,7 +14,7 @@
# Standalone or with Blender
if(NOT WITH_BLENDER AND WITH_CYCLES_STANDALONE)
set(CYCLES_INSTALL_PATH ${CMAKE_INSTALL_PREFIX})
set(CYCLES_INSTALL_PATH "")
else()
set(WITH_CYCLES_BLENDER ON)
# WINDOWS_PYTHON_DEBUG needs to write into the user addons folder since it will
@@ -379,9 +379,6 @@ endif()
# Subdirectories
if(WITH_CYCLES_BLENDER)
# Not needed to make cycles automated tests pass with -march=native.
# However Blender itself needs this flag.
remove_cc_flag("-ffp-contract=off")
add_definitions(-DWITH_BLENDER_GUARDEDALLOC)
add_subdirectory(blender)
endif()

View File

@@ -133,12 +133,12 @@ static void scene_init()
/* Camera width/height override? */
if (!(options.width == 0 || options.height == 0)) {
options.scene->camera->set_full_width(options.width);
options.scene->camera->set_full_height(options.height);
options.scene->camera->width = options.width;
options.scene->camera->height = options.height;
}
else {
options.width = options.scene->camera->get_full_width();
options.height = options.scene->camera->get_full_height();
options.width = options.scene->camera->width;
options.height = options.scene->camera->height;
}
/* Calculate Viewplane */
@@ -233,7 +233,7 @@ static void display()
static void motion(int x, int y, int button)
{
if (options.interactive) {
Transform matrix = options.session->scene->camera->get_matrix();
Transform matrix = options.session->scene->camera->matrix;
/* Translate */
if (button == 0) {
@@ -251,8 +251,8 @@ static void motion(int x, int y, int button)
}
/* Update and Reset */
options.session->scene->camera->set_matrix(matrix);
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->matrix = matrix;
options.session->scene->camera->need_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
@@ -266,10 +266,10 @@ static void resize(int width, int height)
if (options.session) {
/* Update camera */
options.session->scene->camera->set_full_width(options.width);
options.session->scene->camera->set_full_height(options.height);
options.session->scene->camera->width = width;
options.session->scene->camera->height = height;
options.session->scene->camera->compute_auto_viewplane();
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->need_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
@@ -302,7 +302,7 @@ static void keyboard(unsigned char key)
/* Navigation */
else if (options.interactive && (key == 'w' || key == 'a' || key == 's' || key == 'd')) {
Transform matrix = options.session->scene->camera->get_matrix();
Transform matrix = options.session->scene->camera->matrix;
float3 translate;
if (key == 'w')
@@ -317,8 +317,8 @@ static void keyboard(unsigned char key)
matrix = matrix * transform_translate(translate);
/* Update and Reset */
options.session->scene->camera->set_matrix(matrix);
options.session->scene->camera->need_flags_update = true;
options.session->scene->camera->matrix = matrix;
options.session->scene->camera->need_update = true;
options.session->scene->camera->need_device_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
@@ -345,7 +345,10 @@ static void keyboard(unsigned char key)
break;
}
options.session->scene->integrator->set_max_bounce(bounce);
options.session->scene->integrator->max_bounce = bounce;
/* Update and Reset */
options.session->scene->integrator->need_update = true;
options.session->reset(session_buffer_params(), options.session_params.samples);
}

View File

@@ -190,18 +190,17 @@ static void xml_read_camera(XMLReadState &state, xml_node node)
{
Camera *cam = state.scene->camera;
int width = -1, height = -1;
xml_read_int(&width, node, "width");
xml_read_int(&height, node, "height");
xml_read_int(&cam->width, node, "width");
xml_read_int(&cam->height, node, "height");
cam->set_full_width(width);
cam->set_full_height(height);
cam->full_width = cam->width;
cam->full_height = cam->height;
xml_read_node(state, cam, node);
cam->set_matrix(state.tfm);
cam->matrix = state.tfm;
cam->need_flags_update = true;
cam->need_update = true;
cam->update(state.scene);
}
@@ -339,13 +338,11 @@ static void xml_read_shader_graph(XMLReadState &state, Shader *shader, xml_node
if (node_name == "image_texture") {
ImageTextureNode *img = (ImageTextureNode *)snode;
ustring filename(path_join(state.base, img->get_filename().string()));
img->set_filename(filename);
img->filename = path_join(state.base, img->filename.string());
}
else if (node_name == "environment_texture") {
EnvironmentTextureNode *env = (EnvironmentTextureNode *)snode;
ustring filename(path_join(state.base, env->get_filename().string()));
env->set_filename(filename);
env->filename = path_join(state.base, env->filename.string());
}
if (snode) {
@@ -387,8 +384,8 @@ static Mesh *xml_add_mesh(Scene *scene, const Transform &tfm)
/* create object*/
Object *object = new Object();
object->set_geometry(mesh);
object->set_tfm(tfm);
object->geometry = mesh;
object->tfm = tfm;
scene->objects.push_back(object);
return mesh;
@@ -398,9 +395,7 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
{
/* add mesh */
Mesh *mesh = xml_add_mesh(state.scene, state.tfm);
array<Node *> used_shaders = mesh->get_used_shaders();
used_shaders.push_back_slow(state.shader);
mesh->set_used_shaders(used_shaders);
mesh->used_shaders.push_back(state.shader);
/* read state */
int shader = 0;
@@ -416,24 +411,20 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
xml_read_int_array(nverts, node, "nverts");
if (xml_equal_string(node, "subdivision", "catmull-clark")) {
mesh->set_subdivision_type(Mesh::SUBDIVISION_CATMULL_CLARK);
mesh->subdivision_type = Mesh::SUBDIVISION_CATMULL_CLARK;
}
else if (xml_equal_string(node, "subdivision", "linear")) {
mesh->set_subdivision_type(Mesh::SUBDIVISION_LINEAR);
mesh->subdivision_type = Mesh::SUBDIVISION_LINEAR;
}
array<float3> P_array;
P_array = P;
if (mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE) {
if (mesh->subdivision_type == Mesh::SUBDIVISION_NONE) {
/* create vertices */
mesh->set_verts(P_array);
mesh->verts = P;
size_t num_triangles = 0;
for (size_t i = 0; i < nverts.size(); i++)
num_triangles += nverts[i] - 2;
mesh->reserve_mesh(mesh->get_verts().size(), num_triangles);
mesh->reserve_mesh(mesh->verts.size(), num_triangles);
/* create triangles */
int index_offset = 0;
@@ -483,7 +474,7 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
}
else {
/* create vertices */
mesh->set_verts(P_array);
mesh->verts = P;
size_t num_ngons = 0;
size_t num_corners = 0;
@@ -522,20 +513,23 @@ static void xml_read_mesh(const XMLReadState &state, xml_node node)
}
/* setup subd params */
float dicing_rate = state.dicing_rate;
xml_read_float(&dicing_rate, node, "dicing_rate");
dicing_rate = std::max(0.1f, dicing_rate);
if (!mesh->subd_params) {
mesh->subd_params = new SubdParams(mesh);
}
SubdParams &sdparams = *mesh->subd_params;
mesh->set_subd_dicing_rate(dicing_rate);
mesh->set_subd_objecttoworld(state.tfm);
sdparams.dicing_rate = state.dicing_rate;
xml_read_float(&sdparams.dicing_rate, node, "dicing_rate");
sdparams.dicing_rate = std::max(0.1f, sdparams.dicing_rate);
sdparams.objecttoworld = state.tfm;
}
/* we don't yet support arbitrary attributes, for now add vertex
* coordinates as generated coordinates if requested */
if (mesh->need_attribute(state.scene, ATTR_STD_GENERATED)) {
Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
memcpy(
attr->data_float3(), mesh->get_verts().data(), sizeof(float3) * mesh->get_verts().size());
memcpy(attr->data_float3(), mesh->verts.data(), sizeof(float3) * mesh->verts.size());
}
}
@@ -545,7 +539,7 @@ static void xml_read_light(XMLReadState &state, xml_node node)
{
Light *light = new Light();
light->set_shader(state.shader);
light->shader = state.shader;
xml_read_node(state, light, node);
state.scene->lights.push_back(light);

View File

@@ -1148,7 +1148,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
split = layout.split(factor=0.65)
if ob:
split.template_ID(ob, "active_material", new="material.new")
split.template_ID(ob, "active_material", new="material.new", duplicate="material.duplicate")
row = split.row()
if slot:

View File

@@ -67,10 +67,11 @@ static bool ObtainCacheParticleData(
Transform tfm = get_transform(b_ob->matrix_world());
Transform itfm = transform_quick_inverse(tfm);
for (BL::Modifier &b_mod : b_ob->modifiers) {
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
(background ? b_mod.show_render() : b_mod.show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::Object::modifiers_iterator b_mod;
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
(background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -162,10 +163,11 @@ static bool ObtainCacheParticleUV(Hair *hair,
CData->curve_uv.clear();
for (BL::Modifier &b_mod : b_ob->modifiers) {
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
(background ? b_mod.show_render() : b_mod.show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::Object::modifiers_iterator b_mod;
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
(background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -224,10 +226,11 @@ static bool ObtainCacheParticleVcol(Hair *hair,
CData->curve_vcol.clear();
for (BL::Modifier &b_mod : b_ob->modifiers) {
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
(background ? b_mod.show_render() : b_mod.show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::Object::modifiers_iterator b_mod;
for (b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
(background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -507,10 +510,11 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int
bool BlenderSync::object_has_particle_hair(BL::Object b_ob)
{
/* Test if the object has a particle modifier with hair. */
for (BL::Modifier &b_mod : b_ob.modifiers) {
if ((b_mod.type() == b_mod.type_PARTICLE_SYSTEM) &&
(preview ? b_mod.show_viewport() : b_mod.show_render())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod.ptr);
BL::Object::modifiers_iterator b_mod;
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) &&
(preview ? b_mod->show_viewport() : b_mod->show_render())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
@@ -674,7 +678,9 @@ static void export_hair_curves(Scene *scene, Hair *hair, BL::Hair b_hair)
/* Export curves and points. */
vector<float> points_length;
for (BL::HairCurve &b_curve : b_hair.curves) {
BL::Hair::curves_iterator b_curve_iter;
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
BL::HairCurve b_curve = *b_curve_iter;
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
@@ -742,7 +748,9 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st
int num_motion_keys = 0;
int curve_index = 0;
for (BL::HairCurve &b_curve : b_hair.curves) {
BL::Hair::curves_iterator b_curve_iter;
for (b_hair.curves.begin(b_curve_iter); b_curve_iter != b_hair.curves.end(); ++b_curve_iter) {
BL::HairCurve b_curve = *b_curve_iter;
const int first_point_index = b_curve.first_point_index();
const int num_points = b_curve.num_points();
@@ -847,7 +855,10 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *ha
hair->set_value(socket, new_hair, socket);
}
hair->attributes.update(std::move(new_hair.attributes));
hair->attributes.clear();
foreach (Attribute &attr, new_hair.attributes.attributes) {
hair->attributes.attributes.push_back(std::move(attr));
}
/* tag update */

View File

@@ -47,9 +47,11 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
/* Find cycles preferences. */
PointerRNA cpreferences;
for (BL::Addon &b_addon : b_preferences.addons) {
if (b_addon.module() == "cycles") {
cpreferences = b_addon.preferences().ptr;
BL::Preferences::addons_iterator b_addon_iter;
for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
++b_addon_iter) {
if (b_addon_iter->module() == "cycles") {
cpreferences = b_addon_iter->preferences().ptr;
break;
}
}

View File

@@ -42,34 +42,6 @@ static Geometry::Type determine_geom_type(BL::Object &b_ob, bool use_particle_ha
return Geometry::MESH;
}
array<Node *> BlenderSync::find_used_shaders(BL::Object &b_ob)
{
BL::Material material_override = view_layer.material_override;
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
scene->default_surface;
array<Node *> used_shaders;
for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
if (material_override) {
find_shader(material_override, used_shaders, default_shader);
}
else {
BL::ID b_material(b_slot.material());
find_shader(b_material, used_shaders, default_shader);
}
}
if (used_shaders.size() == 0) {
if (material_override)
find_shader(material_override, used_shaders, default_shader);
else
used_shaders.push_back_slow(default_shader);
}
return used_shaders;
}
Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
BL::Object &b_ob,
BL::Object &b_ob_instance,
@@ -80,11 +52,32 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
/* Test if we can instance or if the object is modified. */
BL::ID b_ob_data = b_ob.data();
BL::ID b_key_id = (BKE_object_is_modified(b_ob)) ? b_ob_instance : b_ob_data;
BL::Material material_override = view_layer.material_override;
Shader *default_shader = (b_ob.type() == BL::Object::type_VOLUME) ? scene->default_volume :
scene->default_surface;
Geometry::Type geom_type = determine_geom_type(b_ob, use_particle_hair);
GeometryKey key(b_key_id.ptr.data, geom_type);
/* Find shader indices. */
array<Node *> used_shaders = find_used_shaders(b_ob);
array<Node *> used_shaders;
BL::Object::material_slots_iterator slot;
for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) {
if (material_override) {
find_shader(material_override, used_shaders, default_shader);
}
else {
BL::ID b_material(slot->material());
find_shader(b_material, used_shaders, default_shader);
}
}
if (used_shaders.size() == 0) {
if (material_override)
find_shader(material_override, used_shaders, default_shader);
else
used_shaders.push_back_slow(default_shader);
}
/* Ensure we only sync instanced geometry once. */
Geometry *geom = geometry_map.find(key);
@@ -131,7 +124,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph,
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->need_update_geometry()) {
if (shader->need_update_geometry) {
attribute_recalc = true;
}
}

View File

@@ -285,10 +285,12 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
BL::Mesh &b_mesh,
bool subdivision)
{
for (BL::MeshVertColorLayer &l : b_mesh.sculpt_vertex_colors) {
const bool active_render = l.active_render();
BL::Mesh::sculpt_vertex_colors_iterator l;
for (b_mesh.sculpt_vertex_colors.begin(l); l != b_mesh.sculpt_vertex_colors.end(); ++l) {
const bool active_render = l->active_render();
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
ustring vcol_name = ustring(l.name().c_str());
ustring vcol_name = ustring(l->name().c_str());
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
mesh->need_attribute(scene, vcol_std);
@@ -305,7 +307,7 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
int numverts = b_mesh.vertices.length();
for (int i = 0; i < numverts; i++) {
*(cdata++) = get_float4(l.data[i].color());
*(cdata++) = get_float4(l->data[i].color());
}
}
}
@@ -313,10 +315,12 @@ static void attr_create_sculpt_vertex_color(Scene *scene,
/* Create vertex color attributes. */
static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivision)
{
for (BL::MeshLoopColorLayer &l : b_mesh.vertex_colors) {
const bool active_render = l.active_render();
BL::Mesh::vertex_colors_iterator l;
for (b_mesh.vertex_colors.begin(l); l != b_mesh.vertex_colors.end(); ++l) {
const bool active_render = l->active_render();
AttributeStandard vcol_std = (active_render) ? ATTR_STD_VERTEX_COLOR : ATTR_STD_NONE;
ustring vcol_name = ustring(l.name().c_str());
ustring vcol_name = ustring(l->name().c_str());
const bool need_vcol = mesh->need_attribute(scene, vcol_name) ||
mesh->need_attribute(scene, vcol_std);
@@ -335,12 +339,13 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
vcol_attr = mesh->subd_attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
}
BL::Mesh::polygons_iterator p;
uchar4 *cdata = vcol_attr->data_uchar4();
for (BL::MeshPolygon &p : b_mesh.polygons) {
int n = p.loop_total();
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
int n = p->loop_total();
for (int i = 0; i < n; i++) {
float4 color = get_float4(l.data[p.loop_start() + i].color());
float4 color = get_float4(l->data[p->loop_start() + i].color());
/* Compress/encode vertex color using the sRGB curve. */
*(cdata++) = color_float4_to_uchar4(color);
}
@@ -354,13 +359,14 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
vcol_attr = mesh->attributes.add(vcol_name, TypeRGBA, ATTR_ELEMENT_CORNER_BYTE);
}
BL::Mesh::loop_triangles_iterator t;
uchar4 *cdata = vcol_attr->data_uchar4();
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
int3 li = get_int3(t.loops());
float4 c1 = get_float4(l.data[li[0]].color());
float4 c2 = get_float4(l.data[li[1]].color());
float4 c3 = get_float4(l.data[li[2]].color());
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
int3 li = get_int3(t->loops());
float4 c1 = get_float4(l->data[li[0]].color());
float4 c2 = get_float4(l->data[li[1]].color());
float4 c3 = get_float4(l->data[li[2]].color());
/* Compress/encode vertex color using the sRGB curve. */
cdata[0] = color_float4_to_uchar4(c1);
@@ -377,12 +383,14 @@ static void attr_create_vertex_color(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
{
if (b_mesh.uv_layers.length() != 0) {
for (BL::MeshUVLoopLayer &l : b_mesh.uv_layers) {
const bool active_render = l.active_render();
BL::Mesh::uv_layers_iterator l;
for (b_mesh.uv_layers.begin(l); l != b_mesh.uv_layers.end(); ++l) {
const bool active_render = l->active_render();
AttributeStandard uv_std = (active_render) ? ATTR_STD_UV : ATTR_STD_NONE;
ustring uv_name = ustring(l.name().c_str());
ustring uv_name = ustring(l->name().c_str());
AttributeStandard tangent_std = (active_render) ? ATTR_STD_UV_TANGENT : ATTR_STD_NONE;
ustring tangent_name = ustring((string(l.name().c_str()) + ".tangent").c_str());
ustring tangent_name = ustring((string(l->name().c_str()) + ".tangent").c_str());
/* Denotes whether UV map was requested directly. */
const bool need_uv = mesh->need_attribute(scene, uv_name) ||
@@ -404,13 +412,14 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
uv_attr = mesh->attributes.add(uv_name, TypeFloat2, ATTR_ELEMENT_CORNER);
}
BL::Mesh::loop_triangles_iterator t;
float2 *fdata = uv_attr->data_float2();
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
int3 li = get_int3(t.loops());
fdata[0] = get_float2(l.data[li[0]].uv());
fdata[1] = get_float2(l.data[li[1]].uv());
fdata[2] = get_float2(l.data[li[2]].uv());
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
int3 li = get_int3(t->loops());
fdata[0] = get_float2(l->data[li[0]].uv());
fdata[1] = get_float2(l->data[li[1]].uv());
fdata[2] = get_float2(l->data[li[2]].uv());
fdata += 3;
}
}
@@ -418,10 +427,10 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
/* UV tangent */
if (need_tangent) {
AttributeStandard sign_std = (active_render) ? ATTR_STD_UV_TANGENT_SIGN : ATTR_STD_NONE;
ustring sign_name = ustring((string(l.name().c_str()) + ".tangent_sign").c_str());
ustring sign_name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
bool need_sign = (mesh->need_attribute(scene, sign_name) ||
mesh->need_attribute(scene, sign_std));
mikk_compute_tangents(b_mesh, l.name().c_str(), mesh, need_sign, active_render);
mikk_compute_tangents(b_mesh, l->name().c_str(), mesh, need_sign, active_render);
}
/* Remove temporarily created UV attribute. */
if (!need_uv && uv_attr != NULL) {
@@ -471,12 +480,13 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
uv_attr->flags |= ATTR_SUBDIVIDED;
}
BL::Mesh::polygons_iterator p;
float2 *fdata = uv_attr->data_float2();
for (BL::MeshPolygon &p : b_mesh.polygons) {
int n = p.loop_total();
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
int n = p->loop_total();
for (int j = 0; j < n; j++) {
*(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
*(fdata++) = get_float2(l->data[p->loop_start() + j].uv());
}
}
}
@@ -696,8 +706,9 @@ static void attr_create_random_per_island(Scene *scene,
DisjointSet vertices_sets(number_of_vertices);
for (BL::MeshEdge &e : b_mesh.edges) {
vertices_sets.join(e.vertices()[0], e.vertices()[1]);
BL::Mesh::edges_iterator e;
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
vertices_sets.join(e->vertices()[0], e->vertices()[1]);
}
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
@@ -705,13 +716,15 @@ static void attr_create_random_per_island(Scene *scene,
float *data = attribute->data_float();
if (!subdivision) {
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
data[t.index()] = hash_uint_to_float(vertices_sets.find(t.vertices()[0]));
BL::Mesh::loop_triangles_iterator t;
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
data[t->index()] = hash_uint_to_float(vertices_sets.find(t->vertices()[0]));
}
}
else {
for (BL::MeshPolygon &p : b_mesh.polygons) {
data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
BL::Mesh::polygons_iterator p;
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
data[p->index()] = hash_uint_to_float(vertices_sets.find(p->vertices()[0]));
}
}
}
@@ -743,9 +756,10 @@ static void create_mesh(Scene *scene,
numtris = numfaces;
}
else {
for (BL::MeshPolygon &p : b_mesh.polygons) {
numngons += (p.loop_total() == 4) ? 0 : 1;
numcorners += p.loop_total();
BL::Mesh::polygons_iterator p;
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
numngons += (p->loop_total() == 4) ? 0 : 1;
numcorners += p->loop_total();
}
}
@@ -789,15 +803,17 @@ static void create_mesh(Scene *scene,
/* create faces */
if (!subdivision) {
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
BL::MeshPolygon p = b_mesh.polygons[t.polygon_index()];
int3 vi = get_int3(t.vertices());
BL::Mesh::loop_triangles_iterator t;
for (b_mesh.loop_triangles.begin(t); t != b_mesh.loop_triangles.end(); ++t) {
BL::MeshPolygon p = b_mesh.polygons[t->polygon_index()];
int3 vi = get_int3(t->vertices());
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
bool smooth = p.use_smooth() || use_loop_normals;
if (use_loop_normals) {
BL::Array<float, 9> loop_normals = t.split_normals();
BL::Array<float, 9> loop_normals = t->split_normals();
for (int i = 0; i < 3; i++) {
N[vi[i]] = make_float3(
loop_normals[i * 3], loop_normals[i * 3 + 1], loop_normals[i * 3 + 2]);
@@ -812,17 +828,18 @@ static void create_mesh(Scene *scene,
}
}
else {
BL::Mesh::polygons_iterator p;
vector<int> vi;
for (BL::MeshPolygon &p : b_mesh.polygons) {
int n = p.loop_total();
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
bool smooth = p.use_smooth() || use_loop_normals;
for (b_mesh.polygons.begin(p); p != b_mesh.polygons.end(); ++p) {
int n = p->loop_total();
int shader = clamp(p->material_index(), 0, used_shaders.size() - 1);
bool smooth = p->use_smooth() || use_loop_normals;
vi.resize(n);
for (int i = 0; i < n; i++) {
/* NOTE: Autosmooth is already taken care about. */
vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
vi[i] = b_mesh.loops[p->loop_start() + i].vertex_index();
}
/* create subd faces */
@@ -874,18 +891,19 @@ static void create_subd_mesh(Scene *scene,
/* export creases */
size_t num_creases = 0;
BL::Mesh::edges_iterator e;
for (BL::MeshEdge &e : b_mesh.edges) {
if (e.crease() != 0.0f) {
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
if (e->crease() != 0.0f) {
num_creases++;
}
}
mesh->reserve_subd_creases(num_creases);
for (BL::MeshEdge &e : b_mesh.edges) {
if (e.crease() != 0.0f) {
mesh->add_crease(e.vertices()[0], e.vertices()[1], e.crease());
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) {
if (e->crease() != 0.0f) {
mesh->add_crease(e->vertices()[0], e->vertices()[1], e->crease());
}
}
@@ -1057,8 +1075,15 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *me
mesh->set_value(socket, new_mesh, socket);
}
mesh->attributes.update(std::move(new_mesh.attributes));
mesh->subd_attributes.update(std::move(new_mesh.subd_attributes));
mesh->attributes.clear();
foreach (Attribute &attr, new_mesh.attributes.attributes) {
mesh->attributes.attributes.push_back(std::move(attr));
}
mesh->subd_attributes.clear();
foreach (Attribute &attr, new_mesh.subd_attributes.attributes) {
mesh->subd_attributes.attributes.push_back(std::move(attr));
}
mesh->set_num_subd_faces(new_mesh.get_num_subd_faces());

View File

@@ -51,11 +51,10 @@ bool BlenderSync::BKE_object_is_modified(BL::Object &b_ob)
}
else {
/* object level material links */
for (BL::MaterialSlot &b_slot : b_ob.material_slots) {
if (b_slot.link() == BL::MaterialSlot::link_OBJECT) {
BL::Object::material_slots_iterator slot;
for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot)
if (slot->link() == BL::MaterialSlot::link_OBJECT)
return true;
}
}
}
return false;
@@ -244,6 +243,9 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph,
/* holdout */
object->set_use_holdout(use_holdout);
if (object->use_holdout_is_modified()) {
scene->object_manager->tag_update(scene);
}
object->set_visibility(visibility);

View File

@@ -57,7 +57,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
/* no update needed? */
if (!need_update && !object->get_geometry()->is_modified() &&
!scene->object_manager->need_update())
!scene->object_manager->need_update)
return true;
/* first time used in this sync loop? clear and tag update */
@@ -85,7 +85,7 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob,
object->set_particle_index(psys->particles.size() - 1);
if (object->particle_index_is_modified())
scene->object_manager->tag_update(scene, ObjectManager::PARTICLE_MODIFIED);
scene->object_manager->tag_update(scene);
/* return that this object has particle data */
return true;

View File

@@ -597,19 +597,22 @@ static PyObject *osl_update_node_func(PyObject * /*self*/, PyObject *args)
bool removed;
do {
BL::Node::inputs_iterator b_input;
BL::Node::outputs_iterator b_output;
removed = false;
for (BL::NodeSocket &b_input : b_node.inputs) {
if (used_sockets.find(b_input.ptr.data) == used_sockets.end()) {
b_node.inputs.remove(b_data, b_input);
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
if (used_sockets.find(b_input->ptr.data) == used_sockets.end()) {
b_node.inputs.remove(b_data, *b_input);
removed = true;
break;
}
}
for (BL::NodeSocket &b_output : b_node.outputs) {
if (used_sockets.find(b_output.ptr.data) == used_sockets.end()) {
b_node.outputs.remove(b_data, b_output);
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
if (used_sockets.find(b_output->ptr.data) == used_sockets.end()) {
b_node.outputs.remove(b_data, *b_output);
removed = true;
break;
}

View File

@@ -358,7 +358,11 @@ void BlenderSession::do_write_update_render_tile(RenderTile &rtile,
if (do_read_only) {
/* copy each pass */
for (BL::RenderPass &b_pass : b_rlay.passes) {
BL::RenderLayer::passes_iterator b_iter;
for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
BL::RenderPass b_pass(*b_iter);
/* find matching pass type */
PassType pass_type = BlenderSync::get_pass_type(b_pass);
int components = b_pass.channels();
@@ -548,6 +552,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
int seed = scene->integrator->get_seed();
seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0));
scene->integrator->set_seed(seed);
scene->integrator->tag_update(scene);
}
/* Update number of samples per layer. */
@@ -731,7 +736,10 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay,
if (!do_update_only) {
/* copy each pass */
for (BL::RenderPass &b_pass : b_rlay.passes) {
BL::RenderLayer::passes_iterator b_iter;
for (b_rlay.passes.begin(b_iter); b_iter != b_rlay.passes.end(); ++b_iter) {
BL::RenderPass b_pass(*b_iter);
int components = b_pass.channels();
/* Copy pixels from regular render passes. */
@@ -1108,6 +1116,10 @@ void BlenderSession::update_resumable_tile_manager(int num_samples)
scene->integrator->set_start_sample(rounded_range_start_sample);
if (scene->integrator->is_modified()) {
scene->integrator->tag_update(scene);
}
session->tile_manager.range_start_sample = rounded_range_start_sample;
session->tile_manager.range_num_samples = rounded_range_num_samples;
}

View File

@@ -148,13 +148,15 @@ BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_r
static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name)
{
for (BL::NodeSocket &b_out : b_node.outputs) {
if (b_out.name() == name) {
return b_out;
}
}
BL::Node::outputs_iterator b_out;
for (b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
if (b_out->name() == name)
return *b_out;
assert(0);
return *b_node.outputs.begin();
return *b_out;
}
static float3 get_node_output_rgba(BL::Node &b_node, const string &name)
@@ -721,8 +723,9 @@ static ShaderNode *add_node(Scene *scene,
image->set_alpha_type(get_image_alpha_type(b_image));
array<int> tiles;
for (BL::UDIMTile &b_tile : b_image.tiles) {
tiles.push_back_slow(b_tile.number());
BL::Image::tiles_iterator b_iter;
for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) {
tiles.push_back_slow(b_iter->number());
}
image->set_tiles(tiles);
@@ -882,7 +885,7 @@ static ShaderNode *add_node(Scene *scene,
sky->set_sun_intensity(b_sky_node.sun_intensity());
sky->set_sun_elevation(b_sky_node.sun_elevation());
sky->set_sun_rotation(b_sky_node.sun_rotation());
sky->set_altitude(b_sky_node.altitude());
sky->set_altitude(1000.0f * b_sky_node.altitude());
sky->set_air_density(b_sky_node.air_density());
sky->set_dust_density(b_sky_node.dust_density());
sky->set_ozone_density(b_sky_node.ozone_density());
@@ -1009,18 +1012,18 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node,
string name = b_socket.name();
if (node_use_modified_socket_name(node)) {
BL::Node::inputs_iterator b_input;
bool found = false;
int counter = 0, total = 0;
for (BL::NodeSocket &b_input : b_node.inputs) {
if (b_input.name() == name) {
if (!found) {
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
if (b_input->name() == name) {
if (!found)
counter++;
}
total++;
}
if (b_input.ptr.data == b_socket.ptr.data)
if (b_input->ptr.data == b_socket.ptr.data)
found = true;
}
@@ -1042,20 +1045,19 @@ static ShaderOutput *node_find_output_by_name(ShaderNode *node,
string name = b_socket.name();
if (node_use_modified_socket_name(node)) {
BL::Node::outputs_iterator b_output;
bool found = false;
int counter = 0, total = 0;
for (BL::NodeSocket &b_output : b_node.outputs) {
if (b_output.name() == name) {
if (!found) {
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
if (b_output->name() == name) {
if (!found)
counter++;
}
total++;
}
if (b_output.ptr.data == b_socket.ptr.data) {
if (b_output->ptr.data == b_socket.ptr.data)
found = true;
}
}
/* rename if needed */
@@ -1080,19 +1082,25 @@ static void add_nodes(Scene *scene,
const ProxyMap &proxy_output_map)
{
/* add nodes */
BL::ShaderNodeTree::nodes_iterator b_node;
PtrInputMap input_map;
PtrOutputMap output_map;
BL::Node::inputs_iterator b_input;
BL::Node::outputs_iterator b_output;
/* find the node to use for output if there are multiple */
BL::ShaderNode output_node = b_ntree.get_output_node(
BL::ShaderNodeOutputMaterial::target_CYCLES);
/* add nodes */
for (BL::Node &b_node : b_ntree.nodes) {
if (b_node.mute() || b_node.is_a(&RNA_NodeReroute)) {
for (b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
if (b_node->mute() || b_node->is_a(&RNA_NodeReroute)) {
/* replace muted node with internal links */
for (BL::NodeLink &b_link : b_node.internal_links) {
BL::NodeSocket to_socket(b_link.to_socket());
BL::Node::internal_links_iterator b_link;
for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end();
++b_link) {
BL::NodeSocket to_socket(b_link->to_socket());
SocketType::Type to_socket_type = convert_socket_type(to_socket);
if (to_socket_type == SocketType::UNDEFINED) {
continue;
@@ -1100,22 +1108,22 @@ static void add_nodes(Scene *scene,
ConvertNode *proxy = graph->create_node<ConvertNode>(to_socket_type, to_socket_type, true);
input_map[b_link.from_socket().ptr.data] = proxy->inputs[0];
output_map[b_link.to_socket().ptr.data] = proxy->outputs[0];
input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
graph->add(proxy);
}
}
else if (b_node.is_a(&RNA_ShaderNodeGroup) || b_node.is_a(&RNA_NodeCustomGroup) ||
b_node.is_a(&RNA_ShaderNodeCustomGroup)) {
else if (b_node->is_a(&RNA_ShaderNodeGroup) || b_node->is_a(&RNA_NodeCustomGroup) ||
b_node->is_a(&RNA_ShaderNodeCustomGroup)) {
BL::ShaderNodeTree b_group_ntree(PointerRNA_NULL);
if (b_node.is_a(&RNA_ShaderNodeGroup))
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(b_node)).node_tree());
else if (b_node.is_a(&RNA_NodeCustomGroup))
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(b_node)).node_tree());
if (b_node->is_a(&RNA_ShaderNodeGroup))
b_group_ntree = BL::ShaderNodeTree(((BL::NodeGroup)(*b_node)).node_tree());
else if (b_node->is_a(&RNA_NodeCustomGroup))
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
else
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(b_node)).node_tree());
b_group_ntree = BL::ShaderNodeTree(((BL::ShaderNodeCustomGroup)(*b_node)).node_tree());
ProxyMap group_proxy_input_map, group_proxy_output_map;
@@ -1123,8 +1131,8 @@ static void add_nodes(Scene *scene,
* Do this even if the node group has no internal tree,
* so that links have something to connect to and assert won't fail.
*/
for (BL::NodeSocket &b_input : b_node.inputs) {
SocketType::Type input_type = convert_socket_type(b_input);
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
SocketType::Type input_type = convert_socket_type(*b_input);
if (input_type == SocketType::UNDEFINED) {
continue;
}
@@ -1133,14 +1141,14 @@ static void add_nodes(Scene *scene,
graph->add(proxy);
/* register the proxy node for internal binding */
group_proxy_input_map[b_input.identifier()] = proxy;
group_proxy_input_map[b_input->identifier()] = proxy;
input_map[b_input.ptr.data] = proxy->inputs[0];
input_map[b_input->ptr.data] = proxy->inputs[0];
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
}
for (BL::NodeSocket &b_output : b_node.outputs) {
SocketType::Type output_type = convert_socket_type(b_output);
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
SocketType::Type output_type = convert_socket_type(*b_output);
if (output_type == SocketType::UNDEFINED) {
continue;
}
@@ -1149,9 +1157,9 @@ static void add_nodes(Scene *scene,
graph->add(proxy);
/* register the proxy node for internal binding */
group_proxy_output_map[b_output.identifier()] = proxy;
group_proxy_output_map[b_output->identifier()] = proxy;
output_map[b_output.ptr.data] = proxy->outputs[0];
output_map[b_output->ptr.data] = proxy->outputs[0];
}
if (b_group_ntree) {
@@ -1166,30 +1174,30 @@ static void add_nodes(Scene *scene,
group_proxy_output_map);
}
}
else if (b_node.is_a(&RNA_NodeGroupInput)) {
else if (b_node->is_a(&RNA_NodeGroupInput)) {
/* map each socket to a proxy node */
for (BL::NodeSocket &b_output : b_node.outputs) {
ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output.identifier());
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
if (proxy_it != proxy_input_map.end()) {
ConvertNode *proxy = proxy_it->second;
output_map[b_output.ptr.data] = proxy->outputs[0];
output_map[b_output->ptr.data] = proxy->outputs[0];
}
}
}
else if (b_node.is_a(&RNA_NodeGroupOutput)) {
BL::NodeGroupOutput b_output_node(b_node);
else if (b_node->is_a(&RNA_NodeGroupOutput)) {
BL::NodeGroupOutput b_output_node(*b_node);
/* only the active group output is used */
if (b_output_node.is_active_output()) {
/* map each socket to a proxy node */
for (BL::NodeSocket &b_input : b_node.inputs) {
ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input.identifier());
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
if (proxy_it != proxy_output_map.end()) {
ConvertNode *proxy = proxy_it->second;
input_map[b_input.ptr.data] = proxy->inputs[0];
input_map[b_input->ptr.data] = proxy->inputs[0];
set_default_value(proxy->inputs[0], b_input, b_data, b_ntree);
set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree);
}
}
}
@@ -1197,49 +1205,52 @@ static void add_nodes(Scene *scene,
else {
ShaderNode *node = NULL;
if (b_node.ptr.data == output_node.ptr.data) {
if (b_node->ptr.data == output_node.ptr.data) {
node = graph->output();
}
else {
BL::ShaderNode b_shader_node(b_node);
BL::ShaderNode b_shader_node(*b_node);
node = add_node(
scene, b_engine, b_data, b_depsgraph, b_scene, graph, b_ntree, b_shader_node);
}
if (node) {
/* map node sockets for linking */
for (BL::NodeSocket &b_input : b_node.inputs) {
ShaderInput *input = node_find_input_by_name(node, b_node, b_input);
for (b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
ShaderInput *input = node_find_input_by_name(node, *b_node, *b_input);
if (!input) {
/* XXX should not happen, report error? */
continue;
}
input_map[b_input.ptr.data] = input;
input_map[b_input->ptr.data] = input;
set_default_value(input, b_input, b_data, b_ntree);
set_default_value(input, *b_input, b_data, b_ntree);
}
for (BL::NodeSocket &b_output : b_node.outputs) {
ShaderOutput *output = node_find_output_by_name(node, b_node, b_output);
for (b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
ShaderOutput *output = node_find_output_by_name(node, *b_node, *b_output);
if (!output) {
/* XXX should not happen, report error? */
continue;
}
output_map[b_output.ptr.data] = output;
output_map[b_output->ptr.data] = output;
}
}
}
}
/* connect nodes */
for (BL::NodeLink &b_link : b_ntree.links) {
BL::NodeTree::links_iterator b_link;
for (b_ntree.links.begin(b_link); b_link != b_ntree.links.end(); ++b_link) {
/* Ignore invalid links to avoid unwanted cycles created in graph.
* Also ignore links with unavailable sockets. */
if (!(b_link.is_valid() && b_link.from_socket().enabled() && b_link.to_socket().enabled())) {
if (!(b_link->is_valid() && b_link->from_socket().enabled() &&
b_link->to_socket().enabled())) {
continue;
}
/* get blender link data */
BL::NodeSocket b_from_sock = b_link.from_socket();
BL::NodeSocket b_to_sock = b_link.to_socket();
BL::NodeSocket b_from_sock = b_link->from_socket();
BL::NodeSocket b_to_sock = b_link->to_socket();
ShaderOutput *output = 0;
ShaderInput *input = 0;
@@ -1287,12 +1298,13 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
TaskPool pool;
set<Shader *> updated_shaders;
for (BL::ID &b_id : b_depsgraph.ids) {
if (!b_id.is_a(&RNA_Material)) {
BL::Depsgraph::ids_iterator b_id;
for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
if (!b_id->is_a(&RNA_Material)) {
continue;
}
BL::Material b_mat(b_id);
BL::Material b_mat(*b_id);
Shader *shader;
/* test if we need to sync */
@@ -1485,6 +1497,7 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
shader->set_graph(graph);
shader->tag_update(scene);
background->tag_update(scene);
}
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
@@ -1504,7 +1517,8 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d,
viewport_parameters.custom_viewport_parameters());
background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao);
background->tag_update(scene);
if (background->is_modified())
background->tag_update(scene);
}
/* Sync Lights */
@@ -1513,12 +1527,13 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all)
{
shader_map.set_default(scene->default_light);
for (BL::ID &b_id : b_depsgraph.ids) {
if (!b_id.is_a(&RNA_Light)) {
BL::Depsgraph::ids_iterator b_id;
for (b_depsgraph.ids.begin(b_id); b_id != b_depsgraph.ids.end(); ++b_id) {
if (!b_id->is_a(&RNA_Light)) {
continue;
}
BL::Light b_light(b_id);
BL::Light b_light(*b_id);
Shader *shader;
/* test if we need to sync */

View File

@@ -24,7 +24,6 @@
#include "render/mesh.h"
#include "render/nodes.h"
#include "render/object.h"
#include "render/procedural.h"
#include "render/scene.h"
#include "render/shader.h"
@@ -132,8 +131,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
/* Iterate over all IDs in this depsgraph. */
for (BL::DepsgraphUpdate &b_update : b_depsgraph.updates) {
BL::ID b_id(b_update.id());
BL::Depsgraph::updates_iterator b_update;
for (b_depsgraph.updates.begin(b_update); b_update != b_depsgraph.updates.end(); ++b_update) {
BL::ID b_id(b_update->id());
/* Material */
if (b_id.is_a(&RNA_Material)) {
@@ -151,17 +151,17 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
const bool is_geometry = object_is_geometry(b_ob);
const bool is_light = !is_geometry && object_is_light(b_ob);
if (b_ob.is_instancer() && b_update.is_updated_shading()) {
if (b_ob.is_instancer() && b_update->is_updated_shading()) {
/* Needed for e.g. object color updates on instancer. */
object_map.set_recalc(b_ob);
}
if (is_geometry || is_light) {
const bool updated_geometry = b_update.is_updated_geometry();
const bool updated_geometry = b_update->is_updated_geometry();
/* Geometry (mesh, hair, volume). */
if (is_geometry) {
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
object_map.set_recalc(b_ob);
}
@@ -181,7 +181,7 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
}
/* Light */
else if (is_light) {
if (b_update.is_updated_transform() || b_update.is_updated_shading()) {
if (b_update->is_updated_transform() || b_update->is_updated_shading()) {
object_map.set_recalc(b_ob);
light_map.set_recalc(b_ob);
}
@@ -302,6 +302,11 @@ void BlenderSync::sync_integrator()
integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct"));
integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect"));
if (!preview) {
if (integrator->get_motion_blur() != r.use_motion_blur()) {
scene->object_manager->tag_update(scene);
scene->camera->tag_modified();
}
integrator->set_motion_blur(r.use_motion_blur());
}
@@ -370,8 +375,8 @@ void BlenderSync::sync_integrator()
integrator->set_ao_bounces(0);
}
/* UPDATE_NONE as we don't want to tag the integrator as modified, just tag dependent things */
integrator->tag_update(scene, Integrator::UPDATE_NONE);
if (integrator->is_modified())
integrator->tag_update(scene);
}
/* Film */
@@ -466,15 +471,16 @@ void BlenderSync::sync_images()
return;
}
/* Free buffers used by images which are not needed for render. */
for (BL::Image &b_image : b_data.images) {
BL::BlendData::images_iterator b_image;
for (b_data.images.begin(b_image); b_image != b_data.images.end(); ++b_image) {
/* TODO(sergey): Consider making it an utility function to check
* whether image is considered builtin.
*/
const bool is_builtin = b_image.packed_file() ||
b_image.source() == BL::Image::source_GENERATED ||
b_image.source() == BL::Image::source_MOVIE || b_engine.is_preview();
const bool is_builtin = b_image->packed_file() ||
b_image->source() == BL::Image::source_GENERATED ||
b_image->source() == BL::Image::source_MOVIE || b_engine.is_preview();
if (is_builtin == false) {
b_image.buffers_free();
b_image->buffers_free();
}
/* TODO(sergey): Free builtin images not used by any shader. */
}
@@ -575,7 +581,10 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
vector<Pass> passes;
/* loop over passes */
for (BL::RenderPass &b_pass : b_rlay.passes) {
BL::RenderLayer::passes_iterator b_pass_iter;
for (b_rlay.passes.begin(b_pass_iter); b_pass_iter != b_rlay.passes.end(); ++b_pass_iter) {
BL::RenderPass b_pass(*b_pass_iter);
PassType pass_type = get_pass_type(b_pass);
if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur())
@@ -720,7 +729,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold());
scene->film->tag_passes_update(scene, passes);
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
scene->integrator->tag_update(scene);
return passes;
}
@@ -743,8 +752,9 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
/* TODO(sergey): We can actually remove the whole dependency graph,
* but that will need some API support first.
*/
for (BL::Object &b_ob : b_depsgraph.objects) {
b_ob.cache_release();
BL::Depsgraph::objects_iterator b_ob;
for (b_depsgraph.objects.begin(b_ob); b_ob != b_depsgraph.objects.end(); ++b_ob) {
b_ob->cache_release();
}
}
@@ -843,7 +853,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine,
preview_samples = preview_samples * preview_samples;
}
if (get_enum(cscene, "progressive") == 0 && params.device.has_branched_path) {
if (get_enum(cscene, "progressive") == 0 && (params.device.type != DEVICE_OPTIX)) {
if (background) {
params.samples = aa_samples;
}

View File

@@ -134,7 +134,6 @@ class BlenderSync {
void sync_view();
/* Shader */
array<Node *> find_used_shaders(BL::Object &b_ob);
void sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all);
void sync_shaders(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d);
void sync_nodes(Shader *shader, BL::ShaderNodeTree &b_ntree);

View File

@@ -538,9 +538,11 @@ static inline bool object_use_deform_motion(BL::Object &b_parent, BL::Object &b_
static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object &b_ob)
{
for (BL::Modifier &b_mod : b_ob.modifiers) {
if (b_mod.is_a(&RNA_FluidModifier)) {
BL::FluidModifier b_mmd(b_mod);
BL::Object::modifiers_iterator b_mod;
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
if (b_mod->is_a(&RNA_FluidModifier)) {
BL::FluidModifier b_mmd(*b_mod);
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_LIQUID) {
@@ -554,9 +556,11 @@ static inline BL::FluidDomainSettings object_fluid_liquid_domain_find(BL::Object
static inline BL::FluidDomainSettings object_fluid_gas_domain_find(BL::Object &b_ob)
{
for (BL::Modifier &b_mod : b_ob.modifiers) {
if (b_mod.is_a(&RNA_FluidModifier)) {
BL::FluidModifier b_mmd(b_mod);
BL::Object::modifiers_iterator b_mod;
for (b_ob.modifiers.begin(b_mod); b_mod != b_ob.modifiers.end(); ++b_mod) {
if (b_mod->is_a(&RNA_FluidModifier)) {
BL::FluidModifier b_mmd(*b_mod);
if (b_mmd.fluid_type() == BL::FluidModifier::fluid_type_DOMAIN &&
b_mmd.domain_settings().domain_type() == BL::FluidDomainSettings::domain_type_GAS) {

View File

@@ -222,7 +222,9 @@ class BlenderVolumeLoader : public VDBImageLoader {
b_volume.grids.load(b_data.ptr.data);
#ifdef WITH_OPENVDB
for (BL::VolumeGrid &b_volume_grid : b_volume.grids) {
BL::Volume::grids_iterator b_grid_iter;
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
BL::VolumeGrid b_volume_grid(*b_grid_iter);
if (b_volume_grid.name() == grid_name) {
const bool unload = !b_volume_grid.is_loaded();
@@ -258,7 +260,9 @@ static void sync_volume_object(BL::BlendData &b_data,
volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT));
/* Find grid with matching name. */
for (BL::VolumeGrid &b_grid : b_volume.grids) {
BL::Volume::grids_iterator b_grid_iter;
for (b_volume.grids.begin(b_grid_iter); b_grid_iter != b_volume.grids.end(); ++b_grid_iter) {
BL::VolumeGrid b_grid = *b_grid_iter;
ustring name = ustring(b_grid.name());
AttributeStandard std = ATTR_STD_NONE;

View File

@@ -742,7 +742,6 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
size_t max_size = 0;
bool max_is_image = false;
thread_scoped_lock lock(cuda_mem_map_mutex);
foreach (CUDAMemMap::value_type &pair, cuda_mem_map) {
device_memory &mem = *pair.first;
CUDAMem *cmem = &pair.second;
@@ -774,7 +773,6 @@ void CUDADevice::move_textures_to_host(size_t size, bool for_texture)
max_mem = &mem;
}
}
lock.unlock();
/* Move to host memory. This part is mutex protected since
* multiple CUDA devices could be moving the memory. The
@@ -896,7 +894,6 @@ CUDADevice::CUDAMem *CUDADevice::generic_alloc(device_memory &mem, size_t pitch_
}
/* Insert into map of allocations. */
thread_scoped_lock lock(cuda_mem_map_mutex);
CUDAMem *cmem = &cuda_mem_map[&mem];
if (shared_pointer != 0) {
/* Replace host pointer with our host allocation. Only works if
@@ -938,7 +935,6 @@ void CUDADevice::generic_copy_to(device_memory &mem)
/* If use_mapped_host of mem is false, the current device only uses device memory allocated by
* cuMemAlloc regardless of mem.host_pointer and mem.shared_pointer, and should copy data from
* mem.host_pointer. */
thread_scoped_lock lock(cuda_mem_map_mutex);
if (!cuda_mem_map[&mem].use_mapped_host || mem.host_pointer != mem.shared_pointer) {
const CUDAContextScope scope(this);
cuda_assert(
@@ -950,7 +946,6 @@ void CUDADevice::generic_free(device_memory &mem)
{
if (mem.device_pointer) {
CUDAContextScope scope(this);
thread_scoped_lock lock(cuda_mem_map_mutex);
const CUDAMem &cmem = cuda_mem_map[&mem];
/* If cmem.use_mapped_host is true, reference counting is used
@@ -995,6 +990,7 @@ void CUDADevice::mem_alloc(device_memory &mem)
assert(!"mem_alloc not supported for global memory.");
}
else {
thread_scoped_lock lock(cuda_mem_map_mutex);
generic_alloc(mem);
}
}
@@ -1013,6 +1009,7 @@ void CUDADevice::mem_copy_to(device_memory &mem)
tex_alloc((device_texture &)mem);
}
else {
thread_scoped_lock lock(cuda_mem_map_mutex);
if (!mem.device_pointer) {
generic_alloc(mem);
}
@@ -1076,6 +1073,7 @@ void CUDADevice::mem_free(device_memory &mem)
tex_free((device_texture &)mem);
}
else {
thread_scoped_lock lock(cuda_mem_map_mutex);
generic_free(mem);
}
}
@@ -1099,6 +1097,7 @@ void CUDADevice::const_copy_to(const char *name, void *host, size_t size)
void CUDADevice::global_alloc(device_memory &mem)
{
if (mem.is_resident(this)) {
thread_scoped_lock lock(cuda_mem_map_mutex);
generic_alloc(mem);
generic_copy_to(mem);
}
@@ -1109,6 +1108,7 @@ void CUDADevice::global_alloc(device_memory &mem)
void CUDADevice::global_free(device_memory &mem)
{
if (mem.is_resident(this) && mem.device_pointer) {
thread_scoped_lock lock(cuda_mem_map_mutex);
generic_free(mem);
}
}
@@ -1177,8 +1177,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
size_t src_pitch = mem.data_width * dsize * mem.data_elements;
size_t dst_pitch = src_pitch;
thread_scoped_lock lock(cuda_mem_map_mutex);
if (!mem.is_resident(this)) {
thread_scoped_lock lock(cuda_mem_map_mutex);
cmem = &cuda_mem_map[&mem];
cmem->texobject = 0;
@@ -1228,7 +1229,6 @@ void CUDADevice::tex_alloc(device_texture &mem)
mem.device_size = size;
stats.mem_alloc(size);
thread_scoped_lock lock(cuda_mem_map_mutex);
cmem = &cuda_mem_map[&mem];
cmem->texobject = 0;
cmem->array = array_3d;
@@ -1266,6 +1266,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
cuda_assert(cuMemcpyHtoD(mem.device_pointer, mem.host_pointer, size));
}
/* Unlock mutex before resizing texture info, since that may attempt to lock it again. */
lock.unlock();
/* Resize once */
const uint slot = mem.slot;
if (slot >= texture_info.size()) {
@@ -1314,7 +1317,9 @@ void CUDADevice::tex_alloc(device_texture &mem)
texDesc.filterMode = filter_mode;
texDesc.flags = CU_TRSF_NORMALIZED_COORDINATES;
thread_scoped_lock lock(cuda_mem_map_mutex);
/* Lock again and refresh the data pointer (in case another thread modified the map in the
* meantime). */
lock.lock();
cmem = &cuda_mem_map[&mem];
cuda_assert(cuTexObjectCreate(&cmem->texobject, &resDesc, &texDesc, NULL));
@@ -1352,7 +1357,6 @@ void CUDADevice::tex_free(device_texture &mem)
cuda_mem_map.erase(cuda_mem_map.find(&mem));
}
else {
lock.unlock();
generic_free(mem);
}
}

View File

@@ -620,7 +620,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
info.has_half_images = true;
info.has_volume_decoupled = true;
info.has_branched_path = true;
info.has_adaptive_stop_per_sample = true;
info.has_osl = true;
info.has_profiling = true;
@@ -666,7 +665,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
/* Accumulate device info. */
info.has_half_images &= device.has_half_images;
info.has_volume_decoupled &= device.has_volume_decoupled;
info.has_branched_path &= device.has_branched_path;
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
info.has_osl &= device.has_osl;
info.has_profiling &= device.has_profiling;

View File

@@ -79,7 +79,6 @@ class DeviceInfo {
bool display_device; /* GPU is used as a display device. */
bool has_half_images; /* Support half-float textures. */
bool has_volume_decoupled; /* Decoupled volume shading. */
bool has_branched_path; /* Supports branched path tracing. */
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
bool has_osl; /* Support Open Shading Language. */
bool use_split_kernel; /* Use split or mega kernel. */
@@ -100,7 +99,6 @@ class DeviceInfo {
display_device = false;
has_half_images = false;
has_volume_decoupled = false;
has_branched_path = true;
has_adaptive_stop_per_sample = false;
has_osl = false;
use_split_kernel = false;

View File

@@ -951,7 +951,7 @@ class CPUDevice : public Device {
SIMD_SET_FLUSH_TO_ZERO;
for (int sample = start_sample; sample < end_sample; sample++) {
if (task.get_cancel() || TaskPool::canceled()) {
if (task.get_cancel() || task_pool.canceled()) {
if (task.need_finish_queue == false)
break;
}
@@ -1249,7 +1249,7 @@ class CPUDevice : public Device {
void thread_render(DeviceTask &task)
{
if (TaskPool::canceled()) {
if (task_pool.canceled()) {
if (task.need_finish_queue == false)
return;
}
@@ -1319,7 +1319,7 @@ class CPUDevice : public Device {
task.release_tile(tile);
if (TaskPool::canceled()) {
if (task_pool.canceled()) {
if (task.need_finish_queue == false)
break;
}
@@ -1416,7 +1416,7 @@ class CPUDevice : public Device {
task.offset,
sample);
if (task.get_cancel() || TaskPool::canceled())
if (task.get_cancel() || task_pool.canceled())
break;
task.update_progress(NULL);

View File

@@ -259,8 +259,6 @@ class device_memory {
device_ptr original_device_ptr;
size_t original_device_size;
Device *original_device;
bool need_realloc_;
bool modified;
};
/* Device Only Memory
@@ -331,8 +329,6 @@ template<typename T> class device_vector : public device_memory {
{
data_type = device_type_traits<T>::data_type;
data_elements = device_type_traits<T>::num_elements;
modified = true;
need_realloc_ = true;
assert(data_elements > 0);
}
@@ -351,7 +347,6 @@ template<typename T> class device_vector : public device_memory {
device_free();
host_free();
host_pointer = host_alloc(sizeof(T) * new_size);
modified = true;
assert(device_pointer == 0);
}
@@ -405,19 +400,6 @@ template<typename T> class device_vector : public device_memory {
assert(device_pointer == 0);
}
void give_data(array<T> &to)
{
device_free();
to.set_data((T *)host_pointer, data_size);
data_size = 0;
data_width = 0;
data_height = 0;
data_depth = 0;
host_pointer = 0;
assert(device_pointer == 0);
}
/* Free device and host memory. */
void free()
{
@@ -429,40 +411,10 @@ template<typename T> class device_vector : public device_memory {
data_height = 0;
data_depth = 0;
host_pointer = 0;
modified = true;
need_realloc_ = true;
assert(device_pointer == 0);
}
void free_if_need_realloc(bool force_free)
{
if (need_realloc_ || force_free) {
free();
}
}
bool is_modified() const
{
return modified;
}
bool need_realloc()
{
return need_realloc_;
}
void tag_modified()
{
modified = true;
}
void tag_realloc()
{
need_realloc_ = true;
tag_modified();
}
size_t size() const
size_t size()
{
return data_size;
}
@@ -480,24 +432,7 @@ template<typename T> class device_vector : public device_memory {
void copy_to_device()
{
if (data_size != 0) {
device_copy_to();
}
}
void copy_to_device_if_modified()
{
if (!modified) {
return;
}
copy_to_device();
}
void clear_modified()
{
modified = false;
need_realloc_ = false;
device_copy_to();
}
void copy_from_device()

View File

@@ -151,6 +151,8 @@ string device_opencl_capabilities()
platform_ids.resize(num_platforms);
opencl_assert(clGetPlatformIDs(num_platforms, &platform_ids[0], NULL));
typedef char cl_string[1024];
# define APPEND_INFO(func, id, name, what, type) \
do { \
type data; \
@@ -158,33 +160,22 @@ string device_opencl_capabilities()
opencl_assert(func(id, what, sizeof(data), &data, NULL)); \
result += string_printf("%s: %s\n", name, to_string(data).c_str()); \
} while (false)
# define APPEND_STRING_INFO_IMPL(func, id, name, what, is_optional) \
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
do { \
string value; \
char data[1024] = "\0"; \
size_t length = 0; \
if (func(id, what, 0, NULL, &length) == CL_SUCCESS) { \
vector<char> buffer(length + 1); \
if (func(id, what, buffer.size(), buffer.data(), NULL) == CL_SUCCESS) { \
value = string(buffer.data()); \
if (func(id, what, sizeof(data), &data, &length) == CL_SUCCESS) { \
if (length != 0 && data[0] != '\0') { \
result += string_printf("%s: %s\n", name, data); \
} \
} \
if (is_optional && !(length != 0 && value[0] != '\0')) { \
break; \
} \
result += string_printf("%s: %s\n", name, value.c_str()); \
} while (false)
# define APPEND_PLATFORM_STRING_INFO(id, name, what) \
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, false)
# define APPEND_STRING_EXTENSION_INFO(func, id, name, what) \
APPEND_STRING_INFO_IMPL(clGetPlatformInfo, id, "\tPlatform " name, what, true)
# define APPEND_PLATFORM_INFO(id, name, what, type) \
APPEND_INFO(clGetPlatformInfo, id, "\tPlatform " name, what, type)
# define APPEND_DEVICE_INFO(id, name, what, type) \
APPEND_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what, type)
# define APPEND_DEVICE_STRING_INFO(id, name, what) \
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, false)
# define APPEND_DEVICE_STRING_EXTENSION_INFO(id, name, what) \
APPEND_STRING_INFO_IMPL(clGetDeviceInfo, id, "\t\t\tDevice " name, what, true)
APPEND_STRING_EXTENSION_INFO(clGetDeviceInfo, id, "\t\t\tDevice " name, what)
vector<cl_device_id> device_ids;
for (cl_uint platform = 0; platform < num_platforms; ++platform) {
@@ -192,11 +183,11 @@ string device_opencl_capabilities()
result += string_printf("Platform #%u\n", platform);
APPEND_PLATFORM_STRING_INFO(platform_id, "Name", CL_PLATFORM_NAME);
APPEND_PLATFORM_STRING_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR);
APPEND_PLATFORM_STRING_INFO(platform_id, "Version", CL_PLATFORM_VERSION);
APPEND_PLATFORM_STRING_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE);
APPEND_PLATFORM_STRING_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS);
APPEND_PLATFORM_INFO(platform_id, "Name", CL_PLATFORM_NAME, cl_string);
APPEND_PLATFORM_INFO(platform_id, "Vendor", CL_PLATFORM_VENDOR, cl_string);
APPEND_PLATFORM_INFO(platform_id, "Version", CL_PLATFORM_VERSION, cl_string);
APPEND_PLATFORM_INFO(platform_id, "Profile", CL_PLATFORM_PROFILE, cl_string);
APPEND_PLATFORM_INFO(platform_id, "Extensions", CL_PLATFORM_EXTENSIONS, cl_string);
cl_uint num_devices = 0;
opencl_assert(
@@ -211,13 +202,13 @@ string device_opencl_capabilities()
result += string_printf("\t\tDevice: #%u\n", device);
APPEND_DEVICE_STRING_INFO(device_id, "Name", CL_DEVICE_NAME);
APPEND_DEVICE_INFO(device_id, "Name", CL_DEVICE_NAME, cl_string);
APPEND_DEVICE_STRING_EXTENSION_INFO(device_id, "Board Name", CL_DEVICE_BOARD_NAME_AMD);
APPEND_DEVICE_STRING_INFO(device_id, "Vendor", CL_DEVICE_VENDOR);
APPEND_DEVICE_STRING_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION);
APPEND_DEVICE_STRING_INFO(device_id, "Profile", CL_DEVICE_PROFILE);
APPEND_DEVICE_STRING_INFO(device_id, "Version", CL_DEVICE_VERSION);
APPEND_DEVICE_STRING_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS);
APPEND_DEVICE_INFO(device_id, "Vendor", CL_DEVICE_VENDOR, cl_string);
APPEND_DEVICE_INFO(device_id, "OpenCL C Version", CL_DEVICE_OPENCL_C_VERSION, cl_string);
APPEND_DEVICE_INFO(device_id, "Profile", CL_DEVICE_PROFILE, cl_string);
APPEND_DEVICE_INFO(device_id, "Version", CL_DEVICE_VERSION, cl_string);
APPEND_DEVICE_INFO(device_id, "Extensions", CL_DEVICE_EXTENSIONS, cl_string);
APPEND_DEVICE_INFO(
device_id, "Max clock frequency (MHz)", CL_DEVICE_MAX_CLOCK_FREQUENCY, cl_uint);
APPEND_DEVICE_INFO(device_id, "Max compute units", CL_DEVICE_MAX_COMPUTE_UNITS, cl_uint);
@@ -225,14 +216,9 @@ string device_opencl_capabilities()
}
}
# undef APPEND_INFO
# undef APPEND_STRING_INFO_IMPL
# undef APPEND_STRING_INFO
# undef APPEND_PLATFORM_STRING_INFO
# undef APPEND_STRING_EXTENSION_INFO
# undef APPEND_PLATFORM_INFO
# undef APPEND_DEVICE_INFO
# undef APPEND_DEVICE_STRING_INFO
# undef APPEND_DEVICE_STRING_EXTENSION_INFO
return result;
}

View File

@@ -1857,7 +1857,6 @@ void device_optix_info(const vector<DeviceInfo> &cuda_devices, vector<DeviceInfo
info.type = DEVICE_OPTIX;
info.id += "_OptiX";
info.denoisers |= DENOISER_OPTIX;
info.has_branched_path = false;
devices.push_back(info);
}

View File

@@ -100,9 +100,7 @@ class DenoiseParams {
neighbor_frames = 2;
clamp_input = true;
/* Default to color + albedo only, since normal input does not always have the desired effect
* when denoising with OptiX. */
input_passes = DENOISER_INPUT_RGB_ALBEDO;
input_passes = DENOISER_INPUT_RGB_ALBEDO_NORMAL;
start_sample = 0;
}

View File

@@ -454,7 +454,7 @@ ccl_device_inline bool cylinder_culling_test(const float2 p1, const float2 p2, c
/* Performs culling against a cylinder. */
const float2 dp = p2 - p1;
const float num = dp.x * p1.y - dp.y * p1.x;
const float den2 = dot(dp, dp);
const float den2 = dot(p2 - p1, p2 - p1);
return num * num <= r * r * den2;
}
@@ -571,46 +571,46 @@ ccl_device_inline bool ribbon_intersect(const float3 ray_org,
for (int i = 0; i < N; i++) {
const float u = i * step_size;
const float4 p1 = catmull_rom_basis_eval(curve, u + step_size);
const bool valid = cylinder_culling_test(
bool valid = cylinder_culling_test(
make_float2(p0.x, p0.y), make_float2(p1.x, p1.y), max(p0.w, p1.w));
if (!valid) {
continue;
}
/* Evaluate next point. */
float3 dp1dt = float4_to_float3(catmull_rom_basis_derivative(curve, u + step_size));
dp1dt = (max3(fabs(dp1dt)) < eps) ? float4_to_float3(p1 - p0) : dp1dt;
const float3 wn1 = normalize(make_float3(dp1dt.y, -dp1dt.x, 0.0f)) * p1.w;
if (valid) {
/* Construct quad coordinates. */
const float3 lp0 = float4_to_float3(p0) + wn0;
const float3 lp1 = float4_to_float3(p1) + wn1;
const float3 up0 = float4_to_float3(p0) - wn0;
const float3 up1 = float4_to_float3(p1) - wn1;
/* Construct quad coordinates. */
const float3 lp0 = float4_to_float3(p0) + wn0;
const float3 lp1 = float4_to_float3(p1) + wn1;
const float3 up0 = float4_to_float3(p0) - wn0;
const float3 up1 = float4_to_float3(p1) - wn1;
/* Intersect quad. */
float vu, vv, vt;
bool valid0 = ribbon_intersect_quad(isect->t, lp0, lp1, up1, up0, &vu, &vv, &vt);
/* Intersect quad. */
float vu, vv, vt;
bool valid0 = ribbon_intersect_quad(isect->t, lp0, lp1, up1, up0, &vu, &vv, &vt);
if (valid0) {
/* ignore self intersections */
const float avoidance_factor = 2.0f;
if (avoidance_factor != 0.0f) {
float r = mix(p0.w, p1.w, vu);
valid0 = vt > avoidance_factor * r;
}
if (valid0) {
/* ignore self intersections */
const float avoidance_factor = 2.0f;
if (avoidance_factor != 0.0f) {
float r = mix(p0.w, p1.w, vu);
valid0 = vt > avoidance_factor * r;
}
vv = 2.0f * vv - 1.0f;
if (valid0) {
vv = 2.0f * vv - 1.0f;
/* Record intersection. */
isect->t = vt;
isect->u = u + vu * step_size;
isect->v = vv;
return true;
}
/* Record intersection. */
isect->t = vt;
isect->u = u + vu * step_size;
isect->v = vv;
return true;
}
}
/* Store point for next step. */
p0 = p1;
wn0 = wn1;
}

View File

@@ -15,20 +15,7 @@
*/
#ifdef WITH_NANOVDB
/* Data type to replace `double` used in the NanoVDB headers. Cycles don't need doubles, and is
* safer and more portable to never use double datatype on GPU.
* Use a special structure, so that the following is true:
* - No unnoticed implicit cast or mathematical operations used on scalar 64bit type
* (which rules out trick like using `uint64_t` as a drop-in replacement for double).
* - Padding rules are matching exactly `double`
* (which rules out array of `uint8_t`). */
typedef struct ccl_vdb_double_t {
uint64_t i;
} ccl_vdb_double_t;
# define double ccl_vdb_double_t
# include "nanovdb/CNanoVDB.h"
# undef double
#endif
/* For OpenCL we do manual lookup and interpolation. */

View File

@@ -43,7 +43,7 @@ class ColorSpaceProcessor;
*
* Data needed by OSL render services, that is global to a rendering session.
* This includes all OSL shaders, name to attribute mapping and texture handles.
*/
* */
struct OSLGlobals {
OSLGlobals()

View File

@@ -27,7 +27,6 @@
#include <OSL/oslclosure.h>
#include <OSL/oslexec.h>
#include <OSL/rendererservices.h>
#ifdef WITH_PTEX
class PtexCache;

View File

@@ -23,7 +23,6 @@ set(INC_SYS
)
set(SRC
alembic.cpp
attribute.cpp
background.cpp
bake.cpp
@@ -49,7 +48,6 @@ set(SRC
mesh_displace.cpp
mesh_subdivision.cpp
nodes.cpp
procedural.cpp
object.cpp
osl.cpp
particles.cpp
@@ -66,7 +64,6 @@ set(SRC
)
set(SRC_HEADERS
alembic.h
attribute.h
bake.h
background.h
@@ -93,7 +90,6 @@ set(SRC_HEADERS
object.h
osl.h
particles.h
procedural.h
curves.h
scene.h
session.h
@@ -134,7 +130,7 @@ if(WITH_OPENCOLORIO)
${OPENCOLORIO_INCLUDE_DIRS}
)
if(WIN32)
add_definitions(-DOpenColorIO_SKIP_IMPORTS)
add_definitions(-DOpenColorIO_STATIC)
endif()
endif()
@@ -148,16 +144,6 @@ if(WITH_OPENVDB)
)
endif()
if(WITH_ALEMBIC)
add_definitions(-DWITH_ALEMBIC)
list(APPEND INC_SYS
${ALEMBIC_INCLUDE_DIRS}
)
list(APPEND LIB
${ALEMBIC_LIBRARIES}
)
endif()
if(WITH_NANOVDB)
list(APPEND INC_SYS
${NANOVDB_INCLUDE_DIRS}

File diff suppressed because it is too large Load Diff

View File

@@ -1,404 +0,0 @@
/*
* Copyright 2011-2018 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "graph/node.h"
#include "render/attribute.h"
#include "render/procedural.h"
#include "util/util_set.h"
#include "util/util_transform.h"
#include "util/util_vector.h"
#ifdef WITH_ALEMBIC
# include <Alembic/AbcCoreFactory/All.h>
# include <Alembic/AbcGeom/All.h>
CCL_NAMESPACE_BEGIN
class AlembicProcedural;
class Geometry;
class Object;
class Progress;
class Shader;
using MatrixSampleMap = std::map<Alembic::Abc::chrono_t, Alembic::Abc::M44d>;
/* Helpers to detect if some type is a ccl::array. */
template<typename> struct is_array : public std::false_type {
};
template<typename T> struct is_array<array<T>> : public std::true_type {
};
/* Store the data set for an animation at every time points, or at the beginning of the animation
* for constant data.
*
* The data is supposed to be stored in chronological order, and is looked up using the current
* animation time in seconds using the TimeSampling from the Alembic property. */
template<typename T> class DataStore {
struct DataTimePair {
double time = 0;
T data{};
};
vector<DataTimePair> data{};
Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
double last_loaded_time = std::numeric_limits<double>::max();
public:
void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling_)
{
time_sampling = time_sampling_;
}
Alembic::AbcCoreAbstract::TimeSampling get_time_sampling() const
{
return time_sampling;
}
/* Get the data for the specified time.
* Return nullptr if there is no data or if the data for this time was already loaded. */
T *data_for_time(double time)
{
if (size() == 0) {
return nullptr;
}
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
index_pair = time_sampling.getNearIndex(time, data.size());
DataTimePair &data_pair = data[index_pair.first];
if (last_loaded_time == data_pair.time) {
return nullptr;
}
last_loaded_time = data_pair.time;
return &data_pair.data;
}
/* get the data for the specified time, but do not check if the data was already loaded for this
* time return nullptr if there is no data */
T *data_for_time_no_check(double time)
{
if (size() == 0) {
return nullptr;
}
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
index_pair = time_sampling.getNearIndex(time, data.size());
DataTimePair &data_pair = data[index_pair.first];
return &data_pair.data;
}
void add_data(T &data_, double time)
{
if constexpr (is_array<T>::value) {
data.emplace_back();
data.back().data.steal_data(data_);
data.back().time = time;
return;
}
data.push_back({time, data_});
}
bool is_constant() const
{
return data.size() <= 1;
}
size_t size() const
{
return data.size();
}
void clear()
{
invalidate_last_loaded_time();
data.clear();
}
void invalidate_last_loaded_time()
{
last_loaded_time = std::numeric_limits<double>::max();
}
/* Copy the data for the specified time to the node's socket. If there is no
* data for this time or it was already loaded, do nothing. */
void copy_to_socket(double time, Node *node, const SocketType *socket)
{
T *data_ = data_for_time(time);
if (data_ == nullptr) {
return;
}
/* TODO(kevindietrich): arrays are emptied when passed to the sockets, so for now we copy the
* arrays to avoid reloading the data */
T value = *data_;
node->set(*socket, value);
}
};
/* Actual cache for the stored data.
* This caches the topological, transformation, and attribute data for a Mesh node or a Hair node
* inside of DataStores.
*/
struct CachedData {
DataStore<Transform> transforms{};
/* mesh data */
DataStore<array<float3>> vertices;
DataStore<array<int3>> triangles{};
/* triangle "loops" are the polygons' vertices indices used for indexing face varying attributes
* (like UVs) */
DataStore<array<int3>> triangles_loops{};
DataStore<array<int>> shader{};
/* subd data */
DataStore<array<int>> subd_start_corner;
DataStore<array<int>> subd_num_corners;
DataStore<array<bool>> subd_smooth;
DataStore<array<int>> subd_ptex_offset;
DataStore<array<int>> subd_face_corners;
DataStore<int> num_ngons;
DataStore<array<int>> subd_creases_edge;
DataStore<array<float>> subd_creases_weight;
/* hair data */
DataStore<array<float3>> curve_keys;
DataStore<array<float>> curve_radius;
DataStore<array<int>> curve_first_key;
DataStore<array<int>> curve_shader;
struct CachedAttribute {
AttributeStandard std;
AttributeElement element;
TypeDesc type_desc;
ustring name;
DataStore<array<char>> data{};
};
vector<CachedAttribute> attributes{};
void clear();
CachedAttribute &add_attribute(const ustring &name,
const Alembic::Abc::TimeSampling &time_sampling);
bool is_constant() const;
void invalidate_last_loaded_time(bool attributes_only = false);
void set_time_sampling(Alembic::AbcCoreAbstract::TimeSampling time_sampling);
};
/* Representation of an Alembic object for the AlembicProcedural.
*
* The AlembicObject holds the path to the Alembic IObject inside of the archive that is desired
* for rendering, as well as the list of shaders that it is using.
*
* The names of the shaders should correspond to the names of the FaceSets inside of the Alembic
* archive for per-triangle shader association. If there is no FaceSets, or the names do not
* match, the first shader is used for rendering for all triangles.
*/
class AlembicObject : public Node {
public:
NODE_DECLARE
/* Path to the IObject inside of the archive. */
NODE_SOCKET_API(ustring, path)
/* Shaders used for rendering. */
NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders)
/* Maximum number of subdivisions for ISubD objects. */
NODE_SOCKET_API(int, subd_max_level)
/* Finest level of detail (in pixels) for the subdivision. */
NODE_SOCKET_API(float, subd_dicing_rate)
/* Scale the radius of points and curves. */
NODE_SOCKET_API(float, radius_scale)
AlembicObject();
~AlembicObject();
private:
friend class AlembicProcedural;
void set_object(Object *object);
Object *get_object();
void load_all_data(AlembicProcedural *proc,
Alembic::AbcGeom::IPolyMeshSchema &schema,
float scale,
Progress &progress);
void load_all_data(AlembicProcedural *proc,
Alembic::AbcGeom::ISubDSchema &schema,
float scale,
Progress &progress);
void load_all_data(AlembicProcedural *proc,
const Alembic::AbcGeom::ICurvesSchema &schema,
float scale,
Progress &progress,
float default_radius);
bool has_data_loaded() const;
bool need_shader_update = true;
MatrixSampleMap xform_samples;
Alembic::AbcGeom::IObject iobject;
Transform xform;
CachedData &get_cached_data()
{
return cached_data;
}
bool is_constant() const
{
return cached_data.is_constant();
}
Object *object = nullptr;
bool data_loaded = false;
CachedData cached_data;
void update_shader_attributes(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
Progress &progress);
void read_attribute(const Alembic::AbcGeom::ICompoundProperty &arb_geom_params,
const ustring &attr_name,
Progress &progress);
template<typename SchemaType>
void read_face_sets(SchemaType &schema,
array<int> &polygon_to_shader,
Alembic::AbcGeom::ISampleSelector sample_sel);
void setup_transform_cache(float scale);
AttributeRequestSet get_requested_attributes();
};
/* Procedural to render objects from a single Alembic archive.
*
* Every object desired to be rendered should be passed as an AlembicObject through the objects
* socket.
*
* This procedural will load the data set for the entire animation in memory on the first frame,
* and directly set the data for the new frames on the created Nodes if needed. This allows for
* faster updates between frames as it avoids reseeking the data on disk.
*/
class AlembicProcedural : public Procedural {
Alembic::AbcGeom::IArchive archive;
bool objects_loaded;
Scene *scene_;
public:
NODE_DECLARE
/* The file path to the Alembic archive */
NODE_SOCKET_API(ustring, filepath)
/* The current frame to render. */
NODE_SOCKET_API(float, frame)
/* The first frame to load data for. */
NODE_SOCKET_API(float, start_frame)
/* The last frame to load data for. */
NODE_SOCKET_API(float, end_frame)
/* Subtracted to the current frame. */
NODE_SOCKET_API(float, frame_offset)
/* The frame rate used for rendering in units of frames per second. */
NODE_SOCKET_API(float, frame_rate)
/* List of AlembicObjects to render. */
NODE_SOCKET_API_ARRAY(array<Node *>, objects)
/* Set the default radius to use for curves when the Alembic Curves Schemas do not have radius
* information. */
NODE_SOCKET_API(float, default_radius)
/* Multiplier to account for differences in default units for measuring objects in various
* software. */
NODE_SOCKET_API(float, scale)
AlembicProcedural();
~AlembicProcedural();
/* Populates the Cycles scene with Nodes for every contained AlembicObject on the first
* invocation, and updates the data on subsequent invocations if the frame changed. */
void generate(Scene *scene, Progress &progress);
/* Add an object to our list of objects, and tag the socket as modified. */
void add_object(AlembicObject *object);
/* Tag for an update only if something was modified. */
void tag_update(Scene *scene);
/* Returns a pointer to an exisiting or a newly created AlembicObject for the given path. */
AlembicObject *get_or_create_object(const ustring &path);
private:
/* Load the data for all the objects whose data has not yet been loaded. */
void load_objects(Progress &progress);
/* Traverse the Alembic hierarchy to lookup the IObjects for the AlembicObjects that were
* specified in our objects socket, and accumulate all of the transformations samples along the
* way for each IObject. */
void walk_hierarchy(Alembic::AbcGeom::IObject parent,
const Alembic::AbcGeom::ObjectHeader &ohead,
MatrixSampleMap *xform_samples,
const unordered_map<string, AlembicObject *> &object_map,
Progress &progress);
/* Read the data for an IPolyMesh at the specified frame_time. Creates corresponding Geometry and
* Object Nodes in the Cycles scene if none exist yet. */
void read_mesh(Scene *scene,
AlembicObject *abc_object,
Alembic::AbcGeom::Abc::chrono_t frame_time,
Progress &progress);
/* Read the data for an ICurves at the specified frame_time. Creates corresponding Geometry and
* Object Nodes in the Cycles scene if none exist yet. */
void read_curves(Scene *scene,
AlembicObject *abc_object,
Alembic::AbcGeom::Abc::chrono_t frame_time,
Progress &progress);
/* Read the data for an ISubD at the specified frame_time. Creates corresponding Geometry and
* Object Nodes in the Cycles scene if none exist yet. */
void read_subd(Scene *scene,
AlembicObject *abc_object,
Alembic::AbcGeom::Abc::chrono_t frame_time,
Progress &progress);
};
CCL_NAMESPACE_END
#endif

View File

@@ -28,7 +28,7 @@ CCL_NAMESPACE_BEGIN
Attribute::Attribute(
ustring name, TypeDesc type, AttributeElement element, Geometry *geom, AttributePrimitive prim)
: name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0), modified(true)
: name(name), std(ATTR_STD_NONE), type(type), element(element), flags(0)
{
/* string and matrix not supported! */
assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor ||
@@ -82,8 +82,6 @@ void Attribute::add(const float &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::add(const uchar4 &f)
@@ -95,8 +93,6 @@ void Attribute::add(const uchar4 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::add(const float2 &f)
@@ -108,8 +104,6 @@ void Attribute::add(const float2 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::add(const float3 &f)
@@ -121,8 +115,6 @@ void Attribute::add(const float3 &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::add(const Transform &f)
@@ -134,8 +126,6 @@ void Attribute::add(const Transform &f)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::add(const char *data)
@@ -144,26 +134,6 @@ void Attribute::add(const char *data)
for (size_t i = 0; i < size; i++)
buffer.push_back(data[i]);
modified = true;
}
void Attribute::set_data_from(Attribute &&other)
{
assert(other.std == std);
assert(other.type == type);
assert(other.element == element);
this->flags = other.flags;
if (this->buffer.size() != other.buffer.size()) {
this->buffer = std::move(other.buffer);
modified = true;
}
else if (memcmp(this->data(), other.data(), other.buffer.size()) != 0) {
this->buffer = std::move(other.buffer);
modified = true;
}
}
size_t Attribute::data_sizeof() const
@@ -657,42 +627,6 @@ void AttributeSet::clear(bool preserve_voxel_data)
}
}
void AttributeSet::update(AttributeSet &&new_attributes)
{
/* add or update old_attributes based on the new_attributes */
foreach (Attribute &attr, new_attributes.attributes) {
Attribute *nattr = add(attr.name, attr.type, attr.element);
nattr->std = attr.std;
nattr->set_data_from(std::move(attr));
}
/* remove any attributes not on new_attributes */
list<Attribute>::iterator it;
for (it = attributes.begin(); it != attributes.end();) {
if (it->std != ATTR_STD_NONE) {
if (new_attributes.find(it->std) == nullptr) {
attributes.erase(it++);
continue;
}
}
else if (it->name != "") {
if (new_attributes.find(it->name) == nullptr) {
attributes.erase(it++);
continue;
}
}
it++;
}
}
void AttributeSet::clear_modified()
{
foreach (Attribute &attr, attributes) {
attr.modified = false;
}
}
/* AttributeRequest */
AttributeRequest::AttributeRequest(ustring name_)

View File

@@ -54,8 +54,6 @@ class Attribute {
AttributeElement element;
uint flags; /* enum AttributeFlag */
bool modified;
Attribute(ustring name,
TypeDesc type,
AttributeElement element,
@@ -161,8 +159,6 @@ class Attribute {
void add(const Transform &tfm);
void add(const char *data);
void set_data_from(Attribute &&other);
static bool same_storage(TypeDesc a, TypeDesc b);
static const char *standard_name(AttributeStandard std);
static AttributeStandard name_standard(const char *name);
@@ -198,12 +194,6 @@ class AttributeSet {
void resize(bool reserve_only = false);
void clear(bool preserve_voxel_data = false);
/* Update the attributes in this AttributeSet with the ones from the new set,
* and remove any attribute not found on the new set from this. */
void update(AttributeSet &&new_attributes);
void clear_modified();
};
/* AttributeRequest

View File

@@ -130,9 +130,8 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
void Background::tag_update(Scene *scene)
{
if (ao_factor_is_modified() || use_ao_is_modified()) {
scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
}
scene->integrator->tag_update(scene);
tag_modified();
}
Shader *Background::get_shader(const Scene *scene)

View File

@@ -78,7 +78,7 @@ BakeManager::BakeManager()
type = SHADER_EVAL_BAKE;
pass_filter = 0;
need_update_ = true;
need_update = true;
}
BakeManager::~BakeManager()
@@ -114,9 +114,9 @@ void BakeManager::set(Scene *scene,
/* create device and update scene */
scene->film->tag_modified();
scene->integrator->tag_update(scene, Integrator::UPDATE_ALL);
scene->integrator->tag_update(scene);
need_update_ = true;
need_update = true;
}
void BakeManager::device_update(Device * /*device*/,
@@ -124,7 +124,7 @@ void BakeManager::device_update(Device * /*device*/,
Scene *scene,
Progress & /* progress */)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -152,21 +152,11 @@ void BakeManager::device_update(Device * /*device*/,
object_index++;
}
need_update_ = false;
need_update = false;
}
void BakeManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
{
}
void BakeManager::tag_update()
{
need_update_ = true;
}
bool BakeManager::need_update() const
{
return need_update_;
}
CCL_NAMESPACE_END

View File

@@ -36,12 +36,9 @@ class BakeManager {
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update();
bool need_update() const;
bool need_update;
private:
bool need_update_;
ShaderEvalType type;
int pass_filter;
std::string object_name;

View File

@@ -212,8 +212,8 @@ void Camera::compute_auto_viewplane()
viewplane.top = 1.0f;
}
else {
float aspect = (float)full_width / (float)full_height;
if (full_width >= full_height) {
float aspect = (float)width / (float)height;
if (width >= height) {
viewplane.left = -aspect;
viewplane.right = aspect;
viewplane.bottom = -1.0f;

View File

@@ -192,7 +192,6 @@ void ColorSpaceManager::is_builtin_colorspace(ustring colorspace,
return;
}
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
is_scene_linear = true;
is_srgb = true;
for (int i = 0; i < 256; i++) {
@@ -202,10 +201,10 @@ void ColorSpaceManager::is_builtin_colorspace(ustring colorspace,
float cG[3] = {0, v, 0};
float cB[3] = {0, 0, v};
float cW[3] = {v, v, v};
device_processor->applyRGB(cR);
device_processor->applyRGB(cG);
device_processor->applyRGB(cB);
device_processor->applyRGB(cW);
processor->applyRGB(cR);
processor->applyRGB(cG);
processor->applyRGB(cB);
processor->applyRGB(cW);
/* Make sure that there is no channel crosstalk. */
if (fabsf(cR[1]) > 1e-5f || fabsf(cR[2]) > 1e-5f || fabsf(cG[0]) > 1e-5f ||
@@ -268,7 +267,6 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels,
/* TODO: implement faster version for when we know the conversion
* is a simple matrix transform between linear spaces. In that case
* un-premultiply is not needed. */
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
/* Process large images in chunks to keep temporary memory requirement down. */
const size_t chunk_size = std::min((size_t)(16 * 1024 * 1024), num_pixels);
@@ -291,7 +289,7 @@ inline void processor_apply_pixels(const OCIO::Processor *processor, T *pixels,
}
OCIO::PackedImageDesc desc((float *)float_pixels.data(), width, 1, 4);
device_processor->apply(desc);
processor->apply(desc);
for (size_t i = 0; i < width; i++) {
float4 value = float_pixels[i];
@@ -347,14 +345,13 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_,
const OCIO::Processor *processor = (const OCIO::Processor *)processor_;
if (processor) {
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
if (channels == 3) {
device_processor->applyRGB(pixel);
processor->applyRGB(pixel);
}
else if (channels == 4) {
if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
/* Fast path for RGBA. */
device_processor->applyRGB(pixel);
processor->applyRGB(pixel);
}
else {
/* Un-associate and associate alpha since color management should not
@@ -366,7 +363,7 @@ void ColorSpaceManager::to_scene_linear(ColorSpaceProcessor *processor_,
pixel[1] *= inv_alpha;
pixel[2] *= inv_alpha;
device_processor->applyRGB(pixel);
processor->applyRGB(pixel);
pixel[0] *= alpha;
pixel[1] *= alpha;

View File

@@ -688,16 +688,16 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce
void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes)
{
if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) {
scene->geometry_manager->tag_update(scene, GeometryManager::UV_PASS_NEEDED);
scene->geometry_manager->tag_update(scene);
foreach (Shader *shader, scene->shaders)
shader->need_update_uvs = true;
shader->need_update_geometry = true;
}
else if (Pass::contains(scene->passes, PASS_MOTION) != Pass::contains(passes_, PASS_MOTION)) {
scene->geometry_manager->tag_update(scene, GeometryManager::MOTION_PASS_NEEDED);
scene->geometry_manager->tag_update(scene);
}
else if (Pass::contains(scene->passes, PASS_AO) != Pass::contains(passes_, PASS_AO)) {
scene->integrator->tag_update(scene, Integrator::AO_PASS_MODIFIED);
scene->integrator->tag_update(scene);
}
if (update_passes) {

View File

@@ -240,6 +240,7 @@ void Geometry::compute_bvh(
}
}
clear_modified();
need_update_rebuild = false;
}
@@ -261,21 +262,22 @@ bool Geometry::has_voxel_attributes() const
void Geometry::tag_update(Scene *scene, bool rebuild)
{
tag_modified();
if (rebuild) {
need_update_rebuild = true;
scene->light_manager->tag_update(scene, LightManager::MESH_NEED_REBUILD);
scene->light_manager->need_update = true;
}
else {
foreach (Node *node, used_shaders) {
Shader *shader = static_cast<Shader *>(node);
if (shader->has_surface_emission) {
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
break;
}
if (shader->has_surface_emission)
scene->light_manager->need_update = true;
}
}
scene->geometry_manager->tag_update(scene, GeometryManager::GEOMETRY_MODIFIED);
scene->geometry_manager->need_update = true;
scene->object_manager->need_update = true;
}
void Geometry::tag_bvh_update(bool rebuild)
@@ -291,7 +293,7 @@ void Geometry::tag_bvh_update(bool rebuild)
GeometryManager::GeometryManager()
{
update_flags = UPDATE_ALL;
need_update = true;
need_flags_update = true;
}
@@ -492,10 +494,6 @@ void GeometryManager::update_svm_attributes(Device *,
if (attr_map_size == 0)
return;
if (!dscene->attributes_map.need_realloc()) {
return;
}
/* create attribute map */
uint4 *attr_map = dscene->attributes_map.alloc(attr_map_size);
memset(attr_map, 0, dscene->attributes_map.size() * sizeof(uint));
@@ -604,10 +602,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_uchar4_offset;
assert(attr_uchar4.size() >= offset + size);
if (mattr->modified) {
for (size_t k = 0; k < size; k++) {
attr_uchar4[offset + k] = data[k];
}
for (size_t k = 0; k < size; k++) {
attr_uchar4[offset + k] = data[k];
}
attr_uchar4_offset += size;
}
@@ -616,10 +612,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float_offset;
assert(attr_float.size() >= offset + size);
if (mattr->modified) {
for (size_t k = 0; k < size; k++) {
attr_float[offset + k] = data[k];
}
for (size_t k = 0; k < size; k++) {
attr_float[offset + k] = data[k];
}
attr_float_offset += size;
}
@@ -628,10 +622,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float2_offset;
assert(attr_float2.size() >= offset + size);
if (mattr->modified) {
for (size_t k = 0; k < size; k++) {
attr_float2[offset + k] = data[k];
}
for (size_t k = 0; k < size; k++) {
attr_float2[offset + k] = data[k];
}
attr_float2_offset += size;
}
@@ -640,10 +632,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float3_offset;
assert(attr_float3.size() >= offset + size * 3);
if (mattr->modified) {
for (size_t k = 0; k < size * 3; k++) {
attr_float3[offset + k] = (&tfm->x)[k];
}
for (size_t k = 0; k < size * 3; k++) {
attr_float3[offset + k] = (&tfm->x)[k];
}
attr_float3_offset += size * 3;
}
@@ -652,10 +642,8 @@ void GeometryManager::update_attribute_element_offset(Geometry *geom,
offset = attr_float3_offset;
assert(attr_float3.size() >= offset + size);
if (mattr->modified) {
for (size_t k = 0; k < size; k++) {
attr_float3[offset + k] = data[k];
}
for (size_t k = 0; k < size; k++) {
attr_float3[offset + k] = data[k];
}
attr_float3_offset += size;
}
@@ -820,11 +808,6 @@ void GeometryManager::device_update_attributes(Device *device,
dscene->attributes_float3.alloc(attr_float3_size);
dscene->attributes_uchar4.alloc(attr_uchar4_size);
const bool copy_all_data = dscene->attributes_float.need_realloc() ||
dscene->attributes_float2.need_realloc() ||
dscene->attributes_float3.need_realloc() ||
dscene->attributes_uchar4.need_realloc();
size_t attr_float_offset = 0;
size_t attr_float2_offset = 0;
size_t attr_float3_offset = 0;
@@ -839,12 +822,6 @@ void GeometryManager::device_update_attributes(Device *device,
* they actually refer to the same mesh attributes, optimize */
foreach (AttributeRequest &req, attributes.requests) {
Attribute *attr = geom->attributes.find(req);
if (attr) {
/* force a copy if we need to reallocate all the data */
attr->modified |= copy_all_data;
}
update_attribute_element_offset(geom,
dscene->attributes_float,
attr_float_offset,
@@ -863,11 +840,6 @@ void GeometryManager::device_update_attributes(Device *device,
Mesh *mesh = static_cast<Mesh *>(geom);
Attribute *subd_attr = mesh->subd_attributes.find(req);
if (subd_attr) {
/* force a copy if we need to reallocate all the data */
subd_attr->modified |= copy_all_data;
}
update_attribute_element_offset(mesh,
dscene->attributes_float,
attr_float_offset,
@@ -931,10 +903,18 @@ void GeometryManager::device_update_attributes(Device *device,
/* copy to device */
progress.set_status("Updating Mesh", "Copying Attributes to device");
dscene->attributes_float.copy_to_device();
dscene->attributes_float2.copy_to_device();
dscene->attributes_float3.copy_to_device();
dscene->attributes_uchar4.copy_to_device();
if (dscene->attributes_float.size()) {
dscene->attributes_float.copy_to_device();
}
if (dscene->attributes_float2.size()) {
dscene->attributes_float2.copy_to_device();
}
if (dscene->attributes_float3.size()) {
dscene->attributes_float3.copy_to_device();
}
if (dscene->attributes_uchar4.size()) {
dscene->attributes_uchar4.copy_to_device();
}
if (progress.get_cancel())
return;
@@ -1086,34 +1066,17 @@ void GeometryManager::device_update_mesh(
uint *tri_patch = dscene->tri_patch.alloc(tri_size);
float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size);
const bool copy_all_data = dscene->tri_shader.need_realloc() ||
dscene->tri_vindex.need_realloc() ||
dscene->tri_vnormal.need_realloc() ||
dscene->tri_patch.need_realloc() ||
dscene->tri_patch_uv.need_realloc();
foreach (Geometry *geom, scene->geometry) {
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->shader_is_modified() || mesh->smooth_is_modified() ||
mesh->triangles_is_modified() || copy_all_data) {
mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
}
if (mesh->verts_is_modified() || copy_all_data) {
mesh->pack_normals(&vnormal[mesh->vert_offset]);
}
if (mesh->triangles_is_modified() || mesh->vert_patch_uv_is_modified() || copy_all_data) {
mesh->pack_verts(tri_prim_index,
&tri_vindex[mesh->prim_offset],
&tri_patch[mesh->prim_offset],
&tri_patch_uv[mesh->vert_offset],
mesh->vert_offset,
mesh->prim_offset);
}
mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]);
mesh->pack_normals(&vnormal[mesh->vert_offset]);
mesh->pack_verts(tri_prim_index,
&tri_vindex[mesh->prim_offset],
&tri_patch[mesh->prim_offset],
&tri_patch_uv[mesh->vert_offset],
mesh->vert_offset,
mesh->prim_offset);
if (progress.get_cancel())
return;
}
@@ -1122,11 +1085,11 @@ void GeometryManager::device_update_mesh(
/* vertex coordinates */
progress.set_status("Updating Mesh", "Copying Mesh to device");
dscene->tri_shader.copy_to_device_if_modified();
dscene->tri_vnormal.copy_to_device_if_modified();
dscene->tri_vindex.copy_to_device_if_modified();
dscene->tri_patch.copy_to_device_if_modified();
dscene->tri_patch_uv.copy_to_device_if_modified();
dscene->tri_shader.copy_to_device();
dscene->tri_vnormal.copy_to_device();
dscene->tri_vindex.copy_to_device();
dscene->tri_patch.copy_to_device();
dscene->tri_patch_uv.copy_to_device();
}
if (curve_size != 0) {
@@ -1135,21 +1098,9 @@ void GeometryManager::device_update_mesh(
float4 *curve_keys = dscene->curve_keys.alloc(curve_key_size);
float4 *curves = dscene->curves.alloc(curve_size);
const bool copy_all_data = dscene->curve_keys.need_realloc() || dscene->curves.need_realloc();
foreach (Geometry *geom, scene->geometry) {
if (geom->is_hair()) {
Hair *hair = static_cast<Hair *>(geom);
bool curve_keys_co_modified = hair->curve_radius_is_modified() ||
hair->curve_keys_is_modified();
bool curve_data_modified = hair->curve_shader_is_modified() ||
hair->curve_first_key_is_modified();
if (!curve_keys_co_modified && !curve_data_modified && !copy_all_data) {
continue;
}
hair->pack_curves(scene,
&curve_keys[hair->curvekey_offset],
&curves[hair->prim_offset],
@@ -1159,11 +1110,11 @@ void GeometryManager::device_update_mesh(
}
}
dscene->curve_keys.copy_to_device_if_modified();
dscene->curves.copy_to_device_if_modified();
dscene->curve_keys.copy_to_device();
dscene->curves.copy_to_device();
}
if (patch_size != 0 && dscene->patches.need_realloc()) {
if (patch_size != 0) {
progress.set_status("Updating Mesh", "Copying Patches to device");
uint *patch_data = dscene->patches.alloc(patch_size);
@@ -1229,25 +1180,16 @@ void GeometryManager::device_update_bvh(Device *device,
VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout.";
const bool can_refit = scene->bvh != nullptr &&
(bparams.bvh_layout == BVHLayout::BVH_LAYOUT_OPTIX);
const bool pack_all = scene->bvh == nullptr;
BVH *bvh = scene->bvh;
if (!scene->bvh) {
bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
}
device->build_bvh(bvh, progress, can_refit);
delete scene->bvh;
BVH *bvh = scene->bvh = BVH::create(bparams, scene->geometry, scene->objects, device);
device->build_bvh(bvh, progress, false);
if (progress.get_cancel()) {
return;
}
const bool has_bvh2_layout = (bparams.bvh_layout == BVH_LAYOUT_BVH2);
PackedBVH pack;
if (has_bvh2_layout) {
if (bparams.bvh_layout == BVH_LAYOUT_BVH2) {
pack = std::move(static_cast<BVH2 *>(bvh)->pack);
}
else {
@@ -1268,22 +1210,12 @@ void GeometryManager::device_update_bvh(Device *device,
}
pack.root_index = -1;
if (!pack_all) {
/* if we do not need to recreate the BVH, then only the vertices are updated, so we can
* safely retake the memory */
dscene->prim_tri_verts.give_data(pack.prim_tri_verts);
}
else {
/* It is not strictly necessary to skip those resizes we if do not have to repack, as the OS
* will not allocate pages if we do not touch them, however it does help catching bugs. */
pack.prim_tri_index.resize(num_prims);
pack.prim_tri_verts.resize(num_tri_verts);
pack.prim_type.resize(num_prims);
pack.prim_index.resize(num_prims);
pack.prim_object.resize(num_prims);
pack.prim_visibility.resize(num_prims);
}
pack.prim_tri_index.reserve(num_prims);
pack.prim_tri_verts.reserve(num_tri_verts);
pack.prim_type.reserve(num_prims);
pack.prim_index.reserve(num_prims);
pack.prim_object.reserve(num_prims);
pack.prim_visibility.reserve(num_prims);
// Merge visibility flags of all objects and find object index for non-instanced geometry
unordered_map<const Geometry *, pair<int, uint>> geometry_to_object_info;
@@ -1297,27 +1229,17 @@ void GeometryManager::device_update_bvh(Device *device,
}
}
TaskPool pool;
// Iterate over scene mesh list instead of objects, since 'optix_prim_offset' was calculated
// based on that list, which may be ordered differently from the object list.
foreach (Geometry *geom, scene->geometry) {
if (!pack_all && !geom->is_modified()) {
continue;
}
const pair<int, uint> &info = geometry_to_object_info[geom];
pool.push(function_bind(
&Geometry::pack_primitives, geom, &pack, info.first, info.second, pack_all));
geom->pack_primitives(pack, info.first, info.second);
}
pool.wait_work();
}
/* copy to device */
progress.set_status("Updating Scene BVH", "Copying BVH to device");
/* When using BVH2, we always have to copy/update the data as its layout is dependent on the
* BVH's leaf nodes which may be different when the objects or vertices move. */
if (pack.nodes.size()) {
dscene->bvh_nodes.steal_data(pack.nodes);
dscene->bvh_nodes.copy_to_device();
@@ -1330,7 +1252,7 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->object_node.steal_data(pack.object_node);
dscene->object_node.copy_to_device();
}
if (pack.prim_tri_index.size() && (dscene->prim_tri_index.need_realloc() || has_bvh2_layout)) {
if (pack.prim_tri_index.size()) {
dscene->prim_tri_index.steal_data(pack.prim_tri_index);
dscene->prim_tri_index.copy_to_device();
}
@@ -1338,23 +1260,23 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->prim_tri_verts.steal_data(pack.prim_tri_verts);
dscene->prim_tri_verts.copy_to_device();
}
if (pack.prim_type.size() && (dscene->prim_type.need_realloc() || has_bvh2_layout)) {
if (pack.prim_type.size()) {
dscene->prim_type.steal_data(pack.prim_type);
dscene->prim_type.copy_to_device();
}
if (pack.prim_visibility.size() && (dscene->prim_visibility.need_realloc() || has_bvh2_layout)) {
if (pack.prim_visibility.size()) {
dscene->prim_visibility.steal_data(pack.prim_visibility);
dscene->prim_visibility.copy_to_device();
}
if (pack.prim_index.size() && (dscene->prim_index.need_realloc() || has_bvh2_layout)) {
if (pack.prim_index.size()) {
dscene->prim_index.steal_data(pack.prim_index);
dscene->prim_index.copy_to_device();
}
if (pack.prim_object.size() && (dscene->prim_object.need_realloc() || has_bvh2_layout)) {
if (pack.prim_object.size()) {
dscene->prim_object.steal_data(pack.prim_object);
dscene->prim_object.copy_to_device();
}
if (pack.prim_time.size() && (dscene->prim_time.need_realloc() || has_bvh2_layout)) {
if (pack.prim_time.size()) {
dscene->prim_time.steal_data(pack.prim_time);
dscene->prim_time.copy_to_device();
}
@@ -1367,65 +1289,12 @@ void GeometryManager::device_update_bvh(Device *device,
dscene->data.bvh.scene = NULL;
}
/* Set of flags used to help determining what data has been modified or needs reallocation, so we
* can decide which device data to free or update. */
enum {
DEVICE_CURVE_DATA_MODIFIED = (1 << 0),
DEVICE_MESH_DATA_MODIFIED = (1 << 1),
ATTR_FLOAT_MODIFIED = (1 << 2),
ATTR_FLOAT2_MODIFIED = (1 << 3),
ATTR_FLOAT3_MODIFIED = (1 << 4),
ATTR_UCHAR4_MODIFIED = (1 << 5),
CURVE_DATA_NEED_REALLOC = (1 << 6),
MESH_DATA_NEED_REALLOC = (1 << 7),
ATTR_FLOAT_NEEDS_REALLOC = (1 << 8),
ATTR_FLOAT2_NEEDS_REALLOC = (1 << 9),
ATTR_FLOAT3_NEEDS_REALLOC = (1 << 10),
ATTR_UCHAR4_NEEDS_REALLOC = (1 << 11),
ATTRS_NEED_REALLOC = (ATTR_FLOAT_NEEDS_REALLOC | ATTR_FLOAT2_NEEDS_REALLOC |
ATTR_FLOAT3_NEEDS_REALLOC | ATTR_UCHAR4_NEEDS_REALLOC),
DEVICE_MESH_DATA_NEEDS_REALLOC = (CURVE_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
DEVICE_CURVE_DATA_NEEDS_REALLOC = (MESH_DATA_NEED_REALLOC | ATTRS_NEED_REALLOC),
};
static void update_device_flags_attribute(uint32_t &device_update_flags,
const AttributeSet &attributes)
{
foreach (const Attribute &attr, attributes.attributes) {
if (!attr.modified) {
continue;
}
if (attr.element == ATTR_ELEMENT_CORNER) {
device_update_flags |= ATTR_UCHAR4_MODIFIED;
}
else if (attr.type == TypeDesc::TypeFloat) {
device_update_flags |= ATTR_FLOAT_MODIFIED;
}
else if (attr.type == TypeFloat2) {
device_update_flags |= ATTR_FLOAT2_MODIFIED;
}
else if (attr.type == TypeDesc::TypeMatrix) {
device_update_flags |= ATTR_FLOAT3_MODIFIED;
}
else if (attr.element != ATTR_ELEMENT_VOXEL) {
device_update_flags |= ATTR_FLOAT3_MODIFIED;
}
}
}
void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Progress &progress)
{
if (!need_update() && !need_flags_update) {
if (!need_update && !need_flags_update) {
return;
}
uint32_t device_update_flags = 0;
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->geometry.times.add_entry({"device_update_preprocess", time});
@@ -1445,54 +1314,9 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
if (shader->has_volume) {
geom->has_volume = true;
}
if (shader->has_surface_bssrdf) {
geom->has_surface_bssrdf = true;
}
if (shader->need_update_uvs) {
device_update_flags |= ATTR_FLOAT2_NEEDS_REALLOC;
/* Attributes might need to be tesselated if added. */
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->need_tesselation()) {
mesh->tag_modified();
}
}
}
if (shader->need_update_attribute) {
device_update_flags |= ATTRS_NEED_REALLOC;
/* Attributes might need to be tesselated if added. */
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->need_tesselation()) {
mesh->tag_modified();
}
}
}
if (shader->need_update_displacement) {
/* tag displacement related sockets as modified */
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
mesh->tag_verts_modified();
mesh->tag_subd_dicing_rate_modified();
mesh->tag_subd_max_level_modified();
mesh->tag_subd_objecttoworld_modified();
device_update_flags |= ATTRS_NEED_REALLOC;
}
}
}
/* only check for modified attributes if we do not need to reallocate them already */
if ((device_update_flags & ATTRS_NEED_REALLOC) == 0) {
update_device_flags_attribute(device_update_flags, geom->attributes);
/* don't check for subd_attributes, as if they were modified, we would need to reallocate
* anyway */
}
/* Re-create volume mesh if we will rebuild or refit the BVH. Note we
@@ -1508,119 +1332,13 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
Volume *volume = static_cast<Volume *>(geom);
create_volume_mesh(volume, progress);
/* always reallocate when we have a volume, as we need to rebuild the BVH */
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
}
if (geom->is_hair()) {
/* Set curve shape, still a global scene setting for now. */
Hair *hair = static_cast<Hair *>(geom);
hair->curve_shape = scene->params.hair_shape;
if (hair->need_update_rebuild) {
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
}
else if (hair->is_modified()) {
device_update_flags |= DEVICE_CURVE_DATA_MODIFIED;
}
}
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
if (mesh->need_update_rebuild) {
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
}
else if (mesh->is_modified()) {
device_update_flags |= DEVICE_MESH_DATA_MODIFIED;
}
}
}
if (update_flags & (MESH_ADDED | MESH_REMOVED)) {
device_update_flags |= DEVICE_MESH_DATA_NEEDS_REALLOC;
}
if (update_flags & (HAIR_ADDED | HAIR_REMOVED)) {
device_update_flags |= DEVICE_CURVE_DATA_NEEDS_REALLOC;
}
/* tag the device arrays for reallocation or modification */
DeviceScene *dscene = &scene->dscene;
if (device_update_flags & (DEVICE_MESH_DATA_NEEDS_REALLOC | DEVICE_CURVE_DATA_NEEDS_REALLOC)) {
delete scene->bvh;
scene->bvh = nullptr;
dscene->bvh_nodes.tag_realloc();
dscene->bvh_leaf_nodes.tag_realloc();
dscene->object_node.tag_realloc();
dscene->prim_tri_verts.tag_realloc();
dscene->prim_tri_index.tag_realloc();
dscene->prim_type.tag_realloc();
dscene->prim_visibility.tag_realloc();
dscene->prim_index.tag_realloc();
dscene->prim_object.tag_realloc();
dscene->prim_time.tag_realloc();
if (device_update_flags & DEVICE_MESH_DATA_NEEDS_REALLOC) {
dscene->tri_vnormal.tag_realloc();
dscene->tri_vindex.tag_realloc();
dscene->tri_patch.tag_realloc();
dscene->tri_vnormal.tag_realloc();
dscene->tri_patch_uv.tag_realloc();
dscene->patches.tag_realloc();
}
if (device_update_flags & DEVICE_CURVE_DATA_NEEDS_REALLOC) {
dscene->curves.tag_realloc();
dscene->curve_keys.tag_realloc();
}
}
if (device_update_flags & ATTR_FLOAT_NEEDS_REALLOC) {
dscene->attributes_map.tag_realloc();
dscene->attributes_float.tag_realloc();
}
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
dscene->attributes_float.tag_modified();
}
if (device_update_flags & ATTR_FLOAT2_NEEDS_REALLOC) {
dscene->attributes_map.tag_realloc();
dscene->attributes_float2.tag_realloc();
}
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
dscene->attributes_float.tag_modified();
}
if (device_update_flags & ATTR_FLOAT3_NEEDS_REALLOC) {
dscene->attributes_map.tag_realloc();
dscene->attributes_float3.tag_realloc();
}
else if (device_update_flags & ATTR_FLOAT_MODIFIED) {
dscene->attributes_float.tag_modified();
}
if (device_update_flags & ATTR_UCHAR4_NEEDS_REALLOC) {
dscene->attributes_map.tag_realloc();
dscene->attributes_uchar4.tag_realloc();
}
else if (device_update_flags & ATTR_UCHAR4_MODIFIED) {
dscene->attributes_uchar4.tag_modified();
}
if (device_update_flags & DEVICE_MESH_DATA_MODIFIED) {
/* if anything else than vertices or shaders are modified, we would need to reallocate, so
* these are the only arrays that can be updated */
dscene->tri_vnormal.tag_modified();
dscene->tri_shader.tag_modified();
}
if (device_update_flags & DEVICE_CURVE_DATA_MODIFIED) {
dscene->curve_keys.tag_modified();
dscene->curves.tag_modified();
}
need_flags_update = false;
@@ -1705,7 +1423,7 @@ void GeometryManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
VLOG(1) << "Total " << scene->geometry.size() << " meshes.";
@@ -1721,6 +1439,12 @@ void GeometryManager::device_update(Device *device,
});
foreach (Geometry *geom, scene->geometry) {
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->need_update_geometry)
geom->tag_modified();
}
if (geom->is_modified() &&
(geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) {
Mesh *mesh = static_cast<Mesh *>(geom);
@@ -1817,7 +1541,7 @@ void GeometryManager::device_update(Device *device,
}
/* Device update. */
device_free(device, dscene, false);
device_free(device, dscene);
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
device->get_bvh_layout_mask());
@@ -1890,7 +1614,7 @@ void GeometryManager::device_update(Device *device,
{"device_update (displacement: attributes)", time});
}
});
device_free(device, dscene, false);
device_free(device, dscene);
device_update_attributes(device, dscene, scene, progress);
if (progress.get_cancel()) {
@@ -1898,9 +1622,6 @@ void GeometryManager::device_update(Device *device,
}
}
/* update the bvh even when there is no geometry so the kernel bvh data is still valid,
* especially when removing all of the objects during interactive renders */
bool need_update_scene_bvh = (scene->bvh == nullptr);
{
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
@@ -1912,7 +1633,6 @@ void GeometryManager::device_update(Device *device,
size_t i = 0;
foreach (Geometry *geom, scene->geometry) {
if (geom->is_modified()) {
need_update_scene_bvh = true;
pool.push(function_bind(
&Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh));
if (geom->need_build_bvh(bvh_layout)) {
@@ -1927,9 +1647,7 @@ void GeometryManager::device_update(Device *device,
}
foreach (Shader *shader, scene->shaders) {
shader->need_update_uvs = false;
shader->need_update_attribute = false;
shader->need_update_displacement = false;
shader->need_update_geometry = false;
}
Scene::MotionType need_motion = scene->need_motion();
@@ -1952,7 +1670,7 @@ void GeometryManager::device_update(Device *device,
return;
}
if (need_update_scene_bvh) {
{
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->geometry.times.add_entry({"device_update (build scene BVH)", time});
@@ -1977,6 +1695,8 @@ void GeometryManager::device_update(Device *device,
}
}
need_update = false;
if (true_displacement_used) {
/* Re-tag flags for update, so they're re-evaluated
* for meshes with correct bounding boxes.
@@ -1986,71 +1706,33 @@ void GeometryManager::device_update(Device *device,
*/
scene->object_manager->need_flags_update = old_need_object_flags_update;
}
/* unset flags */
foreach (Geometry *geom, scene->geometry) {
geom->clear_modified();
geom->attributes.clear_modified();
if (geom->is_mesh()) {
Mesh *mesh = static_cast<Mesh *>(geom);
mesh->subd_attributes.clear_modified();
}
}
update_flags = UPDATE_NONE;
dscene->bvh_nodes.clear_modified();
dscene->bvh_leaf_nodes.clear_modified();
dscene->object_node.clear_modified();
dscene->prim_tri_verts.clear_modified();
dscene->prim_tri_index.clear_modified();
dscene->prim_type.clear_modified();
dscene->prim_visibility.clear_modified();
dscene->prim_index.clear_modified();
dscene->prim_object.clear_modified();
dscene->prim_time.clear_modified();
dscene->tri_shader.clear_modified();
dscene->tri_vindex.clear_modified();
dscene->tri_patch.clear_modified();
dscene->tri_vnormal.clear_modified();
dscene->tri_patch_uv.clear_modified();
dscene->curves.clear_modified();
dscene->curve_keys.clear_modified();
dscene->patches.clear_modified();
dscene->attributes_map.clear_modified();
dscene->attributes_float.clear_modified();
dscene->attributes_float2.clear_modified();
dscene->attributes_float3.clear_modified();
dscene->attributes_uchar4.clear_modified();
}
void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool force_free)
void GeometryManager::device_free(Device *device, DeviceScene *dscene)
{
dscene->bvh_nodes.free_if_need_realloc(force_free);
dscene->bvh_leaf_nodes.free_if_need_realloc(force_free);
dscene->object_node.free_if_need_realloc(force_free);
dscene->prim_tri_verts.free_if_need_realloc(force_free);
dscene->prim_tri_index.free_if_need_realloc(force_free);
dscene->prim_type.free_if_need_realloc(force_free);
dscene->prim_visibility.free_if_need_realloc(force_free);
dscene->prim_index.free_if_need_realloc(force_free);
dscene->prim_object.free_if_need_realloc(force_free);
dscene->prim_time.free_if_need_realloc(force_free);
dscene->tri_shader.free_if_need_realloc(force_free);
dscene->tri_vnormal.free_if_need_realloc(force_free);
dscene->tri_vindex.free_if_need_realloc(force_free);
dscene->tri_patch.free_if_need_realloc(force_free);
dscene->tri_patch_uv.free_if_need_realloc(force_free);
dscene->curves.free_if_need_realloc(force_free);
dscene->curve_keys.free_if_need_realloc(force_free);
dscene->patches.free_if_need_realloc(force_free);
dscene->attributes_map.free_if_need_realloc(force_free);
dscene->attributes_float.free_if_need_realloc(force_free);
dscene->attributes_float2.free_if_need_realloc(force_free);
dscene->attributes_float3.free_if_need_realloc(force_free);
dscene->attributes_uchar4.free_if_need_realloc(force_free);
dscene->bvh_nodes.free();
dscene->bvh_leaf_nodes.free();
dscene->object_node.free();
dscene->prim_tri_verts.free();
dscene->prim_tri_index.free();
dscene->prim_type.free();
dscene->prim_visibility.free();
dscene->prim_index.free();
dscene->prim_object.free();
dscene->prim_time.free();
dscene->tri_shader.free();
dscene->tri_vnormal.free();
dscene->tri_vindex.free();
dscene->tri_patch.free();
dscene->tri_patch_uv.free();
dscene->curves.free();
dscene->curve_keys.free();
dscene->patches.free();
dscene->attributes_map.free();
dscene->attributes_float.free();
dscene->attributes_float2.free();
dscene->attributes_float3.free();
dscene->attributes_uchar4.free();
/* Signal for shaders like displacement not to do ray tracing. */
dscene->data.bvh.bvh_layout = BVH_LAYOUT_NONE;
@@ -2068,19 +1750,10 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
#endif
}
void GeometryManager::tag_update(Scene *scene, uint32_t flag)
void GeometryManager::tag_update(Scene *scene)
{
update_flags |= flag;
/* do not tag the object manager for an update if it is the one who tagged us */
if ((flag & OBJECT_MANAGER) == 0) {
scene->object_manager->tag_update(scene, ObjectManager::GEOMETRY_MANAGER);
}
}
bool GeometryManager::need_update() const
{
return update_flags != UPDATE_NONE;
need_update = true;
scene->object_manager->need_update = true;
}
void GeometryManager::collect_statistics(const Scene *scene, RenderStats *stats)

View File

@@ -125,7 +125,7 @@ class Geometry : public Node {
int n,
int total);
virtual void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) = 0;
virtual void pack_primitives(PackedBVH &pack, int object, uint visibility) = 0;
/* Check whether the geometry should have own BVH built separately. Briefly,
* own BVH is needed for geometry, if:
@@ -155,11 +155,6 @@ class Geometry : public Node {
return geometry_type == HAIR;
}
bool is_volume() const
{
return geometry_type == VOLUME;
}
/* Updates */
void tag_update(Scene *scene, bool rebuild);
@@ -169,32 +164,9 @@ class Geometry : public Node {
/* Geometry Manager */
class GeometryManager {
uint32_t update_flags;
public:
enum : uint32_t {
UV_PASS_NEEDED = (1 << 0),
MOTION_PASS_NEEDED = (1 << 1),
GEOMETRY_MODIFIED = (1 << 2),
OBJECT_MANAGER = (1 << 3),
MESH_ADDED = (1 << 4),
MESH_REMOVED = (1 << 5),
HAIR_ADDED = (1 << 6),
HAIR_REMOVED = (1 << 7),
SHADER_ATTRIBUTE_MODIFIED = (1 << 8),
SHADER_DISPLACEMENT_MODIFIED = (1 << 9),
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
/* Update Flags */
bool need_update;
bool need_flags_update;
/* Constructor/Destructor */
@@ -204,12 +176,10 @@ class GeometryManager {
/* Device Updates */
void device_update_preprocess(Device *device, Scene *scene, Progress &progress);
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, bool force_free);
void device_free(Device *device, DeviceScene *dscene);
/* Updates */
void tag_update(Scene *scene, uint32_t flag);
bool need_update() const;
void tag_update(Scene *scene);
/* Statistics */
void collect_statistics(const Scene *scene, RenderStats *stats);

View File

@@ -494,38 +494,33 @@ void Hair::pack_curves(Scene *scene,
}
}
void Hair::pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all)
void Hair::pack_primitives(PackedBVH &pack, int object, uint visibility)
{
if (curve_first_key.empty())
return;
/* If the BVH does not have to be recreated, we can bail out. */
if (!pack_all) {
return;
}
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
int *prim_type = &pack->prim_type[optix_prim_offset];
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
int *prim_index = &pack->prim_index[optix_prim_offset];
int *prim_object = &pack->prim_object[optix_prim_offset];
// 'pack->prim_time' is unused by Embree and OptiX
const size_t num_prims = num_segments();
pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
pack.prim_type.reserve(pack.prim_type.size() + num_prims);
pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
pack.prim_index.reserve(pack.prim_index.size() + num_prims);
pack.prim_object.reserve(pack.prim_object.size() + num_prims);
// 'pack.prim_time' is unused by Embree and OptiX
uint type = has_motion_blur() ?
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON :
PRIMITIVE_MOTION_CURVE_THICK) :
((curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK);
size_t index = 0;
for (size_t j = 0; j < num_curves(); ++j) {
Curve curve = get_curve(j);
for (size_t k = 0; k < curve.num_segments(); ++k, ++index) {
prim_tri_index[index] = -1;
prim_type[index] = PRIMITIVE_PACK_SEGMENT(type, k);
prim_visibility[index] = visibility;
for (size_t k = 0; k < curve.num_segments(); ++k) {
pack.prim_tri_index.push_back_reserved(-1);
pack.prim_type.push_back_reserved(PRIMITIVE_PACK_SEGMENT(type, k));
pack.prim_visibility.push_back_reserved(visibility);
// Each curve segment points back to its curve index
prim_index[index] = j + prim_offset;
prim_object[index] = object;
pack.prim_index.push_back_reserved(j + prim_offset);
pack.prim_object.push_back_reserved(object);
}
}
}

View File

@@ -146,7 +146,7 @@ class Hair : public Geometry {
/* BVH */
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
};
CCL_NAMESPACE_END

View File

@@ -298,7 +298,7 @@ bool ImageLoader::is_vdb_loader() const
ImageManager::ImageManager(const DeviceInfo &info)
{
need_update_ = true;
need_update = true;
osl_texture_system = NULL;
animation_frame = 0;
@@ -451,7 +451,7 @@ int ImageManager::add_image_slot(ImageLoader *loader,
images[slot] = img;
need_update_ = true;
need_update = true;
return slot;
}
@@ -478,7 +478,7 @@ void ImageManager::remove_image_user(int slot)
* the reasons for this is that on shader changes we add and remove nodes
* that use them, but we do not want to reload the image all the time. */
if (image->users == 0)
need_update_ = true;
need_update = true;
}
static bool image_associate_alpha(ImageManager::Image *img)
@@ -810,7 +810,7 @@ void ImageManager::device_free_image(Device *, int slot)
void ImageManager::device_update(Device *device, Scene *scene, Progress &progress)
{
if (!need_update()) {
if (!need_update) {
return;
}
@@ -834,7 +834,7 @@ void ImageManager::device_update(Device *device, Scene *scene, Progress &progres
pool.wait_work();
need_update_ = false;
need_update = false;
}
void ImageManager::device_update_slot(Device *device, Scene *scene, int slot, Progress *progress)
@@ -854,7 +854,7 @@ void ImageManager::device_load_builtin(Device *device, Scene *scene, Progress &p
{
/* Load only builtin images, Blender needs this to load evaluated
* scene data from depsgraph before it is freed. */
if (!need_update()) {
if (!need_update) {
return;
}
@@ -896,14 +896,4 @@ void ImageManager::collect_statistics(RenderStats *stats)
}
}
void ImageManager::tag_update()
{
need_update_ = true;
}
bool ImageManager::need_update() const
{
return need_update_;
}
CCL_NAMESPACE_END

View File

@@ -189,9 +189,7 @@ class ImageManager {
void collect_statistics(RenderStats *stats);
void tag_update();
bool need_update() const;
bool need_update;
struct Image {
ImageParams params;
@@ -211,7 +209,6 @@ class ImageManager {
};
private:
bool need_update_;
bool has_half_images;
thread_mutex device_mutex;

View File

@@ -17,11 +17,9 @@
#include "render/integrator.h"
#include "device/device.h"
#include "render/background.h"
#include "render/camera.h"
#include "render/film.h"
#include "render/jitter.h"
#include "render/light.h"
#include "render/object.h"
#include "render/scene.h"
#include "render/shader.h"
#include "render/sobol.h"
@@ -115,18 +113,6 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
}
});
const bool need_update_lut = ao_samples_is_modified() || diffuse_samples_is_modified() ||
glossy_samples_is_modified() || max_bounce_is_modified() ||
max_transmission_bounce_is_modified() ||
mesh_light_samples_is_modified() || method_is_modified() ||
sampling_pattern_is_modified() ||
subsurface_samples_is_modified() ||
transmission_samples_is_modified() || volume_samples_is_modified();
if (need_update_lut) {
dscene->sample_pattern_lut.tag_realloc();
}
device_free(device, dscene);
KernelIntegrator *kintegrator = &dscene->data.integrator;
@@ -182,7 +168,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
FLT_MAX :
sample_clamp_indirect * 3.0f;
kintegrator->branched = (method == BRANCHED_PATH) && device->info.has_branched_path;
kintegrator->branched = (method == BRANCHED_PATH);
kintegrator->volume_decoupled = device->info.has_volume_decoupled;
kintegrator->diffuse_samples = diffuse_samples;
kintegrator->glossy_samples = glossy_samples;
@@ -193,7 +179,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
kintegrator->volume_samples = volume_samples;
kintegrator->start_sample = start_sample;
if (kintegrator->branched) {
if (method == BRANCHED_PATH) {
kintegrator->sample_all_lights_direct = sample_all_lights_direct;
kintegrator->sample_all_lights_indirect = sample_all_lights_indirect;
}
@@ -238,7 +224,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
/* sobol directions table */
int max_samples = 1;
if (kintegrator->branched) {
if (method == BRANCHED_PATH) {
foreach (Light *light, scene->lights)
max_samples = max(max_samples, light->get_samples());
@@ -256,69 +242,45 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
int dimensions = PRNG_BASE_NUM + max_samples * PRNG_BOUNCE_NUM;
dimensions = min(dimensions, SOBOL_MAX_DIMENSIONS);
if (need_update_lut) {
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
if (sampling_pattern == SAMPLING_PATTERN_SOBOL) {
uint *directions = dscene->sample_pattern_lut.alloc(SOBOL_BITS * dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
sobol_generate_direction_vectors((uint(*)[SOBOL_BITS])directions, dimensions);
dscene->sample_pattern_lut.copy_to_device();
}
else {
constexpr int sequence_size = NUM_PMJ_SAMPLES;
constexpr int num_sequences = NUM_PMJ_PATTERNS;
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size *
num_sequences * 2);
TaskPool pool;
for (int j = 0; j < num_sequences; ++j) {
float2 *sequence = directions + j * sequence_size;
pool.push(
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
}
pool.wait_work();
dscene->sample_pattern_lut.copy_to_device();
dscene->sample_pattern_lut.copy_to_device();
}
else {
constexpr int sequence_size = NUM_PMJ_SAMPLES;
constexpr int num_sequences = NUM_PMJ_PATTERNS;
float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences *
2);
TaskPool pool;
for (int j = 0; j < num_sequences; ++j) {
float2 *sequence = directions + j * sequence_size;
pool.push(
function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j));
}
pool.wait_work();
dscene->sample_pattern_lut.copy_to_device();
}
dscene->sample_pattern_lut.clear_modified();
clear_modified();
}
void Integrator::device_free(Device *, DeviceScene *dscene, bool force_free)
void Integrator::device_free(Device *, DeviceScene *dscene)
{
dscene->sample_pattern_lut.free_if_need_realloc(force_free);
dscene->sample_pattern_lut.free();
}
void Integrator::tag_update(Scene *scene, uint32_t flag)
void Integrator::tag_update(Scene *scene)
{
if (flag & UPDATE_ALL) {
tag_modified();
}
if (flag & (AO_PASS_MODIFIED | BACKGROUND_AO_MODIFIED)) {
/* tag only the ao_bounces socket as modified so we avoid updating sample_pattern_lut
* unnecessarily */
tag_ao_bounces_modified();
}
if ((flag & LIGHT_SAMPLES_MODIFIED) && (method == BRANCHED_PATH)) {
/* the number of light samples may affect the size of the sample_pattern_lut */
tag_sampling_pattern_modified();
}
if (filter_glossy_is_modified()) {
foreach (Shader *shader, scene->shaders) {
if (shader->has_integrator_dependency) {
scene->shader_manager->tag_update(scene, ShaderManager::INTEGRATOR_MODIFIED);
break;
}
foreach (Shader *shader, scene->shaders) {
if (shader->has_integrator_dependency) {
scene->shader_manager->need_update = true;
break;
}
}
if (motion_blur_is_modified()) {
scene->object_manager->tag_update(scene, ObjectManager::MOTION_BLUR_MODIFIED);
scene->camera->tag_modified();
}
tag_modified();
}
CCL_NAMESPACE_END

View File

@@ -89,24 +89,13 @@ class Integrator : public Node {
NODE_SOCKET_API(SamplingPattern, sampling_pattern)
enum : uint32_t {
AO_PASS_MODIFIED = (1 << 0),
BACKGROUND_AO_MODIFIED = (1 << 1),
LIGHT_SAMPLES_MODIFIED = (1 << 2),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
Integrator();
~Integrator();
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene, bool force_free = false);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene, uint32_t flag);
void tag_update(Scene *scene);
};
CCL_NAMESPACE_END

View File

@@ -162,13 +162,7 @@ Light::Light() : Node(node_type)
void Light::tag_update(Scene *scene)
{
if (is_modified()) {
scene->light_manager->tag_update(scene, LightManager::LIGHT_MODIFIED);
if (samples_is_modified()) {
scene->integrator->tag_update(scene, Integrator::LIGHT_SAMPLES_MODIFIED);
}
}
scene->light_manager->need_update = is_modified();
}
bool Light::has_contribution(Scene *scene)
@@ -189,7 +183,7 @@ bool Light::has_contribution(Scene *scene)
LightManager::LightManager()
{
update_flags = UPDATE_ALL;
need_update = true;
need_update_background = true;
use_light_visibility = false;
last_background_enabled = false;
@@ -968,7 +962,7 @@ void LightManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -1006,7 +1000,7 @@ void LightManager::device_update(Device *device,
scene->film->set_use_light_visibility(use_light_visibility);
update_flags = UPDATE_NONE;
need_update = false;
need_update_background = false;
}
@@ -1021,14 +1015,9 @@ void LightManager::device_free(Device *, DeviceScene *dscene, const bool free_ba
dscene->ies_lights.free();
}
void LightManager::tag_update(Scene * /*scene*/, uint32_t flag)
void LightManager::tag_update(Scene * /*scene*/)
{
update_flags |= flag;
}
bool LightManager::need_update() const
{
return update_flags != UPDATE_NONE;
need_update = true;
}
int LightManager::add_ies_from_file(const string &filename)
@@ -1074,7 +1063,7 @@ int LightManager::add_ies(const string &content)
ies_slots[slot]->users = 1;
ies_slots[slot]->hash = hash;
update_flags = UPDATE_ALL;
need_update = true;
need_update_background = true;
return slot;
@@ -1093,10 +1082,8 @@ void LightManager::remove_ies(int slot)
ies_slots[slot]->users--;
/* If the slot has no more users, update the device to remove it. */
if (ies_slots[slot]->users == 0) {
update_flags |= UPDATE_ALL;
need_update_background = true;
}
need_update |= (ies_slots[slot]->users == 0);
need_update_background |= need_update;
}
void LightManager::device_update_ies(DeviceScene *dscene)

View File

@@ -91,23 +91,8 @@ class Light : public Node {
class LightManager {
public:
enum : uint32_t {
MESH_NEED_REBUILD = (1 << 0),
EMISSIVE_MESH_MODIFIED = (1 << 1),
LIGHT_MODIFIED = (1 << 2),
LIGHT_ADDED = (1 << 3),
LIGHT_REMOVED = (1 << 4),
OBJECT_MANAGER = (1 << 5),
SHADER_COMPILED = (1 << 6),
SHADER_MODIFIED = (1 << 7),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
bool use_light_visibility;
bool need_update;
/* Need to update background (including multiple importance map) */
bool need_update_background;
@@ -123,9 +108,7 @@ class LightManager {
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
void device_free(Device *device, DeviceScene *dscene, const bool free_background = true);
void tag_update(Scene *scene, uint32_t flag);
bool need_update() const;
void tag_update(Scene *scene);
/* Check whether there is a background light. */
bool has_background_light(Scene *scene);
@@ -162,8 +145,6 @@ class LightManager {
bool last_background_enabled;
int last_background_resolution;
uint32_t update_flags;
};
CCL_NAMESPACE_END

View File

@@ -805,42 +805,34 @@ void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, ui
}
}
void Mesh::pack_primitives(ccl::PackedBVH *pack, int object, uint visibility, bool pack_all)
void Mesh::pack_primitives(PackedBVH &pack, int object, uint visibility)
{
if (triangles.empty())
return;
const size_t num_prims = num_triangles();
/* Use prim_offset for indexing as it is computed per geometry type, and prim_tri_verts does not
* contain data for Hair geometries. */
float4 *prim_tri_verts = &pack->prim_tri_verts[prim_offset * 3];
// 'pack->prim_time' is unused by Embree and OptiX
pack.prim_tri_index.reserve(pack.prim_tri_index.size() + num_prims);
pack.prim_tri_verts.reserve(pack.prim_tri_verts.size() + num_prims * 3);
pack.prim_type.reserve(pack.prim_type.size() + num_prims);
pack.prim_visibility.reserve(pack.prim_visibility.size() + num_prims);
pack.prim_index.reserve(pack.prim_index.size() + num_prims);
pack.prim_object.reserve(pack.prim_object.size() + num_prims);
// 'pack.prim_time' is unused by Embree and OptiX
uint type = has_motion_blur() ? PRIMITIVE_MOTION_TRIANGLE : PRIMITIVE_TRIANGLE;
if (pack_all) {
/* Use optix_prim_offset for indexing as those arrays also contain data for Hair geometries. */
unsigned int *prim_tri_index = &pack->prim_tri_index[optix_prim_offset];
int *prim_type = &pack->prim_type[optix_prim_offset];
unsigned int *prim_visibility = &pack->prim_visibility[optix_prim_offset];
int *prim_index = &pack->prim_index[optix_prim_offset];
int *prim_object = &pack->prim_object[optix_prim_offset];
for (size_t k = 0; k < num_prims; ++k) {
prim_tri_index[k] = (prim_offset + k) * 3;
prim_type[k] = type;
prim_index[k] = prim_offset + k;
prim_object[k] = object;
prim_visibility[k] = visibility;
}
}
for (size_t k = 0; k < num_prims; ++k) {
pack.prim_tri_index.push_back_reserved(pack.prim_tri_verts.size());
const Mesh::Triangle t = get_triangle(k);
prim_tri_verts[k * 3] = float3_to_float4(verts[t.v[0]]);
prim_tri_verts[k * 3 + 1] = float3_to_float4(verts[t.v[1]]);
prim_tri_verts[k * 3 + 2] = float3_to_float4(verts[t.v[2]]);
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[0]]));
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[1]]));
pack.prim_tri_verts.push_back_reserved(float3_to_float4(verts[t.v[2]]));
pack.prim_type.push_back_reserved(type);
pack.prim_visibility.push_back_reserved(visibility);
pack.prim_index.push_back_reserved(k + prim_offset);
pack.prim_object.push_back_reserved(object);
}
}

View File

@@ -232,7 +232,7 @@ class Mesh : public Geometry {
size_t tri_offset);
void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset);
void pack_primitives(PackedBVH *pack, int object, uint visibility, bool pack_all) override;
void pack_primitives(PackedBVH &pack, int object, uint visibility) override;
void tessellate(DiagSplit *split);

View File

@@ -153,10 +153,6 @@ void Object::update_motion()
void Object::compute_bounds(bool motion_blur)
{
if (!is_modified() && !geometry->is_modified()) {
return;
}
BoundBox mbounds = geometry->bounds;
if (motion_blur && use_motion()) {
@@ -209,39 +205,20 @@ void Object::apply_transform(bool apply_to_motion)
void Object::tag_update(Scene *scene)
{
uint32_t flag = ObjectManager::UPDATE_NONE;
if (is_modified()) {
flag |= ObjectManager::OBJECT_MODIFIED;
if (use_holdout_is_modified()) {
flag |= ObjectManager::HOLDOUT_MODIFIED;
}
}
if (geometry) {
if (tfm_is_modified()) {
/* tag the geometry as modified so the BVH is updated, but do not tag everything as modified
*/
if (geometry->is_mesh() || geometry->is_volume()) {
Mesh *mesh = static_cast<Mesh *>(geometry);
mesh->tag_verts_modified();
}
else if (geometry->is_hair()) {
Hair *hair = static_cast<Hair *>(geometry);
hair->tag_curve_keys_modified();
}
}
if (geometry->transform_applied)
geometry->tag_modified();
foreach (Node *node, geometry->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->tag_update(scene, LightManager::EMISSIVE_MESH_MODIFIED);
scene->light_manager->need_update = true;
}
}
scene->camera->need_flags_update = true;
scene->object_manager->tag_update(scene, flag);
scene->geometry_manager->need_update = true;
scene->object_manager->need_update = true;
}
bool Object::use_motion() const
@@ -384,7 +361,7 @@ int Object::get_device_index() const
ObjectManager::ObjectManager()
{
update_flags = UPDATE_ALL;
need_update = true;
need_flags_update = true;
}
@@ -405,9 +382,7 @@ static float object_volume_density(const Transform &tfm, Geometry *geom)
return 1.0f;
}
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state,
Object *ob,
bool update_all)
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
{
KernelObject &kobject = state->objects[ob->index];
Transform *object_motion_pass = state->object_motion_pass;
@@ -481,11 +456,8 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
kobject.motion_offset = state->motion_offset[ob->index];
/* Decompose transforms for interpolation. */
if (ob->tfm_is_modified() || update_all) {
DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
}
DecomposedTransform *decomp = state->object_motion + kobject.motion_offset;
transform_motion_decompose(decomp, ob->motion.data(), ob->motion.size());
flag |= SD_OBJECT_MOTION;
state->have_motion = true;
}
@@ -508,14 +480,10 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
0;
kobject.patch_map_offset = 0;
kobject.attribute_map_offset = 0;
if (ob->asset_name_is_modified() || update_all) {
uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
kobject.cryptomatte_object = util_hash_to_float(hash_name);
kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
}
uint32_t hash_name = util_murmur_hash3(ob->name.c_str(), ob->name.length(), 0);
uint32_t hash_asset = util_murmur_hash3(ob->asset_name.c_str(), ob->asset_name.length(), 0);
kobject.cryptomatte_object = util_hash_to_float(hash_name);
kobject.cryptomatte_asset = util_hash_to_float(hash_asset);
kobject.shadow_terminator_offset = 1.0f / (1.0f - 0.5f * ob->shadow_terminator_offset);
/* Object flag. */
@@ -576,9 +544,6 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
numparticles += psys->particles.size();
}
/* as all the arrays are the same size, checking only dscene.objects is sufficient */
const bool update_all = dscene->objects.need_realloc();
/* Parallel object update, with grain size to avoid too much threading overhead
* for individual objects. */
static const int OBJECTS_PER_TASK = 32;
@@ -586,7 +551,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
[&](const blocked_range<size_t> &r) {
for (size_t i = r.begin(); i != r.end(); i++) {
Object *ob = state.scene->objects[i];
device_update_object_transform(&state, ob, update_all);
device_update_object_transform(&state, ob);
}
});
@@ -594,7 +559,7 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
return;
}
dscene->objects.copy_to_device_if_modified();
dscene->objects.copy_to_device();
if (state.need_motion == Scene::MOTION_PASS) {
dscene->object_motion_pass.copy_to_device();
}
@@ -604,10 +569,6 @@ void ObjectManager::device_update_transforms(DeviceScene *dscene, Scene *scene,
dscene->data.bvh.have_motion = state.have_motion;
dscene->data.bvh.have_curves = state.have_curves;
dscene->objects.clear_modified();
dscene->object_motion_pass.clear_modified();
dscene->object_motion.clear_modified();
}
void ObjectManager::device_update(Device *device,
@@ -615,28 +576,12 @@ void ObjectManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
if (update_flags & (OBJECT_ADDED | OBJECT_REMOVED)) {
dscene->objects.tag_realloc();
dscene->object_motion_pass.tag_realloc();
dscene->object_motion.tag_realloc();
dscene->object_flag.tag_realloc();
dscene->object_volume_step.tag_realloc();
}
if (update_flags & HOLDOUT_MODIFIED) {
dscene->object_flag.tag_modified();
}
if (update_flags & PARTICLE_MODIFIED) {
dscene->objects.tag_modified();
}
VLOG(1) << "Total " << scene->objects.size() << " objects.";
device_free(device, dscene, false);
device_free(device, dscene);
if (scene->objects.size() == 0)
return;
@@ -652,16 +597,6 @@ void ObjectManager::device_update(Device *device,
int index = 0;
foreach (Object *object, scene->objects) {
object->index = index++;
/* this is a bit too broad, however a bigger refactor might be needed to properly separate
* update each type of data (transform, flags, etc.) */
if (object->is_modified()) {
dscene->objects.tag_modified();
dscene->object_motion_pass.tag_modified();
dscene->object_motion.tag_modified();
dscene->object_flag.tag_modified();
dscene->object_volume_step.tag_modified();
}
}
}
@@ -703,7 +638,7 @@ void ObjectManager::device_update(Device *device,
void ObjectManager::device_update_flags(
Device *, DeviceScene *dscene, Scene *scene, Progress & /*progress*/, bool bounds_valid)
{
if (!need_update() && !need_flags_update)
if (!need_update && !need_flags_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -712,7 +647,7 @@ void ObjectManager::device_update_flags(
}
});
update_flags = UPDATE_NONE;
need_update = false;
need_flags_update = false;
if (scene->objects.size() == 0)
@@ -782,9 +717,6 @@ void ObjectManager::device_update_flags(
/* Copy object flag. */
dscene->object_flag.copy_to_device();
dscene->object_volume_step.copy_to_device();
dscene->object_flag.clear_modified();
dscene->object_volume_step.clear_modified();
}
void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Scene *scene)
@@ -832,13 +764,13 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc
}
}
void ObjectManager::device_free(Device *, DeviceScene *dscene, bool force_free)
void ObjectManager::device_free(Device *, DeviceScene *dscene)
{
dscene->objects.free_if_need_realloc(force_free);
dscene->object_motion_pass.free_if_need_realloc(force_free);
dscene->object_motion.free_if_need_realloc(force_free);
dscene->object_flag.free_if_need_realloc(force_free);
dscene->object_volume_step.free_if_need_realloc(force_free);
dscene->objects.free();
dscene->object_motion_pass.free();
dscene->object_motion.free();
dscene->object_flag.free();
dscene->object_volume_step.free();
}
void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress)
@@ -909,21 +841,11 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P
}
}
void ObjectManager::tag_update(Scene *scene, uint32_t flag)
void ObjectManager::tag_update(Scene *scene)
{
update_flags |= flag;
/* avoid infinite loops if the geometry manager tagged us for an update */
if ((flag & GEOMETRY_MANAGER) == 0) {
scene->geometry_manager->tag_update(scene, GeometryManager::OBJECT_MANAGER);
}
scene->light_manager->tag_update(scene, LightManager::OBJECT_MANAGER);
}
bool ObjectManager::need_update() const
{
return update_flags != UPDATE_NONE;
need_update = true;
scene->geometry_manager->need_update = true;
scene->light_manager->need_update = true;
}
string ObjectManager::get_cryptomatte_objects(Scene *scene)

View File

@@ -122,24 +122,8 @@ class Object : public Node {
/* Object Manager */
class ObjectManager {
uint32_t update_flags;
public:
enum : uint32_t {
PARTICLE_MODIFIED = (1 << 0),
GEOMETRY_MANAGER = (1 << 1),
MOTION_BLUR_MODIFIED = (1 << 2),
OBJECT_ADDED = (1 << 3),
OBJECT_REMOVED = (1 << 4),
OBJECT_MODIFIED = (1 << 5),
HOLDOUT_MODIFIED = (1 << 6),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
bool need_update;
bool need_flags_update;
ObjectManager();
@@ -155,11 +139,9 @@ class ObjectManager {
bool bounds_valid = true);
void device_update_mesh_offsets(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene, bool force_free);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene, uint32_t flag);
bool need_update() const;
void tag_update(Scene *scene);
void apply_static_transforms(DeviceScene *dscene, Scene *scene, Progress &progress);
@@ -167,9 +149,7 @@ class ObjectManager {
string get_cryptomatte_assets(Scene *scene);
protected:
void device_update_object_transform(UpdateObjectTransformState *state,
Object *ob,
bool update_all);
void device_update_object_transform(UpdateObjectTransformState *state, Object *ob);
void device_update_object_transform_task(UpdateObjectTransformState *state);
bool device_update_object_transform_pop_work(UpdateObjectTransformState *state,
int *start_index,

View File

@@ -96,7 +96,7 @@ void OSLShaderManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -132,7 +132,7 @@ void OSLShaderManager::device_update(Device *device,
compiler.compile(og, shader);
if (shader->get_use_mis() && shader->has_surface_emission)
scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
scene->light_manager->need_update = true;
}
/* setup shader engine */
@@ -147,7 +147,7 @@ void OSLShaderManager::device_update(Device *device,
foreach (Shader *shader, scene->shaders)
shader->clear_modified();
update_flags = UPDATE_NONE;
need_update = false;
/* add special builtin texture types */
services->textures.insert(ustring("@ao"), new OSLTextureHandle(OSLTextureHandle::AO));
@@ -323,7 +323,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
string include_path_arg = string("-I") + shader_path;
options.push_back(include_path_arg);
stdosl_path = path_join(shader_path, "stdcycles.h");
stdosl_path = path_get("shader/stdcycles.h");
/* compile */
OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());

View File

@@ -46,14 +46,14 @@ ParticleSystem::~ParticleSystem()
void ParticleSystem::tag_update(Scene *scene)
{
scene->particle_system_manager->tag_update(scene);
scene->particle_system_manager->need_update = true;
}
/* Particle System Manager */
ParticleSystemManager::ParticleSystemManager()
{
need_update_ = true;
need_update = true;
}
ParticleSystemManager::~ParticleSystemManager()
@@ -109,7 +109,7 @@ void ParticleSystemManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -128,7 +128,7 @@ void ParticleSystemManager::device_update(Device *device,
if (progress.get_cancel())
return;
need_update_ = false;
need_update = false;
}
void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
@@ -138,12 +138,7 @@ void ParticleSystemManager::device_free(Device *, DeviceScene *dscene)
void ParticleSystemManager::tag_update(Scene * /*scene*/)
{
need_update_ = true;
}
bool ParticleSystemManager::need_update() const
{
return need_update_;
need_update = true;
}
CCL_NAMESPACE_END

View File

@@ -57,9 +57,9 @@ class ParticleSystem : public Node {
/* ParticleSystem Manager */
class ParticleSystemManager {
bool need_update_;
public:
bool need_update;
ParticleSystemManager();
~ParticleSystemManager();
@@ -71,8 +71,6 @@ class ParticleSystemManager {
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
bool need_update() const;
};
CCL_NAMESPACE_END

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2011-2018 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "procedural.h"
#include "render/scene.h"
#include "render/stats.h"
#include "util/util_foreach.h"
#include "util/util_progress.h"
CCL_NAMESPACE_BEGIN
NODE_ABSTRACT_DEFINE(Procedural)
{
NodeType *type = NodeType::add("procedural_base", NULL);
return type;
}
Procedural::Procedural(const NodeType *type) : Node(type)
{
}
Procedural::~Procedural()
{
}
ProceduralManager::ProceduralManager()
{
need_update_ = true;
}
ProceduralManager::~ProceduralManager()
{
}
void ProceduralManager::update(Scene *scene, Progress &progress)
{
if (!need_update()) {
return;
}
progress.set_status("Updating Procedurals");
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
scene->update_stats->procedurals.times.add_entry({"update", time});
}
});
foreach (Procedural *procedural, scene->procedurals) {
if (progress.get_cancel()) {
return;
}
procedural->generate(scene, progress);
}
if (progress.get_cancel()) {
return;
}
need_update_ = false;
}
void ProceduralManager::tag_update()
{
need_update_ = true;
}
bool ProceduralManager::need_update() const
{
return need_update_;
}
CCL_NAMESPACE_END

View File

@@ -1,73 +0,0 @@
/*
* Copyright 2011-2018 Blender Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "graph/node.h"
CCL_NAMESPACE_BEGIN
class Progress;
class Scene;
/* A Procedural is a Node which can create other Nodes before rendering starts.
*
* The Procedural is supposed to be the owner of any nodes that it creates. It can also create
* Nodes directly in the Scene (through Scene.create_node), it should still be set as the owner of
* those Nodes.
*/
class Procedural : public Node, public NodeOwner {
public:
NODE_ABSTRACT_DECLARE
explicit Procedural(const NodeType *type);
virtual ~Procedural();
/* Called each time the ProceduralManager is tagged for an update, this function is the entry
* point for the data generated by this Procedural. */
virtual void generate(Scene *scene, Progress &progress) = 0;
/* Create a node and set this Procedural as the owner. */
template<typename T> T *create_node()
{
T *node = new T();
node->set_owner(this);
return node;
}
/* Delete a Node created and owned by this Procedural. */
template<typename T> void delete_node(T *node)
{
assert(node->get_owner() == this);
delete node;
}
};
class ProceduralManager {
bool need_update_;
public:
ProceduralManager();
~ProceduralManager();
void update(Scene *scene, Progress &progress);
void tag_update();
bool need_update() const;
};
CCL_NAMESPACE_END

View File

@@ -18,7 +18,6 @@
#include "bvh/bvh.h"
#include "device/device.h"
#include "render/alembic.h"
#include "render/background.h"
#include "render/bake.h"
#include "render/camera.h"
@@ -30,7 +29,6 @@
#include "render/object.h"
#include "render/osl.h"
#include "render/particles.h"
#include "render/procedural.h"
#include "render/scene.h"
#include "render/session.h"
#include "render/shader.h"
@@ -116,7 +114,6 @@ Scene::Scene(const SceneParams &params_, Device *device)
image_manager = new ImageManager(device->info);
particle_system_manager = new ParticleSystemManager();
bake_manager = new BakeManager();
procedural_manager = new ProceduralManager();
kernels_loaded = false;
/* TODO(sergey): Check if it's indeed optimal value for the split kernel. */
@@ -145,9 +142,6 @@ void Scene::free_memory(bool final)
foreach (Shader *s, shaders)
delete s;
/* delete procedurals before other types as they may hold pointers to those types */
foreach (Procedural *p, procedurals)
delete p;
foreach (Geometry *g, geometry)
delete g;
foreach (Object *o, objects)
@@ -162,16 +156,15 @@ void Scene::free_memory(bool final)
objects.clear();
lights.clear();
particle_systems.clear();
procedurals.clear();
if (device) {
camera->device_free(device, &dscene, this);
film->device_free(device, &dscene, this);
background->device_free(device, &dscene);
integrator->device_free(device, &dscene, true);
integrator->device_free(device, &dscene);
object_manager->device_free(device, &dscene, true);
geometry_manager->device_free(device, &dscene, true);
object_manager->device_free(device, &dscene);
geometry_manager->device_free(device, &dscene);
shader_manager->device_free(device, &dscene, this);
light_manager->device_free(device, &dscene);
@@ -202,7 +195,6 @@ void Scene::free_memory(bool final)
delete image_manager;
delete bake_manager;
delete update_stats;
delete procedural_manager;
}
}
@@ -244,11 +236,6 @@ void Scene::device_update(Device *device_, Progress &progress)
if (progress.get_cancel() || device->have_error())
return;
procedural_manager->update(this, progress);
if (progress.get_cancel())
return;
progress.set_status("Updating Background");
background->device_update(device, &dscene, this);
@@ -399,12 +386,11 @@ bool Scene::need_update()
bool Scene::need_data_update()
{
return (background->is_modified() || image_manager->need_update() ||
object_manager->need_update() || geometry_manager->need_update() ||
light_manager->need_update() || lookup_tables->need_update() ||
integrator->is_modified() || shader_manager->need_update() ||
particle_system_manager->need_update() || bake_manager->need_update() ||
film->is_modified() || procedural_manager->need_update());
return (background->is_modified() || image_manager->need_update || object_manager->need_update ||
geometry_manager->need_update || light_manager->need_update ||
lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update ||
particle_system_manager->need_update || bake_manager->need_update ||
film->is_modified());
}
bool Scene::need_reset()
@@ -421,15 +407,12 @@ void Scene::reset()
camera->tag_modified();
dicing_camera->tag_modified();
film->tag_modified();
background->tag_modified();
background->tag_update(this);
integrator->tag_update(this, Integrator::UPDATE_ALL);
object_manager->tag_update(this, ObjectManager::UPDATE_ALL);
geometry_manager->tag_update(this, GeometryManager::UPDATE_ALL);
light_manager->tag_update(this, LightManager::UPDATE_ALL);
integrator->tag_update(this);
object_manager->tag_update(this);
geometry_manager->tag_update(this);
light_manager->tag_update(this);
particle_system_manager->tag_update(this);
procedural_manager->tag_update();
}
void Scene::device_free()
@@ -613,7 +596,7 @@ template<> Light *Scene::create_node<Light>()
Light *node = new Light();
node->set_owner(this);
lights.push_back(node);
light_manager->tag_update(this, LightManager::LIGHT_ADDED);
light_manager->tag_update(this);
return node;
}
@@ -622,7 +605,7 @@ template<> Mesh *Scene::create_node<Mesh>()
Mesh *node = new Mesh();
node->set_owner(this);
geometry.push_back(node);
geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
geometry_manager->tag_update(this);
return node;
}
@@ -631,7 +614,7 @@ template<> Hair *Scene::create_node<Hair>()
Hair *node = new Hair();
node->set_owner(this);
geometry.push_back(node);
geometry_manager->tag_update(this, GeometryManager::HAIR_ADDED);
geometry_manager->tag_update(this);
return node;
}
@@ -640,7 +623,7 @@ template<> Volume *Scene::create_node<Volume>()
Volume *node = new Volume();
node->set_owner(this);
geometry.push_back(node);
geometry_manager->tag_update(this, GeometryManager::MESH_ADDED);
geometry_manager->tag_update(this);
return node;
}
@@ -649,7 +632,7 @@ template<> Object *Scene::create_node<Object>()
Object *node = new Object();
node->set_owner(this);
objects.push_back(node);
object_manager->tag_update(this, ObjectManager::OBJECT_ADDED);
object_manager->tag_update(this);
return node;
}
@@ -667,23 +650,10 @@ template<> Shader *Scene::create_node<Shader>()
Shader *node = new Shader();
node->set_owner(this);
shaders.push_back(node);
shader_manager->tag_update(this, ShaderManager::SHADER_ADDED);
shader_manager->need_update = true;
return node;
}
template<> AlembicProcedural *Scene::create_node<AlembicProcedural>()
{
#ifdef WITH_ALEMBIC
AlembicProcedural *node = new AlembicProcedural();
node->set_owner(this);
procedurals.push_back(node);
procedural_manager->tag_update();
return node;
#else
return nullptr;
#endif
}
template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
{
for (size_t i = 0; i < nodes.size(); ++i) {
@@ -694,52 +664,43 @@ template<typename T> void delete_node_from_array(vector<T> &nodes, T node)
}
nodes.resize(nodes.size() - 1);
delete node;
}
template<> void Scene::delete_node_impl(Light *node)
{
delete_node_from_array(lights, node);
light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
light_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Mesh *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
geometry_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Hair *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
geometry_manager->tag_update(this, GeometryManager::HAIR_REMOVED);
geometry_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Volume *node)
{
delete_node_from_array(geometry, static_cast<Geometry *>(node));
geometry_manager->tag_update(this, GeometryManager::MESH_REMOVED);
geometry_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Geometry *node)
{
uint flag;
if (node->is_hair()) {
flag = GeometryManager::HAIR_REMOVED;
}
else {
flag = GeometryManager::MESH_REMOVED;
}
delete_node_from_array(geometry, node);
geometry_manager->tag_update(this, flag);
geometry_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(Object *node)
{
delete_node_from_array(objects, node);
object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
object_manager->tag_update(this);
}
template<> void Scene::delete_node_impl(ParticleSystem *node)
@@ -753,21 +714,6 @@ template<> void Scene::delete_node_impl(Shader * /*node*/)
/* don't delete unused shaders, not supported */
}
template<> void Scene::delete_node_impl(Procedural *node)
{
delete_node_from_array(procedurals, node);
procedural_manager->tag_update();
}
template<> void Scene::delete_node_impl(AlembicProcedural *node)
{
#ifdef WITH_ALEMBIC
delete_node_impl(static_cast<Procedural *>(node));
#else
(void)node;
#endif
}
template<typename T>
static void remove_nodes_in_set(const set<T *> &nodes_set,
vector<T *> &nodes_array,
@@ -796,19 +742,19 @@ static void remove_nodes_in_set(const set<T *> &nodes_set,
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, lights, owner);
light_manager->tag_update(this, LightManager::LIGHT_REMOVED);
light_manager->tag_update(this);
}
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, geometry, owner);
geometry_manager->tag_update(this, GeometryManager::GEOMETRY_REMOVED);
geometry_manager->tag_update(this);
}
template<> void Scene::delete_nodes(const set<Object *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, objects, owner);
object_manager->tag_update(this, ObjectManager::OBJECT_REMOVED);
object_manager->tag_update(this);
}
template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const NodeOwner *owner)
@@ -822,10 +768,4 @@ template<> void Scene::delete_nodes(const set<Shader *> & /*nodes*/, const NodeO
/* don't delete unused shaders, not supported */
}
template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner)
{
remove_nodes_in_set(nodes, procedurals, owner);
procedural_manager->tag_update();
}
CCL_NAMESPACE_END

View File

@@ -36,7 +36,6 @@
CCL_NAMESPACE_BEGIN
class AlembicProcedural;
class AttributeRequestSet;
class Background;
class BVH;
@@ -54,8 +53,6 @@ class Object;
class ObjectManager;
class ParticleSystemManager;
class ParticleSystem;
class Procedural;
class ProceduralManager;
class CurveSystemManager;
class Shader;
class ShaderManager;
@@ -239,7 +236,6 @@ class Scene : public NodeOwner {
vector<Light *> lights;
vector<ParticleSystem *> particle_systems;
vector<Pass> passes;
vector<Procedural *> procedurals;
/* data managers */
ImageManager *image_manager;
@@ -249,7 +245,6 @@ class Scene : public NodeOwner {
ObjectManager *object_manager;
ParticleSystemManager *particle_system_manager;
BakeManager *bake_manager;
ProceduralManager *procedural_manager;
/* default shaders */
Shader *default_surface;
@@ -384,8 +379,6 @@ template<> ParticleSystem *Scene::create_node<ParticleSystem>();
template<> Shader *Scene::create_node<Shader>();
template<> AlembicProcedural *Scene::create_node<AlembicProcedural>();
template<> void Scene::delete_node_impl(Light *node);
template<> void Scene::delete_node_impl(Mesh *node);
@@ -402,10 +395,6 @@ template<> void Scene::delete_node_impl(ParticleSystem *node);
template<> void Scene::delete_node_impl(Shader *node);
template<> void Scene::delete_node_impl(Procedural *node);
template<> void Scene::delete_node_impl(AlembicProcedural *node);
template<> void Scene::delete_nodes(const set<Light *> &nodes, const NodeOwner *owner);
template<> void Scene::delete_nodes(const set<Geometry *> &nodes, const NodeOwner *owner);
@@ -416,8 +405,6 @@ template<> void Scene::delete_nodes(const set<ParticleSystem *> &nodes, const No
template<> void Scene::delete_nodes(const set<Shader *> &nodes, const NodeOwner *owner);
template<> void Scene::delete_nodes(const set<Procedural *> &nodes, const NodeOwner *owner);
CCL_NAMESPACE_END
#endif /* __SCENE_H__ */

View File

@@ -459,11 +459,7 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
int device_num = device->device_number(tile_device);
while (!tile_manager.next_tile(tile, device_num, tile_types)) {
/* Can only steal tiles on devices that support rendering
* This is because denoising tiles cannot be stolen (see below)
*/
if ((tile_types & (RenderTile::PATH_TRACE | RenderTile::BAKE)) &&
steal_tile(rtile, tile_device, tile_lock)) {
if (steal_tile(rtile, tile_device, tile_lock)) {
return true;
}
@@ -540,14 +536,6 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
tile->buffers = new RenderBuffers(tile_device);
tile->buffers->reset(buffer_params);
}
else if (tile->buffers->buffer.device != tile_device) {
/* Move buffer to current tile device again in case it was stolen before.
* Not needed for denoising since that already handles mapping of tiles and
* neighbors to its own device. */
if (rtile.task != RenderTile::DENOISE) {
tile->buffers->buffer.move_device(tile_device);
}
}
tile->buffers->map_neighbor_copied = false;
@@ -559,13 +547,11 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
if (read_bake_tile_cb) {
/* This will read any passes needed as input for baking. */
if (tile_manager.state.sample == tile_manager.range_start_sample) {
{
thread_scoped_lock tile_lock(tile_mutex);
read_bake_tile_cb(rtile);
}
rtile.buffers->buffer.copy_to_device();
{
thread_scoped_lock tile_lock(tile_mutex);
read_bake_tile_cb(rtile);
}
rtile.buffers->buffer.copy_to_device();
}
else {
/* This will tag tile as IN PROGRESS in blender-side render pipeline,
@@ -1040,7 +1026,13 @@ bool Session::update_scene()
BakeManager *bake_manager = scene->bake_manager;
if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) {
integrator->set_aa_samples(tile_manager.num_samples);
int aa_samples = tile_manager.num_samples;
integrator->set_aa_samples(aa_samples);
if (integrator->is_modified()) {
integrator->tag_update(scene);
}
}
bool kernel_switch_needed = false;

View File

@@ -103,10 +103,10 @@ class SessionParams {
bool modified(const SessionParams &params)
{
/* Modified means we have to recreate the session, any parameter changes
* that can be handled by an existing Session are omitted. */
return !(device == params.device && background == params.background &&
progressive_refine == params.progressive_refine &&
/* samples == params.samples && denoising_start_sample ==
params.denoising_start_sample && */
progressive == params.progressive && experimental == params.experimental &&
tile_size == params.tile_size && start_resolution == params.start_resolution &&
pixel_size == params.pixel_size && threads == params.threads &&
@@ -117,8 +117,7 @@ class SessionParams {
text_timeout == params.text_timeout &&
progressive_update_timeout == params.progressive_update_timeout &&
tile_order == params.tile_order && shadingsystem == params.shadingsystem &&
denoising.type == params.denoising.type &&
(denoising.use == params.denoising.use || (device.denoisers & denoising.type)));
denoising.type == params.denoising.type);
}
};

View File

@@ -16,7 +16,6 @@
#include "device/device.h"
#include "render/alembic.h"
#include "render/background.h"
#include "render/camera.h"
#include "render/colorspace.h"
@@ -35,7 +34,6 @@
#include "util/util_foreach.h"
#include "util/util_murmurhash.h"
#include "util/util_task.h"
#include "util/util_transform.h"
#ifdef WITH_OCIO
# include <OpenColorIO/OpenColorIO.h>
@@ -220,9 +218,7 @@ Shader::Shader() : Node(node_type)
id = -1;
used = false;
need_update_uvs = true;
need_update_attribute = true;
need_update_displacement = true;
need_update_geometry = true;
}
Shader::~Shader()
@@ -295,7 +291,7 @@ void Shader::set_graph(ShaderGraph *graph_)
const char *new_hash = (graph_) ? graph_->displacement_hash.c_str() : "";
if (strcmp(old_hash, new_hash) != 0) {
need_update_displacement = true;
need_update_geometry = true;
}
}
@@ -312,14 +308,13 @@ void Shader::tag_update(Scene *scene)
{
/* update tag */
tag_modified();
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
scene->shader_manager->need_update = true;
/* if the shader previously was emissive, update light distribution,
* if the new shader is emissive, a light manager update tag will be
* done in the shader manager device update. */
if (use_mis && has_surface_emission)
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
scene->light_manager->need_update = true;
/* Special handle of background MIS light for now: for some reason it
* has use_mis set to false. We are quite close to release now, so
@@ -328,7 +323,7 @@ void Shader::tag_update(Scene *scene)
if (this == scene->background->get_shader(scene)) {
scene->light_manager->need_update_background = true;
if (scene->light_manager->has_background_light(scene)) {
scene->light_manager->tag_update(scene, LightManager::SHADER_MODIFIED);
scene->light_manager->need_update = true;
}
}
@@ -357,18 +352,17 @@ void Shader::tag_update(Scene *scene)
attributes.add(ATTR_STD_POSITION_UNDISPLACED);
}
if (displacement_method_is_modified()) {
need_update_displacement = true;
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_DISPLACEMENT_MODIFIED);
need_update_geometry = true;
scene->geometry_manager->need_update = true;
scene->object_manager->need_flags_update = true;
}
}
/* compare if the attributes changed, mesh manager will check
* need_update_attribute, update the relevant meshes and clear it. */
* need_update_geometry, update the relevant meshes and clear it. */
if (attributes.modified(prev_attributes)) {
need_update_attribute = true;
scene->geometry_manager->tag_update(scene, GeometryManager::SHADER_ATTRIBUTE_MODIFIED);
scene->procedural_manager->tag_update();
need_update_geometry = true;
scene->geometry_manager->need_update = true;
}
if (has_volume != prev_has_volume || volume_step_rate != prev_volume_step_rate) {
@@ -384,23 +378,50 @@ void Shader::tag_used(Scene *scene)
* recompiled because it was skipped for compilation before */
if (!used) {
tag_modified();
scene->shader_manager->tag_update(scene, ShaderManager::SHADER_MODIFIED);
scene->shader_manager->need_update = true;
}
}
bool Shader::need_update_geometry() const
{
return need_update_uvs || need_update_attribute || need_update_displacement;
}
/* Shader Manager */
ShaderManager::ShaderManager()
{
update_flags = UPDATE_ALL;
need_update = true;
beckmann_table_offset = TABLE_OFFSET_INVALID;
init_xyz_transforms();
xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
#ifdef WITH_OCIO
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
if (config) {
if (config->hasRole("XYZ") && config->hasRole("scene_linear")) {
OCIO::ConstProcessorRcPtr to_rgb_processor = config->getProcessor("XYZ", "scene_linear");
OCIO::ConstProcessorRcPtr to_xyz_processor = config->getProcessor("scene_linear", "XYZ");
if (to_rgb_processor && to_xyz_processor) {
float r[] = {1.0f, 0.0f, 0.0f};
float g[] = {0.0f, 1.0f, 0.0f};
float b[] = {0.0f, 0.0f, 1.0f};
to_xyz_processor->applyRGB(r);
to_xyz_processor->applyRGB(g);
to_xyz_processor->applyRGB(b);
rgb_to_y = make_float3(r[1], g[1], b[1]);
float x[] = {1.0f, 0.0f, 0.0f};
float y[] = {0.0f, 1.0f, 0.0f};
float z[] = {0.0f, 0.0f, 1.0f};
to_rgb_processor->applyRGB(x);
to_rgb_processor->applyRGB(y);
to_rgb_processor->applyRGB(z);
xyz_to_r = make_float3(x[0], y[0], z[0]);
xyz_to_g = make_float3(x[1], y[1], z[1]);
xyz_to_b = make_float3(x[2], y[2], z[2]);
}
}
}
#endif
}
ShaderManager::~ShaderManager()
@@ -463,7 +484,7 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
void ShaderManager::update_shaders_used(Scene *scene)
{
if (!need_update()) {
if (!need_update) {
return;
}
@@ -483,21 +504,6 @@ void ShaderManager::update_shaders_used(Scene *scene)
if (scene->background->get_shader())
scene->background->get_shader()->used = true;
#ifdef WITH_ALEMBIC
foreach (Procedural *procedural, scene->procedurals) {
AlembicProcedural *abc_proc = static_cast<AlembicProcedural *>(procedural);
foreach (Node *abc_node, abc_proc->get_objects()) {
AlembicObject *abc_object = static_cast<AlembicObject *>(abc_node);
foreach (Node *node, abc_object->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
shader->used = true;
}
}
}
#endif
foreach (Geometry *geom, scene->geometry)
foreach (Node *node, geom->get_used_shaders()) {
Shader *shader = static_cast<Shader *>(node);
@@ -787,100 +793,4 @@ string ShaderManager::get_cryptomatte_materials(Scene *scene)
return manifest;
}
void ShaderManager::tag_update(Scene * /*scene*/, uint32_t /*flag*/)
{
/* update everything for now */
update_flags = ShaderManager::UPDATE_ALL;
}
bool ShaderManager::need_update() const
{
return update_flags != UPDATE_NONE;
}
#ifdef WITH_OCIO
static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
const char *colorspace,
Transform &to_scene_linear)
{
OCIO::ConstProcessorRcPtr processor;
try {
processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
}
catch (OCIO::Exception &exception) {
return false;
}
if (!processor) {
return false;
}
OCIO::ConstCPUProcessorRcPtr device_processor = processor->getDefaultCPUProcessor();
if (!device_processor) {
return false;
}
to_scene_linear = transform_identity();
device_processor->applyRGB(&to_scene_linear.x.x);
device_processor->applyRGB(&to_scene_linear.y.x);
device_processor->applyRGB(&to_scene_linear.z.x);
to_scene_linear = transform_transposed_inverse(to_scene_linear);
return true;
}
#endif
void ShaderManager::init_xyz_transforms()
{
/* Default to ITU-BT.709 in case no appropriate transform found. */
xyz_to_r = make_float3(3.2404542f, -1.5371385f, -0.4985314f);
xyz_to_g = make_float3(-0.9692660f, 1.8760108f, 0.0415560f);
xyz_to_b = make_float3(0.0556434f, -0.2040259f, 1.0572252f);
rgb_to_y = make_float3(0.2126729f, 0.7151522f, 0.0721750f);
#ifdef WITH_OCIO
/* Get from OpenColorO config if it has the required roles. */
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
if (!config && config->hasRole(OCIO::ROLE_SCENE_LINEAR)) {
return;
}
Transform xyz_to_rgb;
if (config->hasRole("aces_interchange")) {
/* Standard OpenColorIO role, defined as ACES2065-1. */
const Transform xyz_to_aces = make_transform(1.0498110175f,
0.0f,
-0.0000974845f,
0.0f,
-0.4959030231f,
1.3733130458f,
0.0982400361f,
0.0f,
0.0f,
0.0f,
0.9912520182f,
0.0f);
Transform aces_to_rgb;
if (!to_scene_linear_transform(config, "aces_interchange", aces_to_rgb)) {
return;
}
xyz_to_rgb = aces_to_rgb * xyz_to_aces;
}
else if (config->hasRole("XYZ")) {
/* Custom role used before the standard existed. */
if (!to_scene_linear_transform(config, "XYZ", xyz_to_rgb)) {
return;
}
}
xyz_to_r = float4_to_float3(xyz_to_rgb.x);
xyz_to_g = float4_to_float3(xyz_to_rgb.y);
xyz_to_b = float4_to_float3(xyz_to_rgb.z);
const Transform rgb_to_xyz = transform_inverse(xyz_to_rgb);
rgb_to_y = float4_to_float3(rgb_to_xyz.y);
#endif
}
CCL_NAMESPACE_END

View File

@@ -100,9 +100,7 @@ class Shader : public Node {
float prev_volume_step_rate;
/* synchronization */
bool need_update_uvs;
bool need_update_attribute;
bool need_update_displacement;
bool need_update_geometry;
/* If the shader has only volume components, the surface is assumed to
* be transparent.
@@ -154,8 +152,6 @@ class Shader : public Node {
void set_graph(ShaderGraph *graph);
void tag_update(Scene *scene);
void tag_used(Scene *scene);
bool need_update_geometry() const;
};
/* Shader Manager virtual base class
@@ -165,16 +161,7 @@ class Shader : public Node {
class ShaderManager {
public:
enum : uint32_t {
SHADER_ADDED = (1 << 0),
SHADER_MODIFIED = (1 << 2),
INTEGRATOR_MODIFIED = (1 << 3),
/* tag everything in the manager for an update */
UPDATE_ALL = ~0u,
UPDATE_NONE = 0u,
};
bool need_update;
static ShaderManager *create(int shadingsystem);
virtual ~ShaderManager();
@@ -217,17 +204,9 @@ class ShaderManager {
string get_cryptomatte_materials(Scene *scene);
void tag_update(Scene *scene, uint32_t flag);
bool need_update() const;
void init_xyz_transforms();
protected:
ShaderManager();
uint32_t update_flags;
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
AttributeIDMap unique_attribute_id;

View File

@@ -375,7 +375,6 @@ string SceneUpdateStats::full_report()
result += "Particles:\n" + particles.full_report(1);
result += "SVM:\n" + svm.full_report(1);
result += "Tables:\n" + tables.full_report(1);
result += "Procedurals:\n" + procedurals.full_report(1);
return result;
}
@@ -395,7 +394,6 @@ void SceneUpdateStats::clear()
scene.times.clear();
svm.times.clear();
tables.times.clear();
procedurals.times.clear();
}
CCL_NAMESPACE_END

View File

@@ -219,7 +219,6 @@ class SceneUpdateStats {
UpdateTimeStats scene;
UpdateTimeStats svm;
UpdateTimeStats tables;
UpdateTimeStats procedurals;
string full_report();

View File

@@ -74,7 +74,7 @@ void SVMShaderManager::device_update(Device *device,
Scene *scene,
Progress &progress)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -125,7 +125,7 @@ void SVMShaderManager::device_update(Device *device,
shader->clear_modified();
if (shader->get_use_mis() && shader->has_surface_emission) {
scene->light_manager->tag_update(scene, LightManager::SHADER_COMPILED);
scene->light_manager->need_update = true;
}
/* Update the global jump table.
@@ -159,7 +159,7 @@ void SVMShaderManager::device_update(Device *device,
device_update_common(device, dscene, scene, progress);
update_flags = UPDATE_NONE;
need_update = false;
VLOG(1) << "Shader manager updated " << num_shaders << " shaders in " << time_dt() - start_time
<< " seconds.";

View File

@@ -28,7 +28,7 @@ CCL_NAMESPACE_BEGIN
LookupTables::LookupTables()
{
need_update_ = true;
need_update = true;
}
LookupTables::~LookupTables()
@@ -38,7 +38,7 @@ LookupTables::~LookupTables()
void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
{
if (!need_update())
if (!need_update)
return;
scoped_callback_timer timer([scene](double time) {
@@ -52,7 +52,7 @@ void LookupTables::device_update(Device *, DeviceScene *dscene, Scene *scene)
if (lookup_tables.size() > 0)
dscene->lookup_table.copy_to_device();
need_update_ = false;
need_update = false;
}
void LookupTables::device_free(Device *, DeviceScene *dscene)
@@ -60,11 +60,6 @@ void LookupTables::device_free(Device *, DeviceScene *dscene)
dscene->lookup_table.free();
}
bool LookupTables::need_update() const
{
return need_update_;
}
static size_t round_up_to_multiple(size_t size, size_t chunk)
{
return ((size + chunk - 1) / chunk) * chunk;
@@ -74,7 +69,7 @@ size_t LookupTables::add_table(DeviceScene *dscene, vector<float> &data)
{
assert(data.size() > 0);
need_update_ = true;
need_update = true;
Table new_table;
new_table.offset = 0;
@@ -112,7 +107,7 @@ void LookupTables::remove_table(size_t *offset)
return;
}
need_update_ = true;
need_update = true;
list<Table>::iterator table;

View File

@@ -30,14 +30,13 @@ enum { TABLE_CHUNK_SIZE = 256 };
enum { TABLE_OFFSET_INVALID = -1 };
class LookupTables {
bool need_update_;
public:
struct Table {
size_t offset;
size_t size;
};
bool need_update;
list<Table> lookup_tables;
LookupTables();
@@ -46,8 +45,6 @@ class LookupTables {
void device_update(Device *device, DeviceScene *dscene, Scene *scene);
void device_free(Device *device, DeviceScene *dscene);
bool need_update() const;
size_t add_table(DeviceScene *dscene, vector<float> &data);
void remove_table(size_t *offset);
};

View File

@@ -55,15 +55,11 @@ set(SRC
)
if(CXX_HAS_AVX)
list(APPEND SRC
util_avxf_avx_test.cpp
)
list(APPEND SRC util_avxf_avx_test.cpp)
set_source_files_properties(util_avxf_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}")
endif()
if(CXX_HAS_AVX2)
list(APPEND SRC
util_avxf_avx2_test.cpp
)
list(APPEND SRC util_avxf_avx2_test.cpp)
set_source_files_properties(util_avxf_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}")
endif()

Some files were not shown because too many files have changed in this diff Show More