Compare commits
5 Commits
temp-attri
...
temp-sprea
Author | SHA1 | Date | |
---|---|---|---|
045bdd5308 | |||
ae51cde3d7 | |||
25f8050830 | |||
ff013946bb | |||
74de45712d |
@@ -2,7 +2,7 @@
|
|||||||
# Configuration of clang-format
|
# Configuration of clang-format
|
||||||
# =============================
|
# =============================
|
||||||
#
|
#
|
||||||
# Tested to work with versions: 8 to 11.
|
# Tested to work with versions: 6 to 8.
|
||||||
|
|
||||||
# This causes parameters on continuations to align to the opening brace.
|
# This causes parameters on continuations to align to the opening brace.
|
||||||
#
|
#
|
||||||
@@ -255,6 +255,7 @@ ForEachMacros:
|
|||||||
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN
|
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN
|
||||||
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN
|
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN
|
||||||
- SEQ_ALL_BEGIN
|
- SEQ_ALL_BEGIN
|
||||||
|
- SEQ_CURRENT_BEGIN
|
||||||
- SURFACE_QUAD_ITER_BEGIN
|
- SURFACE_QUAD_ITER_BEGIN
|
||||||
- foreach
|
- foreach
|
||||||
- ED_screen_areas_iter
|
- ED_screen_areas_iter
|
||||||
@@ -263,5 +264,8 @@ ForEachMacros:
|
|||||||
- MAP_SLOT_PROBING_BEGIN
|
- MAP_SLOT_PROBING_BEGIN
|
||||||
- VECTOR_SET_SLOT_PROBING_BEGIN
|
- VECTOR_SET_SLOT_PROBING_BEGIN
|
||||||
|
|
||||||
StatementMacros:
|
# Use once we bump the minimum version to version 8.
|
||||||
- PyObject_VAR_HEAD
|
# # Without this string literals that in-line 'STRINGIFY' behave strangely (a bug?).
|
||||||
|
# StatementMacros:
|
||||||
|
# - PyObject_VAR_HEAD
|
||||||
|
# - STRINGIFY
|
||||||
|
@@ -35,13 +35,12 @@ Checks: >
|
|||||||
-modernize-use-auto,
|
-modernize-use-auto,
|
||||||
-modernize-use-trailing-return-type,
|
-modernize-use-trailing-return-type,
|
||||||
-modernize-avoid-c-arrays,
|
-modernize-avoid-c-arrays,
|
||||||
|
-modernize-use-equals-default,
|
||||||
-modernize-use-nodiscard,
|
-modernize-use-nodiscard,
|
||||||
-modernize-loop-convert,
|
-modernize-loop-convert,
|
||||||
-modernize-pass-by-value,
|
-modernize-pass-by-value,
|
||||||
# Cannot be enabled yet, because using raw string literals in tests breaks
|
|
||||||
# the windows compiler currently.
|
|
||||||
-modernize-raw-string-literal
|
|
||||||
|
|
||||||
|
WarningsAsErrors: '*'
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
- key: modernize-use-default-member-init.UseAssignment
|
- key: modernize-use-default-member-init.UseAssignment
|
||||||
value: 1
|
value: 1
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -46,6 +46,3 @@ Desktop.ini
|
|||||||
|
|
||||||
# smoke simulation noise tile (generated)
|
# smoke simulation noise tile (generated)
|
||||||
waveletNoiseTile.bin
|
waveletNoiseTile.bin
|
||||||
|
|
||||||
# testing environment
|
|
||||||
/Testing
|
|
||||||
|
@@ -236,7 +236,9 @@ option(WITH_SYSTEM_AUDASPACE "Build with external audaspace library installed on
|
|||||||
mark_as_advanced(WITH_AUDASPACE)
|
mark_as_advanced(WITH_AUDASPACE)
|
||||||
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
|
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
|
||||||
|
|
||||||
set_and_warn_dependency(WITH_AUDASPACE WITH_SYSTEM_AUDASPACE OFF)
|
if(NOT WITH_AUDASPACE)
|
||||||
|
set(WITH_SYSTEM_AUDASPACE OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
|
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
@@ -520,10 +522,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
|||||||
mark_as_advanced(WITH_LINKER_LLD)
|
mark_as_advanced(WITH_LINKER_LLD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
|
|
||||||
mark_as_advanced(WITH_COMPILER_ASAN)
|
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||||
|
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
|
||||||
|
mark_as_advanced(WITH_COMPILER_ASAN)
|
||||||
|
|
||||||
if(WITH_COMPILER_ASAN)
|
if(WITH_COMPILER_ASAN)
|
||||||
set(_asan_defaults "\
|
set(_asan_defaults "\
|
||||||
-fsanitize=address \
|
-fsanitize=address \
|
||||||
@@ -702,8 +704,10 @@ if(WITH_PYTHON_MODULE AND WITH_PYTHON_INSTALL)
|
|||||||
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF")
|
message(FATAL_ERROR "WITH_PYTHON_MODULE requires WITH_PYTHON_INSTALL to be OFF")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_and_warn_dependency(WITH_PYTHON WITH_CYCLES OFF)
|
if(NOT WITH_PYTHON)
|
||||||
set_and_warn_dependency(WITH_PYTHON WITH_DRACO OFF)
|
set(WITH_CYCLES OFF)
|
||||||
|
set(WITH_DRACO OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WITH_DRACO AND NOT WITH_PYTHON_INSTALL)
|
if(WITH_DRACO AND NOT WITH_PYTHON_INSTALL)
|
||||||
message(STATUS "WITH_DRACO requires WITH_PYTHON_INSTALL to be ON, disabling WITH_DRACO for now")
|
message(STATUS "WITH_DRACO requires WITH_PYTHON_INSTALL to be ON, disabling WITH_DRACO for now")
|
||||||
@@ -775,7 +779,6 @@ if(WITH_INSTALL_PORTABLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||||
message(STATUS "Disabling Ghost Wayland, X11, Input IME, and OpenXR")
|
|
||||||
set(WITH_GHOST_WAYLAND OFF)
|
set(WITH_GHOST_WAYLAND OFF)
|
||||||
set(WITH_GHOST_X11 OFF)
|
set(WITH_GHOST_X11 OFF)
|
||||||
set(WITH_X11_XINPUT OFF)
|
set(WITH_X11_XINPUT OFF)
|
||||||
@@ -806,7 +809,7 @@ endif()
|
|||||||
if(NOT WITH_CUDA_DYNLOAD)
|
if(NOT WITH_CUDA_DYNLOAD)
|
||||||
find_package(CUDA)
|
find_package(CUDA)
|
||||||
if(NOT CUDA_FOUND)
|
if(NOT CUDA_FOUND)
|
||||||
message(STATUS "CUDA toolkit not found, using dynamic runtime loading of libraries (WITH_CUDA_DYNLOAD) instead")
|
message("CUDA toolkit not found, using dynamic runtime loading of libraries instead")
|
||||||
set(WITH_CUDA_DYNLOAD ON)
|
set(WITH_CUDA_DYNLOAD ON)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -1232,7 +1235,6 @@ if(WITH_OPENMP)
|
|||||||
string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}")
|
string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}")
|
||||||
string(APPEND CMAKE_CXX_FLAGS " ${OpenMP_CXX_FLAGS}")
|
string(APPEND CMAKE_CXX_FLAGS " ${OpenMP_CXX_FLAGS}")
|
||||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${OpenMP_LINKER_FLAGS}")
|
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${OpenMP_LINKER_FLAGS}")
|
||||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${OpenMP_LINKER_FLAGS}")
|
|
||||||
else()
|
else()
|
||||||
# Typically avoid adding flags as defines but we can't
|
# Typically avoid adding flags as defines but we can't
|
||||||
# pass OpenMP flags to the linker for static builds, meaning
|
# pass OpenMP flags to the linker for static builds, meaning
|
||||||
@@ -1243,7 +1245,6 @@ if(WITH_OPENMP)
|
|||||||
find_library_static(OpenMP_LIBRARIES gomp ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
|
find_library_static(OpenMP_LIBRARIES gomp ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
message(STATUS "OpenMP not found, disabling WITH_OPENMP")
|
|
||||||
set(WITH_OPENMP OFF)
|
set(WITH_OPENMP OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -1319,7 +1320,6 @@ list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
|
|||||||
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
||||||
find_package(Bullet)
|
find_package(Bullet)
|
||||||
if(NOT BULLET_FOUND)
|
if(NOT BULLET_FOUND)
|
||||||
message(STATUS "Bullet not found, disabling WITH_BULLET")
|
|
||||||
set(WITH_BULLET OFF)
|
set(WITH_BULLET OFF)
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
@@ -1955,10 +1955,10 @@ if(FIRST_RUN)
|
|||||||
info_cfg_option(WITH_JACK)
|
info_cfg_option(WITH_JACK)
|
||||||
info_cfg_option(WITH_JACK_DYNLOAD)
|
info_cfg_option(WITH_JACK_DYNLOAD)
|
||||||
info_cfg_option(WITH_OPENAL)
|
info_cfg_option(WITH_OPENAL)
|
||||||
info_cfg_option(WITH_PULSEAUDIO)
|
|
||||||
info_cfg_option(WITH_PULSEAUDIO_DYNLOAD)
|
|
||||||
info_cfg_option(WITH_SDL)
|
info_cfg_option(WITH_SDL)
|
||||||
info_cfg_option(WITH_SDL_DYNLOAD)
|
info_cfg_option(WITH_SDL_DYNLOAD)
|
||||||
|
info_cfg_option(WITH_PULSEAUDIO)
|
||||||
|
info_cfg_option(WITH_PULSEAUDIO_DYNLOAD)
|
||||||
info_cfg_option(WITH_WASAPI)
|
info_cfg_option(WITH_WASAPI)
|
||||||
|
|
||||||
info_cfg_text("Compression:")
|
info_cfg_text("Compression:")
|
||||||
|
21
GNUmakefile
21
GNUmakefile
@@ -128,14 +128,8 @@ Utilities
|
|||||||
* source_archive:
|
* source_archive:
|
||||||
Create a compressed archive of the source code.
|
Create a compressed archive of the source code.
|
||||||
|
|
||||||
* source_archive_complete:
|
|
||||||
Create a compressed archive of the source code and all the libraries of dependencies.
|
|
||||||
|
|
||||||
* update:
|
* update:
|
||||||
Updates git and all submodules and svn.
|
updates git and all submodules
|
||||||
|
|
||||||
* update_code:
|
|
||||||
Updates git and all submodules but not svn.
|
|
||||||
|
|
||||||
* format:
|
* format:
|
||||||
Format source code using clang (uses PATHS if passed in). For example::
|
Format source code using clang (uses PATHS if passed in). For example::
|
||||||
@@ -480,9 +474,6 @@ check_smatch: .FORCE
|
|||||||
cd "$(BUILD_DIR)" ; \
|
cd "$(BUILD_DIR)" ; \
|
||||||
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
|
$(PYTHON) "$(BLENDER_DIR)/build_files/cmake/cmake_static_check_smatch.py"
|
||||||
|
|
||||||
check_mypy: .FORCE
|
|
||||||
$(PYTHON) "$(BLENDER_DIR)/source/tools/check_source/check_mypy.py"
|
|
||||||
|
|
||||||
check_spelling_py: .FORCE
|
check_spelling_py: .FORCE
|
||||||
cd "$(BUILD_DIR)" ; \
|
cd "$(BUILD_DIR)" ; \
|
||||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||||
@@ -517,13 +508,6 @@ check_descriptions: .FORCE
|
|||||||
source_archive: .FORCE
|
source_archive: .FORCE
|
||||||
python3 ./build_files/utils/make_source_archive.py
|
python3 ./build_files/utils/make_source_archive.py
|
||||||
|
|
||||||
source_archive_complete: .FORCE
|
|
||||||
cmake -S "$(BLENDER_DIR)/build_files/build_environment" -B"$(BUILD_DIR)/source_archive" \
|
|
||||||
-DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE) -DPACKAGE_USE_UPSTREAM_SOURCES=OFF
|
|
||||||
# This assumes CMake is still using a default `PACKAGE_DIR` variable:
|
|
||||||
python3 ./build_files/utils/make_source_archive.py --include-packages "$(BUILD_DIR)/source_archive/packages"
|
|
||||||
|
|
||||||
|
|
||||||
INKSCAPE_BIN?="inkscape"
|
INKSCAPE_BIN?="inkscape"
|
||||||
icons: .FORCE
|
icons: .FORCE
|
||||||
BLENDER_BIN=$(BLENDER_BIN) INKSCAPE_BIN=$(INKSCAPE_BIN) \
|
BLENDER_BIN=$(BLENDER_BIN) INKSCAPE_BIN=$(INKSCAPE_BIN) \
|
||||||
@@ -538,9 +522,6 @@ icons_geom: .FORCE
|
|||||||
update: .FORCE
|
update: .FORCE
|
||||||
$(PYTHON) ./build_files/utils/make_update.py
|
$(PYTHON) ./build_files/utils/make_update.py
|
||||||
|
|
||||||
update_code: .FORCE
|
|
||||||
$(PYTHON) ./build_files/utils/make_update.py --no-libraries
|
|
||||||
|
|
||||||
format: .FORCE
|
format: .FORCE
|
||||||
PATH="../lib/${OS_NCASE}_${CPU}/llvm/bin/:../lib/${OS_NCASE}_centos7_${CPU}/llvm/bin/:../lib/${OS_NCASE}/llvm/bin/:$(PATH)" \
|
PATH="../lib/${OS_NCASE}_${CPU}/llvm/bin/:../lib/${OS_NCASE}_centos7_${CPU}/llvm/bin/:../lib/${OS_NCASE}/llvm/bin/:$(PATH)" \
|
||||||
$(PYTHON) source/tools/utils_maintenance/clang_format_paths.py $(PATHS)
|
$(PYTHON) source/tools/utils_maintenance/clang_format_paths.py $(PATHS)
|
||||||
|
@@ -12,7 +12,7 @@ function(download_source dep)
|
|||||||
if(NOT EXISTS ${TARGET_FILE})
|
if(NOT EXISTS ${TARGET_FILE})
|
||||||
message("Checking source : ${dep} - source not found downloading from ${TARGET_URI}")
|
message("Checking source : ${dep} - source not found downloading from ${TARGET_URI}")
|
||||||
file(DOWNLOAD ${TARGET_URI} ${TARGET_FILE}
|
file(DOWNLOAD ${TARGET_URI} ${TARGET_FILE}
|
||||||
TIMEOUT 1800 # seconds
|
TIMEOUT 60 # seconds
|
||||||
EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH}
|
EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH}
|
||||||
TLS_VERIFY ON
|
TLS_VERIFY ON
|
||||||
SHOW_PROGRESS
|
SHOW_PROGRESS
|
||||||
|
@@ -68,6 +68,7 @@ set(OPENIMAGEIO_EXTRA_ARGS
|
|||||||
-DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/
|
-DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/
|
||||||
-DBoost_NO_SYSTEM_PATHS=ON
|
-DBoost_NO_SYSTEM_PATHS=ON
|
||||||
-DBoost_NO_BOOST_CMAKE=ON
|
-DBoost_NO_BOOST_CMAKE=ON
|
||||||
|
-OIIO_BUILD_CPP11=ON
|
||||||
-DUSE_LIBSQUISH=OFF
|
-DUSE_LIBSQUISH=OFF
|
||||||
-DUSE_QT5=OFF
|
-DUSE_QT5=OFF
|
||||||
-DUSE_NUKE=OFF
|
-DUSE_NUKE=OFF
|
||||||
|
@@ -21,8 +21,7 @@ if(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
option(WITH_WEBP "Enable building of oiio with webp support" OFF)
|
option(WITH_WEBP "Enable building of oiio with webp support" OFF)
|
||||||
option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF)
|
option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF)
|
||||||
cmake_host_system_information(RESULT NUM_CORES QUERY NUMBER_OF_LOGICAL_CORES)
|
set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with")
|
||||||
set(MAKE_THREADS ${NUM_CORES} CACHE STRING "Number of threads to run make with")
|
|
||||||
|
|
||||||
if(NOT BUILD_MODE)
|
if(NOT BUILD_MODE)
|
||||||
set(BUILD_MODE "Release")
|
set(BUILD_MODE "Release")
|
||||||
@@ -37,8 +36,14 @@ else(BUILD_MODE STREQUAL "Debug")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")
|
set(DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/downloads" CACHE STRING "Path for downloaded files")
|
||||||
# This path must be hard-coded like this, so that the GNUmakefile knows where it is and can pass it to make_source_archive.py:
|
# look in blenders source folder for packages directory, if that exists
|
||||||
set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages")
|
# it will our package folder, otherwise it will be in the build folder
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/../../packages")
|
||||||
|
set(PACKAGE_DIR_DEFAULT "${CMAKE_SOURCE_DIR}/../../packages")
|
||||||
|
else()
|
||||||
|
set(PACKAGE_DIR_DEFAULT "${CMAKE_CURRENT_BINARY_DIR}/packages")
|
||||||
|
endif()
|
||||||
|
set(PACKAGE_DIR ${PACKAGE_DIR_DEFAULT} CACHE STRING "Path for downloaded source files")
|
||||||
option(PACKAGE_USE_UPSTREAM_SOURCES "Use soures upstream to download the package sources, when OFF the blender mirror will be used" ON)
|
option(PACKAGE_USE_UPSTREAM_SOURCES "Use soures upstream to download the package sources, when OFF the blender mirror will be used" ON)
|
||||||
|
|
||||||
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
|
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
|
||||||
|
@@ -63,19 +63,3 @@ diff -Naur org/CMakeLists.txt external_osl/CMakeLists.txt
|
|||||||
|
|
||||||
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
|
set (OSL_NO_DEFAULT_TEXTURESYSTEM OFF CACHE BOOL "Do not use create a raw OIIO::TextureSystem")
|
||||||
if (OSL_NO_DEFAULT_TEXTURESYSTEM)
|
if (OSL_NO_DEFAULT_TEXTURESYSTEM)
|
||||||
diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp
|
|
||||||
index 445f6400..3d468de2 100644
|
|
||||||
--- a/src/liboslexec/llvm_util.cpp
|
|
||||||
+++ b/src/liboslexec/llvm_util.cpp
|
|
||||||
@@ -3430,8 +3430,9 @@ LLVM_Util::call_function (llvm::Value *func, cspan<llvm::Value *> args)
|
|
||||||
#endif
|
|
||||||
//llvm_gen_debug_printf (std::string("start ") + std::string(name));
|
|
||||||
#if OSL_LLVM_VERSION >= 110
|
|
||||||
- OSL_DASSERT(llvm::isa<llvm::Function>(func));
|
|
||||||
- llvm::Value *r = builder().CreateCall(llvm::cast<llvm::Function>(func), llvm::ArrayRef<llvm::Value *>(args.data(), args.size()));
|
|
||||||
+ llvm::Value* r = builder().CreateCall(
|
|
||||||
+ llvm::cast<llvm::FunctionType>(func->getType()->getPointerElementType()), func,
|
|
||||||
+ llvm::ArrayRef<llvm::Value*>(args.data(), args.size()));
|
|
||||||
#else
|
|
||||||
llvm::Value *r = builder().CreateCall (func, llvm::ArrayRef<llvm::Value *>(args.data(), args.size()));
|
|
||||||
#endif
|
|
||||||
|
@@ -85,8 +85,8 @@ class VersionInfo:
|
|||||||
version_number = int(self._parse_header_file(blender_h, 'BLENDER_VERSION'))
|
version_number = int(self._parse_header_file(blender_h, 'BLENDER_VERSION'))
|
||||||
version_number_patch = int(self._parse_header_file(blender_h, 'BLENDER_VERSION_PATCH'))
|
version_number_patch = int(self._parse_header_file(blender_h, 'BLENDER_VERSION_PATCH'))
|
||||||
version_numbers = (version_number // 100, version_number % 100, version_number_patch)
|
version_numbers = (version_number // 100, version_number % 100, version_number_patch)
|
||||||
self.short_version = "%d.%d" % (version_numbers[0], version_numbers[1])
|
self.short_version = "%d.%02d" % (version_numbers[0], version_numbers[1])
|
||||||
self.version = "%d.%d.%d" % version_numbers
|
self.version = "%d.%02d.%d" % version_numbers
|
||||||
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
|
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
|
||||||
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
|
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
|
||||||
|
|
||||||
|
@@ -75,7 +75,7 @@ FIND_PATH(OSL_SHADER_DIR
|
|||||||
/usr/share/OSL/
|
/usr/share/OSL/
|
||||||
/usr/include/OSL/
|
/usr/include/OSL/
|
||||||
PATH_SUFFIXES
|
PATH_SUFFIXES
|
||||||
share/OSL/shaders
|
shaders
|
||||||
)
|
)
|
||||||
|
|
||||||
# handle the QUIETLY and REQUIRED arguments and set OSL_FOUND to TRUE if
|
# handle the QUIETLY and REQUIRED arguments and set OSL_FOUND to TRUE if
|
||||||
|
@@ -28,14 +28,6 @@ if sys.version_info.major < 3:
|
|||||||
sys.version.partition(" ")[0])
|
sys.version.partition(" ")[0])
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
import os
|
|
||||||
from os.path import (
|
|
||||||
dirname,
|
|
||||||
join,
|
|
||||||
normpath,
|
|
||||||
splitext,
|
|
||||||
)
|
|
||||||
|
|
||||||
from cmake_consistency_check_config import (
|
from cmake_consistency_check_config import (
|
||||||
IGNORE_SOURCE,
|
IGNORE_SOURCE,
|
||||||
IGNORE_SOURCE_MISSING,
|
IGNORE_SOURCE_MISSING,
|
||||||
@@ -45,35 +37,32 @@ from cmake_consistency_check_config import (
|
|||||||
BUILD_DIR,
|
BUILD_DIR,
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Callable,
|
|
||||||
Dict,
|
|
||||||
Generator,
|
|
||||||
Iterator,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
Tuple,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
import os
|
||||||
|
from os.path import (
|
||||||
|
dirname,
|
||||||
|
join,
|
||||||
|
normpath,
|
||||||
|
splitext,
|
||||||
|
)
|
||||||
|
|
||||||
global_h = set()
|
global_h = set()
|
||||||
global_c = set()
|
global_c = set()
|
||||||
global_refs: Dict[str, List[Tuple[str, int]]] = {}
|
global_refs = {}
|
||||||
|
|
||||||
# Flatten `IGNORE_SOURCE_MISSING` to avoid nested looping.
|
# Flatten `IGNORE_SOURCE_MISSING` to avoid nested looping.
|
||||||
IGNORE_SOURCE_MISSING_FLAT = [
|
IGNORE_SOURCE_MISSING = [
|
||||||
(k, ignore_path) for k, ig_list in IGNORE_SOURCE_MISSING
|
(k, ignore_path) for k, ig_list in IGNORE_SOURCE_MISSING
|
||||||
for ignore_path in ig_list
|
for ignore_path in ig_list
|
||||||
]
|
]
|
||||||
|
|
||||||
# Ignore cmake file, path pairs.
|
# Ignore cmake file, path pairs.
|
||||||
global_ignore_source_missing: Dict[str, List[str]] = {}
|
global_ignore_source_missing = {}
|
||||||
for k, v in IGNORE_SOURCE_MISSING_FLAT:
|
for k, v in IGNORE_SOURCE_MISSING:
|
||||||
global_ignore_source_missing.setdefault(k, []).append(v)
|
global_ignore_source_missing.setdefault(k, []).append(v)
|
||||||
del IGNORE_SOURCE_MISSING_FLAT
|
|
||||||
|
|
||||||
|
|
||||||
def replace_line(f: str, i: int, text: str, keep_indent: bool = True) -> None:
|
def replace_line(f, i, text, keep_indent=True):
|
||||||
file_handle = open(f, 'r')
|
file_handle = open(f, 'r')
|
||||||
data = file_handle.readlines()
|
data = file_handle.readlines()
|
||||||
file_handle.close()
|
file_handle.close()
|
||||||
@@ -88,10 +77,7 @@ def replace_line(f: str, i: int, text: str, keep_indent: bool = True) -> None:
|
|||||||
file_handle.close()
|
file_handle.close()
|
||||||
|
|
||||||
|
|
||||||
def source_list(
|
def source_list(path, filename_check=None):
|
||||||
path: str,
|
|
||||||
filename_check: Optional[Callable[[str], bool]] = None,
|
|
||||||
) -> Generator[str, None, None]:
|
|
||||||
for dirpath, dirnames, filenames in os.walk(path):
|
for dirpath, dirnames, filenames in os.walk(path):
|
||||||
# skip '.git'
|
# skip '.git'
|
||||||
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||||
@@ -102,37 +88,37 @@ def source_list(
|
|||||||
|
|
||||||
|
|
||||||
# extension checking
|
# extension checking
|
||||||
def is_cmake(filename: str) -> bool:
|
def is_cmake(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext == ".cmake") or (filename == "CMakeLists.txt")
|
return (ext == ".cmake") or (filename == "CMakeLists.txt")
|
||||||
|
|
||||||
|
|
||||||
def is_c_header(filename: str) -> bool:
|
def is_c_header(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||||
|
|
||||||
|
|
||||||
def is_c(filename: str) -> bool:
|
def is_c(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
|
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl"})
|
||||||
|
|
||||||
|
|
||||||
def is_c_any(filename: str) -> bool:
|
def is_c_any(filename):
|
||||||
return is_c(filename) or is_c_header(filename)
|
return is_c(filename) or is_c_header(filename)
|
||||||
|
|
||||||
|
|
||||||
def cmake_get_src(f: str) -> None:
|
def cmake_get_src(f):
|
||||||
|
|
||||||
sources_h = []
|
sources_h = []
|
||||||
sources_c = []
|
sources_c = []
|
||||||
|
|
||||||
filen = open(f, "r", encoding="utf8")
|
filen = open(f, "r", encoding="utf8")
|
||||||
it: Optional[Iterator[str]] = iter(filen)
|
it = iter(filen)
|
||||||
found = False
|
found = False
|
||||||
i = 0
|
i = 0
|
||||||
# print(f)
|
# print(f)
|
||||||
|
|
||||||
def is_definition(l: str, f: str, i: int, name: str) -> bool:
|
def is_definition(l, f, i, name):
|
||||||
if l.startswith("unset("):
|
if l.startswith("unset("):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -145,7 +131,6 @@ def cmake_get_src(f: str) -> None:
|
|||||||
if l.endswith(")"):
|
if l.endswith(")"):
|
||||||
raise Exception("strict formatting not kept 'list(APPEND %s...)' on 1 line %s:%d" % (name, f, i))
|
raise Exception("strict formatting not kept 'list(APPEND %s...)' on 1 line %s:%d" % (name, f, i))
|
||||||
return True
|
return True
|
||||||
return False
|
|
||||||
|
|
||||||
while it is not None:
|
while it is not None:
|
||||||
context_name = ""
|
context_name = ""
|
||||||
@@ -284,7 +269,7 @@ def cmake_get_src(f: str) -> None:
|
|||||||
filen.close()
|
filen.close()
|
||||||
|
|
||||||
|
|
||||||
def is_ignore_source(f: str, ignore_used: List[bool]) -> bool:
|
def is_ignore_source(f, ignore_used):
|
||||||
for index, ignore_path in enumerate(IGNORE_SOURCE):
|
for index, ignore_path in enumerate(IGNORE_SOURCE):
|
||||||
if ignore_path in f:
|
if ignore_path in f:
|
||||||
ignore_used[index] = True
|
ignore_used[index] = True
|
||||||
@@ -292,7 +277,7 @@ def is_ignore_source(f: str, ignore_used: List[bool]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def is_ignore_cmake(f: str, ignore_used: List[bool]) -> bool:
|
def is_ignore_cmake(f, ignore_used):
|
||||||
for index, ignore_path in enumerate(IGNORE_CMAKE):
|
for index, ignore_path in enumerate(IGNORE_CMAKE):
|
||||||
if ignore_path in f:
|
if ignore_path in f:
|
||||||
ignore_used[index] = True
|
ignore_used[index] = True
|
||||||
@@ -300,7 +285,7 @@ def is_ignore_cmake(f: str, ignore_used: List[bool]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
|
|
||||||
print("Scanning:", SOURCE_DIR)
|
print("Scanning:", SOURCE_DIR)
|
||||||
|
|
||||||
@@ -374,7 +359,7 @@ def main() -> None:
|
|||||||
if "extern" not in f:
|
if "extern" not in f:
|
||||||
i = 1
|
i = 1
|
||||||
try:
|
try:
|
||||||
for _ in open(f, "r", encoding="utf8"):
|
for l in open(f, "r", encoding="utf8"):
|
||||||
i += 1
|
i += 1
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
print("Non utf8: %s:%d" % (f, i))
|
print("Non utf8: %s:%d" % (f, i))
|
||||||
|
@@ -25,14 +25,6 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Any,
|
|
||||||
Callable,
|
|
||||||
List,
|
|
||||||
Tuple,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||||
|
|
||||||
CHECKER_IGNORE_PREFIX = [
|
CHECKER_IGNORE_PREFIX = [
|
||||||
@@ -51,7 +43,7 @@ CHECKER_ARGS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||||
|
|
||||||
check_commands = []
|
check_commands = []
|
||||||
@@ -60,19 +52,18 @@ def main() -> None:
|
|||||||
# ~if "source/blender" not in c:
|
# ~if "source/blender" not in c:
|
||||||
# ~ continue
|
# ~ continue
|
||||||
|
|
||||||
cmd = (
|
cmd = ([CHECKER_BIN] +
|
||||||
[CHECKER_BIN] +
|
CHECKER_ARGS +
|
||||||
CHECKER_ARGS +
|
[c] +
|
||||||
[c] +
|
[("-I%s" % i) for i in inc_dirs] +
|
||||||
[("-I%s" % i) for i in inc_dirs] +
|
[("-D%s" % d) for d in defs]
|
||||||
[("-D%s" % d) for d in defs]
|
)
|
||||||
)
|
|
||||||
|
|
||||||
check_commands.append((c, cmd))
|
check_commands.append((c, cmd))
|
||||||
|
|
||||||
process_functions = []
|
process_functions = []
|
||||||
|
|
||||||
def my_process(i: int, c: str, cmd: str) -> subprocess.Popen[Any]:
|
def my_process(i, c, cmd):
|
||||||
if not USE_QUIET:
|
if not USE_QUIET:
|
||||||
percent = 100.0 * (i / (len(check_commands) - 1))
|
percent = 100.0 * (i / (len(check_commands) - 1))
|
||||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||||
|
@@ -25,12 +25,6 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Any,
|
|
||||||
List,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||||
|
|
||||||
CHECKER_IGNORE_PREFIX = [
|
CHECKER_IGNORE_PREFIX = [
|
||||||
@@ -53,26 +47,25 @@ if USE_QUIET:
|
|||||||
CHECKER_ARGS.append("--quiet")
|
CHECKER_ARGS.append("--quiet")
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||||
source_defines = project_source_info.build_defines_as_args()
|
source_defines = project_source_info.build_defines_as_args()
|
||||||
|
|
||||||
check_commands = []
|
check_commands = []
|
||||||
for c, inc_dirs, defs in source_info:
|
for c, inc_dirs, defs in source_info:
|
||||||
cmd = (
|
cmd = ([CHECKER_BIN] +
|
||||||
[CHECKER_BIN] +
|
CHECKER_ARGS +
|
||||||
CHECKER_ARGS +
|
[c] +
|
||||||
[c] +
|
[("-I%s" % i) for i in inc_dirs] +
|
||||||
[("-I%s" % i) for i in inc_dirs] +
|
[("-D%s" % d) for d in defs] +
|
||||||
[("-D%s" % d) for d in defs] +
|
source_defines
|
||||||
source_defines
|
)
|
||||||
)
|
|
||||||
|
|
||||||
check_commands.append((c, cmd))
|
check_commands.append((c, cmd))
|
||||||
|
|
||||||
process_functions = []
|
process_functions = []
|
||||||
|
|
||||||
def my_process(i: int, c: str, cmd: List[str]) -> subprocess.Popen[Any]:
|
def my_process(i, c, cmd):
|
||||||
if not USE_QUIET:
|
if not USE_QUIET:
|
||||||
percent = 100.0 * (i / len(check_commands))
|
percent = 100.0 * (i / len(check_commands))
|
||||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||||
|
@@ -9,10 +9,10 @@ set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_COMPILER_ASAN ON CACHE BOOL "" FORCE)
|
set(WITH_COMPILER_ASAN ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_DEBUG ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_DEBUG ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_NATIVE_ONLY ON CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_NATIVE_ONLY ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_GTESTS ON CACHE BOOL "" FORCE)
|
set(WITH_GTESTS ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS OFF CACHE BOOL "" FORCE)
|
set(WITH_LIBMV_SCHUR_SPECIALIZATIONS OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_PYTHON_SAFETY ON CACHE BOOL "" FORCE)
|
set(WITH_PYTHON_SAFETY ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(WITH_WINDOWS_BUNDLE_CRT OFF CACHE BOOL "" FORCE)
|
set(WITH_WINDOWS_BUNDLE_CRT OFF CACHE BOOL "" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -37,7 +37,6 @@ set(WITH_LZO ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
|
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
|
||||||
@@ -48,6 +47,8 @@ set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_PUGIXML 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)
|
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
|
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL ON CACHE BOOL "" FORCE)
|
set(WITH_SDL ON CACHE BOOL "" FORCE)
|
||||||
|
@@ -10,14 +10,14 @@ set(WITH_HEADLESS ON CACHE BOOL "" FORCE)
|
|||||||
# disable audio, its possible some devs may want this but for now disable
|
# disable audio, its possible some devs may want this but for now disable
|
||||||
# so the python module doesn't hold the audio device and loads quickly.
|
# so the python module doesn't hold the audio device and loads quickly.
|
||||||
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
# other features which are not especially useful as a python module
|
# other features which are not especially useful as a python module
|
||||||
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
|
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
|
||||||
|
@@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
|
set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_BOOST OFF CACHE BOOL "" FORCE)
|
set(WITH_BOOST OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
|
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
||||||
@@ -18,9 +18,9 @@ set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
|
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
set(WITH_CYCLES_OSL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
|
||||||
@@ -44,11 +44,12 @@ set(WITH_LZO OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_MOD_FLUID OFF CACHE BOOL "" FORCE)
|
set(WITH_MOD_FLUID OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_OCEANSIM OFF CACHE BOOL "" FORCE)
|
set(WITH_MOD_OCEANSIM OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_REMESH OFF CACHE BOOL "" FORCE)
|
set(WITH_MOD_REMESH OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLORIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_XR_OPENXR OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENIMAGEIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||||
@@ -56,12 +57,11 @@ set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
|||||||
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
|
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
|
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
|
set(WITH_QUADRIFLOW OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_TBB OFF CACHE BOOL "" FORCE)
|
set(WITH_TBB OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_USD OFF CACHE BOOL "" FORCE)
|
set(WITH_USD OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_XR_OPENXR OFF CACHE BOOL "" FORCE)
|
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
|
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
|
||||||
|
@@ -4,9 +4,9 @@
|
|||||||
# cmake -C../blender/build_files/cmake/config/blender_release.cmake ../blender
|
# cmake -C../blender/build_files/cmake/config/blender_release.cmake ../blender
|
||||||
#
|
#
|
||||||
|
|
||||||
|
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_ALEMBIC ON CACHE BOOL "" FORCE)
|
set(WITH_ALEMBIC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_ASSERT_ABORT OFF CACHE BOOL "" FORCE)
|
set(WITH_ASSERT_ABORT OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
|
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_BULLET ON CACHE BOOL "" FORCE)
|
set(WITH_BULLET ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||||
@@ -21,8 +21,8 @@ set(WITH_FFTW3 ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
set(WITH_FREESTYLE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
set(WITH_GMP ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
set(WITH_HARU ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
set(WITH_IK_SOLVER ON CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_IK_ITASC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_DDS ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
|
set(WITH_IMAGE_HDR ON CACHE BOOL "" FORCE)
|
||||||
@@ -38,7 +38,6 @@ set(WITH_LZO ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_OCEANSIM ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
|
set(WITH_MOD_REMESH ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
|
set(WITH_OPENAL ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLLADA ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
|
set(WITH_OPENCOLORIO ON CACHE BOOL "" FORCE)
|
||||||
@@ -49,6 +48,8 @@ set(WITH_OPENVDB ON CACHE BOOL "" FORCE)
|
|||||||
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
set(WITH_OPENVDB_BLOSC ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_PUGIXML 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)
|
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
|
set(WITH_QUADRIFLOW ON CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL ON CACHE BOOL "" FORCE)
|
set(WITH_SDL ON CACHE BOOL "" FORCE)
|
||||||
|
@@ -15,24 +15,24 @@ set(WITH_PYTHON_INSTALL OFF CACHE BOOL "" FORCE)
|
|||||||
# disable audio, its possible some devs may want this but for now disable
|
# disable audio, its possible some devs may want this but for now disable
|
||||||
# so the python module doesn't hold the audio device and loads quickly.
|
# so the python module doesn't hold the audio device and loads quickly.
|
||||||
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
set(WITH_JACK OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||||
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
# other features which are not especially useful as a python module
|
# other features which are not especially useful as a python module
|
||||||
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
|
||||||
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
|
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_NANOVDB OFF CACHE BOOL "" FORCE)
|
||||||
|
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
||||||
|
|
||||||
# Depends on Python install, do this to quiet warning.
|
# Depends on Python install, do this to quiet warning.
|
||||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||||
|
119
build_files/cmake/example_scripts/make_quicky.py
Executable file
119
build_files/cmake/example_scripts/make_quicky.py
Executable file
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ##### 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 #####
|
||||||
|
|
||||||
|
# <pep8 compliant>
|
||||||
|
|
||||||
|
|
||||||
|
def print_help(targets):
|
||||||
|
print("CMake quicky wrapper, no valid targets given.")
|
||||||
|
print(" * targets can contain a subset of the full target name.")
|
||||||
|
print(" * arguments with a '-' prefix are passed onto make.")
|
||||||
|
print(" * this must run from the cmake build dir")
|
||||||
|
print(" * alias this with a short command for speedy access, in bash:")
|
||||||
|
print(" alias mk='../blender/build_files/cmake/example_scripts/make_quicky.py'")
|
||||||
|
print("")
|
||||||
|
print(" eg: make_quicky.py -j3 extern python")
|
||||||
|
print(" ...will execute")
|
||||||
|
print(" make -j3 extern_binreloc extern_glew bf_python bf_python_ext blender/fast")
|
||||||
|
print("")
|
||||||
|
print("Target List:")
|
||||||
|
for t in targets:
|
||||||
|
print(" %s" % t)
|
||||||
|
print("...exiting")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
targets = set()
|
||||||
|
|
||||||
|
# collect targets
|
||||||
|
makefile = open("Makefile", "r")
|
||||||
|
for line in makefile:
|
||||||
|
line = line.rstrip()
|
||||||
|
if not line or line[0] in ". \t@$#":
|
||||||
|
continue
|
||||||
|
|
||||||
|
line = line.split("#", 1)[0]
|
||||||
|
if ":" not in line:
|
||||||
|
continue
|
||||||
|
|
||||||
|
line = line.split(":", 1)[0]
|
||||||
|
|
||||||
|
if "/" in line: # cmake terget options, dont need these
|
||||||
|
continue
|
||||||
|
|
||||||
|
targets.add(line)
|
||||||
|
makefile.close()
|
||||||
|
|
||||||
|
# remove cmake targets
|
||||||
|
bad = set([
|
||||||
|
"help",
|
||||||
|
"clean",
|
||||||
|
"all",
|
||||||
|
"preinstall",
|
||||||
|
"install",
|
||||||
|
"default_target",
|
||||||
|
"edit_cache",
|
||||||
|
"cmake_force",
|
||||||
|
"rebuild_cache",
|
||||||
|
"depend",
|
||||||
|
"cmake_check_build_system",
|
||||||
|
])
|
||||||
|
|
||||||
|
targets -= set(bad)
|
||||||
|
|
||||||
|
# parse args
|
||||||
|
targets = list(targets)
|
||||||
|
targets.sort()
|
||||||
|
|
||||||
|
import sys
|
||||||
|
if len(sys.argv) == 1:
|
||||||
|
print_help(targets)
|
||||||
|
return
|
||||||
|
|
||||||
|
targets_new = []
|
||||||
|
args = []
|
||||||
|
for arg in sys.argv[1:]:
|
||||||
|
if arg[0] in "/-":
|
||||||
|
args.append(arg)
|
||||||
|
else:
|
||||||
|
found = False
|
||||||
|
for t in targets:
|
||||||
|
if arg in t and t not in targets_new:
|
||||||
|
targets_new.append(t)
|
||||||
|
found = True
|
||||||
|
|
||||||
|
if not found:
|
||||||
|
print("Error '%s' not found in...")
|
||||||
|
for t in targets:
|
||||||
|
print(" %s" % t)
|
||||||
|
print("...aborting.")
|
||||||
|
return
|
||||||
|
|
||||||
|
# execute
|
||||||
|
cmd = ["make"] + args + targets_new + ["blender/fast"]
|
||||||
|
print("cmake building with targets: %s" % " ".join(targets_new))
|
||||||
|
print("executing: %s" % " ".join(cmd))
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
subprocess.call(cmd)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@@ -56,7 +56,6 @@ list(APPEND ZLIB_LIBRARIES ${BZIP2_LIBRARIES})
|
|||||||
if(WITH_OPENAL)
|
if(WITH_OPENAL)
|
||||||
find_package(OpenAL)
|
find_package(OpenAL)
|
||||||
if(NOT OPENAL_FOUND)
|
if(NOT OPENAL_FOUND)
|
||||||
message(WARNING "OpenAL not found, disabling WITH_OPENAL")
|
|
||||||
set(WITH_OPENAL OFF)
|
set(WITH_OPENAL OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -66,7 +65,6 @@ if(WITH_JACK)
|
|||||||
NAMES jackmp
|
NAMES jackmp
|
||||||
)
|
)
|
||||||
if(NOT JACK_FRAMEWORK)
|
if(NOT JACK_FRAMEWORK)
|
||||||
message(STATUS "JACK not found, disabling WITH_JACK")
|
|
||||||
set(WITH_JACK OFF)
|
set(WITH_JACK OFF)
|
||||||
else()
|
else()
|
||||||
set(JACK_INCLUDE_DIRS ${JACK_FRAMEWORK}/headers)
|
set(JACK_INCLUDE_DIRS ${JACK_FRAMEWORK}/headers)
|
||||||
@@ -104,7 +102,6 @@ endif()
|
|||||||
if(WITH_USD)
|
if(WITH_USD)
|
||||||
find_package(USD)
|
find_package(USD)
|
||||||
if(NOT USD_FOUND)
|
if(NOT USD_FOUND)
|
||||||
message(STATUS "USD not found, disabling WITH_USD")
|
|
||||||
set(WITH_USD OFF)
|
set(WITH_USD OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -149,7 +146,7 @@ if(WITH_PYTHON)
|
|||||||
|
|
||||||
set(PYTHON_INCLUDE_DIR "${_py_framework}/include/python${PYTHON_VERSION}")
|
set(PYTHON_INCLUDE_DIR "${_py_framework}/include/python${PYTHON_VERSION}")
|
||||||
set(PYTHON_EXECUTABLE "${_py_framework}/bin/python${PYTHON_VERSION}")
|
set(PYTHON_EXECUTABLE "${_py_framework}/bin/python${PYTHON_VERSION}")
|
||||||
set(PYTHON_LIBPATH "${_py_framework}/lib/python${PYTHON_VERSION}")
|
set(PYTHON_LIBPATH "${_py_framework}/lib/python${PYTHON_VERSION}/config-${PYTHON_VERSION}")
|
||||||
# set(PYTHON_LIBRARY python${PYTHON_VERSION})
|
# set(PYTHON_LIBRARY python${PYTHON_VERSION})
|
||||||
# set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled
|
# set(PYTHON_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled
|
||||||
|
|
||||||
@@ -311,7 +308,7 @@ if(WITH_OPENCOLORIO)
|
|||||||
|
|
||||||
if(NOT OPENCOLORIO_FOUND)
|
if(NOT OPENCOLORIO_FOUND)
|
||||||
set(WITH_OPENCOLORIO OFF)
|
set(WITH_OPENCOLORIO OFF)
|
||||||
message(STATUS "OpenColorIO not found, disabling WITH_OPENCOLORIO")
|
message(STATUS "OpenColorIO not found")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -360,7 +357,7 @@ if(WITH_CYCLES_OSL)
|
|||||||
if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER AND OSL_SHADER_DIR)
|
if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER AND OSL_SHADER_DIR)
|
||||||
set(OSL_FOUND TRUE)
|
set(OSL_FOUND TRUE)
|
||||||
else()
|
else()
|
||||||
message(WARNING "OSL not found, disabling WITH_CYCLES_OSL")
|
message(STATUS "OSL not found")
|
||||||
set(WITH_CYCLES_OSL OFF)
|
set(WITH_CYCLES_OSL OFF)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
@@ -388,7 +385,7 @@ if(WITH_OPENIMAGEDENOISE)
|
|||||||
|
|
||||||
if(NOT OPENIMAGEDENOISE_FOUND)
|
if(NOT OPENIMAGEDENOISE_FOUND)
|
||||||
set(WITH_OPENIMAGEDENOISE OFF)
|
set(WITH_OPENIMAGEDENOISE OFF)
|
||||||
message(STATUS "OpenImageDenoise not found, disabling WITH_OPENIMAGEDENOISE")
|
message(STATUS "OpenImageDenoise not found")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -416,7 +413,7 @@ if(WITH_OPENMP)
|
|||||||
set(OpenMP_LINKER_FLAGS "-L'${LIBDIR}/openmp/lib' -lomp")
|
set(OpenMP_LINKER_FLAGS "-L'${LIBDIR}/openmp/lib' -lomp")
|
||||||
|
|
||||||
# Copy libomp.dylib to allow executables like datatoc and tests to work.
|
# Copy libomp.dylib to allow executables like datatoc and tests to work.
|
||||||
# `@executable_path/../Resources/lib/` `LC_ID_DYLIB` is added by the deps builder.
|
# `@executable_path/../Resources/lib/` is a default dylib search path.
|
||||||
# For single config generator datatoc, tests etc.
|
# For single config generator datatoc, tests etc.
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Resources/lib
|
COMMAND mkdir -p ${CMAKE_BINARY_DIR}/Resources/lib
|
||||||
|
@@ -149,6 +149,11 @@ add_definitions(-D_WIN32_WINNT=0x601)
|
|||||||
include(build_files/cmake/platform/platform_win32_bundle_crt.cmake)
|
include(build_files/cmake/platform/platform_win32_bundle_crt.cmake)
|
||||||
remove_cc_flag("/MDd" "/MD" "/Zi")
|
remove_cc_flag("/MDd" "/MD" "/Zi")
|
||||||
|
|
||||||
|
if(WITH_WINDOWS_PDB)
|
||||||
|
set(PDB_INFO_OVERRIDE_FLAGS "/Z7")
|
||||||
|
set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC_CLANG) # Clangs version of cl doesn't support all flags
|
if(MSVC_CLANG) # Clangs version of cl doesn't support all flags
|
||||||
string(APPEND CMAKE_CXX_FLAGS " ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ")
|
string(APPEND CMAKE_CXX_FLAGS " ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ")
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference")
|
||||||
@@ -157,21 +162,6 @@ else()
|
|||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# X64 ASAN is available and usable on MSVC 16.9 preview 4 and up)
|
|
||||||
if(WITH_COMPILER_ASAN AND MSVC AND NOT MSVC_CLANG)
|
|
||||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28.29828)
|
|
||||||
#set a flag so we don't have to do this comparison all the time
|
|
||||||
SET(MSVC_ASAN On)
|
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address")
|
|
||||||
string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /INCREMENTAL:NO")
|
|
||||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG " /INCREMENTAL:NO")
|
|
||||||
else()
|
|
||||||
message("-- ASAN not supported on MSVC ${CMAKE_CXX_COMPILER_VERSION}")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# C++ standards conformace (/permissive-) is available on msvc 15.5 (1912) and up
|
# C++ standards conformace (/permissive-) is available on msvc 15.5 (1912) and up
|
||||||
if(MSVC_VERSION GREATER 1911 AND NOT MSVC_CLANG)
|
if(MSVC_VERSION GREATER 1911 AND NOT MSVC_CLANG)
|
||||||
string(APPEND CMAKE_CXX_FLAGS " /permissive-")
|
string(APPEND CMAKE_CXX_FLAGS " /permissive-")
|
||||||
@@ -184,41 +174,14 @@ if(WITH_WINDOWS_SCCACHE AND CMAKE_VS_MSBUILD_COMMAND)
|
|||||||
set(WITH_WINDOWS_SCCACHE Off)
|
set(WITH_WINDOWS_SCCACHE Off)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Debug Symbol format
|
|
||||||
# sccache # MSVC_ASAN # format # why
|
|
||||||
# On # On # Z7 # sccache will only play nice with Z7
|
|
||||||
# On # Off # Z7 # sccache will only play nice with Z7
|
|
||||||
# Off # On # Zi # Asan will not play nice with Edit and Continue
|
|
||||||
# Off # Off # ZI # Neither asan nor sscache is enabled Edit and Continue is available
|
|
||||||
|
|
||||||
# Release Symbol format
|
|
||||||
# sccache # MSVC_ASAN # format # why
|
|
||||||
# On # On # Z7 # sccache will only play nice with Z7
|
|
||||||
# On # Off # Z7 # sccache will only play nice with Z7
|
|
||||||
# Off # On # Zi # Asan will not play nice with Edit and Continue
|
|
||||||
# Off # Off # Zi # Edit and Continue disables some optimizations
|
|
||||||
|
|
||||||
|
|
||||||
if(WITH_WINDOWS_SCCACHE)
|
if(WITH_WINDOWS_SCCACHE)
|
||||||
set(CMAKE_C_COMPILER_LAUNCHER sccache)
|
set(CMAKE_C_COMPILER_LAUNCHER sccache)
|
||||||
set(CMAKE_CXX_COMPILER_LAUNCHER sccache)
|
set(CMAKE_CXX_COMPILER_LAUNCHER sccache)
|
||||||
set(SYMBOL_FORMAT /Z7)
|
set(SYMBOL_FORMAT /Z7)
|
||||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
|
||||||
else()
|
else()
|
||||||
unset(CMAKE_C_COMPILER_LAUNCHER)
|
unset(CMAKE_C_COMPILER_LAUNCHER)
|
||||||
unset(CMAKE_CXX_COMPILER_LAUNCHER)
|
unset(CMAKE_CXX_COMPILER_LAUNCHER)
|
||||||
if(MSVC_ASAN)
|
set(SYMBOL_FORMAT /ZI)
|
||||||
set(SYMBOL_FORMAT /Z7)
|
|
||||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
|
||||||
else()
|
|
||||||
set(SYMBOL_FORMAT /ZI)
|
|
||||||
set(SYMBOL_FORMAT_RELEASE /Zi)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WITH_WINDOWS_PDB)
|
|
||||||
set(PDB_INFO_OVERRIDE_FLAGS "${SYMBOL_FORMAT_RELEASE}")
|
|
||||||
set(PDB_INFO_OVERRIDE_LINKER_FLAGS "/DEBUG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /MDd ${SYMBOL_FORMAT}")
|
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /MDd ${SYMBOL_FORMAT}")
|
||||||
@@ -227,11 +190,9 @@ string(APPEND CMAKE_CXX_FLAGS_RELEASE " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
|||||||
string(APPEND CMAKE_C_FLAGS_RELEASE " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
string(APPEND CMAKE_C_FLAGS_RELEASE " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
||||||
string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
||||||
string(APPEND CMAKE_C_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
string(APPEND CMAKE_C_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}")
|
||||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT_RELEASE}")
|
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}")
|
||||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT_RELEASE}")
|
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}")
|
||||||
unset(SYMBOL_FORMAT)
|
unset(SYMBOL_FORMAT)
|
||||||
unset(SYMBOL_FORMAT_RELEASE)
|
|
||||||
|
|
||||||
# JMC is available on msvc 15.8 (1915) and up
|
# JMC is available on msvc 15.8 (1915) and up
|
||||||
if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
|
if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
|
||||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC")
|
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC")
|
||||||
|
@@ -44,15 +44,6 @@ __all__ = (
|
|||||||
"init",
|
"init",
|
||||||
)
|
)
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Callable,
|
|
||||||
Generator,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
Union,
|
|
||||||
Tuple,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
if sys.version_info.major < 3:
|
if sys.version_info.major < 3:
|
||||||
@@ -79,11 +70,10 @@ SOURCE_DIR = abspath(SOURCE_DIR)
|
|||||||
SIMPLE_PROJECTFILE = False
|
SIMPLE_PROJECTFILE = False
|
||||||
|
|
||||||
# must initialize from 'init'
|
# must initialize from 'init'
|
||||||
CMAKE_DIR = ""
|
CMAKE_DIR = None
|
||||||
PROJECT_DIR = ""
|
|
||||||
|
|
||||||
|
|
||||||
def init(cmake_path: str) -> bool:
|
def init(cmake_path):
|
||||||
global CMAKE_DIR, PROJECT_DIR
|
global CMAKE_DIR, PROJECT_DIR
|
||||||
|
|
||||||
# get cmake path
|
# get cmake path
|
||||||
@@ -101,10 +91,7 @@ def init(cmake_path: str) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def source_list(
|
def source_list(path, filename_check=None):
|
||||||
path: str,
|
|
||||||
filename_check: Optional[Callable[[str], bool]] = None,
|
|
||||||
) -> Generator[str, None, None]:
|
|
||||||
for dirpath, dirnames, filenames in os.walk(path):
|
for dirpath, dirnames, filenames in os.walk(path):
|
||||||
# skip '.git'
|
# skip '.git'
|
||||||
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||||
@@ -116,57 +103,53 @@ def source_list(
|
|||||||
|
|
||||||
|
|
||||||
# extension checking
|
# extension checking
|
||||||
def is_cmake(filename: str) -> bool:
|
def is_cmake(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext == ".cmake") or (filename.endswith("CMakeLists.txt"))
|
return (ext == ".cmake") or (filename.endswith("CMakeLists.txt"))
|
||||||
|
|
||||||
|
|
||||||
def is_c_header(filename: str) -> bool:
|
def is_c_header(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||||
|
|
||||||
|
|
||||||
def is_py(filename: str) -> bool:
|
def is_py(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext == ".py")
|
return (ext == ".py")
|
||||||
|
|
||||||
|
|
||||||
def is_glsl(filename: str) -> bool:
|
def is_glsl(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext == ".glsl")
|
return (ext == ".glsl")
|
||||||
|
|
||||||
|
|
||||||
def is_c(filename: str) -> bool:
|
def is_c(filename):
|
||||||
ext = splitext(filename)[1]
|
ext = splitext(filename)[1]
|
||||||
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
||||||
|
|
||||||
|
|
||||||
def is_c_any(filename: str) -> bool:
|
def is_c_any(filename):
|
||||||
return is_c(filename) or is_c_header(filename)
|
return is_c(filename) or is_c_header(filename)
|
||||||
|
|
||||||
|
|
||||||
def is_svn_file(filename: str) -> bool:
|
def is_svn_file(filename):
|
||||||
dn, fn = os.path.split(filename)
|
dn, fn = os.path.split(filename)
|
||||||
filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn)
|
filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn)
|
||||||
return exists(filename_svn)
|
return exists(filename_svn)
|
||||||
|
|
||||||
|
|
||||||
def is_project_file(filename: str) -> bool:
|
def is_project_file(filename):
|
||||||
return (is_c_any(filename) or is_cmake(filename) or is_glsl(filename)) # and is_svn_file(filename)
|
return (is_c_any(filename) or is_cmake(filename) or is_glsl(filename)) # and is_svn_file(filename)
|
||||||
|
|
||||||
|
|
||||||
def cmake_advanced_info() -> Union[Tuple[List[str], List[Tuple[str, str]]], Tuple[None, None]]:
|
def cmake_advanced_info():
|
||||||
""" Extract includes and defines from cmake.
|
""" Extract includes and defines from cmake.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||||
if make_exe is None:
|
|
||||||
print("Make command not found in: %r not found" % project_path)
|
|
||||||
return None, None
|
|
||||||
|
|
||||||
make_exe_basename = os.path.basename(make_exe)
|
make_exe_basename = os.path.basename(make_exe)
|
||||||
|
|
||||||
def create_eclipse_project() -> str:
|
def create_eclipse_project():
|
||||||
print("CMAKE_DIR %r" % CMAKE_DIR)
|
print("CMAKE_DIR %r" % CMAKE_DIR)
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
raise Exception("Error: win32 is not supported")
|
raise Exception("Error: win32 is not supported")
|
||||||
@@ -236,7 +219,7 @@ def cmake_advanced_info() -> Union[Tuple[List[str], List[Tuple[str, str]]], Tupl
|
|||||||
return includes, defines
|
return includes, defines
|
||||||
|
|
||||||
|
|
||||||
def cmake_cache_var(var: str) -> Optional[str]:
|
def cmake_cache_var(var):
|
||||||
with open(os.path.join(CMAKE_DIR, "CMakeCache.txt"), encoding='utf-8') as cache_file:
|
with open(os.path.join(CMAKE_DIR, "CMakeCache.txt"), encoding='utf-8') as cache_file:
|
||||||
lines = [
|
lines = [
|
||||||
l_strip for l in cache_file
|
l_strip for l in cache_file
|
||||||
@@ -250,12 +233,12 @@ def cmake_cache_var(var: str) -> Optional[str]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def cmake_compiler_defines() -> Optional[List[str]]:
|
def cmake_compiler_defines():
|
||||||
compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too
|
compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too
|
||||||
|
|
||||||
if compiler is None:
|
if compiler is None:
|
||||||
print("Couldn't find the compiler, os defines will be omitted...")
|
print("Couldn't find the compiler, os defines will be omitted...")
|
||||||
return None
|
return
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
temp_c = tempfile.mkstemp(suffix=".c")[1]
|
temp_c = tempfile.mkstemp(suffix=".c")[1]
|
||||||
@@ -272,5 +255,5 @@ def cmake_compiler_defines() -> Optional[List[str]]:
|
|||||||
return lines
|
return lines
|
||||||
|
|
||||||
|
|
||||||
def project_name_get() -> Optional[str]:
|
def project_name_get():
|
||||||
return cmake_cache_var("CMAKE_PROJECT_NAME")
|
return cmake_cache_var("CMAKE_PROJECT_NAME")
|
||||||
|
@@ -34,45 +34,30 @@ if sys.version_info.major < 3:
|
|||||||
import os
|
import os
|
||||||
from os.path import join, dirname, normpath, abspath
|
from os.path import join, dirname, normpath, abspath
|
||||||
|
|
||||||
import subprocess
|
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Any,
|
|
||||||
Callable,
|
|
||||||
Generator,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
Sequence,
|
|
||||||
Tuple,
|
|
||||||
Union,
|
|
||||||
cast,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
SOURCE_DIR = join(dirname(__file__), "..", "..")
|
SOURCE_DIR = join(dirname(__file__), "..", "..")
|
||||||
SOURCE_DIR = normpath(SOURCE_DIR)
|
SOURCE_DIR = normpath(SOURCE_DIR)
|
||||||
SOURCE_DIR = abspath(SOURCE_DIR)
|
SOURCE_DIR = abspath(SOURCE_DIR)
|
||||||
|
|
||||||
|
|
||||||
def is_c_header(filename: str) -> bool:
|
def is_c_header(filename):
|
||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||||
|
|
||||||
|
|
||||||
def is_c(filename: str) -> bool:
|
def is_c(filename):
|
||||||
ext = os.path.splitext(filename)[1]
|
ext = os.path.splitext(filename)[1]
|
||||||
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
||||||
|
|
||||||
|
|
||||||
def is_c_any(filename: str) -> bool:
|
def is_c_any(filename):
|
||||||
return is_c(filename) or is_c_header(filename)
|
return os.path.s_c(filename) or is_c_header(filename)
|
||||||
|
|
||||||
|
|
||||||
# copied from project_info.py
|
# copied from project_info.py
|
||||||
CMAKE_DIR = "."
|
CMAKE_DIR = "."
|
||||||
|
|
||||||
|
|
||||||
def cmake_cache_var_iter() -> Generator[Tuple[str, str, str], None, None]:
|
def cmake_cache_var_iter():
|
||||||
import re
|
import re
|
||||||
re_cache = re.compile(r'([A-Za-z0-9_\-]+)?:?([A-Za-z0-9_\-]+)?=(.*)$')
|
re_cache = re.compile(r'([A-Za-z0-9_\-]+)?:?([A-Za-z0-9_\-]+)?=(.*)$')
|
||||||
with open(join(CMAKE_DIR, "CMakeCache.txt"), 'r', encoding='utf-8') as cache_file:
|
with open(join(CMAKE_DIR, "CMakeCache.txt"), 'r', encoding='utf-8') as cache_file:
|
||||||
@@ -83,22 +68,14 @@ def cmake_cache_var_iter() -> Generator[Tuple[str, str, str], None, None]:
|
|||||||
yield (var, type_ or "", val)
|
yield (var, type_ or "", val)
|
||||||
|
|
||||||
|
|
||||||
def cmake_cache_var(var: str) -> Optional[str]:
|
def cmake_cache_var(var):
|
||||||
for var_iter, type_iter, value_iter in cmake_cache_var_iter():
|
for var_iter, type_iter, value_iter in cmake_cache_var_iter():
|
||||||
if var == var_iter:
|
if var == var_iter:
|
||||||
return value_iter
|
return value_iter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def cmake_cache_var_or_exit(var: str) -> str:
|
def do_ignore(filepath, ignore_prefix_list):
|
||||||
value = cmake_cache_var(var)
|
|
||||||
if value is None:
|
|
||||||
print("Unable to find %r exiting!" % value)
|
|
||||||
sys.exit(1)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
def do_ignore(filepath: str, ignore_prefix_list: Optional[Sequence[str]]) -> bool:
|
|
||||||
if ignore_prefix_list is None:
|
if ignore_prefix_list is None:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -106,13 +83,12 @@ def do_ignore(filepath: str, ignore_prefix_list: Optional[Sequence[str]]) -> boo
|
|||||||
return any([relpath.startswith(prefix) for prefix in ignore_prefix_list])
|
return any([relpath.startswith(prefix) for prefix in ignore_prefix_list])
|
||||||
|
|
||||||
|
|
||||||
def makefile_log() -> List[str]:
|
def makefile_log():
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
|
|
||||||
# support both make and ninja
|
# support both make and ninja
|
||||||
make_exe = cmake_cache_var_or_exit("CMAKE_MAKE_PROGRAM")
|
make_exe = cmake_cache_var("CMAKE_MAKE_PROGRAM")
|
||||||
|
|
||||||
make_exe_basename = os.path.basename(make_exe)
|
make_exe_basename = os.path.basename(make_exe)
|
||||||
|
|
||||||
if make_exe_basename.startswith(("make", "gmake")):
|
if make_exe_basename.startswith(("make", "gmake")):
|
||||||
@@ -126,37 +102,26 @@ def makefile_log() -> List[str]:
|
|||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
)
|
)
|
||||||
|
|
||||||
if process is None:
|
|
||||||
print("Can't execute process")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
while process.poll():
|
while process.poll():
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
# We know this is always true based on the input arguments to `Popen`.
|
out = process.stdout.read()
|
||||||
stdout: IO[bytes] = process.stdout # type: ignore
|
process.stdout.close()
|
||||||
|
|
||||||
out = stdout.read()
|
|
||||||
stdout.close()
|
|
||||||
print("done!", len(out), "bytes")
|
print("done!", len(out), "bytes")
|
||||||
return cast(List[str], out.decode("utf-8", errors="ignore").split("\n"))
|
return out.decode("utf-8", errors="ignore").split("\n")
|
||||||
|
|
||||||
|
|
||||||
def build_info(
|
def build_info(use_c=True, use_cxx=True, ignore_prefix_list=None):
|
||||||
use_c: bool = True,
|
|
||||||
use_cxx: bool = True,
|
|
||||||
ignore_prefix_list: Optional[List[str]] = None,
|
|
||||||
) -> List[Tuple[str, List[str], List[str]]]:
|
|
||||||
makelog = makefile_log()
|
makelog = makefile_log()
|
||||||
|
|
||||||
source = []
|
source = []
|
||||||
|
|
||||||
compilers = []
|
compilers = []
|
||||||
if use_c:
|
if use_c:
|
||||||
compilers.append(cmake_cache_var_or_exit("CMAKE_C_COMPILER"))
|
compilers.append(cmake_cache_var("CMAKE_C_COMPILER"))
|
||||||
if use_cxx:
|
if use_cxx:
|
||||||
compilers.append(cmake_cache_var_or_exit("CMAKE_CXX_COMPILER"))
|
compilers.append(cmake_cache_var("CMAKE_CXX_COMPILER"))
|
||||||
|
|
||||||
print("compilers:", " ".join(compilers))
|
print("compilers:", " ".join(compilers))
|
||||||
|
|
||||||
@@ -166,7 +131,7 @@ def build_info(
|
|||||||
|
|
||||||
for line in makelog:
|
for line in makelog:
|
||||||
|
|
||||||
args: Union[str, List[str]] = line.split()
|
args = line.split()
|
||||||
|
|
||||||
if not any([(c in args) for c in compilers]):
|
if not any([(c in args) for c in compilers]):
|
||||||
continue
|
continue
|
||||||
@@ -211,40 +176,29 @@ def build_info(
|
|||||||
return source
|
return source
|
||||||
|
|
||||||
|
|
||||||
def build_defines_as_source() -> str:
|
def build_defines_as_source():
|
||||||
"""
|
"""
|
||||||
Returns a string formatted as an include:
|
Returns a string formatted as an include:
|
||||||
'#defines A=B\n#define....'
|
'#defines A=B\n#define....'
|
||||||
"""
|
"""
|
||||||
import subprocess
|
import subprocess
|
||||||
# works for both gcc and clang
|
# works for both gcc and clang
|
||||||
cmd = (cmake_cache_var_or_exit("CMAKE_C_COMPILER"), "-dM", "-E", "-")
|
cmd = (cmake_cache_var("CMAKE_C_COMPILER"), "-dM", "-E", "-")
|
||||||
process = subprocess.Popen(
|
return subprocess.Popen(cmd,
|
||||||
cmd,
|
stdout=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE,
|
stdin=subprocess.DEVNULL,
|
||||||
stdin=subprocess.DEVNULL,
|
).stdout.read().strip().decode('ascii')
|
||||||
)
|
|
||||||
|
|
||||||
# We know this is always true based on the input arguments to `Popen`.
|
|
||||||
stdout: IO[bytes] = process.stdout # type: ignore
|
|
||||||
|
|
||||||
return cast(str, stdout.read().strip().decode('ascii'))
|
|
||||||
|
|
||||||
|
|
||||||
def build_defines_as_args() -> List[str]:
|
def build_defines_as_args():
|
||||||
return [
|
return [("-D" + "=".join(l.split(maxsplit=2)[1:]))
|
||||||
("-D" + "=".join(l.split(maxsplit=2)[1:]))
|
for l in build_defines_as_source().split("\n")
|
||||||
for l in build_defines_as_source().split("\n")
|
if l.startswith('#define')]
|
||||||
if l.startswith('#define')
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
# could be moved elsewhere!, this just happens to be used by scripts that also
|
# could be moved elsewhere!, this just happens to be used by scripts that also
|
||||||
# use this module.
|
# use this module.
|
||||||
def queue_processes(
|
def queue_processes(process_funcs, job_total=-1):
|
||||||
process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]],
|
|
||||||
job_total: int =-1,
|
|
||||||
) -> None:
|
|
||||||
""" Takes a list of function arg pairs, each function must return a process
|
""" Takes a list of function arg pairs, each function must return a process
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -263,7 +217,7 @@ def queue_processes(
|
|||||||
else:
|
else:
|
||||||
import time
|
import time
|
||||||
|
|
||||||
processes: List[subprocess.Popen[Any]] = []
|
processes = []
|
||||||
for func, args in process_funcs:
|
for func, args in process_funcs:
|
||||||
# wait until a thread is free
|
# wait until a thread is free
|
||||||
while 1:
|
while 1:
|
||||||
@@ -280,7 +234,7 @@ def queue_processes(
|
|||||||
processes.append(func(*args))
|
processes.append(func(*args))
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main():
|
||||||
if not os.path.exists(join(CMAKE_DIR, "CMakeCache.txt")):
|
if not os.path.exists(join(CMAKE_DIR, "CMakeCache.txt")):
|
||||||
print("This script must run from the cmake build dir")
|
print("This script must run from the cmake build dir")
|
||||||
return
|
return
|
||||||
|
@@ -1,12 +1,11 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import argparse
|
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Iterable, TextIO, Optional, Any, Union
|
from typing import Iterable, TextIO
|
||||||
|
|
||||||
# This script can run from any location,
|
# This script can run from any location,
|
||||||
# output is created in the $CWD
|
# output is created in the $CWD
|
||||||
@@ -19,43 +18,21 @@ SKIP_NAMES = {
|
|||||||
".gitignore",
|
".gitignore",
|
||||||
".gitmodules",
|
".gitmodules",
|
||||||
".arcconfig",
|
".arcconfig",
|
||||||
".svn",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
|
output_dir = Path(".").absolute()
|
||||||
blender_srcdir = Path(__file__).absolute().parent.parent.parent
|
blender_srcdir = Path(__file__).absolute().parent.parent.parent
|
||||||
|
|
||||||
cli_parser = argparse.ArgumentParser(
|
|
||||||
description=f"Create a tarball of the Blender sources, optionally including sources of dependencies.",
|
|
||||||
epilog="This script is intended to be run by `make source_archive_complete`.",
|
|
||||||
)
|
|
||||||
cli_parser.add_argument(
|
|
||||||
"-p",
|
|
||||||
"--include-packages",
|
|
||||||
type=Path,
|
|
||||||
default=None,
|
|
||||||
metavar="PACKAGE_PATH",
|
|
||||||
help="Include all source files from the given package directory as well.",
|
|
||||||
)
|
|
||||||
|
|
||||||
cli_args = cli_parser.parse_args()
|
|
||||||
|
|
||||||
print(f"Source dir: {blender_srcdir}")
|
print(f"Source dir: {blender_srcdir}")
|
||||||
|
|
||||||
curdir = blender_srcdir.parent
|
|
||||||
os.chdir(curdir)
|
|
||||||
blender_srcdir = blender_srcdir.relative_to(curdir)
|
|
||||||
|
|
||||||
print(f"Output dir: {curdir}")
|
|
||||||
|
|
||||||
version = parse_blender_version(blender_srcdir)
|
version = parse_blender_version(blender_srcdir)
|
||||||
tarball = tarball_path(curdir, version, cli_args)
|
manifest = output_dir / f"blender-{version}-manifest.txt"
|
||||||
manifest = manifest_path(tarball)
|
tarball = output_dir / f"blender-{version}.tar.xz"
|
||||||
packages_dir = packages_path(curdir, cli_args)
|
|
||||||
|
|
||||||
create_manifest(version, manifest, blender_srcdir, packages_dir)
|
os.chdir(blender_srcdir)
|
||||||
create_tarball(version, tarball, manifest, blender_srcdir, packages_dir)
|
create_manifest(version, manifest)
|
||||||
|
create_tarball(version, tarball, manifest)
|
||||||
create_checksum_file(tarball)
|
create_checksum_file(tarball)
|
||||||
cleanup(manifest)
|
cleanup(manifest)
|
||||||
print("Done!")
|
print("Done!")
|
||||||
@@ -107,109 +84,43 @@ def parse_blender_version(blender_srcdir: Path) -> BlenderVersion:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def tarball_path(output_dir: Path, version: BlenderVersion, cli_args: Any) -> Path:
|
|
||||||
extra = ""
|
|
||||||
if cli_args.include_packages:
|
|
||||||
extra = "-with-libraries"
|
|
||||||
|
|
||||||
return output_dir / f"blender{extra}-{version}.tar.xz"
|
|
||||||
|
|
||||||
|
|
||||||
def manifest_path(tarball: Path) -> Path:
|
|
||||||
"""Return the manifest path for the given tarball path.
|
|
||||||
|
|
||||||
>>> from pathlib import Path
|
|
||||||
>>> tarball = Path("/home/sybren/workspace/blender-git/blender-test.tar.gz")
|
|
||||||
>>> manifest_path(tarball).as_posix()
|
|
||||||
'/home/sybren/workspace/blender-git/blender-test-manifest.txt'
|
|
||||||
"""
|
|
||||||
# ".tar.gz" is seen as two suffixes.
|
|
||||||
without_suffix = tarball.with_suffix("").with_suffix("")
|
|
||||||
name = without_suffix.name
|
|
||||||
return without_suffix.with_name(f"{name}-manifest.txt")
|
|
||||||
|
|
||||||
|
|
||||||
def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]:
|
|
||||||
if not cli_args.include_packages:
|
|
||||||
return None
|
|
||||||
|
|
||||||
abspath = cli_args.include_packages.absolute()
|
|
||||||
|
|
||||||
# os.path.relpath() can return paths like "../../packages", where
|
|
||||||
# Path.relative_to() will not go up directories (so its return value never
|
|
||||||
# has "../" in there).
|
|
||||||
relpath = os.path.relpath(abspath, current_directory)
|
|
||||||
|
|
||||||
return Path(relpath)
|
|
||||||
|
|
||||||
|
|
||||||
### Manifest creation
|
### Manifest creation
|
||||||
|
|
||||||
|
|
||||||
def create_manifest(
|
def create_manifest(version: BlenderVersion, outpath: Path) -> None:
|
||||||
version: BlenderVersion,
|
|
||||||
outpath: Path,
|
|
||||||
blender_srcdir: Path,
|
|
||||||
packages_dir: Optional[Path],
|
|
||||||
) -> None:
|
|
||||||
print(f'Building manifest of files: "{outpath}"...', end="", flush=True)
|
print(f'Building manifest of files: "{outpath}"...', end="", flush=True)
|
||||||
with outpath.open("w", encoding="utf-8") as outfile:
|
with outpath.open("w", encoding="utf-8") as outfile:
|
||||||
main_files_to_manifest(blender_srcdir, outfile)
|
main_files_to_manifest(outfile)
|
||||||
submodules_to_manifest(blender_srcdir, version, outfile)
|
submodules_to_manifest(version, outfile)
|
||||||
|
|
||||||
if packages_dir:
|
|
||||||
packages_to_manifest(outfile, packages_dir)
|
|
||||||
print("OK")
|
print("OK")
|
||||||
|
|
||||||
|
|
||||||
def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None:
|
def main_files_to_manifest(outfile: TextIO) -> None:
|
||||||
assert not blender_srcdir.is_absolute()
|
for path in git_ls_files():
|
||||||
for path in git_ls_files(blender_srcdir):
|
|
||||||
print(path, file=outfile)
|
print(path, file=outfile)
|
||||||
|
|
||||||
|
|
||||||
def submodules_to_manifest(
|
def submodules_to_manifest(version: BlenderVersion, outfile: TextIO) -> None:
|
||||||
blender_srcdir: Path, version: BlenderVersion, outfile: TextIO
|
|
||||||
) -> None:
|
|
||||||
skip_addon_contrib = version.is_release
|
skip_addon_contrib = version.is_release
|
||||||
assert not blender_srcdir.is_absolute()
|
|
||||||
|
|
||||||
for line in git_command("-C", blender_srcdir, "submodule"):
|
for line in git_command("submodule"):
|
||||||
submodule = line.split()[1]
|
submodule = line.split()[1]
|
||||||
|
|
||||||
# Don't use native slashes as GIT for MS-Windows outputs forward slashes.
|
# Don't use native slashes as GIT for MS-Windows outputs forward slashes.
|
||||||
if skip_addon_contrib and submodule == "release/scripts/addons_contrib":
|
if skip_addon_contrib and submodule == "release/scripts/addons_contrib":
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for path in git_ls_files(blender_srcdir / submodule):
|
for path in git_ls_files(Path(submodule)):
|
||||||
print(path, file=outfile)
|
print(path, file=outfile)
|
||||||
|
|
||||||
|
|
||||||
def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None:
|
def create_tarball(version: BlenderVersion, tarball: Path, manifest: Path) -> None:
|
||||||
for path in packages_dir.glob("*"):
|
|
||||||
if not path.is_file():
|
|
||||||
continue
|
|
||||||
if path.name in SKIP_NAMES:
|
|
||||||
continue
|
|
||||||
print(path, file=outfile)
|
|
||||||
|
|
||||||
|
|
||||||
### Higher-level functions
|
|
||||||
|
|
||||||
|
|
||||||
def create_tarball(
|
|
||||||
version: BlenderVersion, tarball: Path, manifest: Path, blender_srcdir: Path, packages_dir: Optional[Path]
|
|
||||||
) -> None:
|
|
||||||
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
|
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
|
||||||
command = ["tar"]
|
|
||||||
|
|
||||||
# Requires GNU `tar`, since `--transform` is used.
|
# Requires GNU `tar`, since `--transform` is used.
|
||||||
if packages_dir:
|
command = [
|
||||||
command += ["--transform", f"s,{packages_dir}/,packages/,g"]
|
"tar",
|
||||||
|
|
||||||
command += [
|
|
||||||
"--transform",
|
"--transform",
|
||||||
f"s,^{blender_srcdir.name}/,blender-{version}/,g",
|
f"s,^,blender-{version}/,g",
|
||||||
"--use-compress-program=xz -9",
|
"--use-compress-program=xz -9",
|
||||||
"--create",
|
"--create",
|
||||||
f"--file={tarball}",
|
f"--file={tarball}",
|
||||||
@@ -219,8 +130,7 @@ def create_tarball(
|
|||||||
"--owner=0",
|
"--owner=0",
|
||||||
"--group=0",
|
"--group=0",
|
||||||
]
|
]
|
||||||
|
subprocess.run(command, check=True, timeout=300)
|
||||||
subprocess.run(command, check=True, timeout=3600)
|
|
||||||
print("OK")
|
print("OK")
|
||||||
|
|
||||||
|
|
||||||
@@ -264,7 +174,7 @@ def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]:
|
|||||||
yield path
|
yield path
|
||||||
|
|
||||||
|
|
||||||
def git_command(*cli_args: Union[bytes, str, Path] ) -> Iterable[str]:
|
def git_command(*cli_args) -> Iterable[str]:
|
||||||
"""Generator, yields lines of output from a Git command."""
|
"""Generator, yields lines of output from a Git command."""
|
||||||
command = ("git", *cli_args)
|
command = ("git", *cli_args)
|
||||||
|
|
||||||
|
@@ -9,10 +9,14 @@ if "%BUILD_WITH_SCCACHE%"=="1" (
|
|||||||
|
|
||||||
if "%WITH_CLANG%"=="1" (
|
if "%WITH_CLANG%"=="1" (
|
||||||
set CLANG_CMAKE_ARGS=-T"llvm"
|
set CLANG_CMAKE_ARGS=-T"llvm"
|
||||||
)
|
if "%WITH_ASAN%"=="1" (
|
||||||
|
|
||||||
if "%WITH_ASAN%"=="1" (
|
|
||||||
set ASAN_CMAKE_ARGS=-DWITH_COMPILER_ASAN=On
|
set ASAN_CMAKE_ARGS=-DWITH_COMPILER_ASAN=On
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
if "%WITH_ASAN%"=="1" (
|
||||||
|
echo ASAN is only supported with clang.
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%WITH_PYDEBUG%"=="1" (
|
if "%WITH_PYDEBUG%"=="1" (
|
||||||
|
@@ -46,10 +46,16 @@ set LLVM_DIR=
|
|||||||
set CFLAGS=-m64 -fmsc-version=1914
|
set CFLAGS=-m64 -fmsc-version=1914
|
||||||
set CXXFLAGS=-m64 -fmsc-version=1914
|
set CXXFLAGS=-m64 -fmsc-version=1914
|
||||||
)
|
)
|
||||||
|
if "%WITH_ASAN%"=="1" (
|
||||||
|
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_COMPILER_ASAN=On
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%WITH_ASAN%"=="1" (
|
if "%WITH_ASAN%"=="1" (
|
||||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DWITH_COMPILER_ASAN=On
|
if "%WITH_CLANG%" == "" (
|
||||||
|
echo ASAN is only supported with clang.
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if NOT "%verbose%" == "" (
|
if NOT "%verbose%" == "" (
|
||||||
|
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
|||||||
# could be handy for archiving the generated documentation or if some version
|
# could be handy for archiving the generated documentation or if some version
|
||||||
# control system is used.
|
# control system is used.
|
||||||
|
|
||||||
PROJECT_NUMBER = "V3.0"
|
PROJECT_NUMBER = "V2.93"
|
||||||
|
|
||||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
# 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
|
# for a project that appears at the top of each page and should give viewer a
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
This script generates the blender.1 man page, embedding the help text
|
This script generates the blender.1 man page, embedding the help text
|
||||||
from the Blender executable itself. Invoke it as follows:
|
from the Blender executable itself. Invoke it as follows:
|
||||||
|
|
||||||
blender.1.py --blender <path-to-blender> --output <output-filename>
|
blender.1.py <path-to-blender> <output-filename>
|
||||||
|
|
||||||
where <path-to-blender> is the path to the Blender executable,
|
where <path-to-blender> is the path to the Blender executable,
|
||||||
and <output-filename> is where to write the generated man page.
|
and <output-filename> is where to write the generated man page.
|
||||||
@@ -30,147 +30,108 @@ and <output-filename> is where to write the generated man page.
|
|||||||
|
|
||||||
# <pep8 compliant>
|
# <pep8 compliant>
|
||||||
|
|
||||||
import argparse
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from typing import (
|
|
||||||
Dict,
|
|
||||||
TextIO,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
def man_format(data):
|
||||||
def man_format(data: str) -> str:
|
|
||||||
data = data.replace("-", "\\-")
|
data = data.replace("-", "\\-")
|
||||||
data = data.replace("\t", " ")
|
data = data.replace("\t", " ")
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def blender_extract_info(blender_bin: str) -> Dict[str, str]:
|
if len(sys.argv) != 3:
|
||||||
|
import getopt
|
||||||
|
raise getopt.GetoptError("Usage: %s <path-to-blender> <output-filename>" % sys.argv[0])
|
||||||
|
|
||||||
blender_env = {
|
blender_bin = sys.argv[1]
|
||||||
"ASAN_OPTIONS": "exitcode=0:" + os.environ.get("ASAN_OPTIONS", ""),
|
outfilename = sys.argv[2]
|
||||||
}
|
|
||||||
|
|
||||||
blender_help = subprocess.run(
|
cmd = [blender_bin, "--help"]
|
||||||
[blender_bin, "--help"],
|
print(" executing:", " ".join(cmd))
|
||||||
env=blender_env,
|
ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
|
||||||
check=True,
|
blender_help = subprocess.run(
|
||||||
stdout=subprocess.PIPE,
|
cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
|
||||||
).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_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:
|
||||||
|
# Happens when built without WITH_BUILD_INFO e.g.
|
||||||
|
date_string = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
|
||||||
|
else:
|
||||||
|
blender_date = blender_date.strip().partition(" ")[2] # remove 'date:' prefix
|
||||||
|
date_string = time.strftime("%B %d, %Y", time.strptime(blender_date, "%Y-%m-%d"))
|
||||||
|
|
||||||
blender_version_ouput = subprocess.run(
|
outfile = open(outfilename, "w")
|
||||||
[blender_bin, "--version"],
|
fw = outfile.write
|
||||||
env=blender_env,
|
|
||||||
check=True,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
).stdout.decode(encoding="utf-8")
|
|
||||||
|
|
||||||
# Extract information from the version string.
|
fw('.TH "BLENDER" "1" "%s" "Blender %s"\n' % (date_string, blender_version.replace(".", "\\&.")))
|
||||||
# Note that some internal modules may print errors (e.g. color management),
|
|
||||||
# check for each lines prefix to ensure these aren't included.
|
|
||||||
blender_version = ""
|
|
||||||
blender_date = ""
|
|
||||||
for l in blender_version_ouput.split("\n"):
|
|
||||||
if l.startswith("Blender "):
|
|
||||||
# Remove 'Blender' prefix.
|
|
||||||
blender_version = l.split(" ", 1)[1].strip()
|
|
||||||
elif l.lstrip().startswith("build date:"):
|
|
||||||
# Remove 'build date:' prefix.
|
|
||||||
blender_date = l.split(":", 1)[1].strip()
|
|
||||||
if blender_version and blender_date:
|
|
||||||
break
|
|
||||||
|
|
||||||
if not blender_date:
|
fw('''
|
||||||
# Happens when built without WITH_BUILD_INFO e.g.
|
|
||||||
date_string = time.strftime("%B %d, %Y", time.gmtime(int(os.environ.get('SOURCE_DATE_EPOCH', time.time()))))
|
|
||||||
else:
|
|
||||||
date_string = time.strftime("%B %d, %Y", time.strptime(blender_date, "%Y-%m-%d"))
|
|
||||||
|
|
||||||
return {
|
|
||||||
"help": blender_help,
|
|
||||||
"version": blender_version,
|
|
||||||
"date": date_string,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def man_page_from_blender_help(fh: TextIO, blender_bin: str) -> None:
|
|
||||||
blender_info = blender_extract_info(blender_bin)
|
|
||||||
|
|
||||||
# Header Content.
|
|
||||||
fh.write(
|
|
||||||
'.TH "BLENDER" "1" "%s" "Blender %s"\n' %
|
|
||||||
(blender_info["date"], blender_info["version"].replace(".", "\\&."))
|
|
||||||
)
|
|
||||||
|
|
||||||
fh.write(r'''
|
|
||||||
.SH NAME
|
.SH NAME
|
||||||
blender \- a full-featured 3D application''')
|
blender \- a full-featured 3D application''')
|
||||||
|
|
||||||
fh.write(r'''
|
fw('''
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B blender [args ...] [file] [args ...]''')
|
.B blender [args ...] [file] [args ...]''')
|
||||||
|
|
||||||
fh.write(r'''
|
fw('''
|
||||||
.br
|
.br
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.PP
|
.PP
|
||||||
.B blender
|
.B blender
|
||||||
is a full-featured 3D application. It supports the entirety of the 3D pipeline - '''
|
is a full-featured 3D application. It supports the entirety of the 3D pipeline - modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
|
||||||
'''modeling, rigging, animation, simulation, rendering, compositing, motion tracking, and video editing.
|
|
||||||
|
|
||||||
Use Blender to create 3D images and animations, films and commercials, content for games, '''
|
Use Blender to create 3D images and animations, films and commercials, content for games, architectural and industrial visualizatons, and scientific visualizations.
|
||||||
r'''architectural and industrial visualizatons, and scientific visualizations.
|
|
||||||
|
|
||||||
https://www.blender.org''')
|
https://www.blender.org''')
|
||||||
|
|
||||||
fh.write(r'''
|
fw('''
|
||||||
.SH OPTIONS''')
|
.SH OPTIONS''')
|
||||||
|
|
||||||
fh.write("\n\n")
|
fw("\n\n")
|
||||||
|
|
||||||
# Body Content.
|
lines = [line.rstrip() for line in blender_help.split("\n")]
|
||||||
|
|
||||||
lines = [line.rstrip() for line in blender_info["help"].split("\n")]
|
while lines:
|
||||||
|
l = lines.pop(0)
|
||||||
|
if l.startswith("Environment Variables:"):
|
||||||
|
fw('.SH "ENVIRONMENT VARIABLES"\n')
|
||||||
|
elif l.endswith(":"): # one line
|
||||||
|
fw('.SS "%s"\n\n' % l)
|
||||||
|
elif l.startswith("-") or l.startswith("/"): # can be multi line
|
||||||
|
|
||||||
while lines:
|
fw('.TP\n')
|
||||||
l = lines.pop(0)
|
fw('.B %s\n' % man_format(l))
|
||||||
if l.startswith("Environment Variables:"):
|
|
||||||
fh.write('.SH "ENVIRONMENT VARIABLES"\n')
|
|
||||||
elif l.endswith(":"): # One line.
|
|
||||||
fh.write('.SS "%s"\n\n' % l)
|
|
||||||
elif l.startswith("-") or l.startswith("/"): # Can be multi line.
|
|
||||||
fh.write('.TP\n')
|
|
||||||
fh.write('.B %s\n' % man_format(l))
|
|
||||||
|
|
||||||
while lines:
|
while lines:
|
||||||
# line with no
|
# line with no
|
||||||
if lines[0].strip() and len(lines[0].lstrip()) == len(lines[0]): # No white space.
|
if lines[0].strip() and len(lines[0].lstrip()) == len(lines[0]): # no white space
|
||||||
break
|
break
|
||||||
|
|
||||||
if not l: # Second blank line.
|
if not l: # second blank line
|
||||||
fh.write('.IP\n')
|
fw('.IP\n')
|
||||||
else:
|
|
||||||
fh.write('.br\n')
|
|
||||||
|
|
||||||
l = lines.pop(0)
|
|
||||||
if l:
|
|
||||||
assert(l.startswith('\t'))
|
|
||||||
l = l[1:] # Remove first white-space (tab).
|
|
||||||
|
|
||||||
fh.write('%s\n' % man_format(l))
|
|
||||||
|
|
||||||
else:
|
|
||||||
if not l.strip():
|
|
||||||
fh.write('.br\n')
|
|
||||||
else:
|
else:
|
||||||
fh.write('%s\n' % man_format(l))
|
fw('.br\n')
|
||||||
|
|
||||||
# Footer Content.
|
l = lines.pop(0)
|
||||||
|
l = l[1:] # remove first whitespace (tab)
|
||||||
|
|
||||||
fh.write(r'''
|
fw('%s\n' % man_format(l))
|
||||||
|
|
||||||
|
else:
|
||||||
|
if not l.strip():
|
||||||
|
fw('.br\n')
|
||||||
|
else:
|
||||||
|
fw('%s\n' % man_format(l))
|
||||||
|
|
||||||
|
# footer
|
||||||
|
|
||||||
|
fw('''
|
||||||
.br
|
.br
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.B luxrender(1)
|
.B luxrender(1)
|
||||||
@@ -182,33 +143,5 @@ This manpage was written for a Debian GNU/Linux system by Daniel Mester
|
|||||||
<cyril.brulebois@enst-bretagne.fr> and Dan Eicher <dan@trollwerks.org>.
|
<cyril.brulebois@enst-bretagne.fr> and Dan Eicher <dan@trollwerks.org>.
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
outfile.close()
|
||||||
def create_argparse() -> argparse.ArgumentParser:
|
print("written:", outfilename)
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument(
|
|
||||||
"--output",
|
|
||||||
required=True,
|
|
||||||
help="The man page to write to."
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"--blender",
|
|
||||||
required=True,
|
|
||||||
help="Path to the blender binary."
|
|
||||||
)
|
|
||||||
|
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def main() -> None:
|
|
||||||
parser = create_argparse()
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
blender_bin = args.blender
|
|
||||||
output_filename = args.output
|
|
||||||
|
|
||||||
with open(output_filename, "w", encoding="utf-8") as fh:
|
|
||||||
man_page_from_blender_help(fh, blender_bin)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
|
@@ -61,3 +61,4 @@ def unregister():
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
register()
|
register()
|
||||||
|
|
||||||
|
@@ -1,2 +1,2 @@
|
|||||||
Sphinx==3.5.3
|
Sphinx==3.5.1
|
||||||
sphinx_rtd_theme==0.5.2
|
sphinx_rtd_theme==0.5.1
|
||||||
|
@@ -50,8 +50,7 @@ you should be able to find the poll function with no knowledge of C.
|
|||||||
|
|
||||||
Blender does have the functionality for poll functions to describe why they fail,
|
Blender does have the functionality for poll functions to describe why they fail,
|
||||||
but its currently not used much, if you're interested to help improve the API
|
but its currently not used much, if you're interested to help improve the API
|
||||||
feel free to add calls to :class:`bpy.types.Operator.poll_message_set` (``CTX_wm_operator_poll_msg_set`` in C)
|
feel free to add calls to ``CTX_wm_operator_poll_msg_set`` where its not obvious why poll fails, e.g:
|
||||||
where its not obvious why poll fails, e.g:
|
|
||||||
|
|
||||||
>>> bpy.ops.gpencil.draw()
|
>>> bpy.ops.gpencil.draw()
|
||||||
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
|
RuntimeError: Operator bpy.ops.gpencil.draw.poll() Failed to find Grease Pencil data to draw into
|
||||||
|
@@ -553,7 +553,7 @@ def example_extract_docstring(filepath):
|
|||||||
line_no += 1
|
line_no += 1
|
||||||
else:
|
else:
|
||||||
file.close()
|
file.close()
|
||||||
return "", 0, False
|
return "", 0
|
||||||
|
|
||||||
for line in file:
|
for line in file:
|
||||||
line_no += 1
|
line_no += 1
|
||||||
@@ -563,17 +563,15 @@ def example_extract_docstring(filepath):
|
|||||||
text.append(line.rstrip())
|
text.append(line.rstrip())
|
||||||
|
|
||||||
line_no += 1
|
line_no += 1
|
||||||
line_no_has_content = False
|
|
||||||
|
|
||||||
# Skip over blank lines so the Python code doesn't have blank lines at the top.
|
# Skip over blank lines so the Python code doesn't have blank lines at the top.
|
||||||
for line in file:
|
for line in file:
|
||||||
if line.strip():
|
if line.strip():
|
||||||
line_no_has_content = True
|
|
||||||
break
|
break
|
||||||
line_no += 1
|
line_no += 1
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
return "\n".join(text), line_no, line_no_has_content
|
return "\n".join(text), line_no
|
||||||
|
|
||||||
|
|
||||||
def title_string(text, heading_char, double=False):
|
def title_string(text, heading_char, double=False):
|
||||||
@@ -592,18 +590,16 @@ def write_example_ref(ident, fw, example_id, ext="py"):
|
|||||||
filepath = os.path.join("..", "examples", "%s.%s" % (example_id, ext))
|
filepath = os.path.join("..", "examples", "%s.%s" % (example_id, ext))
|
||||||
filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
|
filepath_full = os.path.join(os.path.dirname(fw.__self__.name), filepath)
|
||||||
|
|
||||||
text, line_no, line_no_has_content = example_extract_docstring(filepath_full)
|
text, line_no = example_extract_docstring(filepath_full)
|
||||||
|
|
||||||
for line in text.split("\n"):
|
for line in text.split("\n"):
|
||||||
fw("%s\n" % (ident + line).rstrip())
|
fw("%s\n" % (ident + line).rstrip())
|
||||||
fw("\n")
|
fw("\n")
|
||||||
|
|
||||||
# Some files only contain a doc-string.
|
fw("%s.. literalinclude:: %s\n" % (ident, filepath))
|
||||||
if line_no_has_content:
|
if line_no > 0:
|
||||||
fw("%s.. literalinclude:: %s\n" % (ident, filepath))
|
fw("%s :lines: %d-\n" % (ident, line_no))
|
||||||
if line_no > 0:
|
fw("\n")
|
||||||
fw("%s :lines: %d-\n" % (ident, line_no))
|
|
||||||
fw("\n")
|
|
||||||
EXAMPLE_SET_USED.add(example_id)
|
EXAMPLE_SET_USED.add(example_id)
|
||||||
else:
|
else:
|
||||||
if bpy.app.debug:
|
if bpy.app.debug:
|
||||||
@@ -1412,8 +1408,7 @@ def pyrna2sphinx(basepath):
|
|||||||
else:
|
else:
|
||||||
fw(" .. attribute:: %s\n\n" % prop.identifier)
|
fw(" .. attribute:: %s\n\n" % prop.identifier)
|
||||||
if prop.description:
|
if prop.description:
|
||||||
write_indented_lines(" ", fw, prop.description, False)
|
fw(" %s\n\n" % prop.description)
|
||||||
fw("\n")
|
|
||||||
|
|
||||||
# special exception, can't use generic code here for enums
|
# special exception, can't use generic code here for enums
|
||||||
if prop.type == "enum":
|
if prop.type == "enum":
|
||||||
|
4
extern/CMakeLists.txt
vendored
4
extern/CMakeLists.txt
vendored
@@ -109,7 +109,3 @@ endif()
|
|||||||
if(WITH_MOD_FLUID)
|
if(WITH_MOD_FLUID)
|
||||||
add_subdirectory(mantaflow)
|
add_subdirectory(mantaflow)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_COMPOSITOR)
|
|
||||||
add_subdirectory(smaa_areatex)
|
|
||||||
endif()
|
|
||||||
|
2
extern/audaspace/CMakeLists.txt
vendored
2
extern/audaspace/CMakeLists.txt
vendored
@@ -42,7 +42,6 @@ set(SRC
|
|||||||
src/devices/NULLDevice.cpp
|
src/devices/NULLDevice.cpp
|
||||||
src/devices/ReadDevice.cpp
|
src/devices/ReadDevice.cpp
|
||||||
src/devices/SoftwareDevice.cpp
|
src/devices/SoftwareDevice.cpp
|
||||||
src/devices/ThreadedDevice.cpp
|
|
||||||
src/Exception.cpp
|
src/Exception.cpp
|
||||||
src/file/File.cpp
|
src/file/File.cpp
|
||||||
src/file/FileManager.cpp
|
src/file/FileManager.cpp
|
||||||
@@ -149,7 +148,6 @@ set(PUBLIC_HDR
|
|||||||
include/devices/NULLDevice.h
|
include/devices/NULLDevice.h
|
||||||
include/devices/ReadDevice.h
|
include/devices/ReadDevice.h
|
||||||
include/devices/SoftwareDevice.h
|
include/devices/SoftwareDevice.h
|
||||||
include/devices/ThreadedDevice.h
|
|
||||||
include/Exception.h
|
include/Exception.h
|
||||||
include/file/File.h
|
include/file/File.h
|
||||||
include/file/FileManager.h
|
include/file/FileManager.h
|
||||||
|
@@ -255,7 +255,6 @@ protected:
|
|||||||
/**
|
/**
|
||||||
* This function tells the device, to start or pause playback.
|
* This function tells the device, to start or pause playback.
|
||||||
* \param playing True if device should playback.
|
* \param playing True if device should playback.
|
||||||
* \note This method is only called when the device is locked.
|
|
||||||
*/
|
*/
|
||||||
virtual void playing(bool playing)=0;
|
virtual void playing(bool playing)=0;
|
||||||
|
|
||||||
|
@@ -1,95 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright 2009-2016 Jörg Müller
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @file ThreadedDevice.h
|
|
||||||
* @ingroup plugin
|
|
||||||
* The ThreadedDevice class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "devices/SoftwareDevice.h"
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
AUD_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This device extends the SoftwareDevice with code for running mixing in a separate thread.
|
|
||||||
*/
|
|
||||||
class AUD_PLUGIN_API ThreadedDevice : public SoftwareDevice
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/**
|
|
||||||
* Whether there is currently playback.
|
|
||||||
*/
|
|
||||||
bool m_playing;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether the current playback should stop.
|
|
||||||
*/
|
|
||||||
bool m_stop;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The streaming thread.
|
|
||||||
*/
|
|
||||||
std::thread m_thread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts the streaming thread.
|
|
||||||
*/
|
|
||||||
AUD_LOCAL void start();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Streaming thread main function.
|
|
||||||
*/
|
|
||||||
AUD_LOCAL virtual void runMixingThread()=0;
|
|
||||||
|
|
||||||
// delete copy constructor and operator=
|
|
||||||
ThreadedDevice(const ThreadedDevice&) = delete;
|
|
||||||
ThreadedDevice& operator=(const ThreadedDevice&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void playing(bool playing);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Empty default constructor. To setup the device call the function create()
|
|
||||||
* and to uninitialize call destroy().
|
|
||||||
*/
|
|
||||||
ThreadedDevice();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates that the mixing thread should be stopped.
|
|
||||||
* \return Whether the mixing thread should be stopping.
|
|
||||||
* \warning For thread safety, the device needs to be locked, when this method is called.
|
|
||||||
*/
|
|
||||||
inline bool shouldStop() { return m_stop; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method needs to be called when the mixing thread is stopping.
|
|
||||||
* \warning For thread safety, the device needs to be locked, when this method is called.
|
|
||||||
*/
|
|
||||||
inline void doStop() { m_stop = m_playing = false; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stops all playback and notifies the mixing thread to stop.
|
|
||||||
* \warning The device has to be unlocked to not run into a deadlock.
|
|
||||||
*/
|
|
||||||
void stopMixingThread();
|
|
||||||
};
|
|
||||||
|
|
||||||
AUD_NAMESPACE_END
|
|
@@ -27,9 +27,9 @@ void PulseAudioDevice::PulseAudio_state_callback(pa_context *context, void *data
|
|||||||
{
|
{
|
||||||
PulseAudioDevice* device = (PulseAudioDevice*)data;
|
PulseAudioDevice* device = (PulseAudioDevice*)data;
|
||||||
|
|
||||||
std::lock_guard<ILockable> lock(*device);
|
|
||||||
|
|
||||||
device->m_state = AUD_pa_context_get_state(context);
|
device->m_state = AUD_pa_context_get_state(context);
|
||||||
|
|
||||||
|
AUD_pa_threaded_mainloop_signal(device->m_mainloop, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t num_bytes, void *data)
|
void PulseAudioDevice::PulseAudio_request(pa_stream *stream, size_t num_bytes, void *data)
|
||||||
@@ -68,40 +68,29 @@ void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PulseAudioDevice::runMixingThread()
|
void PulseAudioDevice::playing(bool playing)
|
||||||
{
|
{
|
||||||
for(;;)
|
m_playback = playing;
|
||||||
{
|
|
||||||
{
|
|
||||||
std::lock_guard<ILockable> lock(*this);
|
|
||||||
|
|
||||||
if(shouldStop())
|
AUD_pa_stream_cork(m_stream, playing ? 0 : 1, nullptr, nullptr);
|
||||||
{
|
|
||||||
AUD_pa_stream_cork(m_stream, 1, nullptr, nullptr);
|
|
||||||
doStop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(AUD_pa_stream_is_corked(m_stream))
|
|
||||||
AUD_pa_stream_cork(m_stream, 0, nullptr, nullptr);
|
|
||||||
|
|
||||||
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
|
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
|
||||||
|
m_playback(false),
|
||||||
m_state(PA_CONTEXT_UNCONNECTED),
|
m_state(PA_CONTEXT_UNCONNECTED),
|
||||||
m_buffersize(buffersize),
|
m_buffersize(buffersize),
|
||||||
m_underflows(0)
|
m_underflows(0)
|
||||||
{
|
{
|
||||||
m_mainloop = AUD_pa_mainloop_new();
|
m_mainloop = AUD_pa_threaded_mainloop_new();
|
||||||
|
|
||||||
m_context = AUD_pa_context_new(AUD_pa_mainloop_get_api(m_mainloop), name.c_str());
|
AUD_pa_threaded_mainloop_lock(m_mainloop);
|
||||||
|
|
||||||
|
m_context = AUD_pa_context_new(AUD_pa_threaded_mainloop_get_api(m_mainloop), name.c_str());
|
||||||
|
|
||||||
if(!m_context)
|
if(!m_context)
|
||||||
{
|
{
|
||||||
AUD_pa_mainloop_free(m_mainloop);
|
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||||
|
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||||
|
|
||||||
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
||||||
}
|
}
|
||||||
@@ -110,21 +99,26 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
|||||||
|
|
||||||
AUD_pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
|
AUD_pa_context_connect(m_context, nullptr, PA_CONTEXT_NOFLAGS, nullptr);
|
||||||
|
|
||||||
|
AUD_pa_threaded_mainloop_start(m_mainloop);
|
||||||
|
|
||||||
while(m_state != PA_CONTEXT_READY)
|
while(m_state != PA_CONTEXT_READY)
|
||||||
{
|
{
|
||||||
switch(m_state)
|
switch(m_state)
|
||||||
{
|
{
|
||||||
case PA_CONTEXT_FAILED:
|
case PA_CONTEXT_FAILED:
|
||||||
case PA_CONTEXT_TERMINATED:
|
case PA_CONTEXT_TERMINATED:
|
||||||
|
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||||
|
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||||
|
|
||||||
AUD_pa_context_disconnect(m_context);
|
AUD_pa_context_disconnect(m_context);
|
||||||
AUD_pa_context_unref(m_context);
|
AUD_pa_context_unref(m_context);
|
||||||
|
|
||||||
AUD_pa_mainloop_free(m_mainloop);
|
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||||
|
|
||||||
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
|
AUD_pa_threaded_mainloop_wait(m_mainloop);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,10 +166,13 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
|||||||
|
|
||||||
if(!m_stream)
|
if(!m_stream)
|
||||||
{
|
{
|
||||||
|
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||||
|
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||||
|
|
||||||
AUD_pa_context_disconnect(m_context);
|
AUD_pa_context_disconnect(m_context);
|
||||||
AUD_pa_context_unref(m_context);
|
AUD_pa_context_unref(m_context);
|
||||||
|
|
||||||
AUD_pa_mainloop_free(m_mainloop);
|
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||||
|
|
||||||
AUD_THROW(DeviceException, "Could not create PulseAudio stream.");
|
AUD_THROW(DeviceException, "Could not create PulseAudio stream.");
|
||||||
}
|
}
|
||||||
@@ -191,27 +188,32 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
|||||||
buffer_attr.prebuf = -1U;
|
buffer_attr.prebuf = -1U;
|
||||||
buffer_attr.tlength = buffersize;
|
buffer_attr.tlength = buffersize;
|
||||||
|
|
||||||
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_START_CORKED | PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
|
if(AUD_pa_stream_connect_playback(m_stream, nullptr, &buffer_attr, static_cast<pa_stream_flags_t>(PA_STREAM_INTERPOLATE_TIMING | PA_STREAM_ADJUST_LATENCY | PA_STREAM_AUTO_TIMING_UPDATE), nullptr, nullptr) < 0)
|
||||||
{
|
{
|
||||||
|
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||||
|
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||||
|
|
||||||
AUD_pa_context_disconnect(m_context);
|
AUD_pa_context_disconnect(m_context);
|
||||||
AUD_pa_context_unref(m_context);
|
AUD_pa_context_unref(m_context);
|
||||||
|
|
||||||
AUD_pa_mainloop_free(m_mainloop);
|
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||||
|
|
||||||
AUD_THROW(DeviceException, "Could not connect PulseAudio stream.");
|
AUD_THROW(DeviceException, "Could not connect PulseAudio stream.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AUD_pa_threaded_mainloop_unlock(m_mainloop);
|
||||||
|
|
||||||
create();
|
create();
|
||||||
}
|
}
|
||||||
|
|
||||||
PulseAudioDevice::~PulseAudioDevice()
|
PulseAudioDevice::~PulseAudioDevice()
|
||||||
{
|
{
|
||||||
stopMixingThread();
|
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||||
|
|
||||||
AUD_pa_context_disconnect(m_context);
|
AUD_pa_context_disconnect(m_context);
|
||||||
AUD_pa_context_unref(m_context);
|
AUD_pa_context_unref(m_context);
|
||||||
|
|
||||||
AUD_pa_mainloop_free(m_mainloop);
|
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||||
|
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
* The PulseAudioDevice class.
|
* The PulseAudioDevice class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "devices/ThreadedDevice.h"
|
#include "devices/SoftwareDevice.h"
|
||||||
|
|
||||||
#include <pulse/pulseaudio.h>
|
#include <pulse/pulseaudio.h>
|
||||||
|
|
||||||
@@ -35,10 +35,15 @@ AUD_NAMESPACE_BEGIN
|
|||||||
/**
|
/**
|
||||||
* This device plays back through PulseAudio, the simple direct media layer.
|
* This device plays back through PulseAudio, the simple direct media layer.
|
||||||
*/
|
*/
|
||||||
class AUD_PLUGIN_API PulseAudioDevice : public ThreadedDevice
|
class AUD_PLUGIN_API PulseAudioDevice : public SoftwareDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
pa_mainloop* m_mainloop;
|
/**
|
||||||
|
* Whether there is currently playback.
|
||||||
|
*/
|
||||||
|
volatile bool m_playback;
|
||||||
|
|
||||||
|
pa_threaded_mainloop* m_mainloop;
|
||||||
pa_context* m_context;
|
pa_context* m_context;
|
||||||
pa_stream* m_stream;
|
pa_stream* m_stream;
|
||||||
pa_context_state_t m_state;
|
pa_context_state_t m_state;
|
||||||
@@ -69,15 +74,13 @@ private:
|
|||||||
*/
|
*/
|
||||||
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);
|
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);
|
||||||
|
|
||||||
/**
|
|
||||||
* Streaming thread main function.
|
|
||||||
*/
|
|
||||||
AUD_LOCAL void runMixingThread();
|
|
||||||
|
|
||||||
// delete copy constructor and operator=
|
// delete copy constructor and operator=
|
||||||
PulseAudioDevice(const PulseAudioDevice&) = delete;
|
PulseAudioDevice(const PulseAudioDevice&) = delete;
|
||||||
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;
|
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void playing(bool playing);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Opens the PulseAudio audio device for playback.
|
* Opens the PulseAudio audio device for playback.
|
||||||
|
@@ -24,14 +24,18 @@ PULSEAUDIO_SYMBOL(pa_context_unref);
|
|||||||
PULSEAUDIO_SYMBOL(pa_stream_begin_write);
|
PULSEAUDIO_SYMBOL(pa_stream_begin_write);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_connect_playback);
|
PULSEAUDIO_SYMBOL(pa_stream_connect_playback);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_cork);
|
PULSEAUDIO_SYMBOL(pa_stream_cork);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_is_corked);
|
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_new);
|
PULSEAUDIO_SYMBOL(pa_stream_new);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
|
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_set_underflow_callback);
|
PULSEAUDIO_SYMBOL(pa_stream_set_underflow_callback);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_set_write_callback);
|
PULSEAUDIO_SYMBOL(pa_stream_set_write_callback);
|
||||||
PULSEAUDIO_SYMBOL(pa_stream_write);
|
PULSEAUDIO_SYMBOL(pa_stream_write);
|
||||||
|
|
||||||
PULSEAUDIO_SYMBOL(pa_mainloop_free);
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_free);
|
||||||
PULSEAUDIO_SYMBOL(pa_mainloop_get_api);
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_get_api);
|
||||||
PULSEAUDIO_SYMBOL(pa_mainloop_new);
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_lock);
|
||||||
PULSEAUDIO_SYMBOL(pa_mainloop_iterate);
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_new);
|
||||||
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_signal);
|
||||||
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_start);
|
||||||
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_stop);
|
||||||
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_unlock);
|
||||||
|
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_wait);
|
||||||
|
133
extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
vendored
133
extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
vendored
@@ -31,43 +31,63 @@ template <class T> void SafeRelease(T **ppT)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WASAPIDevice::runMixingThread()
|
void WASAPIDevice::start()
|
||||||
|
{
|
||||||
|
lock();
|
||||||
|
|
||||||
|
if(!m_playing)
|
||||||
|
{
|
||||||
|
if(m_thread.joinable())
|
||||||
|
m_thread.join();
|
||||||
|
|
||||||
|
m_playing = true;
|
||||||
|
|
||||||
|
m_thread = std::thread(&WASAPIDevice::updateStream, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WASAPIDevice::updateStream()
|
||||||
{
|
{
|
||||||
UINT32 buffer_size;
|
UINT32 buffer_size;
|
||||||
UINT32 padding;
|
|
||||||
UINT32 length;
|
|
||||||
data_t* buffer;
|
data_t* buffer;
|
||||||
|
|
||||||
|
if(FAILED(m_audio_client->GetBufferSize(&buffer_size)))
|
||||||
|
return;
|
||||||
|
|
||||||
IAudioRenderClient* render_client = nullptr;
|
IAudioRenderClient* render_client = nullptr;
|
||||||
|
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
|
||||||
|
|
||||||
|
if(FAILED(m_audio_client->GetService(IID_IAudioRenderClient, reinterpret_cast<void**>(&render_client))))
|
||||||
|
return;
|
||||||
|
|
||||||
|
UINT32 padding;
|
||||||
|
|
||||||
|
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
|
||||||
{
|
{
|
||||||
std::lock_guard<ILockable> lock(*this);
|
SafeRelease(&render_client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
|
UINT32 length = buffer_size - padding;
|
||||||
|
|
||||||
if(FAILED(m_audio_client->GetBufferSize(&buffer_size)))
|
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
||||||
goto init_error;
|
{
|
||||||
|
SafeRelease(&render_client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(FAILED(m_audio_client->GetService(IID_IAudioRenderClient, reinterpret_cast<void**>(&render_client))))
|
lock();
|
||||||
goto init_error;
|
|
||||||
|
|
||||||
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
|
mix((data_t*)buffer, length);
|
||||||
goto init_error;
|
|
||||||
|
|
||||||
length = buffer_size - padding;
|
unlock();
|
||||||
|
|
||||||
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||||
goto init_error;
|
{
|
||||||
|
SafeRelease(&render_client);
|
||||||
mix((data_t*)buffer, length);
|
return;
|
||||||
|
|
||||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
|
||||||
{
|
|
||||||
init_error:
|
|
||||||
SafeRelease(&render_client);
|
|
||||||
doStop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_audio_client->Start();
|
m_audio_client->Start();
|
||||||
@@ -76,38 +96,58 @@ void WASAPIDevice::runMixingThread()
|
|||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
|
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
|
||||||
{
|
{
|
||||||
std::lock_guard<ILockable> lock(*this);
|
m_audio_client->Stop();
|
||||||
|
SafeRelease(&render_client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
|
length = buffer_size - padding;
|
||||||
goto stop_thread;
|
|
||||||
|
|
||||||
length = buffer_size - padding;
|
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
||||||
|
{
|
||||||
|
m_audio_client->Stop();
|
||||||
|
SafeRelease(&render_client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
lock();
|
||||||
goto stop_thread;
|
|
||||||
|
|
||||||
mix((data_t*)buffer, length);
|
mix((data_t*)buffer, length);
|
||||||
|
|
||||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
unlock();
|
||||||
goto stop_thread;
|
|
||||||
|
|
||||||
// stop thread
|
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||||
if(shouldStop())
|
{
|
||||||
{
|
m_audio_client->Stop();
|
||||||
stop_thread:
|
SafeRelease(&render_client);
|
||||||
m_audio_client->Stop();
|
return;
|
||||||
SafeRelease(&render_client);
|
}
|
||||||
doStop();
|
|
||||||
return;
|
// stop thread
|
||||||
}
|
if(!m_playing)
|
||||||
|
{
|
||||||
|
m_audio_client->Stop();
|
||||||
|
SafeRelease(&render_client);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(sleepDuration);
|
std::this_thread::sleep_for(sleepDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WASAPIDevice::playing(bool playing)
|
||||||
|
{
|
||||||
|
if(!m_playing && playing)
|
||||||
|
start();
|
||||||
|
else
|
||||||
|
m_playing = playing;
|
||||||
|
}
|
||||||
|
|
||||||
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
||||||
|
m_playing(false),
|
||||||
|
|
||||||
m_imm_device_enumerator(nullptr),
|
m_imm_device_enumerator(nullptr),
|
||||||
m_imm_device(nullptr),
|
m_imm_device(nullptr),
|
||||||
m_audio_client(nullptr),
|
m_audio_client(nullptr),
|
||||||
@@ -285,7 +325,14 @@ WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
|||||||
|
|
||||||
WASAPIDevice::~WASAPIDevice()
|
WASAPIDevice::~WASAPIDevice()
|
||||||
{
|
{
|
||||||
stopMixingThread();
|
lock();
|
||||||
|
|
||||||
|
stopAll();
|
||||||
|
|
||||||
|
unlock();
|
||||||
|
|
||||||
|
if(m_thread.joinable())
|
||||||
|
m_thread.join();
|
||||||
|
|
||||||
SafeRelease(&m_audio_client);
|
SafeRelease(&m_audio_client);
|
||||||
SafeRelease(&m_imm_device);
|
SafeRelease(&m_imm_device);
|
||||||
|
24
extern/audaspace/plugins/wasapi/WASAPIDevice.h
vendored
24
extern/audaspace/plugins/wasapi/WASAPIDevice.h
vendored
@@ -26,7 +26,7 @@
|
|||||||
* The WASAPIDevice class.
|
* The WASAPIDevice class.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "devices/ThreadedDevice.h"
|
#include "devices/SoftwareDevice.h"
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
@@ -40,23 +40,41 @@ AUD_NAMESPACE_BEGIN
|
|||||||
/**
|
/**
|
||||||
* This device plays back through WASAPI, the Windows audio API.
|
* This device plays back through WASAPI, the Windows audio API.
|
||||||
*/
|
*/
|
||||||
class AUD_PLUGIN_API WASAPIDevice : public ThreadedDevice
|
class AUD_PLUGIN_API WASAPIDevice : public SoftwareDevice
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Whether there is currently playback.
|
||||||
|
*/
|
||||||
|
bool m_playing;
|
||||||
|
|
||||||
IMMDeviceEnumerator* m_imm_device_enumerator;
|
IMMDeviceEnumerator* m_imm_device_enumerator;
|
||||||
IMMDevice* m_imm_device;
|
IMMDevice* m_imm_device;
|
||||||
IAudioClient* m_audio_client;
|
IAudioClient* m_audio_client;
|
||||||
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
|
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The streaming thread.
|
||||||
|
*/
|
||||||
|
std::thread m_thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the streaming thread.
|
||||||
|
*/
|
||||||
|
AUD_LOCAL void start();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Streaming thread main function.
|
* Streaming thread main function.
|
||||||
*/
|
*/
|
||||||
AUD_LOCAL void runMixingThread();
|
AUD_LOCAL void updateStream();
|
||||||
|
|
||||||
// delete copy constructor and operator=
|
// delete copy constructor and operator=
|
||||||
WASAPIDevice(const WASAPIDevice&) = delete;
|
WASAPIDevice(const WASAPIDevice&) = delete;
|
||||||
WASAPIDevice& operator=(const WASAPIDevice&) = delete;
|
WASAPIDevice& operator=(const WASAPIDevice&) = delete;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void playing(bool playing);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Opens the WASAPI audio device for playback.
|
* Opens the WASAPI audio device for playback.
|
||||||
|
@@ -737,7 +737,7 @@ void SoftwareDevice::mix(data_t* buffer, int length)
|
|||||||
{
|
{
|
||||||
m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
|
m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
|
||||||
|
|
||||||
std::lock_guard<ILockable> lock(*this);
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
{
|
{
|
||||||
std::shared_ptr<SoftwareDevice::SoftwareHandle> sound;
|
std::shared_ptr<SoftwareDevice::SoftwareHandle> sound;
|
||||||
@@ -880,7 +880,7 @@ std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<IReader> reader, b
|
|||||||
// play sound
|
// play sound
|
||||||
std::shared_ptr<SoftwareDevice::SoftwareHandle> sound = std::shared_ptr<SoftwareDevice::SoftwareHandle>(new SoftwareDevice::SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
|
std::shared_ptr<SoftwareDevice::SoftwareHandle> sound = std::shared_ptr<SoftwareDevice::SoftwareHandle>(new SoftwareDevice::SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
|
||||||
|
|
||||||
std::lock_guard<ILockable> lock(*this);
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
m_playingSounds.push_back(sound);
|
m_playingSounds.push_back(sound);
|
||||||
|
|
||||||
@@ -897,7 +897,7 @@ std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<ISound> sound, boo
|
|||||||
|
|
||||||
void SoftwareDevice::stopAll()
|
void SoftwareDevice::stopAll()
|
||||||
{
|
{
|
||||||
std::lock_guard<ILockable> lock(*this);
|
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||||
|
|
||||||
while(!m_playingSounds.empty())
|
while(!m_playingSounds.empty())
|
||||||
m_playingSounds.front()->stop();
|
m_playingSounds.front()->stop();
|
||||||
|
65
extern/audaspace/src/devices/ThreadedDevice.cpp
vendored
65
extern/audaspace/src/devices/ThreadedDevice.cpp
vendored
@@ -1,65 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* Copyright 2009-2016 Jörg Müller
|
|
||||||
*
|
|
||||||
* 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 "devices/ThreadedDevice.h"
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
AUD_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
void ThreadedDevice::start()
|
|
||||||
{
|
|
||||||
std::lock_guard<ILockable> lock(*this);
|
|
||||||
|
|
||||||
// thread is still running, we can abort stopping it
|
|
||||||
if(m_stop)
|
|
||||||
m_stop = false;
|
|
||||||
|
|
||||||
// thread is not running, let's start it
|
|
||||||
else if(!m_playing)
|
|
||||||
{
|
|
||||||
if(m_thread.joinable())
|
|
||||||
m_thread.join();
|
|
||||||
|
|
||||||
m_playing = true;
|
|
||||||
|
|
||||||
m_thread = std::thread(&ThreadedDevice::runMixingThread, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadedDevice::playing(bool playing)
|
|
||||||
{
|
|
||||||
if((!m_playing || m_stop) && playing)
|
|
||||||
start();
|
|
||||||
else
|
|
||||||
m_stop = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ThreadedDevice::ThreadedDevice() :
|
|
||||||
m_playing(false),
|
|
||||||
m_stop(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void aud::ThreadedDevice::stopMixingThread()
|
|
||||||
{
|
|
||||||
stopAll();
|
|
||||||
|
|
||||||
if(m_thread.joinable())
|
|
||||||
m_thread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
AUD_NAMESPACE_END
|
|
26
extern/smaa_areatex/CMakeLists.txt
vendored
26
extern/smaa_areatex/CMakeLists.txt
vendored
@@ -1,26 +0,0 @@
|
|||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU General Public License
|
|
||||||
# as published by the Free Software Foundation; either version 2
|
|
||||||
# of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
#
|
|
||||||
# The Original Code is Copyright (C) 2017, Blender Foundation
|
|
||||||
# All rights reserved.
|
|
||||||
#
|
|
||||||
# The Original Code is: all of this file.
|
|
||||||
#
|
|
||||||
# Contributor(s): IRIE Shinsuke
|
|
||||||
#
|
|
||||||
# ***** END GPL LICENSE BLOCK *****
|
|
||||||
|
|
||||||
add_executable(smaa_areatex smaa_areatex.cpp)
|
|
5
extern/smaa_areatex/README.blender
vendored
5
extern/smaa_areatex/README.blender
vendored
@@ -1,5 +0,0 @@
|
|||||||
Project: smaa-cpp
|
|
||||||
URL: https://github.com/iRi-E/smaa-cpp
|
|
||||||
License: MIT
|
|
||||||
Upstream version: 0.4.0
|
|
||||||
Local modifications:
|
|
1208
extern/smaa_areatex/smaa_areatex.cpp
vendored
1208
extern/smaa_areatex/smaa_areatex.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -21,7 +21,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@@ -41,9 +41,6 @@ class AddPresetIntegrator(AddPresetBase, Operator):
|
|||||||
"cycles.caustics_reflective",
|
"cycles.caustics_reflective",
|
||||||
"cycles.caustics_refractive",
|
"cycles.caustics_refractive",
|
||||||
"cycles.blur_glossy"
|
"cycles.blur_glossy"
|
||||||
"cycles.use_fast_gi"
|
|
||||||
"cycles.ao_bounces"
|
|
||||||
"cycles.ao_bounces_render"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
preset_subdir = "cycles/integrator"
|
preset_subdir = "cycles/integrator"
|
||||||
|
@@ -801,22 +801,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
|||||||
items=enum_texture_limit
|
items=enum_texture_limit
|
||||||
)
|
)
|
||||||
|
|
||||||
use_fast_gi: BoolProperty(
|
|
||||||
name="Fast GI Approximation",
|
|
||||||
description="Approximate diffuse indirect light with background tinted ambient occlusion. This provides fast alternative to full global illumination, for interactive viewport rendering or final renders with reduced quality",
|
|
||||||
default=False,
|
|
||||||
)
|
|
||||||
ao_bounces: IntProperty(
|
ao_bounces: IntProperty(
|
||||||
name="AO Bounces",
|
name="AO Bounces",
|
||||||
default=1,
|
default=0,
|
||||||
description="After this number of light bounces, use approximate global illumination. 0 disables this feature",
|
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||||
min=0, max=1024,
|
min=0, max=1024,
|
||||||
)
|
)
|
||||||
|
|
||||||
ao_bounces_render: IntProperty(
|
ao_bounces_render: IntProperty(
|
||||||
name="AO Bounces Render",
|
name="AO Bounces Render",
|
||||||
default=1,
|
default=0,
|
||||||
description="After this number of light bounces, use approximate global illumination. 0 disables this feature",
|
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||||
min=0, max=1024,
|
min=0, max=1024,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -526,35 +526,6 @@ class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
|
|||||||
col.prop(cscene, "caustics_refractive", text="Refractive")
|
col.prop(cscene, "caustics_refractive", text="Refractive")
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_light_paths_fast_gi(CyclesButtonsPanel, Panel):
|
|
||||||
bl_label = "Fast GI Approximation"
|
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
|
||||||
bl_parent_id = "CYCLES_RENDER_PT_light_paths"
|
|
||||||
|
|
||||||
def draw_header(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
cscene = scene.cycles
|
|
||||||
|
|
||||||
self.layout.prop(cscene, "use_fast_gi", text="")
|
|
||||||
|
|
||||||
def draw(self, context):
|
|
||||||
scene = context.scene
|
|
||||||
cscene = scene.cycles
|
|
||||||
world = scene.world
|
|
||||||
|
|
||||||
layout = self.layout
|
|
||||||
layout.use_property_split = True
|
|
||||||
layout.use_property_decorate = False
|
|
||||||
|
|
||||||
col = layout.column(align=True)
|
|
||||||
col.prop(cscene, "ao_bounces", text="Viewport Bounces")
|
|
||||||
col.prop(cscene, "ao_bounces_render", text="Render Bounces")
|
|
||||||
|
|
||||||
if world:
|
|
||||||
light = world.light_settings
|
|
||||||
layout.prop(light, "distance", text="AO Distance")
|
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_motion_blur(CyclesButtonsPanel, Panel):
|
||||||
bl_label = "Motion Blur"
|
bl_label = "Motion Blur"
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
@@ -775,7 +746,7 @@ class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
|
|||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
|
||||||
col.prop(rd, "use_save_buffers")
|
col.prop(rd, "use_save_buffers")
|
||||||
col.prop(rd, "use_persistent_data", text="Persistent Data")
|
col.prop(rd, "use_persistent_data", text="Persistent Images")
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_performance_viewport(CyclesButtonsPanel, Panel):
|
||||||
@@ -1438,15 +1409,15 @@ class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
|
|||||||
panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface')
|
panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface')
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_LIGHT_PT_beam_shape(CyclesButtonsPanel, Panel):
|
class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
|
||||||
bl_label = "Beam Shape"
|
bl_label = "Spot Shape"
|
||||||
bl_parent_id = "CYCLES_LIGHT_PT_light"
|
bl_parent_id = "CYCLES_LIGHT_PT_light"
|
||||||
bl_context = "data"
|
bl_context = "data"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
if context.light.type in {'SPOT', 'AREA'}:
|
light = context.light
|
||||||
return context.light and CyclesButtonsPanel.poll(context)
|
return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
@@ -1454,12 +1425,9 @@ class CYCLES_LIGHT_PT_beam_shape(CyclesButtonsPanel, Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
if light.type == 'SPOT':
|
col.prop(light, "spot_size", text="Size")
|
||||||
col.prop(light, "spot_size", text="Spot Size")
|
col.prop(light, "spot_blend", text="Blend", slider=True)
|
||||||
col.prop(light, "spot_blend", text="Blend", slider=True)
|
col.prop(light, "show_cone")
|
||||||
col.prop(light, "show_cone")
|
|
||||||
elif light.type == 'AREA':
|
|
||||||
col.prop(light, "spread", text="Spread")
|
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel):
|
class CYCLES_WORLD_PT_preview(CyclesButtonsPanel, Panel):
|
||||||
@@ -2070,6 +2038,7 @@ class CYCLES_RENDER_PT_simplify_viewport(CyclesButtonsPanel, Panel):
|
|||||||
col.prop(rd, "simplify_subdivision", text="Max Subdivision")
|
col.prop(rd, "simplify_subdivision", text="Max Subdivision")
|
||||||
col.prop(rd, "simplify_child_particles", text="Child Particles")
|
col.prop(rd, "simplify_child_particles", text="Child Particles")
|
||||||
col.prop(cscene, "texture_limit", text="Texture Limit")
|
col.prop(cscene, "texture_limit", text="Texture Limit")
|
||||||
|
col.prop(cscene, "ao_bounces", text="AO Bounces")
|
||||||
col.prop(rd, "simplify_volumes", text="Volume Resolution")
|
col.prop(rd, "simplify_volumes", text="Volume Resolution")
|
||||||
|
|
||||||
|
|
||||||
@@ -2095,6 +2064,7 @@ class CYCLES_RENDER_PT_simplify_render(CyclesButtonsPanel, Panel):
|
|||||||
col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
|
col.prop(rd, "simplify_subdivision_render", text="Max Subdivision")
|
||||||
col.prop(rd, "simplify_child_particles_render", text="Child Particles")
|
col.prop(rd, "simplify_child_particles_render", text="Child Particles")
|
||||||
col.prop(cscene, "texture_limit_render", text="Texture Limit")
|
col.prop(cscene, "texture_limit_render", text="Texture Limit")
|
||||||
|
col.prop(cscene, "ao_bounces_render", text="AO Bounces")
|
||||||
|
|
||||||
|
|
||||||
class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
|
class CYCLES_RENDER_PT_simplify_culling(CyclesButtonsPanel, Panel):
|
||||||
@@ -2272,7 +2242,6 @@ classes = (
|
|||||||
CYCLES_RENDER_PT_light_paths_max_bounces,
|
CYCLES_RENDER_PT_light_paths_max_bounces,
|
||||||
CYCLES_RENDER_PT_light_paths_clamping,
|
CYCLES_RENDER_PT_light_paths_clamping,
|
||||||
CYCLES_RENDER_PT_light_paths_caustics,
|
CYCLES_RENDER_PT_light_paths_caustics,
|
||||||
CYCLES_RENDER_PT_light_paths_fast_gi,
|
|
||||||
CYCLES_RENDER_PT_volumes,
|
CYCLES_RENDER_PT_volumes,
|
||||||
CYCLES_RENDER_PT_subdivision,
|
CYCLES_RENDER_PT_subdivision,
|
||||||
CYCLES_RENDER_PT_hair,
|
CYCLES_RENDER_PT_hair,
|
||||||
@@ -2315,7 +2284,7 @@ classes = (
|
|||||||
CYCLES_LIGHT_PT_preview,
|
CYCLES_LIGHT_PT_preview,
|
||||||
CYCLES_LIGHT_PT_light,
|
CYCLES_LIGHT_PT_light,
|
||||||
CYCLES_LIGHT_PT_nodes,
|
CYCLES_LIGHT_PT_nodes,
|
||||||
CYCLES_LIGHT_PT_beam_shape,
|
CYCLES_LIGHT_PT_spot,
|
||||||
CYCLES_WORLD_PT_preview,
|
CYCLES_WORLD_PT_preview,
|
||||||
CYCLES_WORLD_PT_surface,
|
CYCLES_WORLD_PT_surface,
|
||||||
CYCLES_WORLD_PT_volume,
|
CYCLES_WORLD_PT_volume,
|
||||||
@@ -2345,7 +2314,7 @@ classes = (
|
|||||||
node_panel(CYCLES_WORLD_PT_settings_surface),
|
node_panel(CYCLES_WORLD_PT_settings_surface),
|
||||||
node_panel(CYCLES_WORLD_PT_settings_volume),
|
node_panel(CYCLES_WORLD_PT_settings_volume),
|
||||||
node_panel(CYCLES_LIGHT_PT_light),
|
node_panel(CYCLES_LIGHT_PT_light),
|
||||||
node_panel(CYCLES_LIGHT_PT_beam_shape)
|
node_panel(CYCLES_LIGHT_PT_spot),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -217,18 +217,6 @@ def do_versions(self):
|
|||||||
baov.name = caov.get("name", "AOV")
|
baov.name = caov.get("name", "AOV")
|
||||||
baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE"
|
baov.type = "COLOR" if caov.get("type", 1) == 1 else "VALUE"
|
||||||
|
|
||||||
if version <= (2, 93, 16):
|
|
||||||
cscene = scene.cycles
|
|
||||||
ao_bounces = cscene.get("ao_bounces", 0)
|
|
||||||
ao_bounces_render = cscene.get("ao_bounces_render", 0)
|
|
||||||
if scene.render.use_simplify and (ao_bounces or ao_bounces_render):
|
|
||||||
cscene.use_fast_gi = True
|
|
||||||
cscene.ao_bounces = ao_bounces
|
|
||||||
cscene.ao_bounces_render = ao_bounces_render
|
|
||||||
else:
|
|
||||||
cscene.ao_bounces = 1
|
|
||||||
cscene.ao_bounces_render = 1
|
|
||||||
|
|
||||||
# Lamps
|
# Lamps
|
||||||
for light in bpy.data.lights:
|
for light in bpy.data.lights:
|
||||||
if light.library not in libraries:
|
if light.library not in libraries:
|
||||||
|
@@ -29,7 +29,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image, int frame)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata)
|
bool BlenderImageLoader::load_metadata(ImageMetaData &metadata)
|
||||||
{
|
{
|
||||||
metadata.width = b_image.size()[0];
|
metadata.width = b_image.size()[0];
|
||||||
metadata.height = b_image.size()[1];
|
metadata.height = b_image.size()[1];
|
||||||
@@ -171,7 +171,7 @@ BlenderPointDensityLoader::BlenderPointDensityLoader(BL::Depsgraph b_depsgraph,
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlenderPointDensityLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata)
|
bool BlenderPointDensityLoader::load_metadata(ImageMetaData &metadata)
|
||||||
{
|
{
|
||||||
metadata.channels = 4;
|
metadata.channels = 4;
|
||||||
metadata.width = b_node.resolution();
|
metadata.width = b_node.resolution();
|
||||||
|
@@ -27,7 +27,7 @@ class BlenderImageLoader : public ImageLoader {
|
|||||||
public:
|
public:
|
||||||
BlenderImageLoader(BL::Image b_image, int frame);
|
BlenderImageLoader(BL::Image b_image, int frame);
|
||||||
|
|
||||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
bool load_metadata(ImageMetaData &metadata) override;
|
||||||
bool load_pixels(const ImageMetaData &metadata,
|
bool load_pixels(const ImageMetaData &metadata,
|
||||||
void *pixels,
|
void *pixels,
|
||||||
const size_t pixels_size,
|
const size_t pixels_size,
|
||||||
@@ -44,7 +44,7 @@ class BlenderPointDensityLoader : public ImageLoader {
|
|||||||
public:
|
public:
|
||||||
BlenderPointDensityLoader(BL::Depsgraph depsgraph, BL::ShaderNodeTexPointDensity b_node);
|
BlenderPointDensityLoader(BL::Depsgraph depsgraph, BL::ShaderNodeTexPointDensity b_node);
|
||||||
|
|
||||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
bool load_metadata(ImageMetaData &metadata) override;
|
||||||
bool load_pixels(const ImageMetaData &metadata,
|
bool load_pixels(const ImageMetaData &metadata,
|
||||||
void *pixels,
|
void *pixels,
|
||||||
const size_t pixels_size,
|
const size_t pixels_size,
|
||||||
|
@@ -82,7 +82,6 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||||||
light->set_axisu(transform_get_column(&tfm, 0));
|
light->set_axisu(transform_get_column(&tfm, 0));
|
||||||
light->set_axisv(transform_get_column(&tfm, 1));
|
light->set_axisv(transform_get_column(&tfm, 1));
|
||||||
light->set_sizeu(b_area_light.size());
|
light->set_sizeu(b_area_light.size());
|
||||||
light->set_spread(b_area_light.spread());
|
|
||||||
switch (b_area_light.shape()) {
|
switch (b_area_light.shape()) {
|
||||||
case BL::AreaLight::shape_SQUARE:
|
case BL::AreaLight::shape_SQUARE:
|
||||||
light->set_sizev(light->get_sizeu());
|
light->set_sizev(light->get_sizeu());
|
||||||
|
@@ -375,7 +375,7 @@ static void attr_create_generic(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool
|
|||||||
case BL::Attribute::domain_POINT:
|
case BL::Attribute::domain_POINT:
|
||||||
element = ATTR_ELEMENT_VERTEX;
|
element = ATTR_ELEMENT_VERTEX;
|
||||||
break;
|
break;
|
||||||
case BL::Attribute::domain_FACE:
|
case BL::Attribute::domain_POLYGON:
|
||||||
element = ATTR_ELEMENT_FACE;
|
element = ATTR_ELEMENT_FACE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@@ -143,6 +143,12 @@ void BlenderSession::create_session()
|
|||||||
|
|
||||||
session->scene = scene;
|
session->scene = scene;
|
||||||
|
|
||||||
|
/* There is no single depsgraph to use for the entire render.
|
||||||
|
* So we need to handle this differently.
|
||||||
|
*
|
||||||
|
* We could loop over the final render result render layers in pipeline and keep Cycles unaware
|
||||||
|
* of multiple layers, or perhaps move syncing further down in the pipeline.
|
||||||
|
*/
|
||||||
/* create sync */
|
/* create sync */
|
||||||
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
||||||
BL::Object b_camera_override(b_engine.camera_override());
|
BL::Object b_camera_override(b_engine.camera_override());
|
||||||
@@ -207,7 +213,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
|||||||
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
|
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
|
||||||
|
|
||||||
if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
|
if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
|
||||||
!this->b_render.use_persistent_data()) {
|
!scene_params.persistent_data) {
|
||||||
/* if scene or session parameters changed, it's easier to simply re-create
|
/* if scene or session parameters changed, it's easier to simply re-create
|
||||||
* them rather than trying to distinguish which settings need to be updated
|
* them rather than trying to distinguish which settings need to be updated
|
||||||
*/
|
*/
|
||||||
@@ -219,6 +225,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
|||||||
}
|
}
|
||||||
|
|
||||||
session->progress.reset();
|
session->progress.reset();
|
||||||
|
scene->reset();
|
||||||
|
|
||||||
session->tile_manager.set_tile_order(session_params.tile_order);
|
session->tile_manager.set_tile_order(session_params.tile_order);
|
||||||
|
|
||||||
@@ -227,15 +234,12 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
|||||||
*/
|
*/
|
||||||
session->stats.mem_peak = session->stats.mem_used;
|
session->stats.mem_peak = session->stats.mem_used;
|
||||||
|
|
||||||
if (is_new_session) {
|
/* There is no single depsgraph to use for the entire render.
|
||||||
/* Sync object should be re-created for new scene. */
|
* See note on create_session().
|
||||||
delete sync;
|
*/
|
||||||
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
/* sync object should be re-created */
|
||||||
}
|
delete sync;
|
||||||
else {
|
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
||||||
/* Sync recalculations to do just the required updates. */
|
|
||||||
sync->sync_recalc(b_depsgraph, b_v3d);
|
|
||||||
}
|
|
||||||
|
|
||||||
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
|
BL::SpaceView3D b_null_space_view3d(PointerRNA_NULL);
|
||||||
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
|
BL::RegionView3D b_null_region_view3d(PointerRNA_NULL);
|
||||||
@@ -498,7 +502,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
|
|
||||||
/* Compute render passes and film settings. */
|
/* Compute render passes and film settings. */
|
||||||
vector<Pass> passes = sync->sync_render_passes(
|
vector<Pass> passes = sync->sync_render_passes(
|
||||||
b_scene, b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
|
b_rlay, b_view_layer, session_params.adaptive_sampling, session_params.denoising);
|
||||||
|
|
||||||
/* Set buffer params, using film settings from sync_render_passes. */
|
/* Set buffer params, using film settings from sync_render_passes. */
|
||||||
buffer_params.passes = passes;
|
buffer_params.passes = passes;
|
||||||
@@ -594,6 +598,18 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
/* clear callback */
|
/* clear callback */
|
||||||
session->write_render_tile_cb = function_null;
|
session->write_render_tile_cb = function_null;
|
||||||
session->update_render_tile_cb = function_null;
|
session->update_render_tile_cb = function_null;
|
||||||
|
|
||||||
|
/* TODO: find a way to clear this data for persistent data render */
|
||||||
|
#if 0
|
||||||
|
/* free all memory used (host and device), so we wouldn't leave render
|
||||||
|
* engine with extra memory allocated
|
||||||
|
*/
|
||||||
|
|
||||||
|
session->device_free();
|
||||||
|
|
||||||
|
delete sync;
|
||||||
|
sync = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bake_pass_filter_get(const int pass_filter)
|
static int bake_pass_filter_get(const int pass_filter)
|
||||||
|
@@ -211,11 +211,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b_v3d) {
|
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
||||||
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
if (viewport_parameters.modified(new_viewport_parameters)) {
|
||||||
if (viewport_parameters.modified(new_viewport_parameters)) {
|
world_recalc = true;
|
||||||
world_recalc = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +358,7 @@ void BlenderSync::sync_integrator()
|
|||||||
|
|
||||||
integrator->set_adaptive_min_samples(adaptive_min_samples);
|
integrator->set_adaptive_min_samples(adaptive_min_samples);
|
||||||
|
|
||||||
if (get_boolean(cscene, "use_fast_gi")) {
|
if (b_scene.render().use_simplify()) {
|
||||||
if (preview) {
|
if (preview) {
|
||||||
integrator->set_ao_bounces(get_int(cscene, "ao_bounces"));
|
integrator->set_ao_bounces(get_int(cscene, "ao_bounces"));
|
||||||
}
|
}
|
||||||
@@ -569,8 +567,7 @@ int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
|
vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
|
||||||
BL::RenderLayer &b_rlay,
|
|
||||||
BL::ViewLayer &b_view_layer,
|
BL::ViewLayer &b_view_layer,
|
||||||
bool adaptive_sampling,
|
bool adaptive_sampling,
|
||||||
const DenoiseParams &denoising)
|
const DenoiseParams &denoising)
|
||||||
@@ -581,7 +578,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
|
|||||||
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
for (BL::RenderPass &b_pass : b_rlay.passes) {
|
||||||
PassType pass_type = get_pass_type(b_pass);
|
PassType pass_type = get_pass_type(b_pass);
|
||||||
|
|
||||||
if (pass_type == PASS_MOTION && b_scene.render().use_motion_blur())
|
if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur())
|
||||||
continue;
|
continue;
|
||||||
if (pass_type != PASS_NONE)
|
if (pass_type != PASS_NONE)
|
||||||
Pass::add(pass_type, passes, b_pass.name().c_str());
|
Pass::add(pass_type, passes, b_pass.name().c_str());
|
||||||
@@ -760,6 +757,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
|||||||
|
|
||||||
SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
||||||
{
|
{
|
||||||
|
BL::RenderSettings r = b_scene.render();
|
||||||
SceneParams params;
|
SceneParams params;
|
||||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||||
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
const bool shadingsystem = RNA_boolean_get(&cscene, "shading_system");
|
||||||
@@ -783,6 +781,11 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
|||||||
params.hair_shape = (CurveShapeType)get_enum(
|
params.hair_shape = (CurveShapeType)get_enum(
|
||||||
csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK);
|
csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK);
|
||||||
|
|
||||||
|
if (background && params.shadingsystem != SHADINGSYSTEM_OSL)
|
||||||
|
params.persistent_data = r.use_persistent_data();
|
||||||
|
else
|
||||||
|
params.persistent_data = false;
|
||||||
|
|
||||||
int texture_limit;
|
int texture_limit;
|
||||||
if (background) {
|
if (background) {
|
||||||
texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
|
texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
|
||||||
|
@@ -74,8 +74,7 @@ class BlenderSync {
|
|||||||
int height,
|
int height,
|
||||||
void **python_thread_state);
|
void **python_thread_state);
|
||||||
void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
|
void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
|
||||||
vector<Pass> sync_render_passes(BL::Scene &b_scene,
|
vector<Pass> sync_render_passes(BL::RenderLayer &b_render_layer,
|
||||||
BL::RenderLayer &b_render_layer,
|
|
||||||
BL::ViewLayer &b_view_layer,
|
BL::ViewLayer &b_view_layer,
|
||||||
bool adaptive_sampling,
|
bool adaptive_sampling,
|
||||||
const DenoiseParams &denoising);
|
const DenoiseParams &denoising);
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
#ifdef WITH_OPENVDB
|
#ifdef WITH_OPENVDB
|
||||||
# include <openvdb/openvdb.h>
|
# include <openvdb/openvdb.h>
|
||||||
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
|
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
|
||||||
const struct VolumeGrid *grid);
|
struct VolumeGrid *grid);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
@@ -41,7 +41,7 @@ class BlenderSmokeLoader : public ImageLoader {
|
|||||||
mesh_texture_space(b_mesh, texspace_loc, texspace_size);
|
mesh_texture_space(b_mesh, texspace_loc, texspace_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) override
|
bool load_metadata(ImageMetaData &metadata) override
|
||||||
{
|
{
|
||||||
if (!b_domain) {
|
if (!b_domain) {
|
||||||
return false;
|
return false;
|
||||||
@@ -227,7 +227,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
|
|||||||
const bool unload = !b_volume_grid.is_loaded();
|
const bool unload = !b_volume_grid.is_loaded();
|
||||||
|
|
||||||
::Volume *volume = (::Volume *)b_volume.ptr.data;
|
::Volume *volume = (::Volume *)b_volume.ptr.data;
|
||||||
const VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
|
VolumeGrid *volume_grid = (VolumeGrid *)b_volume_grid.ptr.data;
|
||||||
grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
|
grid = BKE_volume_grid_openvdb_for_read(volume, volume_grid);
|
||||||
|
|
||||||
if (unload) {
|
if (unload) {
|
||||||
|
@@ -619,7 +619,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||||||
info.num = 0;
|
info.num = 0;
|
||||||
|
|
||||||
info.has_half_images = true;
|
info.has_half_images = true;
|
||||||
info.has_nanovdb = true;
|
|
||||||
info.has_volume_decoupled = true;
|
info.has_volume_decoupled = true;
|
||||||
info.has_branched_path = true;
|
info.has_branched_path = true;
|
||||||
info.has_adaptive_stop_per_sample = true;
|
info.has_adaptive_stop_per_sample = true;
|
||||||
@@ -666,7 +665,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
|||||||
|
|
||||||
/* Accumulate device info. */
|
/* Accumulate device info. */
|
||||||
info.has_half_images &= device.has_half_images;
|
info.has_half_images &= device.has_half_images;
|
||||||
info.has_nanovdb &= device.has_nanovdb;
|
|
||||||
info.has_volume_decoupled &= device.has_volume_decoupled;
|
info.has_volume_decoupled &= device.has_volume_decoupled;
|
||||||
info.has_branched_path &= device.has_branched_path;
|
info.has_branched_path &= device.has_branched_path;
|
||||||
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
|
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
|
||||||
|
@@ -78,7 +78,6 @@ class DeviceInfo {
|
|||||||
int num;
|
int num;
|
||||||
bool display_device; /* GPU is used as a display device. */
|
bool display_device; /* GPU is used as a display device. */
|
||||||
bool has_half_images; /* Support half-float textures. */
|
bool has_half_images; /* Support half-float textures. */
|
||||||
bool has_nanovdb; /* Support NanoVDB volumes. */
|
|
||||||
bool has_volume_decoupled; /* Decoupled volume shading. */
|
bool has_volume_decoupled; /* Decoupled volume shading. */
|
||||||
bool has_branched_path; /* Supports branched path tracing. */
|
bool has_branched_path; /* Supports branched path tracing. */
|
||||||
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
|
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
|
||||||
@@ -100,7 +99,6 @@ class DeviceInfo {
|
|||||||
cpu_threads = 0;
|
cpu_threads = 0;
|
||||||
display_device = false;
|
display_device = false;
|
||||||
has_half_images = false;
|
has_half_images = false;
|
||||||
has_nanovdb = false;
|
|
||||||
has_volume_decoupled = false;
|
has_volume_decoupled = false;
|
||||||
has_branched_path = true;
|
has_branched_path = true;
|
||||||
has_adaptive_stop_per_sample = false;
|
has_adaptive_stop_per_sample = false;
|
||||||
|
@@ -1654,7 +1654,6 @@ void device_cpu_info(vector<DeviceInfo> &devices)
|
|||||||
info.has_adaptive_stop_per_sample = true;
|
info.has_adaptive_stop_per_sample = true;
|
||||||
info.has_osl = true;
|
info.has_osl = true;
|
||||||
info.has_half_images = true;
|
info.has_half_images = true;
|
||||||
info.has_nanovdb = true;
|
|
||||||
info.has_profiling = true;
|
info.has_profiling = true;
|
||||||
info.denoisers = DENOISER_NLM;
|
info.denoisers = DENOISER_NLM;
|
||||||
if (openimagedenoise_supported()) {
|
if (openimagedenoise_supported()) {
|
||||||
|
@@ -128,7 +128,6 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
|||||||
info.num = num;
|
info.num = num;
|
||||||
|
|
||||||
info.has_half_images = (major >= 3);
|
info.has_half_images = (major >= 3);
|
||||||
info.has_nanovdb = true;
|
|
||||||
info.has_volume_decoupled = false;
|
info.has_volume_decoupled = false;
|
||||||
info.has_adaptive_stop_per_sample = false;
|
info.has_adaptive_stop_per_sample = false;
|
||||||
info.denoisers = DENOISER_NLM;
|
info.denoisers = DENOISER_NLM;
|
||||||
|
@@ -46,13 +46,10 @@ class MultiDevice : public Device {
|
|||||||
list<SubDevice> devices, denoising_devices;
|
list<SubDevice> devices, denoising_devices;
|
||||||
device_ptr unique_key;
|
device_ptr unique_key;
|
||||||
vector<vector<SubDevice *>> peer_islands;
|
vector<vector<SubDevice *>> peer_islands;
|
||||||
bool use_denoising;
|
|
||||||
bool matching_rendering_and_denoising_devices;
|
bool matching_rendering_and_denoising_devices;
|
||||||
|
|
||||||
MultiDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
|
MultiDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
|
||||||
: Device(info, stats, profiler, background_),
|
: Device(info, stats, profiler, background_), unique_key(1)
|
||||||
unique_key(1),
|
|
||||||
use_denoising(!info.denoising_devices.empty())
|
|
||||||
{
|
{
|
||||||
foreach (DeviceInfo &subinfo, info.multi_devices) {
|
foreach (DeviceInfo &subinfo, info.multi_devices) {
|
||||||
/* Always add CPU devices at the back since GPU devices can change
|
/* Always add CPU devices at the back since GPU devices can change
|
||||||
@@ -197,7 +194,6 @@ class MultiDevice : public Device {
|
|||||||
if (!sub.device->load_kernels(requested_features))
|
if (!sub.device->load_kernels(requested_features))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
use_denoising = requested_features.use_denoising;
|
|
||||||
if (requested_features.use_denoising) {
|
if (requested_features.use_denoising) {
|
||||||
/* Only need denoising feature, everything else is unused. */
|
/* Only need denoising feature, everything else is unused. */
|
||||||
DeviceRequestedFeatures denoising_features;
|
DeviceRequestedFeatures denoising_features;
|
||||||
@@ -404,7 +400,7 @@ class MultiDevice : public Device {
|
|||||||
size_t existing_size = mem.device_size;
|
size_t existing_size = mem.device_size;
|
||||||
|
|
||||||
/* The tile buffers are allocated on each device (see below), so copy to all of them */
|
/* The tile buffers are allocated on each device (see below), so copy to all of them */
|
||||||
if (strcmp(mem.name, "RenderBuffers") == 0 && use_denoising) {
|
if (strcmp(mem.name, "RenderBuffers") == 0) {
|
||||||
foreach (SubDevice &sub, devices) {
|
foreach (SubDevice &sub, devices) {
|
||||||
mem.device = sub.device;
|
mem.device = sub.device;
|
||||||
mem.device_pointer = (existing_key) ? sub.ptr_map[existing_key] : 0;
|
mem.device_pointer = (existing_key) ? sub.ptr_map[existing_key] : 0;
|
||||||
@@ -470,7 +466,7 @@ class MultiDevice : public Device {
|
|||||||
/* This is a hack to only allocate the tile buffers on denoising devices
|
/* This is a hack to only allocate the tile buffers on denoising devices
|
||||||
* Similarly the tile buffers also need to be allocated separately on all devices so any
|
* Similarly the tile buffers also need to be allocated separately on all devices so any
|
||||||
* overlap rendered for denoising does not interfere with each other */
|
* overlap rendered for denoising does not interfere with each other */
|
||||||
if (strcmp(mem.name, "RenderBuffers") == 0 && use_denoising) {
|
if (strcmp(mem.name, "RenderBuffers") == 0) {
|
||||||
vector<device_ptr> device_pointers;
|
vector<device_ptr> device_pointers;
|
||||||
device_pointers.reserve(devices.size());
|
device_pointers.reserve(devices.size());
|
||||||
|
|
||||||
@@ -522,7 +518,7 @@ class MultiDevice : public Device {
|
|||||||
size_t existing_size = mem.device_size;
|
size_t existing_size = mem.device_size;
|
||||||
|
|
||||||
/* Free memory that was allocated for all devices (see above) on each device */
|
/* Free memory that was allocated for all devices (see above) on each device */
|
||||||
if (mem.type == MEM_PIXELS || (strcmp(mem.name, "RenderBuffers") == 0 && use_denoising)) {
|
if (strcmp(mem.name, "RenderBuffers") == 0 || mem.type == MEM_PIXELS) {
|
||||||
foreach (SubDevice &sub, devices) {
|
foreach (SubDevice &sub, devices) {
|
||||||
mem.device = sub.device;
|
mem.device = sub.device;
|
||||||
mem.device_pointer = sub.ptr_map[key];
|
mem.device_pointer = sub.ptr_map[key];
|
||||||
|
@@ -126,9 +126,6 @@ void device_opencl_info(vector<DeviceInfo> &devices)
|
|||||||
/* Check OpenCL extensions */
|
/* Check OpenCL extensions */
|
||||||
info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos;
|
info.has_half_images = platform_device.device_extensions.find("cl_khr_fp16") != string::npos;
|
||||||
|
|
||||||
/* Disabled for now due to apparent AMD driver bug. */
|
|
||||||
info.has_nanovdb = platform_name != "AMD Accelerated Parallel Processing";
|
|
||||||
|
|
||||||
devices.push_back(info);
|
devices.push_back(info);
|
||||||
num_devices++;
|
num_devices++;
|
||||||
}
|
}
|
||||||
|
@@ -362,7 +362,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OptixModuleCompileOptions module_options = {};
|
OptixModuleCompileOptions module_options;
|
||||||
module_options.maxRegisterCount = 0; // Do not set an explicit register limit
|
module_options.maxRegisterCount = 0; // Do not set an explicit register limit
|
||||||
# ifdef WITH_CYCLES_DEBUG
|
# ifdef WITH_CYCLES_DEBUG
|
||||||
module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;
|
module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;
|
||||||
@@ -377,7 +377,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
module_options.numBoundValues = 0;
|
module_options.numBoundValues = 0;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
OptixPipelineCompileOptions pipeline_options = {};
|
OptixPipelineCompileOptions pipeline_options;
|
||||||
// Default to no motion blur and two-level graph, since it is the fastest option
|
// Default to no motion blur and two-level graph, since it is the fastest option
|
||||||
pipeline_options.usesMotionBlur = false;
|
pipeline_options.usesMotionBlur = false;
|
||||||
pipeline_options.traversableGraphFlags =
|
pipeline_options.traversableGraphFlags =
|
||||||
@@ -477,7 +477,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
|
|
||||||
# if OPTIX_ABI_VERSION >= 36
|
# if OPTIX_ABI_VERSION >= 36
|
||||||
if (DebugFlags().optix.curves_api && requested_features.use_hair_thick) {
|
if (DebugFlags().optix.curves_api && requested_features.use_hair_thick) {
|
||||||
OptixBuiltinISOptions builtin_options = {};
|
OptixBuiltinISOptions builtin_options;
|
||||||
builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE;
|
builtin_options.builtinISModuleType = OPTIX_PRIMITIVE_TYPE_ROUND_CUBIC_BSPLINE;
|
||||||
builtin_options.usesMotionBlur = false;
|
builtin_options.usesMotionBlur = false;
|
||||||
|
|
||||||
@@ -571,7 +571,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH);
|
stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
OptixPipelineLinkOptions link_options = {};
|
OptixPipelineLinkOptions link_options;
|
||||||
link_options.maxTraceDepth = 1;
|
link_options.maxTraceDepth = 1;
|
||||||
# ifdef WITH_CYCLES_DEBUG
|
# ifdef WITH_CYCLES_DEBUG
|
||||||
link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
|
link_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_FULL;
|
||||||
@@ -953,7 +953,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create OptiX denoiser handle on demand when it is first used
|
// Create OptiX denoiser handle on demand when it is first used
|
||||||
OptixDenoiserOptions denoiser_options = {};
|
OptixDenoiserOptions denoiser_options;
|
||||||
assert(task.denoising.input_passes >= 1 && task.denoising.input_passes <= 3);
|
assert(task.denoising.input_passes >= 1 && task.denoising.input_passes <= 3);
|
||||||
denoiser_options.inputKind = static_cast<OptixDenoiserInputKind>(
|
denoiser_options.inputKind = static_cast<OptixDenoiserInputKind>(
|
||||||
OPTIX_DENOISER_INPUT_RGB + (task.denoising.input_passes - 1));
|
OPTIX_DENOISER_INPUT_RGB + (task.denoising.input_passes - 1));
|
||||||
@@ -1157,7 +1157,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
|
|
||||||
// Compute memory usage
|
// Compute memory usage
|
||||||
OptixAccelBufferSizes sizes = {};
|
OptixAccelBufferSizes sizes = {};
|
||||||
OptixAccelBuildOptions options = {};
|
OptixAccelBuildOptions options;
|
||||||
options.operation = operation;
|
options.operation = operation;
|
||||||
if (background) {
|
if (background) {
|
||||||
// Prefer best performance and lowest memory consumption in background
|
// Prefer best performance and lowest memory consumption in background
|
||||||
@@ -1195,7 +1195,7 @@ class OptiXDevice : public CUDADevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finally build the acceleration structure
|
// Finally build the acceleration structure
|
||||||
OptixAccelEmitDesc compacted_size_prop = {};
|
OptixAccelEmitDesc compacted_size_prop;
|
||||||
compacted_size_prop.type = OPTIX_PROPERTY_TYPE_COMPACTED_SIZE;
|
compacted_size_prop.type = OPTIX_PROPERTY_TYPE_COMPACTED_SIZE;
|
||||||
// A tiny space was allocated for this property at the end of the temporary buffer above
|
// A tiny space was allocated for this property at the end of the temporary buffer above
|
||||||
// Make sure this pointer is 8-byte aligned
|
// Make sure this pointer is 8-byte aligned
|
||||||
|
@@ -2036,9 +2036,7 @@ string OpenCLDevice::kernel_build_options(const string *debug_src)
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (info.has_nanovdb) {
|
build_options += "-DWITH_NANOVDB ";
|
||||||
build_options += "-DWITH_NANOVDB ";
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
return build_options;
|
return build_options;
|
||||||
|
@@ -93,7 +93,6 @@ set(SRC_BVH_HEADERS
|
|||||||
bvh/bvh_local.h
|
bvh/bvh_local.h
|
||||||
bvh/bvh_traversal.h
|
bvh/bvh_traversal.h
|
||||||
bvh/bvh_types.h
|
bvh/bvh_types.h
|
||||||
bvh/bvh_util.h
|
|
||||||
bvh/bvh_volume.h
|
bvh/bvh_volume.h
|
||||||
bvh/bvh_volume_all.h
|
bvh/bvh_volume_all.h
|
||||||
bvh/bvh_embree.h
|
bvh/bvh_embree.h
|
||||||
|
@@ -29,11 +29,10 @@
|
|||||||
# include "kernel/bvh/bvh_embree.h"
|
# include "kernel/bvh/bvh_embree.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "kernel/bvh/bvh_types.h"
|
|
||||||
#include "kernel/bvh/bvh_util.h"
|
|
||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
CCL_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
#include "kernel/bvh/bvh_types.h"
|
||||||
|
|
||||||
#ifndef __KERNEL_OPTIX__
|
#ifndef __KERNEL_OPTIX__
|
||||||
|
|
||||||
/* Regular BVH traversal */
|
/* Regular BVH traversal */
|
||||||
@@ -534,4 +533,97 @@ ccl_device_intersect uint scene_intersect_volume_all(KernelGlobals *kg,
|
|||||||
}
|
}
|
||||||
#endif /* __VOLUME_RECORD_ALL__ */
|
#endif /* __VOLUME_RECORD_ALL__ */
|
||||||
|
|
||||||
|
/* Ray offset to avoid self intersection.
|
||||||
|
*
|
||||||
|
* This function should be used to compute a modified ray start position for
|
||||||
|
* rays leaving from a surface. */
|
||||||
|
|
||||||
|
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
|
||||||
|
{
|
||||||
|
#ifdef __INTERSECTION_REFINE__
|
||||||
|
const float epsilon_f = 1e-5f;
|
||||||
|
/* ideally this should match epsilon_f, but instancing and motion blur
|
||||||
|
* precision makes it problematic */
|
||||||
|
const float epsilon_test = 1.0f;
|
||||||
|
const int epsilon_i = 32;
|
||||||
|
|
||||||
|
float3 res;
|
||||||
|
|
||||||
|
/* x component */
|
||||||
|
if (fabsf(P.x) < epsilon_test) {
|
||||||
|
res.x = P.x + Ng.x * epsilon_f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint ix = __float_as_uint(P.x);
|
||||||
|
ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
|
||||||
|
res.x = __uint_as_float(ix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* y component */
|
||||||
|
if (fabsf(P.y) < epsilon_test) {
|
||||||
|
res.y = P.y + Ng.y * epsilon_f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint iy = __float_as_uint(P.y);
|
||||||
|
iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
|
||||||
|
res.y = __uint_as_float(iy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* z component */
|
||||||
|
if (fabsf(P.z) < epsilon_test) {
|
||||||
|
res.z = P.z + Ng.z * epsilon_f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint iz = __float_as_uint(P.z);
|
||||||
|
iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
|
||||||
|
res.z = __uint_as_float(iz);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
#else
|
||||||
|
const float epsilon_f = 1e-4f;
|
||||||
|
return P + epsilon_f * Ng;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
|
||||||
|
/* ToDo: Move to another file? */
|
||||||
|
ccl_device int intersections_compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const Intersection *isect_a = (const Intersection *)a;
|
||||||
|
const Intersection *isect_b = (const Intersection *)b;
|
||||||
|
|
||||||
|
if (isect_a->t < isect_b->t)
|
||||||
|
return -1;
|
||||||
|
else if (isect_a->t > isect_b->t)
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SHADOW_RECORD_ALL__)
|
||||||
|
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
|
||||||
|
{
|
||||||
|
# ifdef __KERNEL_GPU__
|
||||||
|
/* Use bubble sort which has more friendly memory pattern on GPU. */
|
||||||
|
bool swapped;
|
||||||
|
do {
|
||||||
|
swapped = false;
|
||||||
|
for (int j = 0; j < num_hits - 1; ++j) {
|
||||||
|
if (hits[j].t > hits[j + 1].t) {
|
||||||
|
struct Intersection tmp = hits[j];
|
||||||
|
hits[j] = hits[j + 1];
|
||||||
|
hits[j + 1] = tmp;
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--num_hits;
|
||||||
|
} while (swapped);
|
||||||
|
# else
|
||||||
|
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
CCL_NAMESPACE_END
|
||||||
|
@@ -180,10 +180,25 @@ ccl_device_inline
|
|||||||
|
|
||||||
/* todo: optimize so primitive visibility flag indicates if
|
/* todo: optimize so primitive visibility flag indicates if
|
||||||
* the primitive has a transparent shadow shader? */
|
* the primitive has a transparent shadow shader? */
|
||||||
const int flags = intersection_get_shader_flags(kg, isect_array);
|
int prim = kernel_tex_fetch(__prim_index, isect_array->prim);
|
||||||
|
int shader = 0;
|
||||||
|
|
||||||
|
#ifdef __HAIR__
|
||||||
|
if (kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
shader = kernel_tex_fetch(__tri_shader, prim);
|
||||||
|
}
|
||||||
|
#ifdef __HAIR__
|
||||||
|
else {
|
||||||
|
float4 str = kernel_tex_fetch(__curves, prim);
|
||||||
|
shader = __float_as_int(str.z);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
int flag = kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
|
||||||
|
|
||||||
/* if no transparent shadows, all light is blocked */
|
/* if no transparent shadows, all light is blocked */
|
||||||
if (!(flags & SD_HAS_TRANSPARENT_SHADOW)) {
|
if (!(flag & SD_HAS_TRANSPARENT_SHADOW)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* if maximum number of hits reached, block all light */
|
/* if maximum number of hits reached, block all light */
|
||||||
|
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2011-2013 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
|
|
||||||
|
|
||||||
CCL_NAMESPACE_BEGIN
|
|
||||||
|
|
||||||
/* Ray offset to avoid self intersection.
|
|
||||||
*
|
|
||||||
* This function should be used to compute a modified ray start position for
|
|
||||||
* rays leaving from a surface. */
|
|
||||||
|
|
||||||
ccl_device_inline float3 ray_offset(float3 P, float3 Ng)
|
|
||||||
{
|
|
||||||
#ifdef __INTERSECTION_REFINE__
|
|
||||||
const float epsilon_f = 1e-5f;
|
|
||||||
/* ideally this should match epsilon_f, but instancing and motion blur
|
|
||||||
* precision makes it problematic */
|
|
||||||
const float epsilon_test = 1.0f;
|
|
||||||
const int epsilon_i = 32;
|
|
||||||
|
|
||||||
float3 res;
|
|
||||||
|
|
||||||
/* x component */
|
|
||||||
if (fabsf(P.x) < epsilon_test) {
|
|
||||||
res.x = P.x + Ng.x * epsilon_f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uint ix = __float_as_uint(P.x);
|
|
||||||
ix += ((ix ^ __float_as_uint(Ng.x)) >> 31) ? -epsilon_i : epsilon_i;
|
|
||||||
res.x = __uint_as_float(ix);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* y component */
|
|
||||||
if (fabsf(P.y) < epsilon_test) {
|
|
||||||
res.y = P.y + Ng.y * epsilon_f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uint iy = __float_as_uint(P.y);
|
|
||||||
iy += ((iy ^ __float_as_uint(Ng.y)) >> 31) ? -epsilon_i : epsilon_i;
|
|
||||||
res.y = __uint_as_float(iy);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* z component */
|
|
||||||
if (fabsf(P.z) < epsilon_test) {
|
|
||||||
res.z = P.z + Ng.z * epsilon_f;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
uint iz = __float_as_uint(P.z);
|
|
||||||
iz += ((iz ^ __float_as_uint(Ng.z)) >> 31) ? -epsilon_i : epsilon_i;
|
|
||||||
res.z = __uint_as_float(iz);
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
#else
|
|
||||||
const float epsilon_f = 1e-4f;
|
|
||||||
return P + epsilon_f * Ng;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__VOLUME_RECORD_ALL__) || (defined(__SHADOW_RECORD_ALL__) && defined(__KERNEL_CPU__))
|
|
||||||
/* ToDo: Move to another file? */
|
|
||||||
ccl_device int intersections_compare(const void *a, const void *b)
|
|
||||||
{
|
|
||||||
const Intersection *isect_a = (const Intersection *)a;
|
|
||||||
const Intersection *isect_b = (const Intersection *)b;
|
|
||||||
|
|
||||||
if (isect_a->t < isect_b->t)
|
|
||||||
return -1;
|
|
||||||
else if (isect_a->t > isect_b->t)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__SHADOW_RECORD_ALL__)
|
|
||||||
ccl_device_inline void sort_intersections(Intersection *hits, uint num_hits)
|
|
||||||
{
|
|
||||||
kernel_assert(num_hits > 0);
|
|
||||||
|
|
||||||
# ifdef __KERNEL_GPU__
|
|
||||||
/* Use bubble sort which has more friendly memory pattern on GPU. */
|
|
||||||
bool swapped;
|
|
||||||
do {
|
|
||||||
swapped = false;
|
|
||||||
for (int j = 0; j < num_hits - 1; ++j) {
|
|
||||||
if (hits[j].t > hits[j + 1].t) {
|
|
||||||
struct Intersection tmp = hits[j];
|
|
||||||
hits[j] = hits[j + 1];
|
|
||||||
hits[j + 1] = tmp;
|
|
||||||
swapped = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
--num_hits;
|
|
||||||
} while (swapped);
|
|
||||||
# else
|
|
||||||
qsort(hits, num_hits, sizeof(Intersection), intersections_compare);
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
#endif /* __SHADOW_RECORD_ALL__ | __VOLUME_RECORD_ALL__ */
|
|
||||||
|
|
||||||
/* Utility to quickly get a shader flags from an intersection. */
|
|
||||||
|
|
||||||
ccl_device_forceinline int intersection_get_shader_flags(KernelGlobals *ccl_restrict kg,
|
|
||||||
const Intersection *isect)
|
|
||||||
{
|
|
||||||
const int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
|
||||||
int shader = 0;
|
|
||||||
|
|
||||||
#ifdef __HAIR__
|
|
||||||
if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
|
||||||
}
|
|
||||||
#ifdef __HAIR__
|
|
||||||
else {
|
|
||||||
float4 str = kernel_tex_fetch(__curves, prim);
|
|
||||||
shader = __float_as_int(str.z);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return kernel_tex_fetch(__shaders, (shader & SHADER_MASK)).flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
ccl_device_forceinline int intersection_get_shader(KernelGlobals *ccl_restrict kg,
|
|
||||||
const Intersection *isect)
|
|
||||||
{
|
|
||||||
const int prim = kernel_tex_fetch(__prim_index, isect->prim);
|
|
||||||
int shader = 0;
|
|
||||||
|
|
||||||
#ifdef __HAIR__
|
|
||||||
if (kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
shader = kernel_tex_fetch(__tri_shader, prim);
|
|
||||||
}
|
|
||||||
#ifdef __HAIR__
|
|
||||||
else {
|
|
||||||
float4 str = kernel_tex_fetch(__curves, prim);
|
|
||||||
shader = __float_as_int(str.z);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return shader & SHADER_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
CCL_NAMESPACE_END
|
|
@@ -119,11 +119,11 @@ ccl_device_inline bool lamp_light_sample(
|
|||||||
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
|
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
|
||||||
float3 axisv = make_float3(
|
float3 axisv = make_float3(
|
||||||
klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
|
klight->area.axisv[0], klight->area.axisv[1], klight->area.axisv[2]);
|
||||||
float3 Ng = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
|
float3 D = make_float3(klight->area.dir[0], klight->area.dir[1], klight->area.dir[2]);
|
||||||
float invarea = fabsf(klight->area.invarea);
|
float invarea = fabsf(klight->area.invarea);
|
||||||
bool is_round = (klight->area.invarea < 0.0f);
|
bool is_round = (klight->area.invarea < 0.0f);
|
||||||
|
|
||||||
if (dot(ls->P - P, Ng) > 0.0f) {
|
if (dot(ls->P - P, D) > 0.0f) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,37 +136,19 @@ ccl_device_inline bool lamp_light_sample(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inplane = ls->P;
|
inplane = ls->P;
|
||||||
|
ls->pdf = rect_light_sample(P, &ls->P, axisu, axisv, randu, randv, true);
|
||||||
float3 sample_axisu = axisu;
|
|
||||||
float3 sample_axisv = axisv;
|
|
||||||
|
|
||||||
if (klight->area.tan_spread > 0.0f) {
|
|
||||||
if (!light_spread_clamp_area_light(
|
|
||||||
P, Ng, &ls->P, &sample_axisu, &sample_axisv, klight->area.tan_spread)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ls->pdf = rect_light_sample(P, &ls->P, sample_axisu, sample_axisv, randu, randv, true);
|
|
||||||
inplane = ls->P - inplane;
|
inplane = ls->P - inplane;
|
||||||
}
|
}
|
||||||
|
|
||||||
ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
|
ls->u = dot(inplane, axisu) * (1.0f / dot(axisu, axisu)) + 0.5f;
|
||||||
ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
|
ls->v = dot(inplane, axisv) * (1.0f / dot(axisv, axisv)) + 0.5f;
|
||||||
|
|
||||||
ls->Ng = Ng;
|
ls->Ng = D;
|
||||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||||
|
|
||||||
ls->eval_fac = 0.25f * invarea;
|
ls->eval_fac = 0.25f * invarea;
|
||||||
|
|
||||||
if (klight->area.tan_spread > 0.0f) {
|
|
||||||
/* Area Light spread angle attenuation */
|
|
||||||
ls->eval_fac *= light_spread_attenuation(
|
|
||||||
ls->D, ls->Ng, klight->area.tan_spread, klight->area.normalize_spread);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_round) {
|
if (is_round) {
|
||||||
ls->pdf *= lamp_light_pdf(kg, Ng, -ls->D, ls->t);
|
ls->pdf *= lamp_light_pdf(kg, D, -ls->D, ls->t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -301,28 +283,9 @@ ccl_device bool lamp_light_eval(
|
|||||||
ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
|
ls->pdf = invarea * lamp_light_pdf(kg, Ng, -D, ls->t);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float3 sample_axisu = axisu;
|
ls->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
|
||||||
float3 sample_axisv = axisv;
|
|
||||||
|
|
||||||
if (klight->area.tan_spread > 0.0f) {
|
|
||||||
if (!light_spread_clamp_area_light(
|
|
||||||
P, Ng, &light_P, &sample_axisu, &sample_axisv, klight->area.tan_spread)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ls->pdf = rect_light_sample(P, &light_P, sample_axisu, sample_axisv, 0, 0, false);
|
|
||||||
}
|
}
|
||||||
ls->eval_fac = 0.25f * invarea;
|
ls->eval_fac = 0.25f * invarea;
|
||||||
|
|
||||||
if (klight->area.tan_spread > 0.0f) {
|
|
||||||
/* Area Light spread angle attenuation */
|
|
||||||
ls->eval_fac *= light_spread_attenuation(
|
|
||||||
ls->D, ls->Ng, klight->area.tan_spread, klight->area.normalize_spread);
|
|
||||||
if (ls->eval_fac == 0.0f) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@@ -146,70 +146,6 @@ ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot
|
|||||||
return attenuation;
|
return attenuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
ccl_device float light_spread_attenuation(const float3 D,
|
|
||||||
const float3 lightNg,
|
|
||||||
const float tan_spread,
|
|
||||||
const float normalize_spread)
|
|
||||||
{
|
|
||||||
/* Model a soft-box grid, computing the ratio of light not hidden by the
|
|
||||||
* slats of the grid at a given angle. (see D10594). */
|
|
||||||
const float cos_a = -dot(D, lightNg);
|
|
||||||
const float sin_a = safe_sqrtf(1.0f - sqr(cos_a));
|
|
||||||
const float tan_a = sin_a / cos_a;
|
|
||||||
return max((1.0f - (tan_spread * tan_a)) * normalize_spread, 0.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute subset of area light that actually has an influence on the shading point, to
|
|
||||||
* reduce noise with low spread. */
|
|
||||||
ccl_device bool light_spread_clamp_area_light(const float3 P,
|
|
||||||
const float3 lightNg,
|
|
||||||
float3 *lightP,
|
|
||||||
float3 *axisu,
|
|
||||||
float3 *axisv,
|
|
||||||
const float tan_spread)
|
|
||||||
{
|
|
||||||
/* Closest point in area light plane and distance to that plane. */
|
|
||||||
const float3 closest_P = P - dot(lightNg, P - *lightP) * lightNg;
|
|
||||||
const float t = len(closest_P - P);
|
|
||||||
|
|
||||||
/* Radius of circle on area light that actually affects the shading point. */
|
|
||||||
const float radius = t / tan_spread;
|
|
||||||
|
|
||||||
/* TODO: would be faster to store as normalized vector + length, also in rect_light_sample. */
|
|
||||||
float len_u, len_v;
|
|
||||||
const float3 u = normalize_len(*axisu, &len_u);
|
|
||||||
const float3 v = normalize_len(*axisv, &len_v);
|
|
||||||
|
|
||||||
/* Local uv coordinates of closest point. */
|
|
||||||
const float closest_u = dot(u, closest_P - *lightP);
|
|
||||||
const float closest_v = dot(v, closest_P - *lightP);
|
|
||||||
|
|
||||||
/* Compute rectangle encompassing the circle that affects the shading point,
|
|
||||||
* clamped to the bounds of the area light. */
|
|
||||||
const float min_u = max(closest_u - radius, -len_u * 0.5f);
|
|
||||||
const float max_u = min(closest_u + radius, len_u * 0.5f);
|
|
||||||
const float min_v = max(closest_v - radius, -len_v * 0.5f);
|
|
||||||
const float max_v = min(closest_v + radius, len_v * 0.5f);
|
|
||||||
|
|
||||||
/* Skip if rectangle is empty. */
|
|
||||||
if (min_u >= max_u || min_v >= max_v) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute new area light center position and axes from rectangle in local
|
|
||||||
* uv coordinates. */
|
|
||||||
const float new_center_u = 0.5f * (min_u + max_u);
|
|
||||||
const float new_center_v = 0.5f * (min_v + max_v);
|
|
||||||
const float new_len_u = 0.5f * (max_u - min_u);
|
|
||||||
const float new_len_v = 0.5f * (max_v - min_v);
|
|
||||||
|
|
||||||
*lightP = *lightP + new_center_u * u + new_center_v * v;
|
|
||||||
*axisu = u * new_len_u * 2.0f;
|
|
||||||
*axisv = v * new_len_v * 2.0f;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
|
ccl_device float lamp_light_pdf(KernelGlobals *kg, const float3 Ng, const float3 I, float t)
|
||||||
{
|
{
|
||||||
float cos_pi = dot(Ng, I);
|
float cos_pi = dot(Ng, I);
|
||||||
|
@@ -65,6 +65,7 @@ ccl_device_forceinline bool kernel_path_scene_intersect(KernelGlobals *kg,
|
|||||||
uint visibility = path_state_ray_visibility(kg, state);
|
uint visibility = path_state_ray_visibility(kg, state);
|
||||||
|
|
||||||
if (path_state_ao_bounce(kg, state)) {
|
if (path_state_ao_bounce(kg, state)) {
|
||||||
|
visibility = PATH_RAY_SHADOW;
|
||||||
ray->t = kernel_data.background.ao_distance;
|
ray->t = kernel_data.background.ao_distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,13 +416,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (path_state_ao_bounce(kg, state)) {
|
else if (path_state_ao_bounce(kg, state)) {
|
||||||
if (intersection_get_shader_flags(kg, &isect) &
|
break;
|
||||||
(SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
|
|
||||||
state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup shader data. */
|
/* Setup shader data. */
|
||||||
@@ -559,13 +554,7 @@ ccl_device_forceinline void kernel_path_integrate(KernelGlobals *kg,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (path_state_ao_bounce(kg, state)) {
|
else if (path_state_ao_bounce(kg, state)) {
|
||||||
if (intersection_get_shader_flags(kg, &isect) &
|
break;
|
||||||
(SD_HAS_TRANSPARENT_SHADOW | SD_HAS_EMISSION)) {
|
|
||||||
state->flag |= PATH_RAY_TERMINATE_AFTER_TRANSPARENT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup shader data. */
|
/* Setup shader data. */
|
||||||
|
@@ -895,8 +895,6 @@ enum ShaderDataFlag {
|
|||||||
SD_HAS_CONSTANT_EMISSION = (1 << 27),
|
SD_HAS_CONSTANT_EMISSION = (1 << 27),
|
||||||
/* Needs to access attributes for volume rendering */
|
/* Needs to access attributes for volume rendering */
|
||||||
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
|
SD_NEED_VOLUME_ATTRIBUTES = (1 << 28),
|
||||||
/* Shader has emission */
|
|
||||||
SD_HAS_EMISSION = (1 << 29),
|
|
||||||
|
|
||||||
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
|
SD_SHADER_FLAGS = (SD_USE_MIS | SD_HAS_TRANSPARENT_SHADOW | SD_HAS_VOLUME | SD_HAS_ONLY_VOLUME |
|
||||||
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
|
SD_HETEROGENEOUS_VOLUME | SD_HAS_BSSRDF_BUMP | SD_VOLUME_EQUIANGULAR |
|
||||||
@@ -1503,9 +1501,9 @@ typedef struct KernelAreaLight {
|
|||||||
float axisu[3];
|
float axisu[3];
|
||||||
float invarea;
|
float invarea;
|
||||||
float axisv[3];
|
float axisv[3];
|
||||||
float tan_spread;
|
float pad1;
|
||||||
float dir[3];
|
float dir[3];
|
||||||
float normalize_spread;
|
float pad2;
|
||||||
} KernelAreaLight;
|
} KernelAreaLight;
|
||||||
|
|
||||||
typedef struct KernelDistantLight {
|
typedef struct KernelDistantLight {
|
||||||
|
@@ -88,13 +88,6 @@ point wrap(point value, point max, point min)
|
|||||||
wrap(value[2], max[2], min[2]));
|
wrap(value[2], max[2], min[2]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Built in OSL faceforward is `(dot(I, Nref) > 0) ? -N : N;` which is different to
|
|
||||||
* GLSL `dot(Nref, I) < 0 ? N : -N` for zero values. */
|
|
||||||
point compatible_faceforward(point vec, point incident, point reference)
|
|
||||||
{
|
|
||||||
return dot(reference, incident) < 0.0 ? vec : -vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix euler_to_mat(point euler)
|
matrix euler_to_mat(point euler)
|
||||||
{
|
{
|
||||||
float cx = cos(euler[0]);
|
float cx = cos(euler[0]);
|
||||||
|
@@ -46,12 +46,6 @@ shader node_vector_math(string math_type = "add",
|
|||||||
else if (math_type == "reflect") {
|
else if (math_type == "reflect") {
|
||||||
Vector = reflect(Vector1, normalize(Vector2));
|
Vector = reflect(Vector1, normalize(Vector2));
|
||||||
}
|
}
|
||||||
else if (math_type == "refract") {
|
|
||||||
Vector = refract(Vector1, normalize(Vector2), Scale);
|
|
||||||
}
|
|
||||||
else if (math_type == "faceforward") {
|
|
||||||
Vector = compatible_faceforward(Vector1, Vector2, Vector3);
|
|
||||||
}
|
|
||||||
else if (math_type == "dot_product") {
|
else if (math_type == "dot_product") {
|
||||||
Value = dot(Vector1, Vector2);
|
Value = dot(Vector1, Vector2);
|
||||||
}
|
}
|
||||||
|
@@ -44,26 +44,26 @@ ccl_device void svm_node_vector_math(KernelGlobals *kg,
|
|||||||
int *offset)
|
int *offset)
|
||||||
{
|
{
|
||||||
uint value_stack_offset, vector_stack_offset;
|
uint value_stack_offset, vector_stack_offset;
|
||||||
uint a_stack_offset, b_stack_offset, param1_stack_offset;
|
uint a_stack_offset, b_stack_offset, scale_stack_offset;
|
||||||
svm_unpack_node_uchar3(
|
svm_unpack_node_uchar3(
|
||||||
inputs_stack_offsets, &a_stack_offset, &b_stack_offset, ¶m1_stack_offset);
|
inputs_stack_offsets, &a_stack_offset, &b_stack_offset, &scale_stack_offset);
|
||||||
svm_unpack_node_uchar2(outputs_stack_offsets, &value_stack_offset, &vector_stack_offset);
|
svm_unpack_node_uchar2(outputs_stack_offsets, &value_stack_offset, &vector_stack_offset);
|
||||||
|
|
||||||
float3 a = stack_load_float3(stack, a_stack_offset);
|
float3 a = stack_load_float3(stack, a_stack_offset);
|
||||||
float3 b = stack_load_float3(stack, b_stack_offset);
|
float3 b = stack_load_float3(stack, b_stack_offset);
|
||||||
float3 c = make_float3(0.0f, 0.0f, 0.0f);
|
float3 c = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
float param1 = stack_load_float(stack, param1_stack_offset);
|
float scale = stack_load_float(stack, scale_stack_offset);
|
||||||
|
|
||||||
float value;
|
float value;
|
||||||
float3 vector;
|
float3 vector;
|
||||||
|
|
||||||
/* 3 Vector Operators */
|
/* 3 Vector Operators */
|
||||||
if (type == NODE_VECTOR_MATH_WRAP || type == NODE_VECTOR_MATH_FACEFORWARD) {
|
if (type == NODE_VECTOR_MATH_WRAP) {
|
||||||
uint4 extra_node = read_node(kg, offset);
|
uint4 extra_node = read_node(kg, offset);
|
||||||
c = stack_load_float3(stack, extra_node.x);
|
c = stack_load_float3(stack, extra_node.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, param1);
|
svm_vector_math(&value, &vector, (NodeVectorMathType)type, a, b, c, scale);
|
||||||
|
|
||||||
if (stack_valid(value_stack_offset))
|
if (stack_valid(value_stack_offset))
|
||||||
stack_store_float(stack, value_stack_offset, value);
|
stack_store_float(stack, value_stack_offset, value);
|
||||||
|
@@ -22,7 +22,7 @@ ccl_device void svm_vector_math(float *value,
|
|||||||
float3 a,
|
float3 a,
|
||||||
float3 b,
|
float3 b,
|
||||||
float3 c,
|
float3 c,
|
||||||
float param1)
|
float scale)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NODE_VECTOR_MATH_ADD:
|
case NODE_VECTOR_MATH_ADD:
|
||||||
@@ -46,12 +46,6 @@ ccl_device void svm_vector_math(float *value,
|
|||||||
case NODE_VECTOR_MATH_REFLECT:
|
case NODE_VECTOR_MATH_REFLECT:
|
||||||
*vector = reflect(a, b);
|
*vector = reflect(a, b);
|
||||||
break;
|
break;
|
||||||
case NODE_VECTOR_MATH_REFRACT:
|
|
||||||
*vector = refract(a, normalize(b), param1);
|
|
||||||
break;
|
|
||||||
case NODE_VECTOR_MATH_FACEFORWARD:
|
|
||||||
*vector = faceforward(a, b, c);
|
|
||||||
break;
|
|
||||||
case NODE_VECTOR_MATH_DOT_PRODUCT:
|
case NODE_VECTOR_MATH_DOT_PRODUCT:
|
||||||
*value = dot(a, b);
|
*value = dot(a, b);
|
||||||
break;
|
break;
|
||||||
@@ -62,7 +56,7 @@ ccl_device void svm_vector_math(float *value,
|
|||||||
*value = len(a);
|
*value = len(a);
|
||||||
break;
|
break;
|
||||||
case NODE_VECTOR_MATH_SCALE:
|
case NODE_VECTOR_MATH_SCALE:
|
||||||
*vector = a * param1;
|
*vector = a * scale;
|
||||||
break;
|
break;
|
||||||
case NODE_VECTOR_MATH_NORMALIZE:
|
case NODE_VECTOR_MATH_NORMALIZE:
|
||||||
*vector = safe_normalize(a);
|
*vector = safe_normalize(a);
|
||||||
@@ -104,7 +98,7 @@ ccl_device void svm_vector_math(float *value,
|
|||||||
*vector = make_float3(tanf(a.x), tanf(a.y), tanf(a.z));
|
*vector = make_float3(tanf(a.x), tanf(a.y), tanf(a.z));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
*vector = zero_float3();
|
*vector = make_float3(0.0f, 0.0f, 0.0f);
|
||||||
*value = 0.0f;
|
*value = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,15 +236,10 @@ ccl_device float3 svm_math_blackbody_color(float t)
|
|||||||
return make_float3(4.70366907f, 0.0f, 0.0f);
|
return make_float3(4.70366907f, 0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manually align for readability. */
|
int i = (t >= 6365.0f) ?
|
||||||
/* clang-format off */
|
5 :
|
||||||
int i = (t >= 6365.0f) ? 5 :
|
(t >= 3315.0f) ? 4 :
|
||||||
(t >= 3315.0f) ? 4 :
|
(t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0;
|
||||||
(t >= 1902.0f) ? 3 :
|
|
||||||
(t >= 1449.0f) ? 2 :
|
|
||||||
(t >= 1167.0f) ? 1 :
|
|
||||||
0;
|
|
||||||
/* clang-format on */
|
|
||||||
|
|
||||||
ccl_constant float *r = blackbody_table_r[i];
|
ccl_constant float *r = blackbody_table_r[i];
|
||||||
ccl_constant float *g = blackbody_table_g[i];
|
ccl_constant float *g = blackbody_table_g[i];
|
||||||
|
@@ -339,8 +339,6 @@ typedef enum NodeVectorMathType {
|
|||||||
NODE_VECTOR_MATH_SINE,
|
NODE_VECTOR_MATH_SINE,
|
||||||
NODE_VECTOR_MATH_COSINE,
|
NODE_VECTOR_MATH_COSINE,
|
||||||
NODE_VECTOR_MATH_TANGENT,
|
NODE_VECTOR_MATH_TANGENT,
|
||||||
NODE_VECTOR_MATH_REFRACT,
|
|
||||||
NODE_VECTOR_MATH_FACEFORWARD,
|
|
||||||
} NodeVectorMathType;
|
} NodeVectorMathType;
|
||||||
|
|
||||||
typedef enum NodeClampType {
|
typedef enum NodeClampType {
|
||||||
|
@@ -396,10 +396,6 @@ static void add_uvs(AlembicProcedural *proc,
|
|||||||
|
|
||||||
ccl::set<chrono_t> times = get_relevant_sample_times(proc, time_sampling, uvs.getNumSamples());
|
ccl::set<chrono_t> times = get_relevant_sample_times(proc, time_sampling, uvs.getNumSamples());
|
||||||
|
|
||||||
/* Keys used to determine if the UVs do actually change over time. */
|
|
||||||
ArraySample::Key previous_indices_key;
|
|
||||||
ArraySample::Key previous_values_key;
|
|
||||||
|
|
||||||
foreach (chrono_t time, times) {
|
foreach (chrono_t time, times) {
|
||||||
if (progress.get_cancel()) {
|
if (progress.get_cancel()) {
|
||||||
return;
|
return;
|
||||||
@@ -426,32 +422,21 @@ static void add_uvs(AlembicProcedural *proc,
|
|||||||
|
|
||||||
float2 *data_float2 = reinterpret_cast<float2 *>(data.data());
|
float2 *data_float2 = reinterpret_cast<float2 *>(data.data());
|
||||||
|
|
||||||
const ArraySample::Key indices_key = uvsample.getIndices()->getKey();
|
const unsigned int *indices = uvsample.getIndices()->get();
|
||||||
const ArraySample::Key values_key = uvsample.getVals()->getKey();
|
const V2f *values = uvsample.getVals()->get();
|
||||||
|
|
||||||
if (indices_key == previous_indices_key && values_key == previous_values_key) {
|
for (const int3 &loop : *triangles_loops) {
|
||||||
attr.data.reuse_data_for_last_time(time);
|
unsigned int v0 = indices[loop.x];
|
||||||
}
|
unsigned int v1 = indices[loop.y];
|
||||||
else {
|
unsigned int v2 = indices[loop.z];
|
||||||
const unsigned int *indices = uvsample.getIndices()->get();
|
|
||||||
const V2f *values = uvsample.getVals()->get();
|
|
||||||
|
|
||||||
for (const int3 &loop : *triangles_loops) {
|
data_float2[0] = make_float2(values[v0][0], values[v0][1]);
|
||||||
unsigned int v0 = indices[loop.x];
|
data_float2[1] = make_float2(values[v1][0], values[v1][1]);
|
||||||
unsigned int v1 = indices[loop.y];
|
data_float2[2] = make_float2(values[v2][0], values[v2][1]);
|
||||||
unsigned int v2 = indices[loop.z];
|
data_float2 += 3;
|
||||||
|
|
||||||
data_float2[0] = make_float2(values[v0][0], values[v0][1]);
|
|
||||||
data_float2[1] = make_float2(values[v1][0], values[v1][1]);
|
|
||||||
data_float2[2] = make_float2(values[v2][0], values[v2][1]);
|
|
||||||
data_float2 += 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
attr.data.add_data(data, time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_indices_key = indices_key;
|
attr.data.add_data(data, time);
|
||||||
previous_values_key = values_key;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -751,11 +736,6 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
|
|||||||
ccl::set<chrono_t> times = get_relevant_sample_times(
|
ccl::set<chrono_t> times = get_relevant_sample_times(
|
||||||
proc, *time_sampling, schema.getNumSamples());
|
proc, *time_sampling, schema.getNumSamples());
|
||||||
|
|
||||||
/* Key used to determine if the triangles change over time, if the key is the same as the
|
|
||||||
* last one, we can avoid creating a new entry in the cache and simply point to the last
|
|
||||||
* frame. */
|
|
||||||
ArraySample::Key previous_key;
|
|
||||||
|
|
||||||
/* read topology */
|
/* read topology */
|
||||||
foreach (chrono_t time, times) {
|
foreach (chrono_t time, times) {
|
||||||
if (progress.get_cancel()) {
|
if (progress.get_cancel()) {
|
||||||
@@ -767,27 +747,22 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
|
|||||||
|
|
||||||
add_positions(sample.getPositions(), time, cached_data);
|
add_positions(sample.getPositions(), time, cached_data);
|
||||||
|
|
||||||
/* Only copy triangles for other frames if the topology is changing over time as well. */
|
/* Only copy triangles for other frames if the topology is changing over time as well.
|
||||||
|
*
|
||||||
|
* TODO(@kevindietrich): even for dynamic simulations, this is a waste of memory and
|
||||||
|
* processing time if only the positions are changing in a subsequence of frames but we
|
||||||
|
* cannot optimize in this current system if the attributes are changing over time as well,
|
||||||
|
* as we need valid data for each time point. This can be solved by using reference counting
|
||||||
|
* on the ccl::array and simply share the array across frames. */
|
||||||
if (schema.getTopologyVariance() != kHomogenousTopology || cached_data.triangles.size() == 0) {
|
if (schema.getTopologyVariance() != kHomogenousTopology || cached_data.triangles.size() == 0) {
|
||||||
const ArraySample::Key key = sample.getFaceIndices()->getKey();
|
/* start by reading the face sets (per face shader), as we directly split polygons to
|
||||||
|
* triangles
|
||||||
|
*/
|
||||||
|
array<int> polygon_to_shader;
|
||||||
|
read_face_sets(schema, polygon_to_shader, iss);
|
||||||
|
|
||||||
if (key == previous_key) {
|
add_triangles(
|
||||||
cached_data.triangles.reuse_data_for_last_time(time);
|
sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
|
||||||
cached_data.triangles_loops.reuse_data_for_last_time(time);
|
|
||||||
cached_data.shader.reuse_data_for_last_time(time);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* start by reading the face sets (per face shader), as we directly split polygons to
|
|
||||||
* triangles
|
|
||||||
*/
|
|
||||||
array<int> polygon_to_shader;
|
|
||||||
read_face_sets(schema, polygon_to_shader, iss);
|
|
||||||
|
|
||||||
add_triangles(
|
|
||||||
sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
previous_key = key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (normals.valid()) {
|
if (normals.valid()) {
|
||||||
@@ -1407,15 +1382,6 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress)
|
|||||||
need_data_updates = true;
|
need_data_updates = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the shaders were modified. */
|
|
||||||
if (object->used_shaders_is_modified() && object->get_object() &&
|
|
||||||
object->get_object()->get_geometry()) {
|
|
||||||
Geometry *geometry = object->get_object()->get_geometry();
|
|
||||||
array<Node *> used_shaders = object->get_used_shaders();
|
|
||||||
geometry->set_used_shaders(used_shaders);
|
|
||||||
need_shader_updates = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for changes in shaders (e.g. newly requested attributes). */
|
/* Check for changes in shaders (e.g. newly requested attributes). */
|
||||||
foreach (Node *shader_node, object->get_used_shaders()) {
|
foreach (Node *shader_node, object->get_used_shaders()) {
|
||||||
Shader *shader = static_cast<Shader *>(shader_node);
|
Shader *shader = static_cast<Shader *>(shader_node);
|
||||||
@@ -1595,11 +1561,6 @@ void AlembicProcedural::read_mesh(AlembicObject *abc_object, Abc::chrono_t frame
|
|||||||
|
|
||||||
Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
|
Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
|
||||||
|
|
||||||
/* Make sure shader ids are also updated. */
|
|
||||||
if (mesh->used_shaders_is_modified()) {
|
|
||||||
mesh->tag_shader_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
|
cached_data.vertices.copy_to_socket(frame_time, mesh, mesh->get_verts_socket());
|
||||||
|
|
||||||
cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
|
cached_data.shader.copy_to_socket(frame_time, mesh, mesh->get_shader_socket());
|
||||||
@@ -1667,11 +1628,6 @@ void AlembicProcedural::read_subd(AlembicObject *abc_object, Abc::chrono_t frame
|
|||||||
|
|
||||||
Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
|
Mesh *mesh = static_cast<Mesh *>(object->get_geometry());
|
||||||
|
|
||||||
/* Make sure shader ids are also updated. */
|
|
||||||
if (mesh->used_shaders_is_modified()) {
|
|
||||||
mesh->tag_shader_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cycles overwrites the original triangles when computing displacement, so we always have to
|
/* Cycles overwrites the original triangles when computing displacement, so we always have to
|
||||||
* repass the data if something is animated (vertices most likely) to avoid buffer overflows. */
|
* repass the data if something is animated (vertices most likely) to avoid buffer overflows. */
|
||||||
if (!cached_data.is_constant()) {
|
if (!cached_data.is_constant()) {
|
||||||
@@ -1762,11 +1718,6 @@ void AlembicProcedural::read_curves(AlembicObject *abc_object, Abc::chrono_t fra
|
|||||||
|
|
||||||
Hair *hair = static_cast<Hair *>(object->get_geometry());
|
Hair *hair = static_cast<Hair *>(object->get_geometry());
|
||||||
|
|
||||||
/* Make sure shader ids are also updated. */
|
|
||||||
if (hair->used_shaders_is_modified()) {
|
|
||||||
hair->tag_curve_shader_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
|
cached_data.curve_keys.copy_to_socket(frame_time, hair, hair->get_curve_keys_socket());
|
||||||
|
|
||||||
cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
|
cached_data.curve_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
|
||||||
|
@@ -43,14 +43,14 @@ struct MatrixSamplesData {
|
|||||||
Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling;
|
Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Helpers to detect if some type is a `ccl::array`. */
|
/* Helpers to detect if some type is a ccl::array. */
|
||||||
template<typename> struct is_array : public std::false_type {
|
template<typename> struct is_array : public std::false_type {
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct is_array<array<T>> : public std::true_type {
|
template<typename T> struct is_array<array<T>> : public std::true_type {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Holds the data for a cache lookup at a given time, as well as information to
|
/* Holds the data for a cache lookup at a given time, as well as informations to
|
||||||
* help disambiguate successes or failures to get data from the cache. */
|
* help disambiguate successes or failures to get data from the cache. */
|
||||||
template<typename T> class CacheLookupResult {
|
template<typename T> class CacheLookupResult {
|
||||||
enum class State {
|
enum class State {
|
||||||
@@ -128,25 +128,12 @@ template<typename T> class CacheLookupResult {
|
|||||||
* The data is supposed to be stored in chronological order, and is looked up using the current
|
* 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. */
|
* animation time in seconds using the TimeSampling from the Alembic property. */
|
||||||
template<typename T> class DataStore {
|
template<typename T> class DataStore {
|
||||||
/* Holds information to map a cache entry for a given time to an index into the data array. */
|
struct DataTimePair {
|
||||||
struct TimeIndexPair {
|
|
||||||
/* Frame time for this entry. */
|
|
||||||
double time = 0;
|
double time = 0;
|
||||||
/* Frame time for the data pointed to by `index`. */
|
T data{};
|
||||||
double source_time = 0;
|
|
||||||
/* Index into the data array. */
|
|
||||||
size_t index = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the actual data that is stored. We deduplicate data across frames to avoid storing
|
vector<DataTimePair> data{};
|
||||||
* values if they have not changed yet (e.g. the triangles for a building before fracturing, or a
|
|
||||||
* fluid simulation before a break or splash) */
|
|
||||||
vector<T> data{};
|
|
||||||
|
|
||||||
/* This is used to map they entry for a given time to an index into the data array, multiple
|
|
||||||
* frames can point to the same index. */
|
|
||||||
vector<TimeIndexPair> index_data_map{};
|
|
||||||
|
|
||||||
Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
|
Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
|
||||||
|
|
||||||
double last_loaded_time = std::numeric_limits<double>::max();
|
double last_loaded_time = std::numeric_limits<double>::max();
|
||||||
@@ -170,21 +157,17 @@ template<typename T> class DataStore {
|
|||||||
return CacheLookupResult<T>::no_data_found_for_time();
|
return CacheLookupResult<T>::no_data_found_for_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimeIndexPair &index = get_index_for_time(time);
|
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 (index.index == -1ul) {
|
if (last_loaded_time == data_pair.time) {
|
||||||
return CacheLookupResult<T>::no_data_found_for_time();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_loaded_time == index.time || last_loaded_time == index.source_time) {
|
|
||||||
return CacheLookupResult<T>::already_loaded();
|
return CacheLookupResult<T>::already_loaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
last_loaded_time = index.source_time;
|
last_loaded_time = data_pair.time;
|
||||||
|
|
||||||
assert(index.index < data.size());
|
return CacheLookupResult<T>::new_data(&data_pair.data);
|
||||||
|
|
||||||
return CacheLookupResult<T>::new_data(&data[index.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the data for the specified time, but do not check if the data was already loaded for this
|
/* get the data for the specified time, but do not check if the data was already loaded for this
|
||||||
@@ -195,34 +178,22 @@ template<typename T> class DataStore {
|
|||||||
return CacheLookupResult<T>::no_data_found_for_time();
|
return CacheLookupResult<T>::no_data_found_for_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimeIndexPair &index = get_index_for_time(time);
|
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
|
||||||
|
index_pair = time_sampling.getNearIndex(time, data.size());
|
||||||
if (index.index == -1ul) {
|
DataTimePair &data_pair = data[index_pair.first];
|
||||||
return CacheLookupResult<T>::no_data_found_for_time();
|
return CacheLookupResult<T>::new_data(&data_pair.data);
|
||||||
}
|
|
||||||
|
|
||||||
assert(index.index < data.size());
|
|
||||||
|
|
||||||
return CacheLookupResult<T>::new_data(&data[index.index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_data(T &data_, double time)
|
void add_data(T &data_, double time)
|
||||||
{
|
{
|
||||||
index_data_map.push_back({time, time, data.size()});
|
|
||||||
|
|
||||||
if constexpr (is_array<T>::value) {
|
if constexpr (is_array<T>::value) {
|
||||||
data.emplace_back();
|
data.emplace_back();
|
||||||
data.back().steal_data(data_);
|
data.back().data.steal_data(data_);
|
||||||
|
data.back().time = time;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.push_back(data_);
|
data.push_back({time, data_});
|
||||||
}
|
|
||||||
|
|
||||||
void reuse_data_for_last_time(double time)
|
|
||||||
{
|
|
||||||
const TimeIndexPair &data_index = index_data_map.back();
|
|
||||||
index_data_map.push_back({time, data_index.source_time, data_index.index});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_constant() const
|
bool is_constant() const
|
||||||
@@ -239,7 +210,6 @@ template<typename T> class DataStore {
|
|||||||
{
|
{
|
||||||
invalidate_last_loaded_time();
|
invalidate_last_loaded_time();
|
||||||
data.clear();
|
data.clear();
|
||||||
index_data_map.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate_last_loaded_time()
|
void invalidate_last_loaded_time()
|
||||||
@@ -262,14 +232,6 @@ template<typename T> class DataStore {
|
|||||||
T value = result.get_data();
|
T value = result.get_data();
|
||||||
node->set(*socket, value);
|
node->set(*socket, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
const TimeIndexPair &get_index_for_time(double time) const
|
|
||||||
{
|
|
||||||
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
|
|
||||||
index_pair = time_sampling.getNearIndex(time, index_data_map.size());
|
|
||||||
return index_data_map[index_pair.first];
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Actual cache for the stored data.
|
/* Actual cache for the stored data.
|
||||||
@@ -481,23 +443,16 @@ class AlembicProcedural : public Procedural {
|
|||||||
* invocation, and updates the data on subsequent invocations if the frame changed. */
|
* invocation, and updates the data on subsequent invocations if the frame changed. */
|
||||||
void generate(Scene *scene, Progress &progress);
|
void generate(Scene *scene, Progress &progress);
|
||||||
|
|
||||||
/* Tag for an update only if something was modified. */
|
|
||||||
void tag_update(Scene *scene);
|
|
||||||
|
|
||||||
/* This should be called by scene exporters to request the rendering of an object located
|
|
||||||
* in the Alembic archive at the given path.
|
|
||||||
*
|
|
||||||
* Since we lazily load object, the function does not validate the existence of the object
|
|
||||||
* in the archive. If no objects with such path if found in the archive during the next call
|
|
||||||
* to `generate`, it will be ignored.
|
|
||||||
*
|
|
||||||
* Returns a pointer to an existing or a newly created AlembicObject for the given path. */
|
|
||||||
AlembicObject *get_or_create_object(const ustring &path);
|
|
||||||
|
|
||||||
private:
|
|
||||||
/* Add an object to our list of objects, and tag the socket as modified. */
|
/* Add an object to our list of objects, and tag the socket as modified. */
|
||||||
void add_object(AlembicObject *object);
|
void add_object(AlembicObject *object);
|
||||||
|
|
||||||
|
/* Tag for an update only if something was modified. */
|
||||||
|
void tag_update(Scene *scene);
|
||||||
|
|
||||||
|
/* Returns a pointer to an existing 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. */
|
/* Load the data for all the objects whose data has not yet been loaded. */
|
||||||
void load_objects(Progress &progress);
|
void load_objects(Progress &progress);
|
||||||
|
|
||||||
|
@@ -130,14 +130,6 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
|||||||
|
|
||||||
void Background::tag_update(Scene *scene)
|
void Background::tag_update(Scene *scene)
|
||||||
{
|
{
|
||||||
Shader *bg_shader = get_shader(scene);
|
|
||||||
if (bg_shader && bg_shader->is_modified()) {
|
|
||||||
/* Tag as modified to update the KernelBackground visibility information.
|
|
||||||
* We only tag the use_shader socket as modified as it is related to the shader
|
|
||||||
* and to avoid doing unnecessary updates anywhere else. */
|
|
||||||
tag_use_shader_modified();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ao_factor_is_modified() || use_ao_is_modified()) {
|
if (ao_factor_is_modified() || use_ao_is_modified()) {
|
||||||
scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
|
scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
|
||||||
}
|
}
|
||||||
|
@@ -90,7 +90,6 @@ void Geometry::clear(bool preserve_shaders)
|
|||||||
transform_applied = false;
|
transform_applied = false;
|
||||||
transform_negative_scaled = false;
|
transform_negative_scaled = false;
|
||||||
transform_normal = transform_identity();
|
transform_normal = transform_identity();
|
||||||
tag_modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
|
bool Geometry::need_attribute(Scene *scene, AttributeStandard std)
|
||||||
@@ -1364,6 +1363,7 @@ void GeometryManager::device_update_bvh(Device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dscene->data.bvh.root = pack.root_index;
|
dscene->data.bvh.root = pack.root_index;
|
||||||
|
dscene->data.bvh.bvh_layout = bparams.bvh_layout;
|
||||||
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
|
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
|
||||||
dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
|
dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
|
||||||
/* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */
|
/* The scene handle is set in 'CPUDevice::const_copy_to' and 'OptiXDevice::const_copy_to' */
|
||||||
@@ -1583,6 +1583,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro
|
|||||||
dscene->tri_vnormal.tag_realloc();
|
dscene->tri_vnormal.tag_realloc();
|
||||||
dscene->tri_vindex.tag_realloc();
|
dscene->tri_vindex.tag_realloc();
|
||||||
dscene->tri_patch.tag_realloc();
|
dscene->tri_patch.tag_realloc();
|
||||||
|
dscene->tri_vnormal.tag_realloc();
|
||||||
dscene->tri_patch_uv.tag_realloc();
|
dscene->tri_patch_uv.tag_realloc();
|
||||||
dscene->tri_shader.tag_realloc();
|
dscene->tri_shader.tag_realloc();
|
||||||
dscene->patches.tag_realloc();
|
dscene->patches.tag_realloc();
|
||||||
@@ -1915,12 +1916,9 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update the BVH even when there is no geometry so the kernel's BVH data is still valid,
|
/* 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.
|
* especially when removing all of the objects during interactive renders */
|
||||||
* Also update the BVH if the transformations change, we cannot rely on tagging the Geometry
|
bool need_update_scene_bvh = (scene->bvh == nullptr);
|
||||||
* as modified in this case, as we may accumulate displacement if the vertices do not also
|
|
||||||
* change. */
|
|
||||||
bool need_update_scene_bvh = (scene->bvh == nullptr || (update_flags & TRANSFORM_MODIFIED) != 0);
|
|
||||||
{
|
{
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
@@ -1962,6 +1960,7 @@ void GeometryManager::device_update(Device *device,
|
|||||||
scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
|
scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
vector<Object *> volume_objects;
|
||||||
foreach (Object *object, scene->objects) {
|
foreach (Object *object, scene->objects) {
|
||||||
object->compute_bounds(motion_blur);
|
object->compute_bounds(motion_blur);
|
||||||
}
|
}
|
||||||
@@ -1983,11 +1982,6 @@ void GeometryManager::device_update(Device *device,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Always set BVH layout again after displacement where it was set to none,
|
|
||||||
* to avoid ray-tracing at that stage. */
|
|
||||||
dscene->data.bvh.bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
|
|
||||||
device->get_bvh_layout_mask());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
scoped_callback_timer timer([scene](double time) {
|
scoped_callback_timer timer([scene](double time) {
|
||||||
if (scene->update_stats) {
|
if (scene->update_stats) {
|
||||||
|
@@ -189,8 +189,6 @@ class GeometryManager {
|
|||||||
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
|
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
|
||||||
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
|
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
|
||||||
|
|
||||||
TRANSFORM_MODIFIED = (1 << 10),
|
|
||||||
|
|
||||||
/* tag everything in the manager for an update */
|
/* tag everything in the manager for an update */
|
||||||
UPDATE_ALL = ~0u,
|
UPDATE_ALL = ~0u,
|
||||||
|
|
||||||
|
@@ -303,8 +303,7 @@ ImageManager::ImageManager(const DeviceInfo &info)
|
|||||||
animation_frame = 0;
|
animation_frame = 0;
|
||||||
|
|
||||||
/* Set image limits */
|
/* Set image limits */
|
||||||
features.has_half_float = info.has_half_images;
|
has_half_images = info.has_half_images;
|
||||||
features.has_nanovdb = info.has_nanovdb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageManager::~ImageManager()
|
ImageManager::~ImageManager()
|
||||||
@@ -348,7 +347,7 @@ void ImageManager::load_image_metadata(Image *img)
|
|||||||
metadata = ImageMetaData();
|
metadata = ImageMetaData();
|
||||||
metadata.colorspace = img->params.colorspace;
|
metadata.colorspace = img->params.colorspace;
|
||||||
|
|
||||||
if (img->loader->load_metadata(features, metadata)) {
|
if (img->loader->load_metadata(metadata)) {
|
||||||
assert(metadata.type != IMAGE_DATA_NUM_TYPES);
|
assert(metadata.type != IMAGE_DATA_NUM_TYPES);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -357,10 +356,15 @@ void ImageManager::load_image_metadata(Image *img)
|
|||||||
|
|
||||||
metadata.detect_colorspace();
|
metadata.detect_colorspace();
|
||||||
|
|
||||||
assert(features.has_half_float ||
|
/* No half textures on OpenCL, use full float instead. */
|
||||||
(metadata.type != IMAGE_DATA_TYPE_HALF4 && metadata.type != IMAGE_DATA_TYPE_HALF));
|
if (!has_half_images) {
|
||||||
assert(features.has_nanovdb || (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT ||
|
if (metadata.type == IMAGE_DATA_TYPE_HALF4) {
|
||||||
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3));
|
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||||
|
}
|
||||||
|
else if (metadata.type == IMAGE_DATA_TYPE_HALF) {
|
||||||
|
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
img->need_metadata = false;
|
img->need_metadata = false;
|
||||||
}
|
}
|
||||||
|
@@ -97,13 +97,6 @@ class ImageMetaData {
|
|||||||
void detect_colorspace();
|
void detect_colorspace();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Information about supported features that Image loaders can use. */
|
|
||||||
class ImageDeviceFeatures {
|
|
||||||
public:
|
|
||||||
bool has_half_float;
|
|
||||||
bool has_nanovdb;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Image loader base class, that can be subclassed to load image data
|
/* Image loader base class, that can be subclassed to load image data
|
||||||
* from custom sources (file, memory, procedurally generated, etc). */
|
* from custom sources (file, memory, procedurally generated, etc). */
|
||||||
class ImageLoader {
|
class ImageLoader {
|
||||||
@@ -112,7 +105,7 @@ class ImageLoader {
|
|||||||
virtual ~ImageLoader(){};
|
virtual ~ImageLoader(){};
|
||||||
|
|
||||||
/* Load metadata without actual image yet, should be fast. */
|
/* Load metadata without actual image yet, should be fast. */
|
||||||
virtual bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) = 0;
|
virtual bool load_metadata(ImageMetaData &metadata) = 0;
|
||||||
|
|
||||||
/* Load actual image contents. */
|
/* Load actual image contents. */
|
||||||
virtual bool load_pixels(const ImageMetaData &metadata,
|
virtual bool load_pixels(const ImageMetaData &metadata,
|
||||||
@@ -219,8 +212,7 @@ class ImageManager {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool need_update_;
|
bool need_update_;
|
||||||
|
bool has_half_images;
|
||||||
ImageDeviceFeatures features;
|
|
||||||
|
|
||||||
thread_mutex device_mutex;
|
thread_mutex device_mutex;
|
||||||
thread_mutex images_mutex;
|
thread_mutex images_mutex;
|
||||||
|
@@ -30,7 +30,7 @@ OIIOImageLoader::~OIIOImageLoader()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata)
|
bool OIIOImageLoader::load_metadata(ImageMetaData &metadata)
|
||||||
{
|
{
|
||||||
/* Perform preliminary checks, with meaningful logging. */
|
/* Perform preliminary checks, with meaningful logging. */
|
||||||
if (!path_exists(filepath.string())) {
|
if (!path_exists(filepath.string())) {
|
||||||
@@ -76,7 +76,7 @@ bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMe
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* check if it's half float */
|
/* check if it's half float */
|
||||||
if (spec.format == TypeDesc::HALF && features.has_half_float) {
|
if (spec.format == TypeDesc::HALF) {
|
||||||
is_half = true;
|
is_half = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ class OIIOImageLoader : public ImageLoader {
|
|||||||
OIIOImageLoader(const string &filepath);
|
OIIOImageLoader(const string &filepath);
|
||||||
~OIIOImageLoader();
|
~OIIOImageLoader();
|
||||||
|
|
||||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
bool load_metadata(ImageMetaData &metadata) override;
|
||||||
|
|
||||||
bool load_pixels(const ImageMetaData &metadata,
|
bool load_pixels(const ImageMetaData &metadata,
|
||||||
void *pixels,
|
void *pixels,
|
||||||
|
@@ -40,7 +40,7 @@ SkyLoader::SkyLoader(float sun_elevation,
|
|||||||
|
|
||||||
SkyLoader::~SkyLoader(){};
|
SkyLoader::~SkyLoader(){};
|
||||||
|
|
||||||
bool SkyLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata)
|
bool SkyLoader::load_metadata(ImageMetaData &metadata)
|
||||||
{
|
{
|
||||||
metadata.width = 512;
|
metadata.width = 512;
|
||||||
metadata.height = 128;
|
metadata.height = 128;
|
||||||
|
@@ -34,7 +34,7 @@ class SkyLoader : public ImageLoader {
|
|||||||
float ozone_density);
|
float ozone_density);
|
||||||
~SkyLoader();
|
~SkyLoader();
|
||||||
|
|
||||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
bool load_metadata(ImageMetaData &metadata) override;
|
||||||
|
|
||||||
bool load_pixels(const ImageMetaData &metadata,
|
bool load_pixels(const ImageMetaData &metadata,
|
||||||
void *pixels,
|
void *pixels,
|
||||||
|
@@ -34,7 +34,7 @@ VDBImageLoader::~VDBImageLoader()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata)
|
bool VDBImageLoader::load_metadata(ImageMetaData &metadata)
|
||||||
{
|
{
|
||||||
#ifdef WITH_OPENVDB
|
#ifdef WITH_OPENVDB
|
||||||
if (!grid) {
|
if (!grid) {
|
||||||
@@ -56,71 +56,55 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
|
|||||||
if (grid->isType<openvdb::FloatGrid>()) {
|
if (grid->isType<openvdb::FloatGrid>()) {
|
||||||
metadata.channels = 1;
|
metadata.channels = 1;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid));
|
||||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::Vec3fGrid>()) {
|
else if (grid->isType<openvdb::Vec3fGrid>()) {
|
||||||
metadata.channels = 3;
|
metadata.channels = 3;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid));
|
||||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::BoolGrid>()) {
|
else if (grid->isType<openvdb::BoolGrid>()) {
|
||||||
metadata.channels = 1;
|
metadata.channels = 1;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid)));
|
||||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::DoubleGrid>()) {
|
else if (grid->isType<openvdb::DoubleGrid>()) {
|
||||||
metadata.channels = 1;
|
metadata.channels = 1;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid)));
|
||||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::Int32Grid>()) {
|
else if (grid->isType<openvdb::Int32Grid>()) {
|
||||||
metadata.channels = 1;
|
metadata.channels = 1;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid)));
|
||||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::Int64Grid>()) {
|
else if (grid->isType<openvdb::Int64Grid>()) {
|
||||||
metadata.channels = 1;
|
metadata.channels = 1;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid)));
|
||||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::Vec3IGrid>()) {
|
else if (grid->isType<openvdb::Vec3IGrid>()) {
|
||||||
metadata.channels = 3;
|
metadata.channels = 3;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid)));
|
||||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::Vec3dGrid>()) {
|
else if (grid->isType<openvdb::Vec3dGrid>()) {
|
||||||
metadata.channels = 3;
|
metadata.channels = 3;
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (features.has_nanovdb) {
|
nanogrid = nanovdb::openToNanoVDB(
|
||||||
nanogrid = nanovdb::openToNanoVDB(
|
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid)));
|
||||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid)));
|
|
||||||
}
|
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
else if (grid->isType<openvdb::MaskGrid>()) {
|
else if (grid->isType<openvdb::MaskGrid>()) {
|
||||||
@@ -134,25 +118,21 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
|
|||||||
}
|
}
|
||||||
|
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (nanogrid) {
|
metadata.byte_size = nanogrid.size();
|
||||||
metadata.byte_size = nanogrid.size();
|
if (metadata.channels == 1) {
|
||||||
if (metadata.channels == 1) {
|
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
|
||||||
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3;
|
||||||
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3;
|
}
|
||||||
}
|
# else
|
||||||
|
if (metadata.channels == 1) {
|
||||||
|
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
# endif
|
# endif
|
||||||
{
|
|
||||||
if (metadata.channels == 1) {
|
|
||||||
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set transform from object space to voxel index. */
|
/* Set transform from object space to voxel index. */
|
||||||
openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4();
|
openvdb::math::Mat4f grid_matrix = grid->transform().baseMap()->getAffineMap()->getMat4();
|
||||||
@@ -163,29 +143,20 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Transform texture_to_index;
|
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (nanogrid) {
|
Transform texture_to_index = transform_identity();
|
||||||
texture_to_index = transform_identity();
|
# else
|
||||||
}
|
openvdb::Coord min = bbox.min();
|
||||||
else
|
Transform texture_to_index = transform_translate(min.x(), min.y(), min.z()) *
|
||||||
|
transform_scale(dim.x(), dim.y(), dim.z());
|
||||||
# endif
|
# endif
|
||||||
{
|
|
||||||
openvdb::Coord min = bbox.min();
|
|
||||||
texture_to_index = transform_translate(min.x(), min.y(), min.z()) *
|
|
||||||
transform_scale(dim.x(), dim.y(), dim.z());
|
|
||||||
}
|
|
||||||
|
|
||||||
metadata.transform_3d = transform_inverse(index_to_object * texture_to_index);
|
metadata.transform_3d = transform_inverse(index_to_object * texture_to_index);
|
||||||
metadata.use_transform_3d = true;
|
metadata.use_transform_3d = true;
|
||||||
|
|
||||||
# ifndef WITH_NANOVDB
|
|
||||||
(void)features;
|
|
||||||
# endif
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
(void)metadata;
|
(void)metadata;
|
||||||
(void)features;
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -194,52 +165,48 @@ bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size
|
|||||||
{
|
{
|
||||||
#ifdef WITH_OPENVDB
|
#ifdef WITH_OPENVDB
|
||||||
# ifdef WITH_NANOVDB
|
# ifdef WITH_NANOVDB
|
||||||
if (nanogrid) {
|
memcpy(pixels, nanogrid.data(), nanogrid.size());
|
||||||
memcpy(pixels, nanogrid.data(), nanogrid.size());
|
# else
|
||||||
|
if (grid->isType<openvdb::FloatGrid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::Vec3fGrid>()) {
|
||||||
|
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
||||||
|
bbox, (openvdb::Vec3f *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::BoolGrid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::DoubleGrid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::Int32Grid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::Int64Grid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::Vec3IGrid>()) {
|
||||||
|
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
||||||
|
bbox, (openvdb::Vec3f *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::Vec3dGrid>()) {
|
||||||
|
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
||||||
|
bbox, (openvdb::Vec3f *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid), dense);
|
||||||
|
}
|
||||||
|
else if (grid->isType<openvdb::MaskGrid>()) {
|
||||||
|
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
||||||
|
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::MaskGrid>(grid), dense);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
# endif
|
# endif
|
||||||
{
|
|
||||||
if (grid->isType<openvdb::FloatGrid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::Vec3fGrid>()) {
|
|
||||||
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
|
||||||
bbox, (openvdb::Vec3f *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::BoolGrid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::DoubleGrid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::Int32Grid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::Int64Grid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::Vec3IGrid>()) {
|
|
||||||
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
|
||||||
bbox, (openvdb::Vec3f *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::Vec3dGrid>()) {
|
|
||||||
openvdb::tools::Dense<openvdb::Vec3f, openvdb::tools::LayoutXYZ> dense(
|
|
||||||
bbox, (openvdb::Vec3f *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
else if (grid->isType<openvdb::MaskGrid>()) {
|
|
||||||
openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels);
|
|
||||||
openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::MaskGrid>(grid), dense);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
(void)pixels;
|
(void)pixels;
|
||||||
|
@@ -33,8 +33,7 @@ class VDBImageLoader : public ImageLoader {
|
|||||||
VDBImageLoader(const string &grid_name);
|
VDBImageLoader(const string &grid_name);
|
||||||
~VDBImageLoader();
|
~VDBImageLoader();
|
||||||
|
|
||||||
virtual bool load_metadata(const ImageDeviceFeatures &features,
|
virtual bool load_metadata(ImageMetaData &metadata) override;
|
||||||
ImageMetaData &metadata) override;
|
|
||||||
|
|
||||||
virtual bool load_pixels(const ImageMetaData &metadata,
|
virtual bool load_pixels(const ImageMetaData &metadata,
|
||||||
void *pixels,
|
void *pixels,
|
||||||
|
@@ -129,7 +129,6 @@ NODE_DEFINE(Light)
|
|||||||
SOCKET_VECTOR(axisv, "Axis V", zero_float3());
|
SOCKET_VECTOR(axisv, "Axis V", zero_float3());
|
||||||
SOCKET_FLOAT(sizev, "Size V", 1.0f);
|
SOCKET_FLOAT(sizev, "Size V", 1.0f);
|
||||||
SOCKET_BOOLEAN(round, "Round", false);
|
SOCKET_BOOLEAN(round, "Round", false);
|
||||||
SOCKET_FLOAT(spread, "Spread", M_PI_F);
|
|
||||||
|
|
||||||
SOCKET_INT(map_resolution, "Map Resolution", 0);
|
SOCKET_INT(map_resolution, "Map Resolution", 0);
|
||||||
|
|
||||||
@@ -859,15 +858,6 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
|
|||||||
float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
|
float invarea = (area != 0.0f) ? 1.0f / area : 1.0f;
|
||||||
float3 dir = light->dir;
|
float3 dir = light->dir;
|
||||||
|
|
||||||
/* Convert from spread angle 0..180 to 90..0, clamping to a minimum
|
|
||||||
* angle to avoid excessive noise. */
|
|
||||||
const float min_spread_angle = 1.0f * M_PI_F / 180.0f;
|
|
||||||
const float spread_angle = 0.5f * (M_PI_F - max(light->spread, min_spread_angle));
|
|
||||||
/* Normalization computed using:
|
|
||||||
* integrate cos(x) (1 - tan(x) * tan(a)) * sin(x) from x = a to pi/2. */
|
|
||||||
const float tan_spread = tanf(spread_angle);
|
|
||||||
const float normalize_spread = 2.0f / (2.0f + (2.0f * spread_angle - M_PI_F) * tan_spread);
|
|
||||||
|
|
||||||
dir = safe_normalize(dir);
|
dir = safe_normalize(dir);
|
||||||
|
|
||||||
if (light->use_mis && area != 0.0f)
|
if (light->use_mis && area != 0.0f)
|
||||||
@@ -887,8 +877,6 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc
|
|||||||
klights[light_index].area.dir[0] = dir.x;
|
klights[light_index].area.dir[0] = dir.x;
|
||||||
klights[light_index].area.dir[1] = dir.y;
|
klights[light_index].area.dir[1] = dir.y;
|
||||||
klights[light_index].area.dir[2] = dir.z;
|
klights[light_index].area.dir[2] = dir.z;
|
||||||
klights[light_index].area.tan_spread = tan_spread;
|
|
||||||
klights[light_index].area.normalize_spread = normalize_spread;
|
|
||||||
}
|
}
|
||||||
else if (light->light_type == LIGHT_SPOT) {
|
else if (light->light_type == LIGHT_SPOT) {
|
||||||
shader_id &= ~SHADER_AREA_LIGHT;
|
shader_id &= ~SHADER_AREA_LIGHT;
|
||||||
|
@@ -58,7 +58,6 @@ class Light : public Node {
|
|||||||
NODE_SOCKET_API(float3, axisv)
|
NODE_SOCKET_API(float3, axisv)
|
||||||
NODE_SOCKET_API(float, sizev)
|
NODE_SOCKET_API(float, sizev)
|
||||||
NODE_SOCKET_API(bool, round)
|
NODE_SOCKET_API(bool, round)
|
||||||
NODE_SOCKET_API(float, spread)
|
|
||||||
|
|
||||||
NODE_SOCKET_API(Transform, tfm)
|
NODE_SOCKET_API(Transform, tfm)
|
||||||
|
|
||||||
|
@@ -6091,9 +6091,6 @@ NODE_DEFINE(VectorMathNode)
|
|||||||
type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
|
type_enum.insert("cross_product", NODE_VECTOR_MATH_CROSS_PRODUCT);
|
||||||
type_enum.insert("project", NODE_VECTOR_MATH_PROJECT);
|
type_enum.insert("project", NODE_VECTOR_MATH_PROJECT);
|
||||||
type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT);
|
type_enum.insert("reflect", NODE_VECTOR_MATH_REFLECT);
|
||||||
type_enum.insert("refract", NODE_VECTOR_MATH_REFRACT);
|
|
||||||
type_enum.insert("faceforward", NODE_VECTOR_MATH_FACEFORWARD);
|
|
||||||
|
|
||||||
type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
|
type_enum.insert("dot_product", NODE_VECTOR_MATH_DOT_PRODUCT);
|
||||||
|
|
||||||
type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE);
|
type_enum.insert("distance", NODE_VECTOR_MATH_DISTANCE);
|
||||||
@@ -6154,24 +6151,24 @@ void VectorMathNode::compile(SVMCompiler &compiler)
|
|||||||
{
|
{
|
||||||
ShaderInput *vector1_in = input("Vector1");
|
ShaderInput *vector1_in = input("Vector1");
|
||||||
ShaderInput *vector2_in = input("Vector2");
|
ShaderInput *vector2_in = input("Vector2");
|
||||||
ShaderInput *param1_in = input("Scale");
|
ShaderInput *scale_in = input("Scale");
|
||||||
ShaderOutput *value_out = output("Value");
|
ShaderOutput *value_out = output("Value");
|
||||||
ShaderOutput *vector_out = output("Vector");
|
ShaderOutput *vector_out = output("Vector");
|
||||||
|
|
||||||
int vector1_stack_offset = compiler.stack_assign(vector1_in);
|
int vector1_stack_offset = compiler.stack_assign(vector1_in);
|
||||||
int vector2_stack_offset = compiler.stack_assign(vector2_in);
|
int vector2_stack_offset = compiler.stack_assign(vector2_in);
|
||||||
int param1_stack_offset = compiler.stack_assign(param1_in);
|
int scale_stack_offset = compiler.stack_assign(scale_in);
|
||||||
int value_stack_offset = compiler.stack_assign_if_linked(value_out);
|
int value_stack_offset = compiler.stack_assign_if_linked(value_out);
|
||||||
int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
|
int vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
|
||||||
|
|
||||||
/* 3 Vector Operators */
|
/* 3 Vector Operators */
|
||||||
if (math_type == NODE_VECTOR_MATH_WRAP || math_type == NODE_VECTOR_MATH_FACEFORWARD) {
|
if (math_type == NODE_VECTOR_MATH_WRAP) {
|
||||||
ShaderInput *vector3_in = input("Vector3");
|
ShaderInput *vector3_in = input("Vector3");
|
||||||
int vector3_stack_offset = compiler.stack_assign(vector3_in);
|
int vector3_stack_offset = compiler.stack_assign(vector3_in);
|
||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_VECTOR_MATH,
|
NODE_VECTOR_MATH,
|
||||||
math_type,
|
math_type,
|
||||||
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
|
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
|
||||||
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
|
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
|
||||||
compiler.add_node(vector3_stack_offset);
|
compiler.add_node(vector3_stack_offset);
|
||||||
}
|
}
|
||||||
@@ -6179,7 +6176,7 @@ void VectorMathNode::compile(SVMCompiler &compiler)
|
|||||||
compiler.add_node(
|
compiler.add_node(
|
||||||
NODE_VECTOR_MATH,
|
NODE_VECTOR_MATH,
|
||||||
math_type,
|
math_type,
|
||||||
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, param1_stack_offset),
|
compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset),
|
||||||
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
|
compiler.encode_uchar4(value_stack_offset, vector_stack_offset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -153,6 +153,10 @@ void Object::update_motion()
|
|||||||
|
|
||||||
void Object::compute_bounds(bool motion_blur)
|
void Object::compute_bounds(bool motion_blur)
|
||||||
{
|
{
|
||||||
|
if (!is_modified() && !geometry->is_modified()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BoundBox mbounds = geometry->bounds;
|
BoundBox mbounds = geometry->bounds;
|
||||||
|
|
||||||
if (motion_blur && use_motion()) {
|
if (motion_blur && use_motion()) {
|
||||||
@@ -217,7 +221,16 @@ void Object::tag_update(Scene *scene)
|
|||||||
|
|
||||||
if (geometry) {
|
if (geometry) {
|
||||||
if (tfm_is_modified()) {
|
if (tfm_is_modified()) {
|
||||||
flag |= ObjectManager::TRANSFORM_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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Node *node, geometry->get_used_shaders()) {
|
foreach (Node *node, geometry->get_used_shaders()) {
|
||||||
@@ -910,10 +923,6 @@ void ObjectManager::tag_update(Scene *scene, uint32_t flag)
|
|||||||
geometry_flag |= (GeometryManager::GEOMETRY_ADDED | GeometryManager::GEOMETRY_REMOVED);
|
geometry_flag |= (GeometryManager::GEOMETRY_ADDED | GeometryManager::GEOMETRY_REMOVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flag & TRANSFORM_MODIFIED) != 0) {
|
|
||||||
geometry_flag |= GeometryManager::TRANSFORM_MODIFIED;
|
|
||||||
}
|
|
||||||
|
|
||||||
scene->geometry_manager->tag_update(scene, geometry_flag);
|
scene->geometry_manager->tag_update(scene, geometry_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -133,7 +133,6 @@ class ObjectManager {
|
|||||||
OBJECT_REMOVED = (1 << 4),
|
OBJECT_REMOVED = (1 << 4),
|
||||||
OBJECT_MODIFIED = (1 << 5),
|
OBJECT_MODIFIED = (1 << 5),
|
||||||
HOLDOUT_MODIFIED = (1 << 6),
|
HOLDOUT_MODIFIED = (1 << 6),
|
||||||
TRANSFORM_MODIFIED = (1 << 7),
|
|
||||||
|
|
||||||
/* tag everything in the manager for an update */
|
/* tag everything in the manager for an update */
|
||||||
UPDATE_ALL = ~0u,
|
UPDATE_ALL = ~0u,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user