Compare commits
5 Commits
virtual-ar
...
temp-sprea
Author | SHA1 | Date | |
---|---|---|---|
045bdd5308 | |||
ae51cde3d7 | |||
25f8050830 | |||
ff013946bb | |||
74de45712d |
@@ -2,7 +2,7 @@
|
||||
# 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.
|
||||
#
|
||||
@@ -255,6 +255,7 @@ ForEachMacros:
|
||||
- SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN
|
||||
- SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN
|
||||
- SEQ_ALL_BEGIN
|
||||
- SEQ_CURRENT_BEGIN
|
||||
- SURFACE_QUAD_ITER_BEGIN
|
||||
- foreach
|
||||
- ED_screen_areas_iter
|
||||
@@ -263,5 +264,8 @@ ForEachMacros:
|
||||
- MAP_SLOT_PROBING_BEGIN
|
||||
- VECTOR_SET_SLOT_PROBING_BEGIN
|
||||
|
||||
StatementMacros:
|
||||
- PyObject_VAR_HEAD
|
||||
# Use once we bump the minimum version to version 8.
|
||||
# # 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-trailing-return-type,
|
||||
-modernize-avoid-c-arrays,
|
||||
-modernize-use-equals-default,
|
||||
-modernize-use-nodiscard,
|
||||
-modernize-loop-convert,
|
||||
-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:
|
||||
- key: modernize-use-default-member-init.UseAssignment
|
||||
value: 1
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@@ -46,6 +46,3 @@ Desktop.ini
|
||||
|
||||
# smoke simulation noise tile (generated)
|
||||
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_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)
|
||||
if(UNIX AND NOT APPLE)
|
||||
@@ -520,10 +522,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
mark_as_advanced(WITH_LINKER_LLD)
|
||||
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")
|
||||
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)
|
||||
set(_asan_defaults "\
|
||||
-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")
|
||||
endif()
|
||||
|
||||
set_and_warn_dependency(WITH_PYTHON WITH_CYCLES OFF)
|
||||
set_and_warn_dependency(WITH_PYTHON WITH_DRACO OFF)
|
||||
if(NOT WITH_PYTHON)
|
||||
set(WITH_CYCLES OFF)
|
||||
set(WITH_DRACO OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_DRACO AND NOT WITH_PYTHON_INSTALL)
|
||||
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()
|
||||
|
||||
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_X11 OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
@@ -806,7 +809,7 @@ endif()
|
||||
if(NOT WITH_CUDA_DYNLOAD)
|
||||
find_package(CUDA)
|
||||
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)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1232,7 +1235,6 @@ if(WITH_OPENMP)
|
||||
string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}")
|
||||
string(APPEND CMAKE_CXX_FLAGS " ${OpenMP_CXX_FLAGS}")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${OpenMP_LINKER_FLAGS}")
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${OpenMP_LINKER_FLAGS}")
|
||||
else()
|
||||
# Typically avoid adding flags as defines but we can't
|
||||
# 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})
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "OpenMP not found, disabling WITH_OPENMP")
|
||||
set(WITH_OPENMP OFF)
|
||||
endif()
|
||||
|
||||
@@ -1319,7 +1320,6 @@ list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
|
||||
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
||||
find_package(Bullet)
|
||||
if(NOT BULLET_FOUND)
|
||||
message(STATUS "Bullet not found, disabling WITH_BULLET")
|
||||
set(WITH_BULLET OFF)
|
||||
endif()
|
||||
else()
|
||||
@@ -1955,10 +1955,10 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_JACK)
|
||||
info_cfg_option(WITH_JACK_DYNLOAD)
|
||||
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_DYNLOAD)
|
||||
info_cfg_option(WITH_PULSEAUDIO)
|
||||
info_cfg_option(WITH_PULSEAUDIO_DYNLOAD)
|
||||
info_cfg_option(WITH_WASAPI)
|
||||
|
||||
info_cfg_text("Compression:")
|
||||
|
21
GNUmakefile
21
GNUmakefile
@@ -128,14 +128,8 @@ Utilities
|
||||
* source_archive:
|
||||
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:
|
||||
Updates git and all submodules and svn.
|
||||
|
||||
* update_code:
|
||||
Updates git and all submodules but not svn.
|
||||
updates git and all submodules
|
||||
|
||||
* format:
|
||||
Format source code using clang (uses PATHS if passed in). For example::
|
||||
@@ -480,9 +474,6 @@ check_smatch: .FORCE
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
$(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
|
||||
cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
@@ -517,13 +508,6 @@ check_descriptions: .FORCE
|
||||
source_archive: .FORCE
|
||||
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"
|
||||
icons: .FORCE
|
||||
BLENDER_BIN=$(BLENDER_BIN) INKSCAPE_BIN=$(INKSCAPE_BIN) \
|
||||
@@ -538,9 +522,6 @@ icons_geom: .FORCE
|
||||
update: .FORCE
|
||||
$(PYTHON) ./build_files/utils/make_update.py
|
||||
|
||||
update_code: .FORCE
|
||||
$(PYTHON) ./build_files/utils/make_update.py --no-libraries
|
||||
|
||||
format: .FORCE
|
||||
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)
|
||||
|
@@ -12,7 +12,7 @@ function(download_source dep)
|
||||
if(NOT EXISTS ${TARGET_FILE})
|
||||
message("Checking source : ${dep} - source not found downloading from ${TARGET_URI}")
|
||||
file(DOWNLOAD ${TARGET_URI} ${TARGET_FILE}
|
||||
TIMEOUT 1800 # seconds
|
||||
TIMEOUT 60 # seconds
|
||||
EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH}
|
||||
TLS_VERIFY ON
|
||||
SHOW_PROGRESS
|
||||
|
@@ -68,6 +68,7 @@ set(OPENIMAGEIO_EXTRA_ARGS
|
||||
-DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/
|
||||
-DBoost_NO_SYSTEM_PATHS=ON
|
||||
-DBoost_NO_BOOST_CMAKE=ON
|
||||
-OIIO_BUILD_CPP11=ON
|
||||
-DUSE_LIBSQUISH=OFF
|
||||
-DUSE_QT5=OFF
|
||||
-DUSE_NUKE=OFF
|
||||
|
@@ -21,8 +21,7 @@ if(WIN32)
|
||||
endif()
|
||||
option(WITH_WEBP "Enable building of oiio with webp 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 ${NUM_CORES} CACHE STRING "Number of threads to run make with")
|
||||
set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with")
|
||||
|
||||
if(NOT BUILD_MODE)
|
||||
set(BUILD_MODE "Release")
|
||||
@@ -37,8 +36,14 @@ else(BUILD_MODE STREQUAL "Debug")
|
||||
endif()
|
||||
|
||||
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:
|
||||
set(PACKAGE_DIR "${CMAKE_CURRENT_BINARY_DIR}/packages")
|
||||
# look in blenders source folder for packages directory, if that exists
|
||||
# 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)
|
||||
|
||||
file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
|
||||
|
@@ -85,8 +85,8 @@ class VersionInfo:
|
||||
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_numbers = (version_number // 100, version_number % 100, version_number_patch)
|
||||
self.short_version = "%d.%d" % (version_numbers[0], version_numbers[1])
|
||||
self.version = "%d.%d.%d" % version_numbers
|
||||
self.short_version = "%d.%02d" % (version_numbers[0], version_numbers[1])
|
||||
self.version = "%d.%02d.%d" % version_numbers
|
||||
self.version_cycle = self._parse_header_file(blender_h, 'BLENDER_VERSION_CYCLE')
|
||||
self.hash = self._parse_header_file(buildinfo_h, 'BUILD_HASH')[1:-1]
|
||||
|
||||
|
@@ -75,7 +75,7 @@ FIND_PATH(OSL_SHADER_DIR
|
||||
/usr/share/OSL/
|
||||
/usr/include/OSL/
|
||||
PATH_SUFFIXES
|
||||
share/OSL/shaders
|
||||
shaders
|
||||
)
|
||||
|
||||
# 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.exit(1)
|
||||
|
||||
import os
|
||||
from os.path import (
|
||||
dirname,
|
||||
join,
|
||||
normpath,
|
||||
splitext,
|
||||
)
|
||||
|
||||
from cmake_consistency_check_config import (
|
||||
IGNORE_SOURCE,
|
||||
IGNORE_SOURCE_MISSING,
|
||||
@@ -45,35 +37,32 @@ from cmake_consistency_check_config import (
|
||||
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_c = set()
|
||||
global_refs: Dict[str, List[Tuple[str, int]]] = {}
|
||||
global_refs = {}
|
||||
|
||||
# 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
|
||||
for ignore_path in ig_list
|
||||
]
|
||||
|
||||
# Ignore cmake file, path pairs.
|
||||
global_ignore_source_missing: Dict[str, List[str]] = {}
|
||||
for k, v in IGNORE_SOURCE_MISSING_FLAT:
|
||||
global_ignore_source_missing = {}
|
||||
for k, v in IGNORE_SOURCE_MISSING:
|
||||
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')
|
||||
data = file_handle.readlines()
|
||||
file_handle.close()
|
||||
@@ -88,10 +77,7 @@ def replace_line(f: str, i: int, text: str, keep_indent: bool = True) -> None:
|
||||
file_handle.close()
|
||||
|
||||
|
||||
def source_list(
|
||||
path: str,
|
||||
filename_check: Optional[Callable[[str], bool]] = None,
|
||||
) -> Generator[str, None, None]:
|
||||
def source_list(path, filename_check=None):
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
# skip '.git'
|
||||
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||
@@ -102,37 +88,37 @@ def source_list(
|
||||
|
||||
|
||||
# extension checking
|
||||
def is_cmake(filename: str) -> bool:
|
||||
def is_cmake(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".cmake") or (filename == "CMakeLists.txt")
|
||||
|
||||
|
||||
def is_c_header(filename: str) -> bool:
|
||||
def is_c_header(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||
|
||||
|
||||
def is_c(filename: str) -> bool:
|
||||
def is_c(filename):
|
||||
ext = splitext(filename)[1]
|
||||
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)
|
||||
|
||||
|
||||
def cmake_get_src(f: str) -> None:
|
||||
def cmake_get_src(f):
|
||||
|
||||
sources_h = []
|
||||
sources_c = []
|
||||
|
||||
filen = open(f, "r", encoding="utf8")
|
||||
it: Optional[Iterator[str]] = iter(filen)
|
||||
it = iter(filen)
|
||||
found = False
|
||||
i = 0
|
||||
# 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("):
|
||||
return False
|
||||
|
||||
@@ -145,7 +131,6 @@ def cmake_get_src(f: str) -> None:
|
||||
if l.endswith(")"):
|
||||
raise Exception("strict formatting not kept 'list(APPEND %s...)' on 1 line %s:%d" % (name, f, i))
|
||||
return True
|
||||
return False
|
||||
|
||||
while it is not None:
|
||||
context_name = ""
|
||||
@@ -284,7 +269,7 @@ def cmake_get_src(f: str) -> None:
|
||||
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):
|
||||
if ignore_path in f:
|
||||
ignore_used[index] = True
|
||||
@@ -292,7 +277,7 @@ def is_ignore_source(f: str, ignore_used: List[bool]) -> bool:
|
||||
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):
|
||||
if ignore_path in f:
|
||||
ignore_used[index] = True
|
||||
@@ -300,7 +285,7 @@ def is_ignore_cmake(f: str, ignore_used: List[bool]) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def main() -> None:
|
||||
def main():
|
||||
|
||||
print("Scanning:", SOURCE_DIR)
|
||||
|
||||
@@ -374,7 +359,7 @@ def main() -> None:
|
||||
if "extern" not in f:
|
||||
i = 1
|
||||
try:
|
||||
for _ in open(f, "r", encoding="utf8"):
|
||||
for l in open(f, "r", encoding="utf8"):
|
||||
i += 1
|
||||
except UnicodeDecodeError:
|
||||
print("Non utf8: %s:%d" % (f, i))
|
||||
|
@@ -25,14 +25,6 @@ import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
from typing import (
|
||||
Any,
|
||||
Callable,
|
||||
List,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
|
||||
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||
|
||||
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)
|
||||
|
||||
check_commands = []
|
||||
@@ -60,19 +52,18 @@ def main() -> None:
|
||||
# ~if "source/blender" not in c:
|
||||
# ~ continue
|
||||
|
||||
cmd = (
|
||||
[CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
cmd = ([CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs]
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
process_functions = []
|
||||
|
||||
def my_process(i: int, c: str, cmd: str) -> subprocess.Popen[Any]:
|
||||
def my_process(i, c, cmd):
|
||||
if not USE_QUIET:
|
||||
percent = 100.0 * (i / (len(check_commands) - 1))
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
@@ -25,12 +25,6 @@ import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
from typing import (
|
||||
Any,
|
||||
List,
|
||||
)
|
||||
|
||||
|
||||
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
@@ -53,26 +47,25 @@ if USE_QUIET:
|
||||
CHECKER_ARGS.append("--quiet")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
def main():
|
||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||
source_defines = project_source_info.build_defines_as_args()
|
||||
|
||||
check_commands = []
|
||||
for c, inc_dirs, defs in source_info:
|
||||
cmd = (
|
||||
[CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs] +
|
||||
source_defines
|
||||
)
|
||||
cmd = ([CHECKER_BIN] +
|
||||
CHECKER_ARGS +
|
||||
[c] +
|
||||
[("-I%s" % i) for i in inc_dirs] +
|
||||
[("-D%s" % d) for d in defs] +
|
||||
source_defines
|
||||
)
|
||||
|
||||
check_commands.append((c, cmd))
|
||||
|
||||
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:
|
||||
percent = 100.0 * (i / len(check_commands))
|
||||
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_CYCLES_DEBUG 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_LIBMV_SCHUR_SPECIALIZATIONS OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_PYTHON_SAFETY ON CACHE BOOL "" FORCE)
|
||||
set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE)
|
||||
if(WIN32)
|
||||
set(WITH_WINDOWS_BUNDLE_CRT OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
@@ -37,7 +37,6 @@ set(WITH_LZO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_FLUID ON CACHE BOOL "" FORCE)
|
||||
set(WITH_MOD_OCEANSIM 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_OPENCOLLADA 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_POTRACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
|
||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_QUADRIFLOW 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
|
||||
# so the python module doesn't hold the audio device and loads quickly.
|
||||
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_JACK OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_PULSEAUDIO 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_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
|
||||
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -7,8 +7,8 @@
|
||||
|
||||
set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(WITH_ALEMBIC 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_BUILDINFO 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_COREAUDIO 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_OSL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_FFTW3 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_OCEANSIM 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_WASAPI OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENCOLLADA OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENCOLORIO 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_OPENMP 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_PUGIXML 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_SDL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_TBB 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)
|
||||
set(WITH_GHOST_XDND OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -4,9 +4,9 @@
|
||||
# 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_ASSERT_ABORT OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_AUDASPACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_BUILDINFO ON CACHE BOOL "" FORCE)
|
||||
set(WITH_BULLET 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_GMP 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_ITASC ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_CINEON ON CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_DDS 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_OCEANSIM 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_OPENCOLLADA 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_POTRACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PUGIXML ON CACHE BOOL "" FORCE)
|
||||
set(WITH_NANOVDB ON CACHE BOOL "" FORCE)
|
||||
set(WITH_POTRACE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_PYTHON_INSTALL ON CACHE BOOL "" FORCE)
|
||||
set(WITH_QUADRIFLOW 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
|
||||
# so the python module doesn't hold the audio device and loads quickly.
|
||||
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_JACK OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_PULSEAUDIO 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_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
|
||||
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_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.
|
||||
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)
|
||||
find_package(OpenAL)
|
||||
if(NOT OPENAL_FOUND)
|
||||
message(WARNING "OpenAL not found, disabling WITH_OPENAL")
|
||||
set(WITH_OPENAL OFF)
|
||||
endif()
|
||||
endif()
|
||||
@@ -66,7 +65,6 @@ if(WITH_JACK)
|
||||
NAMES jackmp
|
||||
)
|
||||
if(NOT JACK_FRAMEWORK)
|
||||
message(STATUS "JACK not found, disabling WITH_JACK")
|
||||
set(WITH_JACK OFF)
|
||||
else()
|
||||
set(JACK_INCLUDE_DIRS ${JACK_FRAMEWORK}/headers)
|
||||
@@ -104,7 +102,6 @@ endif()
|
||||
if(WITH_USD)
|
||||
find_package(USD)
|
||||
if(NOT USD_FOUND)
|
||||
message(STATUS "USD not found, disabling WITH_USD")
|
||||
set(WITH_USD OFF)
|
||||
endif()
|
||||
endif()
|
||||
@@ -149,7 +146,7 @@ if(WITH_PYTHON)
|
||||
|
||||
set(PYTHON_INCLUDE_DIR "${_py_framework}/include/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_LINKFLAGS "-u _PyMac_Error -framework Python") # won't build with this enabled
|
||||
|
||||
@@ -311,7 +308,7 @@ if(WITH_OPENCOLORIO)
|
||||
|
||||
if(NOT OPENCOLORIO_FOUND)
|
||||
set(WITH_OPENCOLORIO OFF)
|
||||
message(STATUS "OpenColorIO not found, disabling WITH_OPENCOLORIO")
|
||||
message(STATUS "OpenColorIO not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -360,7 +357,7 @@ if(WITH_CYCLES_OSL)
|
||||
if(OSL_INCLUDE_DIR AND OSL_LIBRARIES AND OSL_COMPILER AND OSL_SHADER_DIR)
|
||||
set(OSL_FOUND TRUE)
|
||||
else()
|
||||
message(WARNING "OSL not found, disabling WITH_CYCLES_OSL")
|
||||
message(STATUS "OSL not found")
|
||||
set(WITH_CYCLES_OSL OFF)
|
||||
endif()
|
||||
endif()
|
||||
@@ -388,7 +385,7 @@ if(WITH_OPENIMAGEDENOISE)
|
||||
|
||||
if(NOT OPENIMAGEDENOISE_FOUND)
|
||||
set(WITH_OPENIMAGEDENOISE OFF)
|
||||
message(STATUS "OpenImageDenoise not found, disabling WITH_OPENIMAGEDENOISE")
|
||||
message(STATUS "OpenImageDenoise not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -416,7 +413,7 @@ if(WITH_OPENMP)
|
||||
set(OpenMP_LINKER_FLAGS "-L'${LIBDIR}/openmp/lib' -lomp")
|
||||
|
||||
# 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.
|
||||
execute_process(
|
||||
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)
|
||||
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
|
||||
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")
|
||||
@@ -157,21 +162,6 @@ else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj")
|
||||
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
|
||||
if(MSVC_VERSION GREATER 1911 AND NOT MSVC_CLANG)
|
||||
string(APPEND CMAKE_CXX_FLAGS " /permissive-")
|
||||
@@ -184,41 +174,14 @@ if(WITH_WINDOWS_SCCACHE AND CMAKE_VS_MSBUILD_COMMAND)
|
||||
set(WITH_WINDOWS_SCCACHE Off)
|
||||
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)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER sccache)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER sccache)
|
||||
set(SYMBOL_FORMAT /Z7)
|
||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
||||
else()
|
||||
unset(CMAKE_C_COMPILER_LAUNCHER)
|
||||
unset(CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
if(MSVC_ASAN)
|
||||
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")
|
||||
set(SYMBOL_FORMAT /ZI)
|
||||
endif()
|
||||
|
||||
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_CXX_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_C_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT_RELEASE}")
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}")
|
||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}")
|
||||
unset(SYMBOL_FORMAT)
|
||||
unset(SYMBOL_FORMAT_RELEASE)
|
||||
|
||||
# JMC is available on msvc 15.8 (1915) and up
|
||||
if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG)
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC")
|
||||
|
@@ -44,15 +44,6 @@ __all__ = (
|
||||
"init",
|
||||
)
|
||||
|
||||
from typing import (
|
||||
Callable,
|
||||
Generator,
|
||||
List,
|
||||
Optional,
|
||||
Union,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
|
||||
import sys
|
||||
if sys.version_info.major < 3:
|
||||
@@ -79,11 +70,10 @@ SOURCE_DIR = abspath(SOURCE_DIR)
|
||||
SIMPLE_PROJECTFILE = False
|
||||
|
||||
# must initialize from 'init'
|
||||
CMAKE_DIR = ""
|
||||
PROJECT_DIR = ""
|
||||
CMAKE_DIR = None
|
||||
|
||||
|
||||
def init(cmake_path: str) -> bool:
|
||||
def init(cmake_path):
|
||||
global CMAKE_DIR, PROJECT_DIR
|
||||
|
||||
# get cmake path
|
||||
@@ -101,10 +91,7 @@ def init(cmake_path: str) -> bool:
|
||||
return True
|
||||
|
||||
|
||||
def source_list(
|
||||
path: str,
|
||||
filename_check: Optional[Callable[[str], bool]] = None,
|
||||
) -> Generator[str, None, None]:
|
||||
def source_list(path, filename_check=None):
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
# skip '.git'
|
||||
dirnames[:] = [d for d in dirnames if not d.startswith(".")]
|
||||
@@ -116,57 +103,53 @@ def source_list(
|
||||
|
||||
|
||||
# extension checking
|
||||
def is_cmake(filename: str) -> bool:
|
||||
def is_cmake(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".cmake") or (filename.endswith("CMakeLists.txt"))
|
||||
|
||||
|
||||
def is_c_header(filename: str) -> bool:
|
||||
def is_c_header(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||
|
||||
|
||||
def is_py(filename: str) -> bool:
|
||||
def is_py(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".py")
|
||||
|
||||
|
||||
def is_glsl(filename: str) -> bool:
|
||||
def is_glsl(filename):
|
||||
ext = splitext(filename)[1]
|
||||
return (ext == ".glsl")
|
||||
|
||||
|
||||
def is_c(filename: str) -> bool:
|
||||
def is_c(filename):
|
||||
ext = splitext(filename)[1]
|
||||
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)
|
||||
|
||||
|
||||
def is_svn_file(filename: str) -> bool:
|
||||
def is_svn_file(filename):
|
||||
dn, fn = os.path.split(filename)
|
||||
filename_svn = join(dn, ".svn", "text-base", "%s.svn-base" % fn)
|
||||
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)
|
||||
|
||||
|
||||
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.
|
||||
"""
|
||||
|
||||
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)
|
||||
|
||||
def create_eclipse_project() -> str:
|
||||
def create_eclipse_project():
|
||||
print("CMAKE_DIR %r" % CMAKE_DIR)
|
||||
if sys.platform == "win32":
|
||||
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
|
||||
|
||||
|
||||
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:
|
||||
lines = [
|
||||
l_strip for l in cache_file
|
||||
@@ -250,12 +233,12 @@ def cmake_cache_var(var: str) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def cmake_compiler_defines() -> Optional[List[str]]:
|
||||
def cmake_compiler_defines():
|
||||
compiler = cmake_cache_var("CMAKE_C_COMPILER") # could do CXX too
|
||||
|
||||
if compiler is None:
|
||||
print("Couldn't find the compiler, os defines will be omitted...")
|
||||
return None
|
||||
return
|
||||
|
||||
import tempfile
|
||||
temp_c = tempfile.mkstemp(suffix=".c")[1]
|
||||
@@ -272,5 +255,5 @@ def cmake_compiler_defines() -> Optional[List[str]]:
|
||||
return lines
|
||||
|
||||
|
||||
def project_name_get() -> Optional[str]:
|
||||
def project_name_get():
|
||||
return cmake_cache_var("CMAKE_PROJECT_NAME")
|
||||
|
@@ -34,45 +34,30 @@ if sys.version_info.major < 3:
|
||||
import os
|
||||
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 = normpath(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]
|
||||
return (ext in {".h", ".hpp", ".hxx", ".hh"})
|
||||
|
||||
|
||||
def is_c(filename: str) -> bool:
|
||||
def is_c(filename):
|
||||
ext = os.path.splitext(filename)[1]
|
||||
return (ext in {".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc", ".inl", ".osl"})
|
||||
|
||||
|
||||
def is_c_any(filename: str) -> bool:
|
||||
return is_c(filename) or is_c_header(filename)
|
||||
def is_c_any(filename):
|
||||
return os.path.s_c(filename) or is_c_header(filename)
|
||||
|
||||
|
||||
# copied from project_info.py
|
||||
CMAKE_DIR = "."
|
||||
|
||||
|
||||
def cmake_cache_var_iter() -> Generator[Tuple[str, str, str], None, None]:
|
||||
def cmake_cache_var_iter():
|
||||
import re
|
||||
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:
|
||||
@@ -83,22 +68,14 @@ def cmake_cache_var_iter() -> Generator[Tuple[str, str, str], None, None]:
|
||||
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():
|
||||
if var == var_iter:
|
||||
return value_iter
|
||||
return None
|
||||
|
||||
|
||||
def cmake_cache_var_or_exit(var: str) -> str:
|
||||
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:
|
||||
def do_ignore(filepath, ignore_prefix_list):
|
||||
if ignore_prefix_list is None:
|
||||
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])
|
||||
|
||||
|
||||
def makefile_log() -> List[str]:
|
||||
def makefile_log():
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
# 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)
|
||||
|
||||
if make_exe_basename.startswith(("make", "gmake")):
|
||||
@@ -126,37 +102,26 @@ def makefile_log() -> List[str]:
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
if process is None:
|
||||
print("Can't execute process")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
while process.poll():
|
||||
time.sleep(1)
|
||||
|
||||
# We know this is always true based on the input arguments to `Popen`.
|
||||
stdout: IO[bytes] = process.stdout # type: ignore
|
||||
|
||||
out = stdout.read()
|
||||
stdout.close()
|
||||
out = process.stdout.read()
|
||||
process.stdout.close()
|
||||
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(
|
||||
use_c: bool = True,
|
||||
use_cxx: bool = True,
|
||||
ignore_prefix_list: Optional[List[str]] = None,
|
||||
) -> List[Tuple[str, List[str], List[str]]]:
|
||||
def build_info(use_c=True, use_cxx=True, ignore_prefix_list=None):
|
||||
|
||||
makelog = makefile_log()
|
||||
|
||||
source = []
|
||||
|
||||
compilers = []
|
||||
if use_c:
|
||||
compilers.append(cmake_cache_var_or_exit("CMAKE_C_COMPILER"))
|
||||
compilers.append(cmake_cache_var("CMAKE_C_COMPILER"))
|
||||
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))
|
||||
|
||||
@@ -166,7 +131,7 @@ def build_info(
|
||||
|
||||
for line in makelog:
|
||||
|
||||
args: Union[str, List[str]] = line.split()
|
||||
args = line.split()
|
||||
|
||||
if not any([(c in args) for c in compilers]):
|
||||
continue
|
||||
@@ -211,40 +176,29 @@ def build_info(
|
||||
return source
|
||||
|
||||
|
||||
def build_defines_as_source() -> str:
|
||||
def build_defines_as_source():
|
||||
"""
|
||||
Returns a string formatted as an include:
|
||||
'#defines A=B\n#define....'
|
||||
"""
|
||||
import subprocess
|
||||
# works for both gcc and clang
|
||||
cmd = (cmake_cache_var_or_exit("CMAKE_C_COMPILER"), "-dM", "-E", "-")
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stdin=subprocess.DEVNULL,
|
||||
)
|
||||
|
||||
# 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'))
|
||||
cmd = (cmake_cache_var("CMAKE_C_COMPILER"), "-dM", "-E", "-")
|
||||
return subprocess.Popen(cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stdin=subprocess.DEVNULL,
|
||||
).stdout.read().strip().decode('ascii')
|
||||
|
||||
|
||||
def build_defines_as_args() -> List[str]:
|
||||
return [
|
||||
("-D" + "=".join(l.split(maxsplit=2)[1:]))
|
||||
for l in build_defines_as_source().split("\n")
|
||||
if l.startswith('#define')
|
||||
]
|
||||
def build_defines_as_args():
|
||||
return [("-D" + "=".join(l.split(maxsplit=2)[1:]))
|
||||
for l in build_defines_as_source().split("\n")
|
||||
if l.startswith('#define')]
|
||||
|
||||
|
||||
# could be moved elsewhere!, this just happens to be used by scripts that also
|
||||
# use this module.
|
||||
def queue_processes(
|
||||
process_funcs: Sequence[Tuple[Callable[..., subprocess.Popen[Any]], Tuple[Any, ...]]],
|
||||
job_total: int =-1,
|
||||
) -> None:
|
||||
def queue_processes(process_funcs, job_total=-1):
|
||||
""" Takes a list of function arg pairs, each function must return a process
|
||||
"""
|
||||
|
||||
@@ -263,7 +217,7 @@ def queue_processes(
|
||||
else:
|
||||
import time
|
||||
|
||||
processes: List[subprocess.Popen[Any]] = []
|
||||
processes = []
|
||||
for func, args in process_funcs:
|
||||
# wait until a thread is free
|
||||
while 1:
|
||||
@@ -280,7 +234,7 @@ def queue_processes(
|
||||
processes.append(func(*args))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
def main():
|
||||
if not os.path.exists(join(CMAKE_DIR, "CMakeCache.txt")):
|
||||
print("This script must run from the cmake build dir")
|
||||
return
|
||||
|
@@ -1,12 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import dataclasses
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Iterable, TextIO, Optional, Any, Union
|
||||
from typing import Iterable, TextIO
|
||||
|
||||
# This script can run from any location,
|
||||
# output is created in the $CWD
|
||||
@@ -19,43 +18,21 @@ SKIP_NAMES = {
|
||||
".gitignore",
|
||||
".gitmodules",
|
||||
".arcconfig",
|
||||
".svn",
|
||||
}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
output_dir = Path(".").absolute()
|
||||
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}")
|
||||
|
||||
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)
|
||||
tarball = tarball_path(curdir, version, cli_args)
|
||||
manifest = manifest_path(tarball)
|
||||
packages_dir = packages_path(curdir, cli_args)
|
||||
manifest = output_dir / f"blender-{version}-manifest.txt"
|
||||
tarball = output_dir / f"blender-{version}.tar.xz"
|
||||
|
||||
create_manifest(version, manifest, blender_srcdir, packages_dir)
|
||||
create_tarball(version, tarball, manifest, blender_srcdir, packages_dir)
|
||||
os.chdir(blender_srcdir)
|
||||
create_manifest(version, manifest)
|
||||
create_tarball(version, tarball, manifest)
|
||||
create_checksum_file(tarball)
|
||||
cleanup(manifest)
|
||||
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
|
||||
|
||||
|
||||
def create_manifest(
|
||||
version: BlenderVersion,
|
||||
outpath: Path,
|
||||
blender_srcdir: Path,
|
||||
packages_dir: Optional[Path],
|
||||
) -> None:
|
||||
def create_manifest(version: BlenderVersion, outpath: Path) -> None:
|
||||
print(f'Building manifest of files: "{outpath}"...', end="", flush=True)
|
||||
with outpath.open("w", encoding="utf-8") as outfile:
|
||||
main_files_to_manifest(blender_srcdir, outfile)
|
||||
submodules_to_manifest(blender_srcdir, version, outfile)
|
||||
|
||||
if packages_dir:
|
||||
packages_to_manifest(outfile, packages_dir)
|
||||
main_files_to_manifest(outfile)
|
||||
submodules_to_manifest(version, outfile)
|
||||
print("OK")
|
||||
|
||||
|
||||
def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None:
|
||||
assert not blender_srcdir.is_absolute()
|
||||
for path in git_ls_files(blender_srcdir):
|
||||
def main_files_to_manifest(outfile: TextIO) -> None:
|
||||
for path in git_ls_files():
|
||||
print(path, file=outfile)
|
||||
|
||||
|
||||
def submodules_to_manifest(
|
||||
blender_srcdir: Path, version: BlenderVersion, outfile: TextIO
|
||||
) -> None:
|
||||
def submodules_to_manifest(version: BlenderVersion, outfile: TextIO) -> None:
|
||||
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]
|
||||
|
||||
# Don't use native slashes as GIT for MS-Windows outputs forward slashes.
|
||||
if skip_addon_contrib and submodule == "release/scripts/addons_contrib":
|
||||
continue
|
||||
|
||||
for path in git_ls_files(blender_srcdir / submodule):
|
||||
for path in git_ls_files(Path(submodule)):
|
||||
print(path, file=outfile)
|
||||
|
||||
|
||||
def packages_to_manifest(outfile: TextIO, packages_dir: 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:
|
||||
def create_tarball(version: BlenderVersion, tarball: Path, manifest: Path) -> None:
|
||||
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
|
||||
command = ["tar"]
|
||||
|
||||
# Requires GNU `tar`, since `--transform` is used.
|
||||
if packages_dir:
|
||||
command += ["--transform", f"s,{packages_dir}/,packages/,g"]
|
||||
|
||||
command += [
|
||||
command = [
|
||||
"tar",
|
||||
"--transform",
|
||||
f"s,^{blender_srcdir.name}/,blender-{version}/,g",
|
||||
f"s,^,blender-{version}/,g",
|
||||
"--use-compress-program=xz -9",
|
||||
"--create",
|
||||
f"--file={tarball}",
|
||||
@@ -219,8 +130,7 @@ def create_tarball(
|
||||
"--owner=0",
|
||||
"--group=0",
|
||||
]
|
||||
|
||||
subprocess.run(command, check=True, timeout=3600)
|
||||
subprocess.run(command, check=True, timeout=300)
|
||||
print("OK")
|
||||
|
||||
|
||||
@@ -264,7 +174,7 @@ def git_ls_files(directory: Path = Path(".")) -> Iterable[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."""
|
||||
command = ("git", *cli_args)
|
||||
|
||||
|
@@ -9,10 +9,14 @@ if "%BUILD_WITH_SCCACHE%"=="1" (
|
||||
|
||||
if "%WITH_CLANG%"=="1" (
|
||||
set CLANG_CMAKE_ARGS=-T"llvm"
|
||||
)
|
||||
|
||||
if "%WITH_ASAN%"=="1" (
|
||||
if "%WITH_ASAN%"=="1" (
|
||||
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" (
|
||||
|
@@ -46,10 +46,16 @@ set LLVM_DIR=
|
||||
set CFLAGS=-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" (
|
||||
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%" == "" (
|
||||
|
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "V3.0"
|
||||
PROJECT_NUMBER = "V2.93"
|
||||
|
||||
# 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
|
||||
|
@@ -22,7 +22,7 @@
|
||||
This script generates the blender.1 man page, embedding the help text
|
||||
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,
|
||||
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>
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import time
|
||||
|
||||
from typing import (
|
||||
Dict,
|
||||
TextIO,
|
||||
)
|
||||
|
||||
|
||||
def man_format(data: str) -> str:
|
||||
def man_format(data):
|
||||
data = data.replace("-", "\\-")
|
||||
data = data.replace("\t", " ")
|
||||
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 = {
|
||||
"ASAN_OPTIONS": "exitcode=0:" + os.environ.get("ASAN_OPTIONS", ""),
|
||||
}
|
||||
blender_bin = sys.argv[1]
|
||||
outfilename = sys.argv[2]
|
||||
|
||||
blender_help = subprocess.run(
|
||||
[blender_bin, "--help"],
|
||||
env=blender_env,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.decode(encoding="utf-8")
|
||||
cmd = [blender_bin, "--help"]
|
||||
print(" executing:", " ".join(cmd))
|
||||
ASAN_OPTIONS = "exitcode=0:" + os.environ.get("ASAN_OPTIONS", "")
|
||||
blender_help = subprocess.run(
|
||||
cmd, env={"ASAN_OPTIONS": ASAN_OPTIONS}, check=True, stdout=subprocess.PIPE).stdout.decode(encoding="utf-8")
|
||||
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(
|
||||
[blender_bin, "--version"],
|
||||
env=blender_env,
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
).stdout.decode(encoding="utf-8")
|
||||
outfile = open(outfilename, "w")
|
||||
fw = outfile.write
|
||||
|
||||
# Extract information from the version string.
|
||||
# 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
|
||||
fw('.TH "BLENDER" "1" "%s" "Blender %s"\n' % (date_string, blender_version.replace(".", "\\&.")))
|
||||
|
||||
if not blender_date:
|
||||
# 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'''
|
||||
fw('''
|
||||
.SH NAME
|
||||
blender \- a full-featured 3D application''')
|
||||
|
||||
fh.write(r'''
|
||||
fw('''
|
||||
.SH SYNOPSIS
|
||||
.B blender [args ...] [file] [args ...]''')
|
||||
|
||||
fh.write(r'''
|
||||
fw('''
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.B blender
|
||||
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.
|
||||
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.
|
||||
|
||||
Use Blender to create 3D images and animations, films and commercials, content for games, '''
|
||||
r'''architectural and industrial visualizatons, and scientific visualizations.
|
||||
Use Blender to create 3D images and animations, films and commercials, content for games, architectural and industrial visualizatons, and scientific visualizations.
|
||||
|
||||
https://www.blender.org''')
|
||||
|
||||
fh.write(r'''
|
||||
fw('''
|
||||
.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:
|
||||
l = lines.pop(0)
|
||||
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))
|
||||
fw('.TP\n')
|
||||
fw('.B %s\n' % man_format(l))
|
||||
|
||||
while lines:
|
||||
# line with no
|
||||
if lines[0].strip() and len(lines[0].lstrip()) == len(lines[0]): # No white space.
|
||||
break
|
||||
while lines:
|
||||
# line with no
|
||||
if lines[0].strip() and len(lines[0].lstrip()) == len(lines[0]): # no white space
|
||||
break
|
||||
|
||||
if not l: # Second blank line.
|
||||
fh.write('.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')
|
||||
if not l: # second blank line
|
||||
fw('.IP\n')
|
||||
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
|
||||
.SH SEE ALSO
|
||||
.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>.
|
||||
''')
|
||||
|
||||
|
||||
def create_argparse() -> argparse.ArgumentParser:
|
||||
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()
|
||||
outfile.close()
|
||||
print("written:", outfilename)
|
||||
|
@@ -61,3 +61,4 @@ def unregister():
|
||||
|
||||
if __name__ == "__main__":
|
||||
register()
|
||||
|
||||
|
@@ -1,2 +1,2 @@
|
||||
Sphinx==3.5.3
|
||||
sphinx_rtd_theme==0.5.2
|
||||
Sphinx==3.5.1
|
||||
sphinx_rtd_theme==0.5.1
|
||||
|
@@ -553,7 +553,7 @@ def example_extract_docstring(filepath):
|
||||
line_no += 1
|
||||
else:
|
||||
file.close()
|
||||
return "", 0, False
|
||||
return "", 0
|
||||
|
||||
for line in file:
|
||||
line_no += 1
|
||||
@@ -563,17 +563,15 @@ def example_extract_docstring(filepath):
|
||||
text.append(line.rstrip())
|
||||
|
||||
line_no += 1
|
||||
line_no_has_content = False
|
||||
|
||||
# Skip over blank lines so the Python code doesn't have blank lines at the top.
|
||||
for line in file:
|
||||
if line.strip():
|
||||
line_no_has_content = True
|
||||
break
|
||||
line_no += 1
|
||||
|
||||
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):
|
||||
@@ -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_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"):
|
||||
fw("%s\n" % (ident + line).rstrip())
|
||||
fw("\n")
|
||||
|
||||
# Some files only contain a doc-string.
|
||||
if line_no_has_content:
|
||||
fw("%s.. literalinclude:: %s\n" % (ident, filepath))
|
||||
if line_no > 0:
|
||||
fw("%s :lines: %d-\n" % (ident, line_no))
|
||||
fw("\n")
|
||||
fw("%s.. literalinclude:: %s\n" % (ident, filepath))
|
||||
if line_no > 0:
|
||||
fw("%s :lines: %d-\n" % (ident, line_no))
|
||||
fw("\n")
|
||||
EXAMPLE_SET_USED.add(example_id)
|
||||
else:
|
||||
if bpy.app.debug:
|
||||
@@ -1412,8 +1408,7 @@ def pyrna2sphinx(basepath):
|
||||
else:
|
||||
fw(" .. attribute:: %s\n\n" % prop.identifier)
|
||||
if prop.description:
|
||||
write_indented_lines(" ", fw, prop.description, False)
|
||||
fw("\n")
|
||||
fw(" %s\n\n" % prop.description)
|
||||
|
||||
# special exception, can't use generic code here for enums
|
||||
if prop.type == "enum":
|
||||
|
4
extern/CMakeLists.txt
vendored
4
extern/CMakeLists.txt
vendored
@@ -109,7 +109,3 @@ endif()
|
||||
if(WITH_MOD_FLUID)
|
||||
add_subdirectory(mantaflow)
|
||||
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/ReadDevice.cpp
|
||||
src/devices/SoftwareDevice.cpp
|
||||
src/devices/ThreadedDevice.cpp
|
||||
src/Exception.cpp
|
||||
src/file/File.cpp
|
||||
src/file/FileManager.cpp
|
||||
@@ -149,7 +148,6 @@ set(PUBLIC_HDR
|
||||
include/devices/NULLDevice.h
|
||||
include/devices/ReadDevice.h
|
||||
include/devices/SoftwareDevice.h
|
||||
include/devices/ThreadedDevice.h
|
||||
include/Exception.h
|
||||
include/file/File.h
|
||||
include/file/FileManager.h
|
||||
|
@@ -255,7 +255,6 @@ protected:
|
||||
/**
|
||||
* This function tells the device, to start or pause 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;
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
std::lock_guard<ILockable> lock(*device);
|
||||
|
||||
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)
|
||||
@@ -68,40 +68,29 @@ void PulseAudioDevice::PulseAudio_underflow(pa_stream *stream, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
void PulseAudioDevice::runMixingThread()
|
||||
void PulseAudioDevice::playing(bool playing)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
{
|
||||
std::lock_guard<ILockable> lock(*this);
|
||||
m_playback = playing;
|
||||
|
||||
if(shouldStop())
|
||||
{
|
||||
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);
|
||||
}
|
||||
AUD_pa_stream_cork(m_stream, playing ? 0 : 1, nullptr, nullptr);
|
||||
}
|
||||
|
||||
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
|
||||
m_playback(false),
|
||||
m_state(PA_CONTEXT_UNCONNECTED),
|
||||
m_buffersize(buffersize),
|
||||
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)
|
||||
{
|
||||
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.");
|
||||
}
|
||||
@@ -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_threaded_mainloop_start(m_mainloop);
|
||||
|
||||
while(m_state != PA_CONTEXT_READY)
|
||||
{
|
||||
switch(m_state)
|
||||
{
|
||||
case PA_CONTEXT_FAILED:
|
||||
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_unref(m_context);
|
||||
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
|
||||
AUD_THROW(DeviceException, "Could not connect to PulseAudio.");
|
||||
break;
|
||||
default:
|
||||
AUD_pa_mainloop_iterate(m_mainloop, true, nullptr);
|
||||
AUD_pa_threaded_mainloop_wait(m_mainloop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -172,10 +166,13 @@ PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buff
|
||||
|
||||
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_unref(m_context);
|
||||
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
|
||||
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.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_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_pa_threaded_mainloop_unlock(m_mainloop);
|
||||
|
||||
create();
|
||||
}
|
||||
|
||||
PulseAudioDevice::~PulseAudioDevice()
|
||||
{
|
||||
stopMixingThread();
|
||||
AUD_pa_threaded_mainloop_stop(m_mainloop);
|
||||
|
||||
AUD_pa_context_disconnect(m_context);
|
||||
AUD_pa_context_unref(m_context);
|
||||
|
||||
AUD_pa_mainloop_free(m_mainloop);
|
||||
AUD_pa_threaded_mainloop_free(m_mainloop);
|
||||
|
||||
destroy();
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
* The PulseAudioDevice class.
|
||||
*/
|
||||
|
||||
#include "devices/ThreadedDevice.h"
|
||||
#include "devices/SoftwareDevice.h"
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
@@ -35,10 +35,15 @@ AUD_NAMESPACE_BEGIN
|
||||
/**
|
||||
* 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:
|
||||
pa_mainloop* m_mainloop;
|
||||
/**
|
||||
* Whether there is currently playback.
|
||||
*/
|
||||
volatile bool m_playback;
|
||||
|
||||
pa_threaded_mainloop* m_mainloop;
|
||||
pa_context* m_context;
|
||||
pa_stream* m_stream;
|
||||
pa_context_state_t m_state;
|
||||
@@ -69,15 +74,13 @@ private:
|
||||
*/
|
||||
AUD_LOCAL static void PulseAudio_underflow(pa_stream* stream, void* data);
|
||||
|
||||
/**
|
||||
* Streaming thread main function.
|
||||
*/
|
||||
AUD_LOCAL void runMixingThread();
|
||||
|
||||
// delete copy constructor and operator=
|
||||
PulseAudioDevice(const PulseAudioDevice&) = delete;
|
||||
PulseAudioDevice& operator=(const PulseAudioDevice&) = delete;
|
||||
|
||||
protected:
|
||||
virtual void playing(bool playing);
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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_connect_playback);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_cork);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_is_corked);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_new);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_set_buffer_attr);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_set_underflow_callback);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_set_write_callback);
|
||||
PULSEAUDIO_SYMBOL(pa_stream_write);
|
||||
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_free);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_get_api);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_new);
|
||||
PULSEAUDIO_SYMBOL(pa_mainloop_iterate);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_free);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_get_api);
|
||||
PULSEAUDIO_SYMBOL(pa_threaded_mainloop_lock);
|
||||
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 padding;
|
||||
UINT32 length;
|
||||
data_t* buffer;
|
||||
|
||||
if(FAILED(m_audio_client->GetBufferSize(&buffer_size)))
|
||||
return;
|
||||
|
||||
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)))
|
||||
goto init_error;
|
||||
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
||||
{
|
||||
SafeRelease(&render_client);
|
||||
return;
|
||||
}
|
||||
|
||||
if(FAILED(m_audio_client->GetService(IID_IAudioRenderClient, reinterpret_cast<void**>(&render_client))))
|
||||
goto init_error;
|
||||
lock();
|
||||
|
||||
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
|
||||
goto init_error;
|
||||
mix((data_t*)buffer, length);
|
||||
|
||||
length = buffer_size - padding;
|
||||
unlock();
|
||||
|
||||
if(FAILED(render_client->GetBuffer(length, &buffer)))
|
||||
goto init_error;
|
||||
|
||||
mix((data_t*)buffer, length);
|
||||
|
||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||
{
|
||||
init_error:
|
||||
SafeRelease(&render_client);
|
||||
doStop();
|
||||
return;
|
||||
}
|
||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||
{
|
||||
SafeRelease(&render_client);
|
||||
return;
|
||||
}
|
||||
|
||||
m_audio_client->Start();
|
||||
@@ -76,38 +96,58 @@ void WASAPIDevice::runMixingThread()
|
||||
|
||||
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)))
|
||||
goto stop_thread;
|
||||
length = buffer_size - padding;
|
||||
|
||||
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)))
|
||||
goto stop_thread;
|
||||
lock();
|
||||
|
||||
mix((data_t*)buffer, length);
|
||||
mix((data_t*)buffer, length);
|
||||
|
||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||
goto stop_thread;
|
||||
unlock();
|
||||
|
||||
// stop thread
|
||||
if(shouldStop())
|
||||
{
|
||||
stop_thread:
|
||||
m_audio_client->Stop();
|
||||
SafeRelease(&render_client);
|
||||
doStop();
|
||||
return;
|
||||
}
|
||||
if(FAILED(render_client->ReleaseBuffer(length, 0)))
|
||||
{
|
||||
m_audio_client->Stop();
|
||||
SafeRelease(&render_client);
|
||||
return;
|
||||
}
|
||||
|
||||
// stop thread
|
||||
if(!m_playing)
|
||||
{
|
||||
m_audio_client->Stop();
|
||||
SafeRelease(&render_client);
|
||||
return;
|
||||
}
|
||||
|
||||
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) :
|
||||
m_playing(false),
|
||||
|
||||
m_imm_device_enumerator(nullptr),
|
||||
m_imm_device(nullptr),
|
||||
m_audio_client(nullptr),
|
||||
@@ -285,7 +325,14 @@ WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
|
||||
|
||||
WASAPIDevice::~WASAPIDevice()
|
||||
{
|
||||
stopMixingThread();
|
||||
lock();
|
||||
|
||||
stopAll();
|
||||
|
||||
unlock();
|
||||
|
||||
if(m_thread.joinable())
|
||||
m_thread.join();
|
||||
|
||||
SafeRelease(&m_audio_client);
|
||||
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.
|
||||
*/
|
||||
|
||||
#include "devices/ThreadedDevice.h"
|
||||
#include "devices/SoftwareDevice.h"
|
||||
|
||||
#include <thread>
|
||||
|
||||
@@ -40,23 +40,41 @@ AUD_NAMESPACE_BEGIN
|
||||
/**
|
||||
* 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:
|
||||
/**
|
||||
* Whether there is currently playback.
|
||||
*/
|
||||
bool m_playing;
|
||||
|
||||
IMMDeviceEnumerator* m_imm_device_enumerator;
|
||||
IMMDevice* m_imm_device;
|
||||
IAudioClient* m_audio_client;
|
||||
WAVEFORMATEXTENSIBLE m_wave_format_extensible;
|
||||
|
||||
/**
|
||||
* The streaming thread.
|
||||
*/
|
||||
std::thread m_thread;
|
||||
|
||||
/**
|
||||
* Starts the streaming thread.
|
||||
*/
|
||||
AUD_LOCAL void start();
|
||||
|
||||
/**
|
||||
* Streaming thread main function.
|
||||
*/
|
||||
AUD_LOCAL void runMixingThread();
|
||||
AUD_LOCAL void updateStream();
|
||||
|
||||
// delete copy constructor and operator=
|
||||
WASAPIDevice(const WASAPIDevice&) = delete;
|
||||
WASAPIDevice& operator=(const WASAPIDevice&) = delete;
|
||||
|
||||
protected:
|
||||
virtual void playing(bool playing);
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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));
|
||||
|
||||
std::lock_guard<ILockable> lock(*this);
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
{
|
||||
std::shared_ptr<SoftwareDevice::SoftwareHandle> sound;
|
||||
@@ -880,7 +880,7 @@ std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<IReader> reader, b
|
||||
// play sound
|
||||
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);
|
||||
|
||||
@@ -897,7 +897,7 @@ std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<ISound> sound, boo
|
||||
|
||||
void SoftwareDevice::stopAll()
|
||||
{
|
||||
std::lock_guard<ILockable> lock(*this);
|
||||
std::lock_guard<std::recursive_mutex> lock(m_mutex);
|
||||
|
||||
while(!m_playingSounds.empty())
|
||||
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 <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@@ -41,9 +41,6 @@ class AddPresetIntegrator(AddPresetBase, Operator):
|
||||
"cycles.caustics_reflective",
|
||||
"cycles.caustics_refractive",
|
||||
"cycles.blur_glossy"
|
||||
"cycles.use_fast_gi"
|
||||
"cycles.ao_bounces"
|
||||
"cycles.ao_bounces_render"
|
||||
]
|
||||
|
||||
preset_subdir = "cycles/integrator"
|
||||
|
@@ -801,22 +801,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
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(
|
||||
name="AO Bounces",
|
||||
default=1,
|
||||
description="After this number of light bounces, use approximate global illumination. 0 disables this feature",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
ao_bounces_render: IntProperty(
|
||||
name="AO Bounces Render",
|
||||
default=1,
|
||||
description="After this number of light bounces, use approximate global illumination. 0 disables this feature",
|
||||
default=0,
|
||||
description="Approximate indirect light with background tinted ambient occlusion at the specified bounce, 0 disables this feature",
|
||||
min=0, max=1024,
|
||||
)
|
||||
|
||||
|
@@ -526,35 +526,6 @@ class CYCLES_RENDER_PT_light_paths_caustics(CyclesButtonsPanel, Panel):
|
||||
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):
|
||||
bl_label = "Motion Blur"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@@ -775,7 +746,7 @@ class CYCLES_RENDER_PT_performance_final_render(CyclesButtonsPanel, Panel):
|
||||
col = layout.column()
|
||||
|
||||
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):
|
||||
@@ -1438,15 +1409,15 @@ class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
|
||||
panel_node_draw(layout, light, 'OUTPUT_LIGHT', 'Surface')
|
||||
|
||||
|
||||
class CYCLES_LIGHT_PT_beam_shape(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Beam Shape"
|
||||
class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Spot Shape"
|
||||
bl_parent_id = "CYCLES_LIGHT_PT_light"
|
||||
bl_context = "data"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
if context.light.type in {'SPOT', 'AREA'}:
|
||||
return context.light and CyclesButtonsPanel.poll(context)
|
||||
light = context.light
|
||||
return (light and light.type == 'SPOT') and CyclesButtonsPanel.poll(context)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -1454,12 +1425,9 @@ class CYCLES_LIGHT_PT_beam_shape(CyclesButtonsPanel, Panel):
|
||||
layout.use_property_split = True
|
||||
|
||||
col = layout.column()
|
||||
if light.type == 'SPOT':
|
||||
col.prop(light, "spot_size", text="Spot Size")
|
||||
col.prop(light, "spot_blend", text="Blend", slider=True)
|
||||
col.prop(light, "show_cone")
|
||||
elif light.type == 'AREA':
|
||||
col.prop(light, "spread", text="Spread")
|
||||
col.prop(light, "spot_size", text="Size")
|
||||
col.prop(light, "spot_blend", text="Blend", slider=True)
|
||||
col.prop(light, "show_cone")
|
||||
|
||||
|
||||
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_child_particles", text="Child Particles")
|
||||
col.prop(cscene, "texture_limit", text="Texture Limit")
|
||||
col.prop(cscene, "ao_bounces", text="AO Bounces")
|
||||
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_child_particles_render", text="Child Particles")
|
||||
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):
|
||||
@@ -2272,7 +2242,6 @@ classes = (
|
||||
CYCLES_RENDER_PT_light_paths_max_bounces,
|
||||
CYCLES_RENDER_PT_light_paths_clamping,
|
||||
CYCLES_RENDER_PT_light_paths_caustics,
|
||||
CYCLES_RENDER_PT_light_paths_fast_gi,
|
||||
CYCLES_RENDER_PT_volumes,
|
||||
CYCLES_RENDER_PT_subdivision,
|
||||
CYCLES_RENDER_PT_hair,
|
||||
@@ -2315,7 +2284,7 @@ classes = (
|
||||
CYCLES_LIGHT_PT_preview,
|
||||
CYCLES_LIGHT_PT_light,
|
||||
CYCLES_LIGHT_PT_nodes,
|
||||
CYCLES_LIGHT_PT_beam_shape,
|
||||
CYCLES_LIGHT_PT_spot,
|
||||
CYCLES_WORLD_PT_preview,
|
||||
CYCLES_WORLD_PT_surface,
|
||||
CYCLES_WORLD_PT_volume,
|
||||
@@ -2345,7 +2314,7 @@ classes = (
|
||||
node_panel(CYCLES_WORLD_PT_settings_surface),
|
||||
node_panel(CYCLES_WORLD_PT_settings_volume),
|
||||
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.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
|
||||
for light in bpy.data.lights:
|
||||
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.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.width = b_node.resolution();
|
||||
|
@@ -27,7 +27,7 @@ class BlenderImageLoader : public ImageLoader {
|
||||
public:
|
||||
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,
|
||||
void *pixels,
|
||||
const size_t pixels_size,
|
||||
@@ -44,7 +44,7 @@ class BlenderPointDensityLoader : public ImageLoader {
|
||||
public:
|
||||
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,
|
||||
void *pixels,
|
||||
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_axisv(transform_get_column(&tfm, 1));
|
||||
light->set_sizeu(b_area_light.size());
|
||||
light->set_spread(b_area_light.spread());
|
||||
switch (b_area_light.shape()) {
|
||||
case BL::AreaLight::shape_SQUARE:
|
||||
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:
|
||||
element = ATTR_ELEMENT_VERTEX;
|
||||
break;
|
||||
case BL::Attribute::domain_FACE:
|
||||
case BL::Attribute::domain_POLYGON:
|
||||
element = ATTR_ELEMENT_FACE;
|
||||
break;
|
||||
default:
|
||||
|
@@ -143,6 +143,12 @@ void BlenderSession::create_session()
|
||||
|
||||
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 */
|
||||
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
||||
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);
|
||||
|
||||
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
|
||||
* 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();
|
||||
scene->reset();
|
||||
|
||||
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;
|
||||
|
||||
if (is_new_session) {
|
||||
/* Sync object should be re-created for new scene. */
|
||||
delete sync;
|
||||
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
||||
}
|
||||
else {
|
||||
/* Sync recalculations to do just the required updates. */
|
||||
sync->sync_recalc(b_depsgraph, b_v3d);
|
||||
}
|
||||
/* There is no single depsgraph to use for the entire render.
|
||||
* See note on create_session().
|
||||
*/
|
||||
/* sync object should be re-created */
|
||||
delete sync;
|
||||
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
|
||||
|
||||
BL::SpaceView3D b_null_space_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. */
|
||||
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. */
|
||||
buffer_params.passes = passes;
|
||||
@@ -594,6 +598,18 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
||||
/* clear callback */
|
||||
session->write_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)
|
||||
|
@@ -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);
|
||||
if (viewport_parameters.modified(new_viewport_parameters)) {
|
||||
world_recalc = true;
|
||||
}
|
||||
BlenderViewportParameters new_viewport_parameters(b_v3d);
|
||||
if (viewport_parameters.modified(new_viewport_parameters)) {
|
||||
world_recalc = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +358,7 @@ void BlenderSync::sync_integrator()
|
||||
|
||||
integrator->set_adaptive_min_samples(adaptive_min_samples);
|
||||
|
||||
if (get_boolean(cscene, "use_fast_gi")) {
|
||||
if (b_scene.render().use_simplify()) {
|
||||
if (preview) {
|
||||
integrator->set_ao_bounces(get_int(cscene, "ao_bounces"));
|
||||
}
|
||||
@@ -569,8 +567,7 @@ int BlenderSync::get_denoising_pass(BL::RenderPass &b_pass)
|
||||
return -1;
|
||||
}
|
||||
|
||||
vector<Pass> BlenderSync::sync_render_passes(BL::Scene &b_scene,
|
||||
BL::RenderLayer &b_rlay,
|
||||
vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
bool adaptive_sampling,
|
||||
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) {
|
||||
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;
|
||||
if (pass_type != PASS_NONE)
|
||||
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)
|
||||
{
|
||||
BL::RenderSettings r = b_scene.render();
|
||||
SceneParams params;
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
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(
|
||||
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;
|
||||
if (background) {
|
||||
texture_limit = RNA_enum_get(&cscene, "texture_limit_render");
|
||||
|
@@ -74,8 +74,7 @@ class BlenderSync {
|
||||
int height,
|
||||
void **python_thread_state);
|
||||
void sync_view_layer(BL::SpaceView3D &b_v3d, BL::ViewLayer &b_view_layer);
|
||||
vector<Pass> sync_render_passes(BL::Scene &b_scene,
|
||||
BL::RenderLayer &b_render_layer,
|
||||
vector<Pass> sync_render_passes(BL::RenderLayer &b_render_layer,
|
||||
BL::ViewLayer &b_view_layer,
|
||||
bool adaptive_sampling,
|
||||
const DenoiseParams &denoising);
|
||||
|
@@ -26,7 +26,7 @@
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
openvdb::GridBase::ConstPtr BKE_volume_grid_openvdb_for_read(const struct Volume *volume,
|
||||
const struct VolumeGrid *grid);
|
||||
struct VolumeGrid *grid);
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -41,7 +41,7 @@ class BlenderSmokeLoader : public ImageLoader {
|
||||
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) {
|
||||
return false;
|
||||
@@ -227,7 +227,7 @@ class BlenderVolumeLoader : public VDBImageLoader {
|
||||
const bool unload = !b_volume_grid.is_loaded();
|
||||
|
||||
::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);
|
||||
|
||||
if (unload) {
|
||||
|
@@ -619,7 +619,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
||||
info.num = 0;
|
||||
|
||||
info.has_half_images = true;
|
||||
info.has_nanovdb = true;
|
||||
info.has_volume_decoupled = true;
|
||||
info.has_branched_path = true;
|
||||
info.has_adaptive_stop_per_sample = true;
|
||||
@@ -666,7 +665,6 @@ DeviceInfo Device::get_multi_device(const vector<DeviceInfo> &subdevices,
|
||||
|
||||
/* Accumulate device info. */
|
||||
info.has_half_images &= device.has_half_images;
|
||||
info.has_nanovdb &= device.has_nanovdb;
|
||||
info.has_volume_decoupled &= device.has_volume_decoupled;
|
||||
info.has_branched_path &= device.has_branched_path;
|
||||
info.has_adaptive_stop_per_sample &= device.has_adaptive_stop_per_sample;
|
||||
|
@@ -78,7 +78,6 @@ class DeviceInfo {
|
||||
int num;
|
||||
bool display_device; /* GPU is used as a display device. */
|
||||
bool has_half_images; /* Support half-float textures. */
|
||||
bool has_nanovdb; /* Support NanoVDB volumes. */
|
||||
bool has_volume_decoupled; /* Decoupled volume shading. */
|
||||
bool has_branched_path; /* Supports branched path tracing. */
|
||||
bool has_adaptive_stop_per_sample; /* Per-sample adaptive sampling stopping. */
|
||||
@@ -100,7 +99,6 @@ class DeviceInfo {
|
||||
cpu_threads = 0;
|
||||
display_device = false;
|
||||
has_half_images = false;
|
||||
has_nanovdb = false;
|
||||
has_volume_decoupled = false;
|
||||
has_branched_path = true;
|
||||
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_osl = true;
|
||||
info.has_half_images = true;
|
||||
info.has_nanovdb = true;
|
||||
info.has_profiling = true;
|
||||
info.denoisers = DENOISER_NLM;
|
||||
if (openimagedenoise_supported()) {
|
||||
|
@@ -128,7 +128,6 @@ void device_cuda_info(vector<DeviceInfo> &devices)
|
||||
info.num = num;
|
||||
|
||||
info.has_half_images = (major >= 3);
|
||||
info.has_nanovdb = true;
|
||||
info.has_volume_decoupled = false;
|
||||
info.has_adaptive_stop_per_sample = false;
|
||||
info.denoisers = DENOISER_NLM;
|
||||
|
@@ -46,13 +46,10 @@ class MultiDevice : public Device {
|
||||
list<SubDevice> devices, denoising_devices;
|
||||
device_ptr unique_key;
|
||||
vector<vector<SubDevice *>> peer_islands;
|
||||
bool use_denoising;
|
||||
bool matching_rendering_and_denoising_devices;
|
||||
|
||||
MultiDevice(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background_)
|
||||
: Device(info, stats, profiler, background_),
|
||||
unique_key(1),
|
||||
use_denoising(!info.denoising_devices.empty())
|
||||
: Device(info, stats, profiler, background_), unique_key(1)
|
||||
{
|
||||
foreach (DeviceInfo &subinfo, info.multi_devices) {
|
||||
/* 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))
|
||||
return false;
|
||||
|
||||
use_denoising = requested_features.use_denoising;
|
||||
if (requested_features.use_denoising) {
|
||||
/* Only need denoising feature, everything else is unused. */
|
||||
DeviceRequestedFeatures denoising_features;
|
||||
@@ -404,7 +400,7 @@ class MultiDevice : public Device {
|
||||
size_t existing_size = mem.device_size;
|
||||
|
||||
/* 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) {
|
||||
mem.device = sub.device;
|
||||
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
|
||||
* 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 */
|
||||
if (strcmp(mem.name, "RenderBuffers") == 0 && use_denoising) {
|
||||
if (strcmp(mem.name, "RenderBuffers") == 0) {
|
||||
vector<device_ptr> device_pointers;
|
||||
device_pointers.reserve(devices.size());
|
||||
|
||||
@@ -522,7 +518,7 @@ class MultiDevice : public Device {
|
||||
size_t existing_size = mem.device_size;
|
||||
|
||||
/* 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) {
|
||||
mem.device = sub.device;
|
||||
mem.device_pointer = sub.ptr_map[key];
|
||||
|
@@ -126,9 +126,6 @@ void device_opencl_info(vector<DeviceInfo> &devices)
|
||||
/* Check OpenCL extensions */
|
||||
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);
|
||||
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
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_0;
|
||||
@@ -377,7 +377,7 @@ class OptiXDevice : public CUDADevice {
|
||||
module_options.numBoundValues = 0;
|
||||
# endif
|
||||
|
||||
OptixPipelineCompileOptions pipeline_options = {};
|
||||
OptixPipelineCompileOptions pipeline_options;
|
||||
// Default to no motion blur and two-level graph, since it is the fastest option
|
||||
pipeline_options.usesMotionBlur = false;
|
||||
pipeline_options.traversableGraphFlags =
|
||||
@@ -477,7 +477,7 @@ class OptiXDevice : public CUDADevice {
|
||||
|
||||
# if OPTIX_ABI_VERSION >= 36
|
||||
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.usesMotionBlur = false;
|
||||
|
||||
@@ -571,7 +571,7 @@ class OptiXDevice : public CUDADevice {
|
||||
stack_size[PG_HITS_MOTION].cssIS + stack_size[PG_HITS_MOTION].cssAH);
|
||||
# endif
|
||||
|
||||
OptixPipelineLinkOptions link_options = {};
|
||||
OptixPipelineLinkOptions link_options;
|
||||
link_options.maxTraceDepth = 1;
|
||||
# ifdef WITH_CYCLES_DEBUG
|
||||
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
|
||||
OptixDenoiserOptions denoiser_options = {};
|
||||
OptixDenoiserOptions denoiser_options;
|
||||
assert(task.denoising.input_passes >= 1 && task.denoising.input_passes <= 3);
|
||||
denoiser_options.inputKind = static_cast<OptixDenoiserInputKind>(
|
||||
OPTIX_DENOISER_INPUT_RGB + (task.denoising.input_passes - 1));
|
||||
@@ -1157,7 +1157,7 @@ class OptiXDevice : public CUDADevice {
|
||||
|
||||
// Compute memory usage
|
||||
OptixAccelBufferSizes sizes = {};
|
||||
OptixAccelBuildOptions options = {};
|
||||
OptixAccelBuildOptions options;
|
||||
options.operation = operation;
|
||||
if (background) {
|
||||
// Prefer best performance and lowest memory consumption in background
|
||||
@@ -1195,7 +1195,7 @@ class OptiXDevice : public CUDADevice {
|
||||
}
|
||||
|
||||
// Finally build the acceleration structure
|
||||
OptixAccelEmitDesc compacted_size_prop = {};
|
||||
OptixAccelEmitDesc compacted_size_prop;
|
||||
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
|
||||
// Make sure this pointer is 8-byte aligned
|
||||
|
@@ -2036,9 +2036,7 @@ string OpenCLDevice::kernel_build_options(const string *debug_src)
|
||||
# endif
|
||||
|
||||
# ifdef WITH_NANOVDB
|
||||
if (info.has_nanovdb) {
|
||||
build_options += "-DWITH_NANOVDB ";
|
||||
}
|
||||
build_options += "-DWITH_NANOVDB ";
|
||||
# endif
|
||||
|
||||
return build_options;
|
||||
|
@@ -119,11 +119,11 @@ ccl_device_inline bool lamp_light_sample(
|
||||
klight->area.axisu[0], klight->area.axisu[1], klight->area.axisu[2]);
|
||||
float3 axisv = make_float3(
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -136,37 +136,19 @@ ccl_device_inline bool lamp_light_sample(
|
||||
}
|
||||
else {
|
||||
inplane = ls->P;
|
||||
|
||||
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);
|
||||
ls->pdf = rect_light_sample(P, &ls->P, axisu, axisv, randu, randv, true);
|
||||
inplane = ls->P - inplane;
|
||||
}
|
||||
|
||||
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->Ng = Ng;
|
||||
ls->Ng = D;
|
||||
ls->D = normalize_len(ls->P - P, &ls->t);
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
float3 sample_axisu = axisu;
|
||||
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->pdf = rect_light_sample(P, &light_P, axisu, axisv, 0, 0, false);
|
||||
}
|
||||
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 {
|
||||
return false;
|
||||
|
@@ -146,70 +146,6 @@ ccl_device float spot_light_attenuation(float3 dir, float spot_angle, float spot
|
||||
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)
|
||||
{
|
||||
float cos_pi = dot(Ng, I);
|
||||
|
@@ -1501,9 +1501,9 @@ typedef struct KernelAreaLight {
|
||||
float axisu[3];
|
||||
float invarea;
|
||||
float axisv[3];
|
||||
float tan_spread;
|
||||
float pad1;
|
||||
float dir[3];
|
||||
float normalize_spread;
|
||||
float pad2;
|
||||
} KernelAreaLight;
|
||||
|
||||
typedef struct KernelDistantLight {
|
||||
|
@@ -88,13 +88,6 @@ point wrap(point value, point max, point min)
|
||||
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)
|
||||
{
|
||||
float cx = cos(euler[0]);
|
||||
|
@@ -46,12 +46,6 @@ shader node_vector_math(string math_type = "add",
|
||||
else if (math_type == "reflect") {
|
||||
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") {
|
||||
Value = dot(Vector1, Vector2);
|
||||
}
|
||||
|
@@ -44,26 +44,26 @@ ccl_device void svm_node_vector_math(KernelGlobals *kg,
|
||||
int *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(
|
||||
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);
|
||||
|
||||
float3 a = stack_load_float3(stack, a_stack_offset);
|
||||
float3 b = stack_load_float3(stack, b_stack_offset);
|
||||
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;
|
||||
float3 vector;
|
||||
|
||||
/* 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);
|
||||
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))
|
||||
stack_store_float(stack, value_stack_offset, value);
|
||||
|
@@ -22,7 +22,7 @@ ccl_device void svm_vector_math(float *value,
|
||||
float3 a,
|
||||
float3 b,
|
||||
float3 c,
|
||||
float param1)
|
||||
float scale)
|
||||
{
|
||||
switch (type) {
|
||||
case NODE_VECTOR_MATH_ADD:
|
||||
@@ -46,12 +46,6 @@ ccl_device void svm_vector_math(float *value,
|
||||
case NODE_VECTOR_MATH_REFLECT:
|
||||
*vector = reflect(a, b);
|
||||
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:
|
||||
*value = dot(a, b);
|
||||
break;
|
||||
@@ -62,7 +56,7 @@ ccl_device void svm_vector_math(float *value,
|
||||
*value = len(a);
|
||||
break;
|
||||
case NODE_VECTOR_MATH_SCALE:
|
||||
*vector = a * param1;
|
||||
*vector = a * scale;
|
||||
break;
|
||||
case NODE_VECTOR_MATH_NORMALIZE:
|
||||
*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));
|
||||
break;
|
||||
default:
|
||||
*vector = zero_float3();
|
||||
*vector = make_float3(0.0f, 0.0f, 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);
|
||||
}
|
||||
|
||||
/* Manually align for readability. */
|
||||
/* clang-format off */
|
||||
int i = (t >= 6365.0f) ? 5 :
|
||||
(t >= 3315.0f) ? 4 :
|
||||
(t >= 1902.0f) ? 3 :
|
||||
(t >= 1449.0f) ? 2 :
|
||||
(t >= 1167.0f) ? 1 :
|
||||
0;
|
||||
/* clang-format on */
|
||||
int i = (t >= 6365.0f) ?
|
||||
5 :
|
||||
(t >= 3315.0f) ? 4 :
|
||||
(t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0;
|
||||
|
||||
ccl_constant float *r = blackbody_table_r[i];
|
||||
ccl_constant float *g = blackbody_table_g[i];
|
||||
|
@@ -339,8 +339,6 @@ typedef enum NodeVectorMathType {
|
||||
NODE_VECTOR_MATH_SINE,
|
||||
NODE_VECTOR_MATH_COSINE,
|
||||
NODE_VECTOR_MATH_TANGENT,
|
||||
NODE_VECTOR_MATH_REFRACT,
|
||||
NODE_VECTOR_MATH_FACEFORWARD,
|
||||
} NodeVectorMathType;
|
||||
|
||||
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());
|
||||
|
||||
/* 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) {
|
||||
if (progress.get_cancel()) {
|
||||
return;
|
||||
@@ -426,32 +422,21 @@ static void add_uvs(AlembicProcedural *proc,
|
||||
|
||||
float2 *data_float2 = reinterpret_cast<float2 *>(data.data());
|
||||
|
||||
const ArraySample::Key indices_key = uvsample.getIndices()->getKey();
|
||||
const ArraySample::Key values_key = uvsample.getVals()->getKey();
|
||||
const unsigned int *indices = uvsample.getIndices()->get();
|
||||
const V2f *values = uvsample.getVals()->get();
|
||||
|
||||
if (indices_key == previous_indices_key && values_key == previous_values_key) {
|
||||
attr.data.reuse_data_for_last_time(time);
|
||||
}
|
||||
else {
|
||||
const unsigned int *indices = uvsample.getIndices()->get();
|
||||
const V2f *values = uvsample.getVals()->get();
|
||||
for (const int3 &loop : *triangles_loops) {
|
||||
unsigned int v0 = indices[loop.x];
|
||||
unsigned int v1 = indices[loop.y];
|
||||
unsigned int v2 = indices[loop.z];
|
||||
|
||||
for (const int3 &loop : *triangles_loops) {
|
||||
unsigned int v0 = indices[loop.x];
|
||||
unsigned int v1 = indices[loop.y];
|
||||
unsigned int v2 = indices[loop.z];
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
previous_indices_key = indices_key;
|
||||
previous_values_key = values_key;
|
||||
attr.data.add_data(data, time);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,11 +736,6 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
|
||||
ccl::set<chrono_t> times = get_relevant_sample_times(
|
||||
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 */
|
||||
foreach (chrono_t time, times) {
|
||||
if (progress.get_cancel()) {
|
||||
@@ -767,27 +747,22 @@ void AlembicObject::load_all_data(AlembicProcedural *proc,
|
||||
|
||||
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) {
|
||||
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) {
|
||||
cached_data.triangles.reuse_data_for_last_time(time);
|
||||
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;
|
||||
add_triangles(
|
||||
sample.getFaceCounts(), sample.getFaceIndices(), time, cached_data, polygon_to_shader);
|
||||
}
|
||||
|
||||
if (normals.valid()) {
|
||||
@@ -1407,15 +1382,6 @@ void AlembicProcedural::generate(Scene *scene, Progress &progress)
|
||||
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). */
|
||||
foreach (Node *shader_node, object->get_used_shaders()) {
|
||||
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());
|
||||
|
||||
/* 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.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());
|
||||
|
||||
/* 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
|
||||
* repass the data if something is animated (vertices most likely) to avoid buffer overflows. */
|
||||
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());
|
||||
|
||||
/* 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_radius.copy_to_socket(frame_time, hair, hair->get_curve_radius_socket());
|
||||
|
@@ -43,14 +43,14 @@ struct MatrixSamplesData {
|
||||
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 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. */
|
||||
template<typename T> class CacheLookupResult {
|
||||
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
|
||||
* animation time in seconds using the TimeSampling from the Alembic property. */
|
||||
template<typename T> class DataStore {
|
||||
/* Holds information to map a cache entry for a given time to an index into the data array. */
|
||||
struct TimeIndexPair {
|
||||
/* Frame time for this entry. */
|
||||
struct DataTimePair {
|
||||
double time = 0;
|
||||
/* Frame time for the data pointed to by `index`. */
|
||||
double source_time = 0;
|
||||
/* Index into the data array. */
|
||||
size_t index = 0;
|
||||
T data{};
|
||||
};
|
||||
|
||||
/* This is the actual data that is stored. We deduplicate data across frames to avoid storing
|
||||
* 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{};
|
||||
|
||||
vector<DataTimePair> data{};
|
||||
Alembic::AbcCoreAbstract::TimeSampling time_sampling{};
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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) {
|
||||
return CacheLookupResult<T>::no_data_found_for_time();
|
||||
}
|
||||
|
||||
if (last_loaded_time == index.time || last_loaded_time == index.source_time) {
|
||||
if (last_loaded_time == data_pair.time) {
|
||||
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[index.index]);
|
||||
return CacheLookupResult<T>::new_data(&data_pair.data);
|
||||
}
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
const TimeIndexPair &index = get_index_for_time(time);
|
||||
|
||||
if (index.index == -1ul) {
|
||||
return CacheLookupResult<T>::no_data_found_for_time();
|
||||
}
|
||||
|
||||
assert(index.index < data.size());
|
||||
|
||||
return CacheLookupResult<T>::new_data(&data[index.index]);
|
||||
std::pair<size_t, Alembic::Abc::chrono_t> index_pair;
|
||||
index_pair = time_sampling.getNearIndex(time, data.size());
|
||||
DataTimePair &data_pair = data[index_pair.first];
|
||||
return CacheLookupResult<T>::new_data(&data_pair.data);
|
||||
}
|
||||
|
||||
void add_data(T &data_, double time)
|
||||
{
|
||||
index_data_map.push_back({time, time, data.size()});
|
||||
|
||||
if constexpr (is_array<T>::value) {
|
||||
data.emplace_back();
|
||||
data.back().steal_data(data_);
|
||||
data.back().data.steal_data(data_);
|
||||
data.back().time = time;
|
||||
return;
|
||||
}
|
||||
|
||||
data.push_back(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});
|
||||
data.push_back({time, data_});
|
||||
}
|
||||
|
||||
bool is_constant() const
|
||||
@@ -239,7 +210,6 @@ template<typename T> class DataStore {
|
||||
{
|
||||
invalidate_last_loaded_time();
|
||||
data.clear();
|
||||
index_data_map.clear();
|
||||
}
|
||||
|
||||
void invalidate_last_loaded_time()
|
||||
@@ -262,14 +232,6 @@ template<typename T> class DataStore {
|
||||
T value = result.get_data();
|
||||
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.
|
||||
@@ -481,23 +443,16 @@ class AlembicProcedural : public Procedural {
|
||||
* invocation, and updates the data on subsequent invocations if the frame changed. */
|
||||
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. */
|
||||
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. */
|
||||
void load_objects(Progress &progress);
|
||||
|
||||
|
@@ -130,14 +130,6 @@ void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/)
|
||||
|
||||
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()) {
|
||||
scene->integrator->tag_update(scene, Integrator::BACKGROUND_AO_MODIFIED);
|
||||
}
|
||||
|
@@ -90,7 +90,6 @@ void Geometry::clear(bool preserve_shaders)
|
||||
transform_applied = false;
|
||||
transform_negative_scaled = false;
|
||||
transform_normal = transform_identity();
|
||||
tag_modified();
|
||||
}
|
||||
|
||||
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.bvh_layout = bparams.bvh_layout;
|
||||
dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
|
||||
dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions();
|
||||
/* 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_vindex.tag_realloc();
|
||||
dscene->tri_patch.tag_realloc();
|
||||
dscene->tri_vnormal.tag_realloc();
|
||||
dscene->tri_patch_uv.tag_realloc();
|
||||
dscene->tri_shader.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,
|
||||
* 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
|
||||
* 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);
|
||||
/* update the bvh even when there is no geometry so the kernel bvh data is still valid,
|
||||
* especially when removing all of the objects during interactive renders */
|
||||
bool need_update_scene_bvh = (scene->bvh == nullptr);
|
||||
{
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
if (scene->update_stats) {
|
||||
@@ -1962,6 +1960,7 @@ void GeometryManager::device_update(Device *device,
|
||||
scene->update_stats->geometry.times.add_entry({"device_update (compute bounds)", time});
|
||||
}
|
||||
});
|
||||
vector<Object *> volume_objects;
|
||||
foreach (Object *object, scene->objects) {
|
||||
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) {
|
||||
if (scene->update_stats) {
|
||||
|
@@ -189,8 +189,6 @@ class GeometryManager {
|
||||
GEOMETRY_ADDED = MESH_ADDED | HAIR_ADDED,
|
||||
GEOMETRY_REMOVED = MESH_REMOVED | HAIR_REMOVED,
|
||||
|
||||
TRANSFORM_MODIFIED = (1 << 10),
|
||||
|
||||
/* tag everything in the manager for an update */
|
||||
UPDATE_ALL = ~0u,
|
||||
|
||||
|
@@ -303,8 +303,7 @@ ImageManager::ImageManager(const DeviceInfo &info)
|
||||
animation_frame = 0;
|
||||
|
||||
/* Set image limits */
|
||||
features.has_half_float = info.has_half_images;
|
||||
features.has_nanovdb = info.has_nanovdb;
|
||||
has_half_images = info.has_half_images;
|
||||
}
|
||||
|
||||
ImageManager::~ImageManager()
|
||||
@@ -348,7 +347,7 @@ void ImageManager::load_image_metadata(Image *img)
|
||||
metadata = ImageMetaData();
|
||||
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);
|
||||
}
|
||||
else {
|
||||
@@ -357,10 +356,15 @@ void ImageManager::load_image_metadata(Image *img)
|
||||
|
||||
metadata.detect_colorspace();
|
||||
|
||||
assert(features.has_half_float ||
|
||||
(metadata.type != IMAGE_DATA_TYPE_HALF4 && metadata.type != IMAGE_DATA_TYPE_HALF));
|
||||
assert(features.has_nanovdb || (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT ||
|
||||
metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3));
|
||||
/* No half textures on OpenCL, use full float instead. */
|
||||
if (!has_half_images) {
|
||||
if (metadata.type == IMAGE_DATA_TYPE_HALF4) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT4;
|
||||
}
|
||||
else if (metadata.type == IMAGE_DATA_TYPE_HALF) {
|
||||
metadata.type = IMAGE_DATA_TYPE_FLOAT;
|
||||
}
|
||||
}
|
||||
|
||||
img->need_metadata = false;
|
||||
}
|
||||
|
@@ -97,13 +97,6 @@ class ImageMetaData {
|
||||
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
|
||||
* from custom sources (file, memory, procedurally generated, etc). */
|
||||
class ImageLoader {
|
||||
@@ -112,7 +105,7 @@ class ImageLoader {
|
||||
virtual ~ImageLoader(){};
|
||||
|
||||
/* 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. */
|
||||
virtual bool load_pixels(const ImageMetaData &metadata,
|
||||
@@ -219,8 +212,7 @@ class ImageManager {
|
||||
|
||||
private:
|
||||
bool need_update_;
|
||||
|
||||
ImageDeviceFeatures features;
|
||||
bool has_half_images;
|
||||
|
||||
thread_mutex device_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. */
|
||||
if (!path_exists(filepath.string())) {
|
||||
@@ -76,7 +76,7 @@ bool OIIOImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMe
|
||||
}
|
||||
|
||||
/* check if it's half float */
|
||||
if (spec.format == TypeDesc::HALF && features.has_half_float) {
|
||||
if (spec.format == TypeDesc::HALF) {
|
||||
is_half = true;
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,7 @@ class OIIOImageLoader : public ImageLoader {
|
||||
OIIOImageLoader(const string &filepath);
|
||||
~OIIOImageLoader();
|
||||
|
||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
||||
bool load_metadata(ImageMetaData &metadata) override;
|
||||
|
||||
bool load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
|
@@ -40,7 +40,7 @@ SkyLoader::SkyLoader(float sun_elevation,
|
||||
|
||||
SkyLoader::~SkyLoader(){};
|
||||
|
||||
bool SkyLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata)
|
||||
bool SkyLoader::load_metadata(ImageMetaData &metadata)
|
||||
{
|
||||
metadata.width = 512;
|
||||
metadata.height = 128;
|
||||
|
@@ -34,7 +34,7 @@ class SkyLoader : public ImageLoader {
|
||||
float ozone_density);
|
||||
~SkyLoader();
|
||||
|
||||
bool load_metadata(const ImageDeviceFeatures &features, ImageMetaData &metadata) override;
|
||||
bool load_metadata(ImageMetaData &metadata) override;
|
||||
|
||||
bool load_pixels(const ImageMetaData &metadata,
|
||||
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
|
||||
if (!grid) {
|
||||
@@ -56,71 +56,55 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
|
||||
if (grid->isType<openvdb::FloatGrid>()) {
|
||||
metadata.channels = 1;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::Vec3fGrid>()) {
|
||||
metadata.channels = 3;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(*openvdb::gridConstPtrCast<openvdb::Vec3fGrid>(grid));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::BoolGrid>()) {
|
||||
metadata.channels = 1;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::BoolGrid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::DoubleGrid>()) {
|
||||
metadata.channels = 1;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::DoubleGrid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::Int32Grid>()) {
|
||||
metadata.channels = 1;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int32Grid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::Int64Grid>()) {
|
||||
metadata.channels = 1;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::FloatGrid(*openvdb::gridConstPtrCast<openvdb::Int64Grid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::Vec3IGrid>()) {
|
||||
metadata.channels = 3;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3IGrid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::Vec3dGrid>()) {
|
||||
metadata.channels = 3;
|
||||
# ifdef WITH_NANOVDB
|
||||
if (features.has_nanovdb) {
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid)));
|
||||
}
|
||||
nanogrid = nanovdb::openToNanoVDB(
|
||||
openvdb::Vec3fGrid(*openvdb::gridConstPtrCast<openvdb::Vec3dGrid>(grid)));
|
||||
# endif
|
||||
}
|
||||
else if (grid->isType<openvdb::MaskGrid>()) {
|
||||
@@ -134,25 +118,21 @@ bool VDBImageLoader::load_metadata(const ImageDeviceFeatures &features, ImageMet
|
||||
}
|
||||
|
||||
# ifdef WITH_NANOVDB
|
||||
if (nanogrid) {
|
||||
metadata.byte_size = nanogrid.size();
|
||||
if (metadata.channels == 1) {
|
||||
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
|
||||
}
|
||||
else {
|
||||
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT3;
|
||||
}
|
||||
metadata.byte_size = nanogrid.size();
|
||||
if (metadata.channels == 1) {
|
||||
metadata.type = IMAGE_DATA_TYPE_NANOVDB_FLOAT;
|
||||
}
|
||||
else {
|
||||
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
|
||||
{
|
||||
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. */
|
||||
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
|
||||
if (nanogrid) {
|
||||
texture_to_index = transform_identity();
|
||||
}
|
||||
else
|
||||
Transform texture_to_index = transform_identity();
|
||||
# else
|
||||
openvdb::Coord min = bbox.min();
|
||||
Transform texture_to_index = transform_translate(min.x(), min.y(), min.z()) *
|
||||
transform_scale(dim.x(), dim.y(), dim.z());
|
||||
# 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.use_transform_3d = true;
|
||||
|
||||
# ifndef WITH_NANOVDB
|
||||
(void)features;
|
||||
# endif
|
||||
return true;
|
||||
#else
|
||||
(void)metadata;
|
||||
(void)features;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -194,52 +165,48 @@ bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size
|
||||
{
|
||||
#ifdef WITH_OPENVDB
|
||||
# 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
|
||||
{
|
||||
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;
|
||||
#else
|
||||
(void)pixels;
|
||||
|
@@ -33,8 +33,7 @@ class VDBImageLoader : public ImageLoader {
|
||||
VDBImageLoader(const string &grid_name);
|
||||
~VDBImageLoader();
|
||||
|
||||
virtual bool load_metadata(const ImageDeviceFeatures &features,
|
||||
ImageMetaData &metadata) override;
|
||||
virtual bool load_metadata(ImageMetaData &metadata) override;
|
||||
|
||||
virtual bool load_pixels(const ImageMetaData &metadata,
|
||||
void *pixels,
|
||||
|
@@ -129,7 +129,6 @@ NODE_DEFINE(Light)
|
||||
SOCKET_VECTOR(axisv, "Axis V", zero_float3());
|
||||
SOCKET_FLOAT(sizev, "Size V", 1.0f);
|
||||
SOCKET_BOOLEAN(round, "Round", false);
|
||||
SOCKET_FLOAT(spread, "Spread", M_PI_F);
|
||||
|
||||
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;
|
||||
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);
|
||||
|
||||
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[1] = dir.y;
|
||||
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) {
|
||||
shader_id &= ~SHADER_AREA_LIGHT;
|
||||
|
@@ -58,7 +58,6 @@ class Light : public Node {
|
||||
NODE_SOCKET_API(float3, axisv)
|
||||
NODE_SOCKET_API(float, sizev)
|
||||
NODE_SOCKET_API(bool, round)
|
||||
NODE_SOCKET_API(float, spread)
|
||||
|
||||
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("project", NODE_VECTOR_MATH_PROJECT);
|
||||
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("distance", NODE_VECTOR_MATH_DISTANCE);
|
||||
@@ -6154,24 +6151,24 @@ void VectorMathNode::compile(SVMCompiler &compiler)
|
||||
{
|
||||
ShaderInput *vector1_in = input("Vector1");
|
||||
ShaderInput *vector2_in = input("Vector2");
|
||||
ShaderInput *param1_in = input("Scale");
|
||||
ShaderInput *scale_in = input("Scale");
|
||||
ShaderOutput *value_out = output("Value");
|
||||
ShaderOutput *vector_out = output("Vector");
|
||||
|
||||
int vector1_stack_offset = compiler.stack_assign(vector1_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 vector_stack_offset = compiler.stack_assign_if_linked(vector_out);
|
||||
|
||||
/* 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");
|
||||
int vector3_stack_offset = compiler.stack_assign(vector3_in);
|
||||
compiler.add_node(
|
||||
NODE_VECTOR_MATH,
|
||||
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.add_node(vector3_stack_offset);
|
||||
}
|
||||
@@ -6179,7 +6176,7 @@ void VectorMathNode::compile(SVMCompiler &compiler)
|
||||
compiler.add_node(
|
||||
NODE_VECTOR_MATH,
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@@ -153,6 +153,10 @@ void Object::update_motion()
|
||||
|
||||
void Object::compute_bounds(bool motion_blur)
|
||||
{
|
||||
if (!is_modified() && !geometry->is_modified()) {
|
||||
return;
|
||||
}
|
||||
|
||||
BoundBox mbounds = geometry->bounds;
|
||||
|
||||
if (motion_blur && use_motion()) {
|
||||
@@ -217,7 +221,16 @@ void Object::tag_update(Scene *scene)
|
||||
|
||||
if (geometry) {
|
||||
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()) {
|
||||
@@ -910,10 +923,6 @@ void ObjectManager::tag_update(Scene *scene, uint32_t flag)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@@ -133,7 +133,6 @@ class ObjectManager {
|
||||
OBJECT_REMOVED = (1 << 4),
|
||||
OBJECT_MODIFIED = (1 << 5),
|
||||
HOLDOUT_MODIFIED = (1 << 6),
|
||||
TRANSFORM_MODIFIED = (1 << 7),
|
||||
|
||||
/* tag everything in the manager for an update */
|
||||
UPDATE_ALL = ~0u,
|
||||
|
@@ -179,7 +179,7 @@ void Scene::free_memory(bool final)
|
||||
|
||||
bake_manager->device_free(device, &dscene);
|
||||
|
||||
if (final)
|
||||
if (!params.persistent_data || final)
|
||||
image_manager->device_free(device);
|
||||
else
|
||||
image_manager->device_free_builtin(device);
|
||||
|
@@ -178,6 +178,7 @@ class SceneParams {
|
||||
int num_bvh_time_steps;
|
||||
int hair_subdivisions;
|
||||
CurveShapeType hair_shape;
|
||||
bool persistent_data;
|
||||
int texture_limit;
|
||||
|
||||
bool background;
|
||||
@@ -192,6 +193,7 @@ class SceneParams {
|
||||
num_bvh_time_steps = 0;
|
||||
hair_subdivisions = 3;
|
||||
hair_shape = CURVE_RIBBON;
|
||||
persistent_data = false;
|
||||
texture_limit = 0;
|
||||
background = true;
|
||||
}
|
||||
@@ -204,7 +206,7 @@ class SceneParams {
|
||||
use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes &&
|
||||
num_bvh_time_steps == params.num_bvh_time_steps &&
|
||||
hair_subdivisions == params.hair_subdivisions && hair_shape == params.hair_shape &&
|
||||
texture_limit == params.texture_limit);
|
||||
persistent_data == params.persistent_data && texture_limit == params.texture_limit);
|
||||
}
|
||||
|
||||
int curve_subdivisions()
|
||||
|
@@ -18,7 +18,6 @@
|
||||
|
||||
#define TEST_CATEGORY_NAME util_avx2
|
||||
|
||||
#if (defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && \
|
||||
defined(__AVX2__)
|
||||
#if defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
|
||||
# include "util_avxf_test.h"
|
||||
#endif
|
||||
|
@@ -18,7 +18,6 @@
|
||||
|
||||
#define TEST_CATEGORY_NAME util_avx
|
||||
|
||||
#if (defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)) && \
|
||||
defined(__AVX__)
|
||||
#if defined(i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
|
||||
# include "util_avxf_test.h"
|
||||
#endif
|
||||
|
@@ -788,7 +788,7 @@ ccl_device_inline float compare_floats(float a, float b, float abs_diff, int ulp
|
||||
}
|
||||
|
||||
/* Calculate the angle between the two vectors a and b.
|
||||
* The usual approach `acos(dot(a, b))` has severe precision issues for small angles,
|
||||
* The usual approach acos(dot(a, b)) has severe precision issues for small angles,
|
||||
* which are avoided by this method.
|
||||
* Based on "Mangled Angles" from https://people.eecs.berkeley.edu/~wkahan/Mindless.pdf
|
||||
*/
|
||||
|
@@ -388,22 +388,6 @@ ccl_device_inline float3 reflect(const float3 incident, const float3 normal)
|
||||
return incident - 2.0f * unit_normal * dot(incident, unit_normal);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 refract(const float3 incident, const float3 normal, const float eta)
|
||||
{
|
||||
float k = 1.0f - eta * eta * (1.0f - dot(normal, incident) * dot(normal, incident));
|
||||
if (k < 0.0f)
|
||||
return zero_float3();
|
||||
else
|
||||
return eta * incident - (eta * dot(normal, incident) + sqrt(k)) * normal;
|
||||
}
|
||||
|
||||
ccl_device_inline float3 faceforward(const float3 vector,
|
||||
const float3 incident,
|
||||
const float3 reference)
|
||||
{
|
||||
return (dot(reference, incident) < 0.0f) ? vector : -vector;
|
||||
}
|
||||
|
||||
ccl_device_inline float3 project(const float3 v, const float3 v_proj)
|
||||
{
|
||||
float len_squared = dot(v_proj, v_proj);
|
||||
|
@@ -178,8 +178,8 @@ DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dwAllowed)
|
||||
GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject *pDataObject)
|
||||
{
|
||||
/* Text
|
||||
* NOTE: Unicode text is available as CF_TEXT too, the system can do the
|
||||
* conversion, but we do the conversion our self with #WC_NO_BEST_FIT_CHARS.
|
||||
* Note: Unicode text is available as CF_TEXT too, the system can do the
|
||||
* conversion, but we do the conversion ourself with WC_NO_BEST_FIT_CHARS.
|
||||
*/
|
||||
FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
if (pDataObject->QueryGetData(&fmtetc) == S_OK) {
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user