Compare commits
297 Commits
temp-chunk
...
temp-chunk
Author | SHA1 | Date | |
---|---|---|---|
3da0b9e1b9 | |||
d696514283 | |||
![]() |
3ff15a9e23 | ||
![]() |
ce54f48556 | ||
![]() |
095516403c | ||
641bbc820f | |||
0bdb5239c1 | |||
4f284873d0 | |||
8c878ddd34 | |||
0950e6fae6 | |||
8934f00ac5 | |||
6069cab442 | |||
114815816b | |||
44272fdd23 | |||
d74c16ba81 | |||
57e4b6aefb | |||
f8a3ec48e4 | |||
06d85ad64b | |||
bdbf24772a | |||
742268c50b | |||
0621d162f0 | |||
dd0ef74887 | |||
172b0ebe6a | |||
![]() |
468f2ccc0e | ||
a4027658ee | |||
9dcce5be90 | |||
a1aafddcbe | |||
7549e0c5ae | |||
1810b1e4c8 | |||
b37954d03c | |||
34a6952067 | |||
d9930d5fd0 | |||
5f6f2e106c | |||
d4a763d363 | |||
e108d67635 | |||
9c35a5a524 | |||
8fdaf2bddc | |||
02575bcbd0 | |||
4cea4f4c5f | |||
3d93525069 | |||
9ca1abe042 | |||
4d67a995d9 | |||
7042f4e4b2 | |||
c8b9ede4b1 | |||
![]() |
44aaa9893b | ||
2eb19eeb19 | |||
bf05b998b6 | |||
![]() |
4b326d5a78 | ||
13c4af66fc | |||
95f05a6a4b | |||
48d7ff68f0 | |||
8bf0714d50 | |||
ac76da2944 | |||
15d85c54c3 | |||
a231637fae | |||
72253f427d | |||
d255c8e9f7 | |||
a8eeec7b35 | |||
427d669f62 | |||
8342564796 | |||
d5df23d758 | |||
0945ae338b | |||
8b26349d57 | |||
![]() |
9f76d0c8e6 | ||
f70fac6382 | |||
5228b0b74f | |||
335a6c0c87 | |||
5b216aae8b | |||
fbc74c9d93 | |||
f4e6616b83 | |||
c41249d436 | |||
![]() |
a869fcd686 | ||
903709c4eb | |||
![]() |
2310daed3a | ||
3eae1bfe35 | |||
5c4295ee6f | |||
5d69958442 | |||
718d545ff8 | |||
0e172e9732 | |||
2c53970bbf | |||
27e17fed28 | |||
4bbb043bc5 | |||
5cd08e373b | |||
f404dd0b3c | |||
b5115ed80f | |||
530f203e27 | |||
42fe0b6dfc | |||
6d4d74172b | |||
e22198b8d1 | |||
ee23f0f3fb | |||
![]() |
68589a31eb | ||
![]() |
23276bcc37 | ||
1a48548980 | |||
5f4db28c24 | |||
818c9e524d | |||
460fe4a10c | |||
390320a151 | |||
eb3a561a7f | |||
21ed3b3258 | |||
643e94c032 | |||
56fb2a5ed0 | |||
![]() |
22bf5ba4d1 | ||
![]() |
8aca0da952 | ||
![]() |
4e4daa6417 | ||
10a3bfa5ee | |||
a9250cb1f1 | |||
e4b925b9e2 | |||
38a77c1400 | |||
![]() |
609171d8b7 | ||
39c341bf4a | |||
260b75a952 | |||
d26220d97a | |||
7bd60d40ef | |||
f74fa63b5a | |||
![]() |
e1a9c16176 | ||
7518d30f2a | |||
3302b7e6a3 | |||
08a8de739d | |||
![]() |
eaf416693d | ||
d88811aed3 | |||
109cc14dba | |||
8442b0ffc1 | |||
![]() |
b6ebd5591c | ||
34051fcc12 | |||
![]() |
b404548972 | ||
92a92fdca5 | |||
a99a62231e | |||
3839a4dd84 | |||
62cee24003 | |||
3c2c296130 | |||
![]() |
8068b89a68 | ||
bb3a021427 | |||
a45c36efae | |||
8e03df9bbc | |||
602cca671e | |||
cca416cfe6 | |||
146e67b2bd | |||
d92e14af1f | |||
f78219c9a8 | |||
4130f1e674 | |||
4d69b6f525 | |||
75f9b691e2 | |||
5ffa829a0e | |||
060da0858b | |||
41212c1d44 | |||
9189260880 | |||
03885fe120 | |||
90fb212a93 | |||
1a08a26388 | |||
c05ff54795 | |||
400151833d | |||
50913d719c | |||
ddfce277e0 | |||
b3e9ef1924 | |||
ebcf004ecf | |||
2c73175100 | |||
28c9b33870 | |||
c8b6062d6c | |||
8851790dd7 | |||
ad245f1970 | |||
ea474dda62 | |||
5bad311f4c | |||
752a9b743e | |||
bc15c83afa | |||
100fe61f7c | |||
8af59cdb16 | |||
8f6a07bc75 | |||
2c1650ae8f | |||
b5f7af31d6 | |||
3d3c34f345 | |||
9951464571 | |||
54571003dc | |||
9088a1f476 | |||
225b5a3491 | |||
e37f3388b1 | |||
ce07bc3628 | |||
![]() |
7c33d7b4b5 | ||
038a19ce6c | |||
16af35054d | |||
ec2e866aee | |||
2d069b609b | |||
33abb68cf2 | |||
6d0f8d5a19 | |||
ebc385de5f | |||
94e211ced9 | |||
c9a8380426 | |||
f884a34cae | |||
cf9c0a4b50 | |||
caf6225a3d | |||
453b664b07 | |||
1f4dc51d09 | |||
8b8bfb29bc | |||
4ef140d7a3 | |||
8b612c6496 | |||
98c4e1e590 | |||
2c23b4e0bf | |||
325eee2261 | |||
0c3cd68f63 | |||
3a3673dc69 | |||
aa76699393 | |||
d64acada22 | |||
052b039a51 | |||
8cb3b49e51 | |||
489cb7fd7e | |||
c90fbbf75a | |||
66fab6828c | |||
c34b4d35ab | |||
9877d9e145 | |||
5a0447ca88 | |||
eae081f8fd | |||
ef3c49de81 | |||
099ae99589 | |||
6f44f03ad2 | |||
eac00ae370 | |||
352d55b1c8 | |||
f7da4141c4 | |||
7966fb083e | |||
dc91186a0b | |||
324d4f7a88 | |||
ded4604d71 | |||
1e1e9014cf | |||
8611c37f97 | |||
ef7c9e793e | |||
291c313f80 | |||
21f2bacad9 | |||
12c235a1c5 | |||
cef1b9c30f | |||
436f1b4dbe | |||
6039d15732 | |||
05f821b094 | |||
8f8ae06b51 | |||
f4e5a86544 | |||
03f33a6f23 | |||
0fd39da3a9 | |||
e254d8867d | |||
860c3dce1b | |||
04ae0fe46b | |||
1339fec22a | |||
f15fecf0f7 | |||
ac66a819c1 | |||
77a4bb02cc | |||
fa0f18b37d | |||
0817966f14 | |||
dc937c5aee | |||
58945b07f1 | |||
![]() |
3baca31719 | ||
1e6a003860 | |||
87a45db522 | |||
![]() |
43b1624eee | ||
fb07bbb751 | |||
274dc024f6 | |||
0c9749093b | |||
f7a4ede79f | |||
d455f1a0ba | |||
ce5ad66330 | |||
3a01c23a84 | |||
9e0c2f6867 | |||
22b84424c7 | |||
fad7a30de3 | |||
81558783e4 | |||
![]() |
4a71765f9a | ||
ff8cd48418 | |||
06a5741f42 | |||
e5a7470638 | |||
ff7bba8dad | |||
17f37b43f1 | |||
b9727dae82 | |||
59f6c60fb6 | |||
7eda9d8dda | |||
8f6a38ed7e | |||
406243c2fd | |||
462014b59b | |||
4ac69c26db | |||
173d8edb0b | |||
b5fc8f611e | |||
2a769e76a0 | |||
21b92a5f31 | |||
d481fb10ef | |||
5e2d139ee3 | |||
82fc52ffc8 | |||
129993c026 | |||
268e1eff8a | |||
ecf3287533 | |||
a3ddcc6b4d | |||
8a9d1f19ab | |||
9f50bd20eb | |||
d593497421 | |||
17bc292530 | |||
c2c369ebe6 | |||
c36c403cdb | |||
0a32f6b76a | |||
e53405bf15 | |||
67dcdebb3a | |||
715d185dcd | |||
da0c3cdbc9 | |||
0759f671ce | |||
64b10c43c4 |
@@ -273,5 +273,5 @@ StatementMacros:
|
||||
- PyObject_VAR_HEAD
|
||||
- ccl_gpu_kernel_postfix
|
||||
|
||||
MacroBlockBegin: "^BSDF_CLOSURE_CLASS_BEGIN$"
|
||||
MacroBlockEnd: "^BSDF_CLOSURE_CLASS_END$"
|
||||
MacroBlockBegin: "^OSL_CLOSURE_STRUCT_BEGIN$"
|
||||
MacroBlockEnd: "^OSL_CLOSURE_STRUCT_END$"
|
||||
|
211
CMakeLists.txt
211
CMakeLists.txt
@@ -1,11 +1,12 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# We don't allow in-source builds. This causes no end of troubles because
|
||||
# -----------------------------------------------------------------------------
|
||||
# Early Initialization
|
||||
|
||||
# NOTE: We don't allow in-source builds. This causes no end of troubles because
|
||||
# all out-of-source builds will use the CMakeCache.txt file there and even
|
||||
# build the libs and objects in it.
|
||||
|
||||
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
|
||||
if(NOT DEFINED WITH_IN_SOURCE_BUILD)
|
||||
message(FATAL_ERROR
|
||||
@@ -35,7 +36,7 @@ endif()
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/Modules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/build_files/cmake/platform")
|
||||
|
||||
# avoid having empty buildtype
|
||||
# Avoid having an empty `CMAKE_BUILD_TYPE`.
|
||||
if(NOT DEFINED CMAKE_BUILD_TYPE_INIT)
|
||||
set(CMAKE_BUILD_TYPE_INIT "Release")
|
||||
# Internal logic caches this variable, avoid showing it by default
|
||||
@@ -59,7 +60,8 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
|
||||
$<$<CONFIG:RelWithDebInfo>:NDEBUG>
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Set policy
|
||||
|
||||
# see "cmake --help-policy CMP0003"
|
||||
@@ -89,13 +91,16 @@ endif()
|
||||
if(POLICY CMP0087)
|
||||
cmake_policy(SET CMP0087 NEW)
|
||||
endif()
|
||||
#-----------------------------------------------------------------------------
|
||||
# Load some macros.
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Load Blender's Local Macros
|
||||
|
||||
include(build_files/cmake/macros.cmake)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Initialize project.
|
||||
# -----------------------------------------------------------------------------
|
||||
# Initialize Project
|
||||
|
||||
blender_project_hack_pre()
|
||||
|
||||
@@ -105,14 +110,15 @@ blender_project_hack_post()
|
||||
|
||||
enable_testing()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test compiler/library features.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Test Compiler/Library Features
|
||||
|
||||
include(build_files/cmake/have_features.cmake)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Redirect output files
|
||||
# -----------------------------------------------------------------------------
|
||||
# Redirect Output Files
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin CACHE INTERNAL "" FORCE)
|
||||
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib CACHE INTERNAL "" FORCE)
|
||||
@@ -124,14 +130,15 @@ else()
|
||||
set(TESTS_OUTPUT_DIR ${EXECUTABLE_OUTPUT_PATH}/tests/ CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Set default config options
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Set Default Configuration Options
|
||||
|
||||
get_blender_version()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Options
|
||||
# -----------------------------------------------------------------------------
|
||||
# Declare Options
|
||||
|
||||
# Blender internal features
|
||||
option(WITH_BLENDER "Build blender (disable to build only the blender player)" ON)
|
||||
@@ -157,9 +164,6 @@ mark_as_advanced(WITH_PYTHON_SECURITY) # some distributions see this as a secur
|
||||
option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some efficiency, only enable for development)." OFF)
|
||||
mark_as_advanced(WITH_PYTHON_SAFETY)
|
||||
option(WITH_PYTHON_MODULE "Enable building as a python module which runs without a user interface, like running regular blender in background mode (experimental, only enable for development), installs to PYTHON_SITE_PACKAGES (or CMAKE_INSTALL_PREFIX if WITH_INSTALL_PORTABLE is enabled)." OFF)
|
||||
if(APPLE)
|
||||
option(WITH_PYTHON_FRAMEWORK "Enable building using the Python available in the framework (OSX only)" OFF)
|
||||
endif()
|
||||
|
||||
option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
|
||||
set(BUILDINFO_OVERRIDE_DATE "" CACHE STRING "Use instead of the current date for reproducible builds (empty string disables this option)")
|
||||
@@ -753,8 +757,8 @@ if(APPLE)
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Check for conflicting/unsupported configurations
|
||||
# -----------------------------------------------------------------------------
|
||||
# Check for Conflicting/Unsupported Configurations
|
||||
|
||||
if(NOT WITH_BLENDER AND NOT WITH_CYCLES_STANDALONE AND NOT WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
message(FATAL_ERROR
|
||||
@@ -888,7 +892,11 @@ endif()
|
||||
if(WITH_CYCLES AND WITH_CYCLES_DEVICE_CUDA AND 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(
|
||||
STATUS
|
||||
"CUDA toolkit not found, "
|
||||
"using dynamic runtime loading of libraries (WITH_CUDA_DYNLOAD) instead"
|
||||
)
|
||||
set(WITH_CUDA_DYNLOAD ON)
|
||||
endif()
|
||||
endif()
|
||||
@@ -898,14 +906,16 @@ if(WITH_CYCLES_DEVICE_HIP)
|
||||
set(WITH_HIP_DYNLOAD ON)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Check if submodules are cloned.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Check if Sub-modules are Cloned
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/datafiles/locale")
|
||||
list(LENGTH RESULT DIR_LEN)
|
||||
if(DIR_LEN EQUAL 0)
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"Translation path '${CMAKE_SOURCE_DIR}/release/datafiles/locale' is missing, "
|
||||
"This is a 'git submodule', which are known not to work with bridges to other version "
|
||||
"control systems, disabling 'WITH_INTERNATIONAL'."
|
||||
@@ -923,13 +933,17 @@ if(WITH_PYTHON)
|
||||
# because UNIX will search for the old Python paths which may not exist.
|
||||
# giving errors about missing paths before this case is met.
|
||||
if(DEFINED PYTHON_VERSION AND "${PYTHON_VERSION}" VERSION_LESS "3.10")
|
||||
message(FATAL_ERROR "At least Python 3.10 is required to build, but found Python ${PYTHON_VERSION}")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"At least Python 3.10 is required to build, but found Python ${PYTHON_VERSION}"
|
||||
)
|
||||
endif()
|
||||
|
||||
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons")
|
||||
list(LENGTH RESULT DIR_LEN)
|
||||
if(DIR_LEN EQUAL 0)
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"Addons path '${CMAKE_SOURCE_DIR}/release/scripts/addons' is missing, "
|
||||
"This is a 'git submodule', which are known not to work with bridges to other version "
|
||||
"control systems: * CONTINUING WITHOUT ADDONS *"
|
||||
@@ -937,8 +951,9 @@ if(WITH_PYTHON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Initialize un-cached vars, avoid unused warning
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# InitialIze Un-cached Vars, Avoid Unused Warning
|
||||
|
||||
# linux only, not cached
|
||||
set(WITH_BINRELOC OFF)
|
||||
@@ -1013,6 +1028,7 @@ if(WITH_CPU_SIMD)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Main Platform Checks
|
||||
#
|
||||
@@ -1028,8 +1044,9 @@ elseif(APPLE)
|
||||
include(platform_apple)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Common.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Common Checks for Compatible Options
|
||||
|
||||
if(NOT WITH_FFTW3 AND WITH_MOD_OCEANSIM)
|
||||
message(FATAL_ERROR "WITH_MOD_OCEANSIM requires WITH_FFTW3 to be ON")
|
||||
@@ -1037,13 +1054,15 @@ endif()
|
||||
|
||||
if(WITH_CYCLES)
|
||||
if(NOT WITH_OPENIMAGEIO)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles requires WITH_OPENIMAGEIO, the library may not have been found. "
|
||||
"Configure OIIO or disable WITH_CYCLES"
|
||||
)
|
||||
endif()
|
||||
if(NOT WITH_BOOST)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles requires WITH_BOOST, the library may not have been found. "
|
||||
"Configure BOOST or disable WITH_CYCLES"
|
||||
)
|
||||
@@ -1051,7 +1070,8 @@ if(WITH_CYCLES)
|
||||
|
||||
if(WITH_CYCLES_OSL)
|
||||
if(NOT WITH_LLVM)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles OSL requires WITH_LLVM, the library may not have been found. "
|
||||
"Configure LLVM or disable WITH_CYCLES_OSL"
|
||||
)
|
||||
@@ -1061,7 +1081,8 @@ endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
if(NOT WITH_BOOST)
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Internationalization requires WITH_BOOST, the library may not have been found. "
|
||||
"Configure BOOST or disable WITH_INTERNATIONAL"
|
||||
)
|
||||
@@ -1175,15 +1196,18 @@ if(WITH_OPENVDB)
|
||||
list(APPEND OPENVDB_LIBRARIES ${BOOST_LIBRARIES} ${TBB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenGL.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure OpenGL
|
||||
|
||||
if(WITH_OPENGL)
|
||||
add_definitions(-DWITH_OPENGL)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Metal.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure Metal
|
||||
|
||||
if(WITH_METAL_BACKEND)
|
||||
add_definitions(-DWITH_METAL_BACKEND)
|
||||
|
||||
@@ -1192,8 +1216,10 @@ if(WITH_METAL_BACKEND)
|
||||
# build_files/cmake/platform/platform_apple.cmake
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenMP.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure OpenMP
|
||||
|
||||
if(WITH_OPENMP)
|
||||
if(NOT OPENMP_CUSTOM)
|
||||
find_package(OpenMP)
|
||||
@@ -1225,7 +1251,8 @@ if(WITH_OPENMP)
|
||||
)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure Bullet
|
||||
|
||||
if(WITH_BULLET AND WITH_SYSTEM_BULLET)
|
||||
@@ -1239,15 +1266,17 @@ else()
|
||||
# set(BULLET_LIBRARIES "")
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Python.
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure Python
|
||||
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_definitions(-DPy_ENABLE_SHARED)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure GLog/GFlags
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure `GLog/GFlags`
|
||||
|
||||
if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
|
||||
if(WITH_SYSTEM_GFLAGS)
|
||||
@@ -1255,7 +1284,7 @@ if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
|
||||
if(NOT GFLAGS_FOUND)
|
||||
message(FATAL_ERROR "System wide Gflags is requested but was not found")
|
||||
endif()
|
||||
# FindGflags does not define this, and we are not even sure what to use here.
|
||||
# `FindGflags` does not define this, and we are not even sure what to use here.
|
||||
set(GFLAGS_DEFINES)
|
||||
else()
|
||||
set(GFLAGS_DEFINES
|
||||
@@ -1273,7 +1302,7 @@ if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
|
||||
if(NOT GLOG_FOUND)
|
||||
message(FATAL_ERROR "System wide Glog is requested but was not found")
|
||||
endif()
|
||||
# FindGlog does not define this, and we are not even sure what to use here.
|
||||
# `FindGlog` does not define this, and we are not even sure what to use here.
|
||||
set(GLOG_DEFINES)
|
||||
else()
|
||||
set(GLOG_DEFINES
|
||||
@@ -1288,9 +1317,13 @@ if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Ninja Job Limiting
|
||||
|
||||
# Extra limits to number of jobs running in parallel for some kind os tasks.
|
||||
# Only supported by Ninja build system currently.
|
||||
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
|
||||
if(NOT NINJA_MAX_NUM_PARALLEL_COMPILE_JOBS AND
|
||||
NOT NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS AND
|
||||
@@ -1302,7 +1335,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
|
||||
# Note: this gives mem in MB.
|
||||
cmake_host_system_information(RESULT _TOT_MEM QUERY TOTAL_PHYSICAL_MEMORY)
|
||||
|
||||
# Heuristics... the more cores we have, the more free mem we have to keep for the non-heavy tasks too.
|
||||
# Heuristics: the more cores we have, the more free memory we have to keep
|
||||
# for the non-heavy tasks too.
|
||||
if(${_TOT_MEM} LESS 8000 AND ${_NUM_CORES} GREATER 2)
|
||||
set(_compile_heavy_jobs "1")
|
||||
elseif(${_TOT_MEM} LESS 16000 AND ${_NUM_CORES} GREATER 4)
|
||||
@@ -1322,7 +1356,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
|
||||
mark_as_advanced(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
|
||||
set(_compile_heavy_jobs)
|
||||
|
||||
# Only set regular compile jobs if we set heavy jobs, otherwise default (using all cores) if fine.
|
||||
# Only set regular compile jobs if we set heavy jobs,
|
||||
# otherwise default (using all cores) if fine.
|
||||
if(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
|
||||
math(EXPR _compile_jobs "${_NUM_CORES} - 1")
|
||||
else()
|
||||
@@ -1333,8 +1368,8 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
|
||||
mark_as_advanced(NINJA_MAX_NUM_PARALLEL_COMPILE_JOBS)
|
||||
set(_compile_jobs)
|
||||
|
||||
# In practice, even when there is RAM available, this proves to be quicker than running in parallel
|
||||
# (due to slow disks accesses).
|
||||
# In practice, even when there is RAM available,
|
||||
# this proves to be quicker than running in parallel (due to slow disks accesses).
|
||||
set(NINJA_MAX_NUM_PARALLEL_LINK_JOBS "1" CACHE STRING
|
||||
"Define the maximum number of concurrent link jobs, for ninja build system." FORCE)
|
||||
mark_as_advanced(NINJA_MAX_NUM_PARALLEL_LINK_JOBS)
|
||||
@@ -1358,8 +1393,9 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Extra compile flags
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Extra Compile Flags
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
@@ -1449,7 +1485,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
endif()
|
||||
|
||||
|
||||
#----------------------
|
||||
# ---------------------
|
||||
# Suppress Strict Flags
|
||||
#
|
||||
# Exclude the following warnings from this list:
|
||||
@@ -1515,7 +1551,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
|
||||
#----------------------
|
||||
# ---------------------
|
||||
# Suppress Strict Flags
|
||||
|
||||
# flags to undo strict flags
|
||||
@@ -1606,7 +1642,8 @@ endif()
|
||||
# be most problematic.
|
||||
if(WITH_PYTHON)
|
||||
if(NOT EXISTS "${PYTHON_INCLUDE_DIR}/Python.h")
|
||||
message(FATAL_ERROR
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Missing: \"${PYTHON_INCLUDE_DIR}/Python.h\",\n"
|
||||
"Set the cache entry 'PYTHON_INCLUDE_DIR' to point "
|
||||
"to a valid python include path. Containing "
|
||||
@@ -1614,8 +1651,8 @@ if(WITH_PYTHON)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR APPLE)
|
||||
# Windows and macOS have this bundled with Python libraries.
|
||||
if(WIN32)
|
||||
# Always use numpy bundled in precompiled libs.
|
||||
elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR WITH_PYTHON_NUMPY)
|
||||
if(("${PYTHON_NUMPY_PATH}" STREQUAL "") OR (${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
|
||||
find_python_package(numpy "core/include")
|
||||
@@ -1623,13 +1660,13 @@ if(WITH_PYTHON)
|
||||
endif()
|
||||
|
||||
if(WIN32 OR APPLE)
|
||||
# pass, we have this in lib/python/site-packages
|
||||
# Always copy from precompiled libs.
|
||||
elseif(WITH_PYTHON_INSTALL_REQUESTS)
|
||||
find_python_package(requests "")
|
||||
endif()
|
||||
|
||||
if(WIN32 OR APPLE)
|
||||
# pass, we have this in lib/python/site-packages
|
||||
# Always copy from precompiled libs.
|
||||
elseif(WITH_PYTHON_INSTALL_ZSTANDARD)
|
||||
find_python_package(zstandard "")
|
||||
endif()
|
||||
@@ -1675,9 +1712,11 @@ if(WITH_COMPILER_SHORT_FILE_MACRO)
|
||||
if(XCODE AND ${XCODE_VERSION} VERSION_LESS 12.0)
|
||||
# Developers may have say LLVM Clang-10.0.1 toolchain (which supports the flag)
|
||||
# with Xcode-11 (the Clang of which doesn't support the flag).
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"-fmacro-prefix-map flag is NOT supported by Clang shipped with Xcode-${XCODE_VERSION}."
|
||||
" Some Xcode functionality in Product menu may not work. Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
" Some Xcode functionality in Product menu may not work. "
|
||||
"Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
)
|
||||
set(WITH_COMPILER_SHORT_FILE_MACRO OFF)
|
||||
endif()
|
||||
@@ -1693,7 +1732,8 @@ if(WITH_COMPILER_SHORT_FILE_MACRO)
|
||||
unset(_bin_dir)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING
|
||||
message(
|
||||
WARNING
|
||||
"-fmacro-prefix-map flag is NOT supported by C/C++ compiler."
|
||||
" Disabling WITH_COMPILER_SHORT_FILE_MACRO."
|
||||
)
|
||||
@@ -1723,7 +1763,8 @@ mark_as_advanced(
|
||||
LLVM_VERSION
|
||||
)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# -------------------------------------------------------------------------------
|
||||
# Global Defines
|
||||
|
||||
# better not set includes here but this debugging option is off by default.
|
||||
@@ -1739,8 +1780,9 @@ endif()
|
||||
# message(STATUS "Using CFLAGS: ${CMAKE_C_FLAGS}")
|
||||
# message(STATUS "Using CXXFLAGS: ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Libraries
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Add Sub-Directories
|
||||
|
||||
if(WITH_BLENDER)
|
||||
add_subdirectory(intern)
|
||||
@@ -1769,33 +1811,41 @@ elseif(WITH_CYCLES_STANDALONE OR WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Testing
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Add Testing Directory
|
||||
|
||||
add_subdirectory(tests)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Blender Application
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Add Blender Application
|
||||
|
||||
if(WITH_BLENDER)
|
||||
add_subdirectory(source/creator)
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define 'heavy' submodules (for Ninja builder when using pools).
|
||||
# -----------------------------------------------------------------------------
|
||||
# Define 'heavy' sub-modules (for Ninja builder when using pools)
|
||||
setup_heavy_lib_pool()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
# CPack for generating packages
|
||||
|
||||
include(build_files/cmake/packaging.cmake)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Use dynamic loading for OpenMP
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Use Dynamic Loading for OpenMP
|
||||
|
||||
if(WITH_BLENDER)
|
||||
openmp_delayload(blender)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Print Final Configuration
|
||||
|
||||
if(FIRST_RUN)
|
||||
@@ -1891,9 +1941,6 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_LZO)
|
||||
|
||||
info_cfg_text("Python:")
|
||||
if(APPLE)
|
||||
info_cfg_option(WITH_PYTHON_FRAMEWORK)
|
||||
endif()
|
||||
info_cfg_option(WITH_PYTHON_INSTALL)
|
||||
info_cfg_option(WITH_PYTHON_INSTALL_NUMPY)
|
||||
info_cfg_option(WITH_PYTHON_INSTALL_ZSTANDARD)
|
||||
|
28
GNUmakefile
28
GNUmakefile
@@ -162,6 +162,7 @@ CPU:=$(shell uname -m)
|
||||
# Source and Build DIR's
|
||||
BLENDER_DIR:=$(shell pwd -P)
|
||||
BUILD_TYPE:=Release
|
||||
BLENDER_IS_PYTHON_MODULE:=
|
||||
|
||||
# CMake arguments, assigned to local variable to make it mutable.
|
||||
CMAKE_CONFIG_ARGS := $(BUILD_CMAKE_ARGS)
|
||||
@@ -229,9 +230,18 @@ endif
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# additional targets for the build configuration
|
||||
# Additional targets for the build configuration
|
||||
|
||||
# support 'make debug'
|
||||
# NOTE: These targets can be combined and are applied in reverse order listed here.
|
||||
# So it's important that `bpy` comes before `release` (for example)
|
||||
# `make bpy release` first loads `release` configuration, then `bpy`.
|
||||
# This is important as `bpy` will turn off some settings enabled by release.
|
||||
|
||||
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
BLENDER_IS_PYTHON_MODULE:=1
|
||||
endif
|
||||
ifneq "$(findstring debug, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_debug
|
||||
BUILD_TYPE:=Debug
|
||||
@@ -256,10 +266,6 @@ ifneq "$(findstring headless, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_headless
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
|
||||
ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
@@ -297,8 +303,10 @@ endif
|
||||
# use the default build path can still use utility helpers.
|
||||
ifeq ($(OS), Darwin)
|
||||
BLENDER_BIN?="$(BUILD_DIR)/bin/Blender.app/Contents/MacOS/Blender"
|
||||
BLENDER_BIN_DIR?="$(BUILD_DIR)/bin/Blender.app/Contents/MacOS/Blender"
|
||||
else
|
||||
BLENDER_BIN?="$(BUILD_DIR)/bin/blender"
|
||||
BLENDER_BIN_DIR?="$(BUILD_DIR)/bin"
|
||||
endif
|
||||
|
||||
|
||||
@@ -355,8 +363,12 @@ all: .FORCE
|
||||
@echo Building Blender ...
|
||||
$(BUILD_COMMAND) -C "$(BUILD_DIR)" -j $(NPROCS) install
|
||||
@echo
|
||||
@echo edit build configuration with: "$(BUILD_DIR)/CMakeCache.txt" run make again to rebuild.
|
||||
@echo Blender successfully built, run from: $(BLENDER_BIN)
|
||||
@echo Edit build configuration with: \"$(BUILD_DIR)/CMakeCache.txt\" run make again to rebuild.
|
||||
@if test "$(BLENDER_IS_PYTHON_MODULE)" == ""; then \
|
||||
echo Blender successfully built, run from: $(BLENDER_BIN); \
|
||||
else \
|
||||
echo Blender successfully built as a Python module, \"bpy\" can be imported from: $(BLENDER_BIN_DIR); \
|
||||
fi
|
||||
@echo
|
||||
|
||||
debug: all
|
||||
|
@@ -136,7 +136,7 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
|
||||
Build and install the OpenImageDenoise libraries.
|
||||
|
||||
--with-nanovdb
|
||||
Build and install the NanoVDB branch of OpenVDB (instead of official release of OpenVDB).
|
||||
Build and install NanoVDB together with OpenVDB.
|
||||
|
||||
--with-jack
|
||||
Install the jack libraries.
|
||||
@@ -385,7 +385,7 @@ CLANG_FORMAT_VERSION="10.0"
|
||||
CLANG_FORMAT_VERSION_MIN="6.0"
|
||||
CLANG_FORMAT_VERSION_MEX="14.0"
|
||||
|
||||
PYTHON_VERSION="3.10.2"
|
||||
PYTHON_VERSION="3.10.6"
|
||||
PYTHON_VERSION_SHORT="3.10"
|
||||
PYTHON_VERSION_MIN="3.10"
|
||||
PYTHON_VERSION_MEX="3.12"
|
||||
@@ -425,7 +425,7 @@ PYTHON_ZSTANDARD_VERSION_MIN="0.15.2"
|
||||
PYTHON_ZSTANDARD_VERSION_MEX="0.20.0"
|
||||
PYTHON_ZSTANDARD_NAME="zstandard"
|
||||
|
||||
PYTHON_NUMPY_VERSION="1.22.0"
|
||||
PYTHON_NUMPY_VERSION="1.23.2"
|
||||
PYTHON_NUMPY_VERSION_MIN="1.14"
|
||||
PYTHON_NUMPY_VERSION_MEX="2.0"
|
||||
PYTHON_NUMPY_NAME="numpy"
|
||||
@@ -453,8 +453,8 @@ PYTHON_MODULES_PIP=(
|
||||
)
|
||||
|
||||
|
||||
BOOST_VERSION="1.78.0"
|
||||
BOOST_VERSION_SHORT="1.78"
|
||||
BOOST_VERSION="1.80.0"
|
||||
BOOST_VERSION_SHORT="1.80"
|
||||
BOOST_VERSION_MIN="1.49"
|
||||
BOOST_VERSION_MEX="2.0"
|
||||
BOOST_FORCE_BUILD=false
|
||||
@@ -496,7 +496,7 @@ OPENEXR_FORCE_REBUILD=false
|
||||
OPENEXR_SKIP=false
|
||||
_with_built_openexr=false
|
||||
|
||||
OIIO_VERSION="2.3.13.0"
|
||||
OIIO_VERSION="2.3.18.0"
|
||||
OIIO_VERSION_SHORT="2.3"
|
||||
OIIO_VERSION_MIN="2.1.12"
|
||||
OIIO_VERSION_MEX="2.4.0"
|
||||
@@ -534,10 +534,10 @@ OSD_SKIP=false
|
||||
# OpenVDB needs to be compiled for now
|
||||
OPENVDB_BLOSC_VERSION="1.21.1"
|
||||
|
||||
OPENVDB_VERSION="9.0.0"
|
||||
OPENVDB_VERSION_SHORT="9.0"
|
||||
OPENVDB_VERSION="9.1.0"
|
||||
OPENVDB_VERSION_SHORT="9.1"
|
||||
OPENVDB_VERSION_MIN="9.0"
|
||||
OPENVDB_VERSION_MEX="9.1"
|
||||
OPENVDB_VERSION_MEX="9.2"
|
||||
OPENVDB_FORCE_BUILD=false
|
||||
OPENVDB_FORCE_REBUILD=false
|
||||
OPENVDB_SKIP=false
|
||||
@@ -2919,6 +2919,10 @@ compile_OPENVDB() {
|
||||
cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst"
|
||||
cmake_d="$cmake_d -D USE_STATIC_DEPENDENCIES=OFF"
|
||||
cmake_d="$cmake_d -D OPENVDB_BUILD_BINARIES=OFF"
|
||||
# Unfortunately OpenVDB currently forces using recent oneTBB over older versions when it finds it,
|
||||
# even when TBB_ROOT is specified. So have to prevent any check for system library -
|
||||
# in the hope it will not break in some other cases.
|
||||
cmake_d="$cmake_d -D DISABLE_CMAKE_SEARCH_PATHS=ON"
|
||||
|
||||
if [ "$WITH_NANOVDB" = true ]; then
|
||||
cmake_d="$cmake_d -D USE_NANOVDB=ON"
|
||||
@@ -2931,7 +2935,6 @@ compile_OPENVDB() {
|
||||
cmake_d="$cmake_d -D Boost_USE_MULTITHREADED=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_SYSTEM_PATHS=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
|
||||
cmake_d="$cmake_d -D Boost_NO_BOOST_CMAKE=ON"
|
||||
fi
|
||||
if [ -d $INST/tbb ]; then
|
||||
cmake_d="$cmake_d -D TBB_ROOT=$INST/tbb"
|
||||
@@ -3195,7 +3198,7 @@ _init_opencollada() {
|
||||
_inst_shortcut=$INST/opencollada
|
||||
}
|
||||
|
||||
_update_deps_collada() {
|
||||
_update_deps_opencollada() {
|
||||
:
|
||||
}
|
||||
|
||||
@@ -6215,7 +6218,7 @@ print_info() {
|
||||
fi
|
||||
if [ -d $INST/nanovdb ]; then
|
||||
_1="-D WITH_NANOVDB=ON"
|
||||
_2="-D NANOVDB_ROOT_DIR=$INST/nanovdb"
|
||||
_2="-D NANOVDB_ROOT_DIR=$INST/openvdb"
|
||||
PRINT " $_1"
|
||||
PRINT " $_2"
|
||||
_buildargs="$_buildargs $_1 $_2"
|
||||
|
@@ -34,11 +34,17 @@ SET(PYTHON_VERSION 3.10 CACHE STRING "Python Version (major and minor only)")
|
||||
MARK_AS_ADVANCED(PYTHON_VERSION)
|
||||
|
||||
|
||||
# See: http://docs.python.org/extending/embedding.html#linking-requirements
|
||||
# for why this is needed
|
||||
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for python")
|
||||
MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
|
||||
|
||||
if(APPLE)
|
||||
if(WITH_PYTHON_MODULE)
|
||||
set(PYTHON_LINKFLAGS "-undefined dynamic_lookup")
|
||||
else()
|
||||
set(PYTHON_LINKFLAGS)
|
||||
endif()
|
||||
else()
|
||||
# See: http://docs.python.org/extending/embedding.html#linking-requirements
|
||||
SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for python")
|
||||
MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
|
||||
endif()
|
||||
|
||||
# if the user passes these defines as args, we don't want to overwrite
|
||||
SET(_IS_INC_DEF OFF)
|
||||
|
@@ -268,7 +268,8 @@ same as the Google Test name (i.e. ``suite.testcase``); see also
|
||||
cmake_policy(PUSH)
|
||||
cmake_policy(SET CMP0057 NEW) # if IN_LIST
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
function(gtest_add_tests)
|
||||
|
||||
if(ARGC LESS 1)
|
||||
|
@@ -7,8 +7,6 @@
|
||||
# cmake -C../blender/build_files/cmake/config/blender_lite.cmake ../blender
|
||||
#
|
||||
|
||||
set(WITH_INSTALL_PORTABLE ON CACHE BOOL "" FORCE)
|
||||
|
||||
set(WITH_ALEMBIC OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_AUDASPACE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_BLENDER_THUMBNAILER OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -8,41 +8,81 @@
|
||||
|
||||
set(WITH_PYTHON_MODULE ON CACHE BOOL "" FORCE)
|
||||
|
||||
# install into the systems python dir
|
||||
set(WITH_INSTALL_PORTABLE OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# no point int copying python into python
|
||||
# -----------------------------------------------------------------------------
|
||||
# Installation Configuration.
|
||||
#
|
||||
# NOTE: `WITH_INSTALL_PORTABLE` always defaults to ON when building as a Python module and
|
||||
# isn't set here as it makes changing the setting impractical.
|
||||
# Python-developers could prefer either ON/OFF depending on their usage:
|
||||
#
|
||||
# - When using the system's Python, disabling will install into their `site-packages`,
|
||||
# allowing them to run Python from any directory and `import bpy`.
|
||||
# - When using Blender's bundled Python in `./../lib/` it will install there
|
||||
# which isn't especially useful as it requires running Python from this directory too.
|
||||
#
|
||||
# So default `WITH_INSTALL_PORTABLE` to ON, and developers who don't use Python from `./../lib/`
|
||||
# can disable it if they wish to install into their systems Python.
|
||||
|
||||
# There is no point in copying python into Python.
|
||||
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_WASAPI 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)
|
||||
|
||||
# Depends on Python install, do this to quiet warning.
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
|
||||
# Jemalloc does not work with dlopen() of Python modules:
|
||||
# https://github.com/jemalloc/jemalloc/issues/1237
|
||||
set(WITH_MEM_JEMALLOC OFF CACHE BOOL "" FORCE)
|
||||
|
||||
if(WIN32)
|
||||
set(WITH_WINDOWS_BUNDLE_CRT OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Library Compatibility.
|
||||
|
||||
# JEMALLOC does not work with `dlopen()` of Python modules:
|
||||
# https://github.com/jemalloc/jemalloc/issues/1237
|
||||
set(WITH_MEM_JEMALLOC OFF CACHE BOOL "" FORCE)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Application Support.
|
||||
|
||||
# Not useful to include with the Python module.
|
||||
# Although a way to extract this from Python could be handle,
|
||||
# this would be better exposed directly via the Python API.
|
||||
set(WITH_BLENDER_THUMBNAILER OFF CACHE BOOL "" FORCE)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Audio Support.
|
||||
|
||||
# Disable audio, its possible some developers 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_JACK OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENAL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_SDL OFF CACHE BOOL "" FORCE)
|
||||
if(UNIX AND NOT APPLE)
|
||||
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(WIN32)
|
||||
set(WITH_WASAPI OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Input Device Support.
|
||||
|
||||
# Other features which are not especially useful as a python module.
|
||||
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
|
||||
if(WIN32 OR APPLE)
|
||||
set(WITH_INPUT_IME OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Language Support.
|
||||
|
||||
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -418,6 +418,13 @@ function(blender_add_test_lib
|
||||
library_deps
|
||||
)
|
||||
|
||||
# Not currently supported for Python module due to different required
|
||||
# Python link flags.
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_custom_target(${name})
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_cc_flags_custom_test(${name} PARENT_SCOPE)
|
||||
|
||||
# Otherwise external projects will produce warnings that we cannot fix.
|
||||
@@ -464,6 +471,13 @@ function(blender_add_test_executable
|
||||
library_deps
|
||||
)
|
||||
|
||||
# Not currently supported for Python module due to different required
|
||||
# Python link flags.
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_custom_target(${name})
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_cc_flags_custom_test(${name} PARENT_SCOPE)
|
||||
|
||||
## Otherwise external projects will produce warnings that we cannot fix.
|
||||
@@ -1208,16 +1222,8 @@ endmacro()
|
||||
|
||||
macro(without_system_libs_begin)
|
||||
set(CMAKE_IGNORE_PATH "${CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES};${CMAKE_SYSTEM_INCLUDE_PATH};${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES};${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}")
|
||||
if(APPLE)
|
||||
# Avoid searching for headers in frameworks (like Mono), and libraries in LIBDIR.
|
||||
set(CMAKE_FIND_FRAMEWORK NEVER)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(without_system_libs_end)
|
||||
unset(CMAKE_IGNORE_PATH)
|
||||
if(APPLE)
|
||||
# FIRST is the default.
|
||||
set(CMAKE_FIND_FRAMEWORK FIRST)
|
||||
endif()
|
||||
endmacro()
|
||||
|
@@ -36,6 +36,10 @@ endmacro()
|
||||
# ------------------------------------------------------------------------
|
||||
# Find system provided libraries.
|
||||
|
||||
# Avoid searching for headers since this would otherwise override our lib
|
||||
# directory as well as PYTHON_ROOT_DIR.
|
||||
set(CMAKE_FIND_FRAMEWORK NEVER)
|
||||
|
||||
# Find system ZLIB, not the pre-compiled one supplied with OpenCollada.
|
||||
set(ZLIB_ROOT /usr)
|
||||
find_package(ZLIB REQUIRED)
|
||||
@@ -75,6 +79,11 @@ if(NOT EXISTS "${LIBDIR}/")
|
||||
message(FATAL_ERROR "Mac OSX requires pre-compiled libs at: '${LIBDIR}'")
|
||||
endif()
|
||||
|
||||
# Optionally use system Python if PYTHON_ROOT_DIR is specified.
|
||||
if(WITH_PYTHON AND (WITH_PYTHON_MODULE AND PYTHON_ROOT_DIR))
|
||||
find_package(PythonLibsUnix REQUIRED)
|
||||
endif()
|
||||
|
||||
# Prefer lib directory paths
|
||||
file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
|
||||
set(CMAKE_PREFIX_PATH ${LIB_SUBDIRS})
|
||||
@@ -123,34 +132,8 @@ if(WITH_CODEC_SNDFILE)
|
||||
unset(_sndfile_VORBISENC_LIBRARY)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
# Use precompiled libraries by default.
|
||||
set(PYTHON_VERSION 3.10)
|
||||
if(NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
|
||||
# Normally cached but not since we include them with blender.
|
||||
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}")
|
||||
set(PYTHON_EXECUTABLE "${LIBDIR}/python/bin/python${PYTHON_VERSION}")
|
||||
set(PYTHON_LIBRARY ${LIBDIR}/python/lib/libpython${PYTHON_VERSION}.a)
|
||||
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
|
||||
else()
|
||||
# Module must be compiled against Python framework.
|
||||
set(_py_framework "/Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}")
|
||||
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}")
|
||||
unset(_py_framework)
|
||||
endif()
|
||||
|
||||
# uncached vars
|
||||
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
|
||||
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
|
||||
|
||||
# needed for Audaspace, numpy is installed into python site-packages
|
||||
set(PYTHON_NUMPY_INCLUDE_DIRS "${PYTHON_LIBPATH}/site-packages/numpy/core/include")
|
||||
|
||||
if(NOT EXISTS "${PYTHON_EXECUTABLE}")
|
||||
message(FATAL_ERROR "Python executable missing: ${PYTHON_EXECUTABLE}")
|
||||
endif()
|
||||
if(WITH_PYTHON AND NOT (WITH_PYTHON_MODULE AND PYTHON_ROOT_DIR))
|
||||
find_package(PythonLibsUnix REQUIRED)
|
||||
endif()
|
||||
|
||||
if(WITH_FFTW3)
|
||||
@@ -213,11 +196,6 @@ if(WITH_JACK)
|
||||
string(APPEND PLATFORM_LINKFLAGS " -F/Library/Frameworks -weak_framework jackmp")
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON_MODULE OR WITH_PYTHON_FRAMEWORK)
|
||||
# force cmake to link right framework
|
||||
string(APPEND PLATFORM_LINKFLAGS " /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/Python")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLLADA)
|
||||
find_package(OpenCOLLADA)
|
||||
find_library(PCRE_LIBRARIES NAMES pcre HINTS ${LIBDIR}/opencollada/lib)
|
||||
@@ -462,6 +440,9 @@ if(EXISTS ${LIBDIR})
|
||||
without_system_libs_end()
|
||||
endif()
|
||||
|
||||
# Restore to default.
|
||||
set(CMAKE_FIND_FRAMEWORK FIRST)
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Set compiler and linker flags.
|
||||
|
||||
|
@@ -16,9 +16,16 @@ if(NOT DEFINED LIBDIR)
|
||||
# Choose the best suitable libraries.
|
||||
if(EXISTS ${LIBDIR_NATIVE_ABI})
|
||||
set(LIBDIR ${LIBDIR_NATIVE_ABI})
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
|
||||
elseif(EXISTS ${LIBDIR_CENTOS7_ABI})
|
||||
set(LIBDIR ${LIBDIR_CENTOS7_ABI})
|
||||
set(WITH_CXX11_ABI OFF)
|
||||
if(WITH_MEM_JEMALLOC)
|
||||
# jemalloc provides malloc hooks.
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False)
|
||||
else()
|
||||
set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True)
|
||||
endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND
|
||||
CMAKE_C_COMPILER_VERSION VERSION_LESS 9.3)
|
||||
@@ -136,14 +143,38 @@ if(NOT WITH_SYSTEM_FREETYPE)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
# No way to set py35, remove for now.
|
||||
# find_package(PythonLibs)
|
||||
# This could be used, see: D14954 for details.
|
||||
# `find_package(PythonLibs)`
|
||||
|
||||
# Use our own instead, since without py is such a rare case,
|
||||
# require this package
|
||||
# XXX Linking errors with debian static python :/
|
||||
# find_package_wrapper(PythonLibsUnix REQUIRED)
|
||||
# Use our own instead, since without Python is such a rare case,
|
||||
# require this package.
|
||||
# XXX: Linking errors with Debian static Python (sigh).
|
||||
# find_package_wrapper(PythonLibsUnix REQUIRED)
|
||||
find_package(PythonLibsUnix REQUIRED)
|
||||
|
||||
if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE)
|
||||
# Installing into `site-packages`, warn when installing into `./../lib/`
|
||||
# which script authors almost certainly don't want.
|
||||
if(EXISTS ${LIBDIR})
|
||||
cmake_path(IS_PREFIX LIBDIR "${PYTHON_SITE_PACKAGES}" NORMALIZE _is_prefix)
|
||||
if(_is_prefix)
|
||||
message(WARNING "
|
||||
Building Blender with the following configuration:
|
||||
- WITH_PYTHON_MODULE=ON
|
||||
- WITH_INSTALL_PORTABLE=OFF
|
||||
- LIBDIR=\"${LIBDIR}\"
|
||||
- PYTHON_SITE_PACKAGES=\"${PYTHON_SITE_PACKAGES}\"
|
||||
In this case you may want to either:
|
||||
- Use the system Python's site-packages, see:
|
||||
python -c \"import site; print(site.getsitepackages()[0])\"
|
||||
- Set WITH_INSTALL_PORTABLE=ON to create a stand-alone \"bpy\" module
|
||||
which you will need to ensure is in Python's module search path.
|
||||
Proceeding with PYTHON_SITE_PACKAGES install target, you have been warned!"
|
||||
)
|
||||
endif()
|
||||
unset(_is_prefix)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
|
@@ -504,12 +504,16 @@ if(WITH_JACK)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
set(PYTHON_VERSION 3.10) # CACHE STRING)
|
||||
# Cache version for make_bpy_wheel.py to detect.
|
||||
unset(PYTHON_VERSION CACHE)
|
||||
set(PYTHON_VERSION "3.10" CACHE STRING "Python version")
|
||||
|
||||
string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION})
|
||||
set(PYTHON_LIBRARY ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}.lib)
|
||||
set(PYTHON_LIBRARY_DEBUG ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/libs/python${_PYTHON_VERSION_NO_DOTS}_d.lib)
|
||||
|
||||
set(PYTHON_EXECUTABLE ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/bin/python$<$<CONFIG:Debug>:_d>.exe)
|
||||
|
||||
set(PYTHON_INCLUDE_DIR ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/include)
|
||||
set(PYTHON_NUMPY_INCLUDE_DIRS ${LIBDIR}/python/${_PYTHON_VERSION_NO_DOTS}/lib/site-packages/numpy/core/include)
|
||||
set(NUMPY_FOUND ON)
|
||||
|
@@ -3,20 +3,22 @@
|
||||
# First generate the manifest for tests since it will not need the dependency on the CRT.
|
||||
configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/tests.exe.manifest @ONLY)
|
||||
|
||||
# Always detect system libraries, since they are also used by oneAPI.
|
||||
# But don't always install them, only for WITH_WINDOWS_BUNDLE_CRT=ON.
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
|
||||
set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
|
||||
|
||||
# This sometimes can change when updates are installed and the compiler version
|
||||
# changes, so test if it exists and if not, give InstallRequiredSystemLibraries
|
||||
# another chance to figure out the path.
|
||||
if(MSVC_REDIST_DIR AND NOT EXISTS "${MSVC_REDIST_DIR}")
|
||||
unset(MSVC_REDIST_DIR CACHE)
|
||||
endif()
|
||||
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
if(WITH_WINDOWS_BUNDLE_CRT)
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE)
|
||||
set(CMAKE_INSTALL_OPENMP_LIBRARIES ${WITH_OPENMP})
|
||||
|
||||
# This sometimes can change when updates are installed and the compiler version
|
||||
# changes, so test if it exists and if not, give InstallRequiredSystemLibraries
|
||||
# another chance to figure out the path.
|
||||
if(MSVC_REDIST_DIR AND NOT EXISTS "${MSVC_REDIST_DIR}")
|
||||
unset(MSVC_REDIST_DIR CACHE)
|
||||
endif()
|
||||
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
||||
# redirects for this dll, for details see T88813.
|
||||
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
||||
|
@@ -30,6 +30,8 @@ from typing import (
|
||||
cast,
|
||||
)
|
||||
|
||||
import shlex
|
||||
|
||||
|
||||
SOURCE_DIR = join(dirname(__file__), "..", "..")
|
||||
SOURCE_DIR = normpath(SOURCE_DIR)
|
||||
@@ -160,7 +162,7 @@ def build_info(
|
||||
|
||||
for c in compilers:
|
||||
args = args.replace(c, fake_compiler)
|
||||
args = args.split()
|
||||
args = shlex.split(args)
|
||||
# end
|
||||
|
||||
# remove compiler
|
||||
|
222
build_files/utils/make_bpy_wheel.py
Executable file
222
build_files/utils/make_bpy_wheel.py
Executable file
@@ -0,0 +1,222 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
"""
|
||||
Make Python wheel package (`*.whl`) file from Blender built with 'WITH_PYTHON_MODULE' enabled.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
If the "bpy" module was build on Linux using the command:
|
||||
|
||||
make bpy lite
|
||||
|
||||
The command to package it as a wheel is:
|
||||
|
||||
./build_files/utils/make_bpy_wheel.py ../build_linux_bpy_lite/bin --output-dir=./
|
||||
|
||||
This will create a `*.whl` file in the current directory.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import make_utils
|
||||
import os
|
||||
import re
|
||||
import platform
|
||||
import string
|
||||
import setuptools # type: ignore
|
||||
import sys
|
||||
|
||||
from typing import (
|
||||
Generator,
|
||||
List,
|
||||
Optional,
|
||||
Sequence,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Generic Functions
|
||||
|
||||
def find_dominating_file(
|
||||
path: str,
|
||||
search: Sequence[str],
|
||||
) -> str:
|
||||
while True:
|
||||
for d in search:
|
||||
if os.path.exists(os.path.join(path, d)):
|
||||
return os.path.join(path, d)
|
||||
path_next = os.path.normpath(os.path.join(path, ".."))
|
||||
if path == path_next:
|
||||
break
|
||||
path = path_next
|
||||
return ""
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# CMake Cache Access
|
||||
|
||||
def cmake_cache_var_iter(filepath_cmake_cache: str) -> Generator[Tuple[str, str, str], None, None]:
|
||||
import re
|
||||
re_cache = re.compile(r"([A-Za-z0-9_\-]+)?:?([A-Za-z0-9_\-]+)?=(.*)$")
|
||||
with open(filepath_cmake_cache, "r", encoding="utf-8") as cache_file:
|
||||
for l in cache_file:
|
||||
match = re_cache.match(l.strip())
|
||||
if match is not None:
|
||||
var, type_, val = match.groups()
|
||||
yield (var, type_ or "", val)
|
||||
|
||||
|
||||
def cmake_cache_var(filepath_cmake_cache: str, var: str) -> Optional[str]:
|
||||
for var_iter, type_iter, value_iter in cmake_cache_var_iter(filepath_cmake_cache):
|
||||
if var == var_iter:
|
||||
return value_iter
|
||||
return None
|
||||
|
||||
|
||||
def cmake_cache_var_or_exit(filepath_cmake_cache: str, var: str) -> str:
|
||||
value = cmake_cache_var(filepath_cmake_cache, var)
|
||||
if value is None:
|
||||
sys.stderr.write("Unable to find %r in %r, abort!\n" % (var, filepath_cmake_cache))
|
||||
sys.exit(1)
|
||||
return value
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Argument Parser
|
||||
|
||||
def argparse_create() -> argparse.ArgumentParser:
|
||||
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument(
|
||||
"install_dir",
|
||||
metavar='INSTALL_DIR',
|
||||
type=str,
|
||||
help="The installation directory containing the \"bpy\" package.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--build-dir",
|
||||
metavar='BUILD_DIR',
|
||||
default=None,
|
||||
help="The build directory containing 'CMakeCache.txt' (search parent directories of INSTALL_DIR when omitted).",
|
||||
required=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output-dir",
|
||||
metavar='OUTPUT_DIR',
|
||||
default=None,
|
||||
help="The destination directory for the '*.whl' file (use INSTALL_DIR when omitted).",
|
||||
required=False,
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Main Function
|
||||
|
||||
def main() -> None:
|
||||
|
||||
# Parse arguments.
|
||||
args = argparse_create().parse_args()
|
||||
|
||||
install_dir = os.path.abspath(args.install_dir)
|
||||
output_dir = os.path.abspath(args.output_dir) if args.output_dir else install_dir
|
||||
|
||||
if args.build_dir:
|
||||
build_dir = os.path.abspath(args.build_dir)
|
||||
filepath_cmake_cache = os.path.join(build_dir, "CMakeCache.txt")
|
||||
del build_dir
|
||||
if not os.path.exists(filepath_cmake_cache):
|
||||
sys.stderr.write("File not found %r, abort!\n" % filepath_cmake_cache)
|
||||
sys.exit(1)
|
||||
else:
|
||||
filepath_cmake_cache = find_dominating_file(install_dir, ("CMakeCache.txt",))
|
||||
if not filepath_cmake_cache:
|
||||
# Should never fail.
|
||||
sys.stderr.write("Unable to find CMakeCache.txt in or above %r, abort!\n" % install_dir)
|
||||
sys.exit(1)
|
||||
|
||||
# Get the major and minor Python version.
|
||||
python_version = cmake_cache_var_or_exit(filepath_cmake_cache, "PYTHON_VERSION")
|
||||
python_version_number = (
|
||||
tuple(int("".join(c for c in digit if c in string.digits)) for digit in python_version.split(".")) +
|
||||
# Support version without a minor version "3" (add zero).
|
||||
tuple((0, 0, 0))
|
||||
)
|
||||
python_version_str = "%d.%d" % python_version_number[:2]
|
||||
|
||||
# Get Blender version.
|
||||
blender_version_str = str(make_utils.parse_blender_version())
|
||||
|
||||
# Set platform tag following conventions.
|
||||
if sys.platform == "darwin":
|
||||
target = cmake_cache_var_or_exit(filepath_cmake_cache, "CMAKE_OSX_DEPLOYMENT_TARGET").split(".")
|
||||
machine = cmake_cache_var_or_exit(filepath_cmake_cache, "CMAKE_OSX_ARCHITECTURES")
|
||||
platform_tag = "macosx_%d_%d_%s" % (int(target[0]), int(target[1]), machine)
|
||||
elif sys.platform == "win32":
|
||||
platform_tag = "win_%s" % (platform.machine().lower())
|
||||
elif sys.platform == "linux":
|
||||
glibc = os.confstr("CS_GNU_LIBC_VERSION")
|
||||
if glibc is None:
|
||||
sys.stderr.write("Unable to find \"CS_GNU_LIBC_VERSION\", abort!\n")
|
||||
sys.exit(1)
|
||||
glibc = "%s_%s" % tuple(glibc.split()[1].split(".")[:2])
|
||||
platform_tag = "manylinux_%s_%s" % (glibc, platform.machine().lower())
|
||||
else:
|
||||
sys.stderr.write("Unsupported platform: %s, abort!\n" % (sys.platform))
|
||||
sys.exit(1)
|
||||
|
||||
os.chdir(install_dir)
|
||||
|
||||
# Include all files recursively.
|
||||
def package_files(root_dir: str) -> List[str]:
|
||||
paths = []
|
||||
for path, dirs, files in os.walk(root_dir):
|
||||
paths += [os.path.join("..", path, f) for f in files]
|
||||
return paths
|
||||
|
||||
# Ensure this wheel is marked platform specific.
|
||||
class BinaryDistribution(setuptools.dist.Distribution): # type: ignore
|
||||
def has_ext_modules(self) -> bool:
|
||||
return True
|
||||
|
||||
# Build wheel.
|
||||
sys.argv = [sys.argv[0], "bdist_wheel"]
|
||||
|
||||
setuptools.setup(
|
||||
name="bpy",
|
||||
version=blender_version_str,
|
||||
install_requires=["cython", "numpy", "requests", "zstandard"],
|
||||
python_requires="==%d.%d.*" % (python_version_number[0], python_version_number[1]),
|
||||
packages=["bpy"],
|
||||
package_data={"": package_files("bpy")},
|
||||
distclass=BinaryDistribution,
|
||||
options={"bdist_wheel": {"plat_name": platform_tag}},
|
||||
|
||||
description="Blender as a Python module",
|
||||
license="GPL-3.0",
|
||||
author="Blender Foundation",
|
||||
author_email="bf-committers@blender.org",
|
||||
url="https://www.blender.org"
|
||||
)
|
||||
|
||||
if not os.path.exists(output_dir):
|
||||
os.makedirs(output_dir)
|
||||
|
||||
# Move wheel to output directory.
|
||||
dist_dir = os.path.join(install_dir, "dist")
|
||||
for f in os.listdir(dist_dir):
|
||||
if f.endswith(".whl"):
|
||||
# No apparent way to override this ABI version with setuptools, so rename.
|
||||
sys_py = "cp%d%d" % (sys.version_info.major, sys.version_info.minor)
|
||||
sys_py_abi = sys_py + sys.abiflags
|
||||
blender_py = "cp%d%d" % (python_version_number[0], python_version_number[1])
|
||||
|
||||
renamed_f = f.replace(sys_py_abi, blender_py).replace(sys_py, blender_py)
|
||||
|
||||
os.rename(os.path.join(dist_dir, f), os.path.join(output_dir, renamed_f))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@@ -2,7 +2,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import argparse
|
||||
import dataclasses
|
||||
import make_utils
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
@@ -19,6 +19,8 @@ from typing import Iterable, TextIO, Optional, Any, Union
|
||||
SKIP_NAMES = {
|
||||
".gitignore",
|
||||
".gitmodules",
|
||||
".gitattributes",
|
||||
".git-blame-ignore-revs",
|
||||
".arcconfig",
|
||||
".svn",
|
||||
}
|
||||
@@ -50,7 +52,7 @@ def main() -> None:
|
||||
|
||||
print(f"Output dir: {curdir}")
|
||||
|
||||
version = parse_blender_version(blender_srcdir)
|
||||
version = make_utils.parse_blender_version()
|
||||
tarball = tarball_path(curdir, version, cli_args)
|
||||
manifest = manifest_path(tarball)
|
||||
packages_dir = packages_path(curdir, cli_args)
|
||||
@@ -62,53 +64,7 @@ def main() -> None:
|
||||
print("Done!")
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class BlenderVersion:
|
||||
version: int # 293 for 2.93.1
|
||||
patch: int # 1 for 2.93.1
|
||||
cycle: str # 'alpha', 'beta', 'release', maybe others.
|
||||
|
||||
@property
|
||||
def is_release(self) -> bool:
|
||||
return self.cycle == "release"
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Convert to version string.
|
||||
|
||||
>>> str(BlenderVersion(293, 1, "alpha"))
|
||||
'2.93.1-alpha'
|
||||
>>> str(BlenderVersion(327, 0, "release"))
|
||||
'3.27.0'
|
||||
"""
|
||||
version_major = self.version // 100
|
||||
version_minor = self.version % 100
|
||||
as_string = f"{version_major}.{version_minor}.{self.patch}"
|
||||
if self.is_release:
|
||||
return as_string
|
||||
return f"{as_string}-{self.cycle}"
|
||||
|
||||
|
||||
def parse_blender_version(blender_srcdir: Path) -> BlenderVersion:
|
||||
version_path = blender_srcdir / "source/blender/blenkernel/BKE_blender_version.h"
|
||||
|
||||
version_info = {}
|
||||
line_re = re.compile(r"^#define (BLENDER_VERSION[A-Z_]*)\s+([0-9a-z]+)$")
|
||||
|
||||
with version_path.open(encoding="utf-8") as version_file:
|
||||
for line in version_file:
|
||||
match = line_re.match(line.strip())
|
||||
if not match:
|
||||
continue
|
||||
version_info[match.group(1)] = match.group(2)
|
||||
|
||||
return BlenderVersion(
|
||||
int(version_info["BLENDER_VERSION"]),
|
||||
int(version_info["BLENDER_VERSION_PATCH"]),
|
||||
version_info["BLENDER_VERSION_CYCLE"],
|
||||
)
|
||||
|
||||
|
||||
def tarball_path(output_dir: Path, version: BlenderVersion, cli_args: Any) -> Path:
|
||||
def tarball_path(output_dir: Path, version: make_utils.BlenderVersion, cli_args: Any) -> Path:
|
||||
extra = ""
|
||||
if cli_args.include_packages:
|
||||
extra = "-with-libraries"
|
||||
@@ -148,7 +104,7 @@ def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]:
|
||||
|
||||
|
||||
def create_manifest(
|
||||
version: BlenderVersion,
|
||||
version: make_utils.BlenderVersion,
|
||||
outpath: Path,
|
||||
blender_srcdir: Path,
|
||||
packages_dir: Optional[Path],
|
||||
@@ -170,9 +126,9 @@ def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None:
|
||||
|
||||
|
||||
def submodules_to_manifest(
|
||||
blender_srcdir: Path, version: BlenderVersion, outfile: TextIO
|
||||
blender_srcdir: Path, version: make_utils.BlenderVersion, outfile: TextIO
|
||||
) -> None:
|
||||
skip_addon_contrib = version.is_release
|
||||
skip_addon_contrib = version.is_release()
|
||||
assert not blender_srcdir.is_absolute()
|
||||
|
||||
for line in git_command("-C", blender_srcdir, "submodule"):
|
||||
@@ -200,7 +156,11 @@ def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None:
|
||||
|
||||
|
||||
def create_tarball(
|
||||
version: BlenderVersion, tarball: Path, manifest: Path, blender_srcdir: Path, packages_dir: Optional[Path]
|
||||
version: make_utils.BlenderVersion,
|
||||
tarball: Path,
|
||||
manifest: Path,
|
||||
blender_srcdir: Path,
|
||||
packages_dir: Optional[Path],
|
||||
) -> None:
|
||||
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
|
||||
command = ["tar"]
|
||||
|
@@ -9,9 +9,15 @@ import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from typing import (
|
||||
Sequence,
|
||||
Optional,
|
||||
)
|
||||
|
||||
|
||||
def call(cmd, exit_on_error=True, silent=False):
|
||||
def call(cmd: Sequence[str], exit_on_error: bool = True, silent: bool = False) -> int:
|
||||
if not silent:
|
||||
print(" ".join(cmd))
|
||||
|
||||
@@ -29,7 +35,7 @@ def call(cmd, exit_on_error=True, silent=False):
|
||||
return retcode
|
||||
|
||||
|
||||
def check_output(cmd, exit_on_error=True):
|
||||
def check_output(cmd: Sequence[str], exit_on_error: bool = True) -> str:
|
||||
# Flush to ensure correct order output on Windows.
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
@@ -46,14 +52,14 @@ def check_output(cmd, exit_on_error=True):
|
||||
return output.strip()
|
||||
|
||||
|
||||
def git_branch_exists(git_command, branch):
|
||||
def git_branch_exists(git_command: str, branch: str) -> bool:
|
||||
return (
|
||||
call([git_command, "rev-parse", "--verify", branch], exit_on_error=False, silent=True) == 0 or
|
||||
call([git_command, "rev-parse", "--verify", "remotes/origin/" + branch], exit_on_error=False, silent=True) == 0
|
||||
)
|
||||
|
||||
|
||||
def git_branch(git_command):
|
||||
def git_branch(git_command: str) -> str:
|
||||
# Get current branch name.
|
||||
try:
|
||||
branch = subprocess.check_output([git_command, "rev-parse", "--abbrev-ref", "HEAD"])
|
||||
@@ -64,7 +70,7 @@ def git_branch(git_command):
|
||||
return branch.strip().decode('utf8')
|
||||
|
||||
|
||||
def git_tag(git_command):
|
||||
def git_tag(git_command: str) -> Optional[str]:
|
||||
# Get current tag name.
|
||||
try:
|
||||
tag = subprocess.check_output([git_command, "describe", "--exact-match"], stderr=subprocess.STDOUT)
|
||||
@@ -74,18 +80,19 @@ def git_tag(git_command):
|
||||
return tag.strip().decode('utf8')
|
||||
|
||||
|
||||
def git_branch_release_version(branch, tag):
|
||||
release_version = re.search("^blender-v(.*)-release$", branch)
|
||||
if release_version:
|
||||
release_version = release_version.group(1)
|
||||
def git_branch_release_version(branch: str, tag: str) -> Optional[str]:
|
||||
re_match = re.search("^blender-v(.*)-release$", branch)
|
||||
release_version = None
|
||||
if re_match:
|
||||
release_version = re_match.group(1)
|
||||
elif tag:
|
||||
release_version = re.search(r"^v([0-9]*\.[0-9]*).*", tag)
|
||||
if release_version:
|
||||
release_version = release_version.group(1)
|
||||
re_match = re.search(r"^v([0-9]*\.[0-9]*).*", tag)
|
||||
if re_match:
|
||||
release_version = re_match.group(1)
|
||||
return release_version
|
||||
|
||||
|
||||
def svn_libraries_base_url(release_version, branch=None):
|
||||
def svn_libraries_base_url(release_version: Optional[str], branch: Optional[str] = None) -> str:
|
||||
if release_version:
|
||||
svn_branch = "tags/blender-" + release_version + "-release"
|
||||
elif branch:
|
||||
@@ -95,9 +102,58 @@ def svn_libraries_base_url(release_version, branch=None):
|
||||
return "https://svn.blender.org/svnroot/bf-blender/" + svn_branch + "/lib/"
|
||||
|
||||
|
||||
def command_missing(command):
|
||||
def command_missing(command: str) -> bool:
|
||||
# Support running with Python 2 for macOS
|
||||
if sys.version_info >= (3, 0):
|
||||
return shutil.which(command) is None
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
class BlenderVersion:
|
||||
def __init__(self, version: int, patch: int, cycle: str):
|
||||
# 293 for 2.93.1
|
||||
self.version = version
|
||||
# 1 for 2.93.1
|
||||
self.patch = patch
|
||||
# 'alpha', 'beta', 'release', maybe others.
|
||||
self.cycle = cycle
|
||||
|
||||
def is_release(self) -> bool:
|
||||
return self.cycle == "release"
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Convert to version string.
|
||||
|
||||
>>> str(BlenderVersion(293, 1, "alpha"))
|
||||
'2.93.1-alpha'
|
||||
>>> str(BlenderVersion(327, 0, "release"))
|
||||
'3.27.0'
|
||||
"""
|
||||
version_major = self.version // 100
|
||||
version_minor = self.version % 100
|
||||
as_string = f"{version_major}.{version_minor}.{self.patch}"
|
||||
if self.is_release():
|
||||
return as_string
|
||||
return f"{as_string}-{self.cycle}"
|
||||
|
||||
|
||||
def parse_blender_version() -> BlenderVersion:
|
||||
blender_srcdir = Path(__file__).absolute().parent.parent.parent
|
||||
version_path = blender_srcdir / "source/blender/blenkernel/BKE_blender_version.h"
|
||||
|
||||
version_info = {}
|
||||
line_re = re.compile(r"^#define (BLENDER_VERSION[A-Z_]*)\s+([0-9a-z]+)$")
|
||||
|
||||
with version_path.open(encoding="utf-8") as version_file:
|
||||
for line in version_file:
|
||||
match = line_re.match(line.strip())
|
||||
if not match:
|
||||
continue
|
||||
version_info[match.group(1)] = match.group(2)
|
||||
|
||||
return BlenderVersion(
|
||||
int(version_info["BLENDER_VERSION"]),
|
||||
int(version_info["BLENDER_VERSION_PATCH"]),
|
||||
version_info["BLENDER_VERSION_CYCLE"],
|
||||
)
|
||||
|
@@ -139,7 +139,7 @@ https://www.blender.org''')
|
||||
|
||||
l = lines.pop(0)
|
||||
if l:
|
||||
assert(l.startswith('\t'))
|
||||
assert l.startswith('\t')
|
||||
l = l[1:] # Remove first white-space (tab).
|
||||
|
||||
fh.write('%s\n' % man_format(l))
|
||||
|
@@ -1,11 +1,11 @@
|
||||
sphinx==5.0.1
|
||||
sphinx==5.1.1
|
||||
|
||||
# Sphinx dependencies that are important
|
||||
Jinja2==3.1.2
|
||||
Pygments==2.12.0
|
||||
Pygments==2.13.0
|
||||
docutils==0.17.1
|
||||
snowballstemmer==2.2.0
|
||||
babel==2.10.1
|
||||
babel==2.10.3
|
||||
requests==2.27.1
|
||||
|
||||
# Only needed to match the theme used for the official documentation.
|
||||
|
@@ -1,7 +1,9 @@
|
||||
:tocdepth: 2
|
||||
|
||||
Blender API Change Log
|
||||
**********************
|
||||
Change Log
|
||||
**********
|
||||
|
||||
Changes in Blender's Python API between releases.
|
||||
|
||||
.. note, this document is auto generated by sphinx_changelog_gen.py
|
||||
|
||||
|
15
doc/python_api/rst/info_advanced.rst
Normal file
15
doc/python_api/rst/info_advanced.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
.. _info_advanced-index:
|
||||
|
||||
********
|
||||
Advanced
|
||||
********
|
||||
|
||||
This chapter covers advanced use (topics which may not be required for typical usage).
|
||||
|
||||
.. NOTE(@campbellbarton): Blender-as-a-Python-module is too obscure a topic to list directly on the main-page,
|
||||
so opt for an "Advanced" page which can be expanded on as needed.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
info_advanced_blender_as_bpy.rst
|
124
doc/python_api/rst/info_advanced_blender_as_bpy.rst
Normal file
124
doc/python_api/rst/info_advanced_blender_as_bpy.rst
Normal file
@@ -0,0 +1,124 @@
|
||||
|
||||
**************************
|
||||
Blender as a Python Module
|
||||
**************************
|
||||
|
||||
Blender supports being built as a Python module,
|
||||
allowing ``import bpy`` to be added to any Python script, providing access to Blender's features.
|
||||
|
||||
.. note::
|
||||
|
||||
At time of writing official builds are not available,
|
||||
using this requires compiling Blender yourself see
|
||||
`build instructions <https://wiki.blender.org/w/index.php?title=Building_Blender/Other/BlenderAsPyModule>`__.
|
||||
|
||||
|
||||
Use Cases
|
||||
=========
|
||||
|
||||
Python developers may wish to integrate Blender scripts which don't center around Blender.
|
||||
|
||||
Possible uses include:
|
||||
|
||||
- Visualizing data by rendering images and animations.
|
||||
- Image processing using Blender's compositor.
|
||||
- Video editing (using Blender's sequencer).
|
||||
- 3D file conversion.
|
||||
- Development, accessing ``bpy`` from Python IDE's and debugging tools for example.
|
||||
- Automation.
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
For the most part using Blender as a Python module is equivalent to running a script in background-mode
|
||||
(passing the command-line arguments ``--background`` or ``-b``),
|
||||
however there are some differences to be aware of.
|
||||
|
||||
.. Sorted alphabetically as there isn't an especially a logical order to show them.
|
||||
|
||||
Blender's Executable Access
|
||||
The attribute :class:`bpy.app.binary_path` defaults to an empty string.
|
||||
|
||||
If you wish to point this to the location of a known executable you may set the value.
|
||||
|
||||
This example searches for the binary, setting it when found:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
import shutil
|
||||
|
||||
blender_bin = shutil.which("blender")
|
||||
if blender_bin:
|
||||
print("Found:", blender_bin)
|
||||
bpy.app.binary_path = blender_bin
|
||||
else:
|
||||
print("Unable to find blender!")
|
||||
|
||||
Blender's Internal Modules
|
||||
There are many modules included with Blender such as :mod:`gpu` and :mod:`mathuils`.
|
||||
It's important that these are imported after ``bpy`` or they will not be found.
|
||||
|
||||
Command Line Arguments Unsupported
|
||||
Functionality controlled by command line arguments (shown by calling ``blender --help`` aren't accessible).
|
||||
|
||||
Typically this isn't such a limitation although there are some command line arguments that don't have
|
||||
equivalents in Blender's Python API (``--threads`` and ``--log`` for example).
|
||||
|
||||
.. note::
|
||||
|
||||
Access to these settings may be added in the future as needed.
|
||||
|
||||
Resource Sharing (GPU)
|
||||
It's possible other Python modules make use of the GPU in a way that prevents Blender/Cycles from accessing the GPU.
|
||||
|
||||
Signal Handlers
|
||||
Blender's typical signal handlers are not initialized, so there is no special handling for ``Control-C``
|
||||
to cancel a render and a crash log is not written in the event of a crash.
|
||||
|
||||
Startup and Preferences
|
||||
When the ``bpy`` module loads, the file is not empty as you might expect,
|
||||
there is a default cube, camera and light. If you wish to start from a blank file use:
|
||||
``bpy.ops.wm.read_factory_settings(use_empty=True)``.
|
||||
|
||||
The users startup and preferences are ignored to prevent your local configuration from impacting scripts behavior.
|
||||
The Python module behaves as if ``--factory-startup`` was passed as a command line argument.
|
||||
|
||||
The users preferences and startup can be loaded using operators:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import bpy
|
||||
|
||||
bpy.ops.wm.read_userpref()
|
||||
bpy.ops.wm.read_homefile()
|
||||
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
Most constraints of Blender as an application still apply:
|
||||
|
||||
Reloading Unsupported
|
||||
Reloading via ``importlib.reload`` will raise an exception instead of reloading and resetting the module.
|
||||
|
||||
The operator ``bpy.ops.wm.read_factory_settings()`` can be used to reset the internal state.
|
||||
|
||||
Single Blend File Restriction
|
||||
Only a single ``.blend`` file can be edited at a time.
|
||||
|
||||
.. hint::
|
||||
|
||||
As with the application it's possible to start multiple instances,
|
||||
each with their own ``bpy`` and therefor Blender state.
|
||||
Python provides the ``multiprocessing`` module to make communicating with sub-processes more convenient.
|
||||
|
||||
In some cases the library API may be an alternative to starting separate processes,
|
||||
although this API operates on reading and writing ID data-blocks and isn't
|
||||
a complete substitute for loading ``.blend`` files, see:
|
||||
|
||||
- :meth:`bpy.types.BlendDataLibraries.load`
|
||||
- :meth:`bpy.types.BlendDataLibraries.write`
|
||||
- :meth:`bpy.types.BlendData.temp_data`
|
||||
supports a temporary data-context to avoid manipulating the current ``.blend`` file.
|
@@ -1,6 +1,6 @@
|
||||
|
||||
*******************
|
||||
Reference API Usage
|
||||
API Reference Usage
|
||||
*******************
|
||||
|
||||
Blender has many interlinking data types which have an auto-generated reference API which often has the information
|
||||
|
@@ -1,8 +1,8 @@
|
||||
.. _info_overview:
|
||||
|
||||
*******************
|
||||
Python API Overview
|
||||
*******************
|
||||
************
|
||||
API Overview
|
||||
************
|
||||
|
||||
The purpose of this document is to explain how Python and Blender fit together,
|
||||
covering some of the functionality that may not be obvious from reading the API references
|
||||
|
@@ -241,9 +241,9 @@ def main():
|
||||
comment_washed = []
|
||||
comment = [] if comment is None else comment
|
||||
for i, l in enumerate(comment):
|
||||
assert((l.strip() == "") or
|
||||
(l in {"/*", " *"}) or
|
||||
(l.startswith(("/* ", " * "))))
|
||||
assert ((l.strip() == "") or
|
||||
(l in {"/*", " *"}) or
|
||||
(l.startswith(("/* ", " * "))))
|
||||
|
||||
l = l[3:]
|
||||
if i == 0 and not l.strip():
|
||||
@@ -270,7 +270,7 @@ def main():
|
||||
tp_sub = None
|
||||
else:
|
||||
print(arg)
|
||||
assert(0)
|
||||
assert 0
|
||||
|
||||
tp_str = ""
|
||||
|
||||
@@ -315,7 +315,7 @@ def main():
|
||||
tp_str += " or any sequence of 3 floats"
|
||||
elif tp == BMO_OP_SLOT_PTR:
|
||||
tp_str = "dict"
|
||||
assert(tp_sub is not None)
|
||||
assert tp_sub is not None
|
||||
if tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_BMESH:
|
||||
tp_str = ":class:`bmesh.types.BMesh`"
|
||||
elif tp_sub == BMO_OP_SLOT_SUBTYPE_PTR_SCENE:
|
||||
@@ -330,10 +330,10 @@ def main():
|
||||
tp_str = ":class:`bpy.types.bpy_struct`"
|
||||
else:
|
||||
print("Can't find", vars_dict_reverse[tp_sub])
|
||||
assert(0)
|
||||
assert 0
|
||||
|
||||
elif tp == BMO_OP_SLOT_ELEMENT_BUF:
|
||||
assert(tp_sub is not None)
|
||||
assert tp_sub is not None
|
||||
|
||||
ls = []
|
||||
if tp_sub & BM_VERT:
|
||||
@@ -342,7 +342,7 @@ def main():
|
||||
ls.append(":class:`bmesh.types.BMEdge`")
|
||||
if tp_sub & BM_FACE:
|
||||
ls.append(":class:`bmesh.types.BMFace`")
|
||||
assert(ls) # must be at least one
|
||||
assert ls # Must be at least one.
|
||||
|
||||
if tp_sub & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE:
|
||||
tp_str = "/".join(ls)
|
||||
@@ -367,10 +367,10 @@ def main():
|
||||
tp_str += "unknown internal data, not compatible with python"
|
||||
else:
|
||||
print("Can't find", vars_dict_reverse[tp_sub])
|
||||
assert(0)
|
||||
assert 0
|
||||
else:
|
||||
print("Can't find", vars_dict_reverse[tp])
|
||||
assert(0)
|
||||
assert 0
|
||||
|
||||
args_wash.append((name, tp_str, comment))
|
||||
return args_wash
|
||||
@@ -394,7 +394,7 @@ def main():
|
||||
fw(" :return:\n\n")
|
||||
|
||||
for (name, tp, comment) in args_out_wash:
|
||||
assert(name.endswith(".out"))
|
||||
assert name.endswith(".out")
|
||||
name = name[:-4]
|
||||
fw(" - ``%s``: %s\n\n" % (name, comment))
|
||||
fw(" **type** %s\n" % tp)
|
||||
|
@@ -101,7 +101,7 @@ def api_dump(args):
|
||||
|
||||
version, version_key = api_version()
|
||||
if version is None:
|
||||
raise(ValueError("API dumps can only be generated from within Blender."))
|
||||
raise ValueError("API dumps can only be generated from within Blender.")
|
||||
|
||||
dump = {}
|
||||
dump_module = dump["bpy.types"] = {}
|
||||
@@ -250,7 +250,7 @@ def api_changelog(args):
|
||||
|
||||
version, version_key = api_version()
|
||||
if version is None and (filepath_in_from is None or filepath_in_to is None):
|
||||
raise(ValueError("API dumps files must be given when ran outside of Blender."))
|
||||
raise ValueError("API dumps files must be given when ran outside of Blender.")
|
||||
|
||||
with open(indexpath, 'r', encoding='utf-8') as file_handle:
|
||||
index = json.load(file_handle)
|
||||
@@ -258,17 +258,21 @@ def api_changelog(args):
|
||||
if filepath_in_to is None:
|
||||
filepath_in_to = index.get(version_key, None)
|
||||
if filepath_in_to is None:
|
||||
raise(ValueError("Cannot find API dump file for Blender version " + str(version) + " in index file."))
|
||||
raise ValueError("Cannot find API dump file for Blender version " + str(version) + " in index file.")
|
||||
|
||||
print("Found to file: %r" % filepath_in_to)
|
||||
|
||||
if filepath_in_from is None:
|
||||
version_from, version_from_key = api_version_previous_in_index(index, version)
|
||||
if version_from is None:
|
||||
raise(ValueError("No previous version of Blender could be found in the index."))
|
||||
raise ValueError("No previous version of Blender could be found in the index.")
|
||||
filepath_in_from = index.get(version_from_key, None)
|
||||
if filepath_in_from is None:
|
||||
raise(ValueError("Cannot find API dump file for previous Blender version " + str(version_from) + " in index file."))
|
||||
raise ValueError(
|
||||
"Cannot find API dump file for previous Blender version " +
|
||||
str(version_from) +
|
||||
" in index file."
|
||||
)
|
||||
|
||||
print("Found from file: %r" % filepath_in_from)
|
||||
|
||||
@@ -277,7 +281,7 @@ def api_changelog(args):
|
||||
|
||||
with open(os.path.join(rootpath, filepath_in_to), 'r', encoding='utf-8') as file_handle:
|
||||
dump_version, dict_to = json.load(file_handle)
|
||||
assert(tuple(dump_version) == version)
|
||||
assert tuple(dump_version) == version
|
||||
|
||||
api_changes = []
|
||||
|
||||
@@ -345,8 +349,10 @@ def api_changelog(args):
|
||||
fw(""
|
||||
":tocdepth: 2\n"
|
||||
"\n"
|
||||
"Blender API Change Log\n"
|
||||
"**********************\n"
|
||||
"Change Log\n"
|
||||
"**********\n"
|
||||
"\n"
|
||||
"Changes in Blender's Python API between releases.\n"
|
||||
"\n"
|
||||
".. note, this document is auto generated by sphinx_changelog_gen.py\n"
|
||||
"\n"
|
||||
|
@@ -387,23 +387,35 @@ EXAMPLE_SET_USED = set()
|
||||
# RST files directory.
|
||||
RST_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "rst"))
|
||||
|
||||
# extra info, not api reference docs
|
||||
# stored in ./rst/info_*
|
||||
# Extra info, not api reference docs stored in `./rst/info_*`.
|
||||
# Pairs of (file, description), the title makes from the RST files are displayed before the description.
|
||||
INFO_DOCS = (
|
||||
("info_quickstart.rst",
|
||||
"Quickstart: New to Blender or scripting and want to get your feet wet?"),
|
||||
"New to Blender or scripting and want to get your feet wet?"),
|
||||
("info_overview.rst",
|
||||
"API Overview: A more complete explanation of Python integration"),
|
||||
"A more complete explanation of Python integration."),
|
||||
("info_api_reference.rst",
|
||||
"API Reference Usage: examples of how to use the API reference docs"),
|
||||
"Examples of how to use the API reference docs."),
|
||||
("info_best_practice.rst",
|
||||
"Best Practice: Conventions to follow for writing good scripts"),
|
||||
"Conventions to follow for writing good scripts."),
|
||||
("info_tips_and_tricks.rst",
|
||||
"Tips and Tricks: Hints to help you while writing scripts for Blender"),
|
||||
"Hints to help you while writing scripts for Blender."),
|
||||
("info_gotcha.rst",
|
||||
"Gotcha's: Some of the problems you may encounter when writing scripts"),
|
||||
("change_log.rst", "Change Log: List of changes since last Blender release"),
|
||||
"Some of the problems you may encounter when writing scripts."),
|
||||
("info_advanced.rst",
|
||||
"Topics which may not be required for typical usage."),
|
||||
("change_log.rst",
|
||||
"List of changes since last Blender release"),
|
||||
)
|
||||
# Referenced indirectly.
|
||||
INFO_DOCS_OTHER = (
|
||||
# Included by: `info_advanced.rst`.
|
||||
"info_advanced_blender_as_bpy.rst",
|
||||
)
|
||||
|
||||
# Hide the actual TOC, use a separate list that links to the items.
|
||||
# This is done so a short description can be included with each link.
|
||||
USE_INFO_DOCS_FANCY_INDEX = True
|
||||
|
||||
# only support for properties atm.
|
||||
RNA_BLACKLIST = {
|
||||
@@ -1470,7 +1482,7 @@ def pyrna2sphinx(basepath):
|
||||
|
||||
struct_module_name = struct.module_name
|
||||
if USE_ONLY_BUILTIN_RNA_TYPES:
|
||||
assert(struct_module_name == "bpy.types")
|
||||
assert struct_module_name == "bpy.types"
|
||||
filepath = os.path.join(basepath, "%s.%s.rst" % (struct_module_name, struct.identifier))
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
@@ -1904,7 +1916,7 @@ except ModuleNotFoundError:
|
||||
# fw(" 'collapse_navigation': True,\n")
|
||||
fw(" 'sticky_navigation': False,\n")
|
||||
fw(" 'navigation_depth': 1,\n")
|
||||
# fw(" 'includehidden': True,\n")
|
||||
fw(" 'includehidden': False,\n")
|
||||
# fw(" 'titles_only': False\n")
|
||||
fw(" }\n\n")
|
||||
|
||||
@@ -1976,12 +1988,21 @@ def write_rst_index(basepath):
|
||||
|
||||
if not EXCLUDE_INFO_DOCS:
|
||||
fw(".. toctree::\n")
|
||||
if USE_INFO_DOCS_FANCY_INDEX:
|
||||
fw(" :hidden:\n")
|
||||
fw(" :maxdepth: 1\n")
|
||||
fw(" :caption: Documentation\n\n")
|
||||
for info, info_desc in INFO_DOCS:
|
||||
fw(" %s <%s>\n" % (info_desc, info))
|
||||
fw(" %s\n" % info)
|
||||
fw("\n")
|
||||
|
||||
if USE_INFO_DOCS_FANCY_INDEX:
|
||||
# Show a fake TOC, allowing for an extra description to be shown as well as the title.
|
||||
fw(title_string("Documentation", "="))
|
||||
for info, info_desc in INFO_DOCS:
|
||||
fw("- :doc:`%s`: %s\n" % (info.removesuffix(".rst"), info_desc))
|
||||
fw("\n")
|
||||
|
||||
fw(".. toctree::\n")
|
||||
fw(" :maxdepth: 1\n")
|
||||
fw(" :caption: Application Modules\n\n")
|
||||
@@ -2314,6 +2335,8 @@ def copy_handwritten_rsts(basepath):
|
||||
if not EXCLUDE_INFO_DOCS:
|
||||
for info, _info_desc in INFO_DOCS:
|
||||
shutil.copy2(os.path.join(RST_DIR, info), basepath)
|
||||
for info in INFO_DOCS_OTHER:
|
||||
shutil.copy2(os.path.join(RST_DIR, info), basepath)
|
||||
|
||||
# TODO: put this docs in Blender's code and use import as per modules above.
|
||||
handwritten_modules = [
|
||||
|
@@ -224,27 +224,24 @@ static void export_pointcloud_motion(PointCloud *pointcloud,
|
||||
const int num_points = pointcloud->num_points();
|
||||
float3 *mP = attr_mP->data_float3() + motion_step * num_points;
|
||||
bool have_motion = false;
|
||||
int num_motion_points = 0;
|
||||
const array<float3> &pointcloud_points = pointcloud->get_points();
|
||||
|
||||
const int b_points_num = b_pointcloud.points.length();
|
||||
BL::FloatVectorAttribute b_attr_position = find_position_attribute(b_pointcloud);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_radius_attribute(b_pointcloud);
|
||||
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
if (num_motion_points < num_points) {
|
||||
const float3 co = get_float3(b_attr_position.data[i].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
|
||||
float3 P = co;
|
||||
P.w = radius;
|
||||
mP[num_motion_points] = P;
|
||||
have_motion = have_motion || (P != pointcloud_points[num_motion_points]);
|
||||
num_motion_points++;
|
||||
}
|
||||
for (int i = 0; i < std::min(num_points, b_points_num); i++) {
|
||||
const float3 co = get_float3(b_attr_position.data[i].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[i].value() : 0.0f;
|
||||
float3 P = co;
|
||||
P.w = radius;
|
||||
mP[i] = P;
|
||||
have_motion = have_motion || (P != pointcloud_points[i]);
|
||||
}
|
||||
|
||||
/* In case of new attribute, we verify if there really was any motion. */
|
||||
if (new_attribute) {
|
||||
if (num_motion_points != num_points || !have_motion) {
|
||||
if (b_points_num != num_points || !have_motion) {
|
||||
pointcloud->attributes.remove(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
}
|
||||
else if (motion_step > 0) {
|
||||
|
@@ -704,7 +704,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
buffer_params.window_width = bake_width;
|
||||
buffer_params.window_height = bake_height;
|
||||
/* Unique layer name for multi-image baking. */
|
||||
buffer_params.layer = string_printf("bake_%d\n", (int)full_buffer_files_.size());
|
||||
buffer_params.layer = string_printf("bake_%d\n", bake_id++);
|
||||
|
||||
/* Update session. */
|
||||
session->reset(session_params, buffer_params);
|
||||
|
@@ -146,6 +146,8 @@ class BlenderSession {
|
||||
BlenderDisplayDriver *display_driver_ = nullptr;
|
||||
|
||||
vector<string> full_buffer_files_;
|
||||
|
||||
int bake_id = 0;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -515,7 +515,7 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
|
||||
int dim,
|
||||
float pos)
|
||||
{
|
||||
/* initialize boundboxes */
|
||||
/* Initialize bounding-boxes. */
|
||||
BoundBox left_bounds = BoundBox::empty;
|
||||
BoundBox right_bounds = BoundBox::empty;
|
||||
|
||||
|
@@ -28,7 +28,6 @@
|
||||
#include "kernel/device/cpu/kernel.h"
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/osl/shader.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
// clang-format on
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
#include "kernel/device/cpu/kernel.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/osl/shader.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
// clang-format on
|
||||
|
||||
|
@@ -3,10 +3,7 @@
|
||||
|
||||
#include "device/cpu/kernel_thread_globals.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/osl/shader.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
// clang-format on
|
||||
|
||||
#include "util/profiling.h"
|
||||
|
||||
@@ -20,7 +17,7 @@ CPUKernelThreadGlobals::CPUKernelThreadGlobals(const KernelGlobalsCPU &kernel_gl
|
||||
reset_runtime_memory();
|
||||
|
||||
#ifdef WITH_OSL
|
||||
OSLShader::thread_init(this, reinterpret_cast<OSLGlobals *>(osl_globals_memory));
|
||||
OSLGlobals::thread_init(this, static_cast<OSLGlobals *>(osl_globals_memory));
|
||||
#else
|
||||
(void)osl_globals_memory;
|
||||
#endif
|
||||
@@ -35,7 +32,7 @@ CPUKernelThreadGlobals::CPUKernelThreadGlobals(CPUKernelThreadGlobals &&other) n
|
||||
CPUKernelThreadGlobals::~CPUKernelThreadGlobals()
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
OSLShader::thread_free(this);
|
||||
OSLGlobals::thread_free(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@@ -25,10 +25,12 @@ static OneAPIDLLInterface oneapi_dll;
|
||||
|
||||
#ifdef _WIN32
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY(path) (void *)(LoadLibrary(path))
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() GetLastError()
|
||||
# define FREE_SHARED_LIBRARY(handle) FreeLibrary((HMODULE)handle)
|
||||
# define GET_SHARED_LIBRARY_SYMBOL(handle, name) GetProcAddress((HMODULE)handle, name)
|
||||
#elif __linux__
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY(path) dlopen(path, RTLD_NOW)
|
||||
# define LOAD_ONEAPI_SHARED_LIBRARY_ERROR() dlerror()
|
||||
# define FREE_SHARED_LIBRARY(handle) dlclose(handle)
|
||||
# define GET_SHARED_LIBRARY_SYMBOL(handle, name) dlsym(handle, name)
|
||||
#endif
|
||||
@@ -49,8 +51,8 @@ bool device_oneapi_init()
|
||||
|
||||
/* This shouldn't happen, but it still makes sense to have a branch for this. */
|
||||
if (lib_handle == NULL) {
|
||||
LOG(ERROR) << "oneAPI kernel shared library cannot be loaded for some reason. This should not "
|
||||
"happen, however, it occurs hence oneAPI rendering will be disabled";
|
||||
LOG(ERROR) << "oneAPI kernel shared library cannot be loaded: "
|
||||
<< LOAD_ONEAPI_SHARED_LIBRARY_ERROR();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -544,8 +544,6 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
cycles_set_solution_folder(cycles_kernel_cuda)
|
||||
endif()
|
||||
|
||||
####################################################### START
|
||||
|
||||
# HIP module
|
||||
|
||||
if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||
@@ -620,7 +618,6 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||
cycles_set_solution_folder(cycles_kernel_hip)
|
||||
endif()
|
||||
|
||||
####################################################### END
|
||||
# OptiX PTX modules
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
|
||||
@@ -712,6 +709,8 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
|
||||
cycles_set_solution_folder(cycles_kernel_optix)
|
||||
endif()
|
||||
|
||||
# oneAPI module
|
||||
|
||||
if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if(WIN32)
|
||||
set(cycles_kernel_oneapi_lib ${CMAKE_CURRENT_BINARY_DIR}/cycles_kernel_oneapi.dll)
|
||||
@@ -793,7 +792,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(NOT WITH_CXX11_ABI)
|
||||
check_library_exists(sycl
|
||||
_ZN2cl4sycl7handler22verifyUsedKernelBundleERKSs ${sycl_compiler_root}/../lib SYCL_NO_CXX11_ABI)
|
||||
_ZN4sycl3_V17handler22verifyUsedKernelBundleERKSs ${sycl_compiler_root}/../lib SYCL_NO_CXX11_ABI)
|
||||
if(SYCL_NO_CXX11_ABI)
|
||||
list(APPEND sycl_compiler_flags -D_GLIBCXX_USE_CXX11_ABI=0)
|
||||
endif()
|
||||
|
@@ -59,39 +59,10 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
|
||||
* we will not allocate new closure. */
|
||||
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
|
||||
ccl_private ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
|
||||
if (sc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc->sample_weight = sample_weight;
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef __OSL__
|
||||
ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
|
||||
int size,
|
||||
Spectrum weight,
|
||||
void *data)
|
||||
{
|
||||
kernel_assert(isfinite_safe(weight));
|
||||
|
||||
const float sample_weight = fabsf(average(weight));
|
||||
|
||||
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
|
||||
* we will not allocate new closure. */
|
||||
if (sample_weight >= CLOSURE_WEIGHT_CUTOFF) {
|
||||
ShaderClosure *sc = closure_alloc(sd, size, CLOSURE_NONE_ID, weight);
|
||||
if (!sc) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy((void *)sc, data, size);
|
||||
|
||||
sc->weight = weight;
|
||||
sc->sample_weight = sample_weight;
|
||||
|
||||
return sc;
|
||||
@@ -99,6 +70,5 @@ ccl_device_inline ShaderClosure *bsdf_alloc_osl(ShaderData *sd,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -116,7 +116,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
break;
|
||||
#ifdef __SVM__
|
||||
#if defined(__SVM__) || defined(__OSL__)
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf);
|
||||
break;
|
||||
@@ -246,7 +246,7 @@ ccl_device_inline
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
eval = bsdf_diffuse_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
#ifdef __SVM__
|
||||
#if defined(__SVM__) || defined(__OSL__)
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
@@ -337,7 +337,7 @@ ccl_device_inline
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
eval = bsdf_diffuse_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
#ifdef __SVM__
|
||||
#if defined(__SVM__) || defined(__OSL__)
|
||||
case CLOSURE_BSDF_OREN_NAYAR_ID:
|
||||
eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
|
||||
break;
|
||||
@@ -419,7 +419,7 @@ ccl_device_inline
|
||||
ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float roughness)
|
||||
{
|
||||
/* TODO: do we want to blur volume closures? */
|
||||
#ifdef __SVM__
|
||||
#if defined(__SVM__) || defined(__OSL__)
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID:
|
||||
|
@@ -371,7 +371,7 @@ ccl_device void bsdf_microfacet_multi_ggx_blur(ccl_private ShaderClosure *sc, fl
|
||||
|
||||
/* === Closure implementations === */
|
||||
|
||||
/* Multiscattering GGX Glossy closure */
|
||||
/* Multi-scattering GGX Glossy closure */
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_common_setup(ccl_private MicrofacetBsdf *bsdf)
|
||||
{
|
||||
@@ -546,7 +546,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
|
||||
return LABEL_REFLECT | LABEL_GLOSSY;
|
||||
}
|
||||
|
||||
/* Multiscattering GGX Glass closure */
|
||||
/* Multi-scattering GGX Glass closure */
|
||||
|
||||
ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf)
|
||||
{
|
||||
|
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "kernel/geom/geom.h"
|
||||
|
||||
#include "kernel/camera/camera.h"
|
||||
|
||||
#include "kernel/film/cryptomatte_passes.h"
|
||||
#include "kernel/film/write.h"
|
||||
|
||||
|
@@ -30,8 +30,8 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals
|
||||
if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) {
|
||||
const Spectrum denoising_feature_throughput = INTEGRATOR_STATE(
|
||||
state, path, denoising_feature_throughput);
|
||||
const float denoising_depth = ensure_finite(average(denoising_feature_throughput) *
|
||||
sd->ray_length);
|
||||
const float depth = sd->ray_length - INTEGRATOR_STATE(state, ray, tmin);
|
||||
const float denoising_depth = ensure_finite(average(denoising_feature_throughput) * depth);
|
||||
film_write_pass_float(buffer + kernel_data.film.pass_denoising_depth, denoising_depth);
|
||||
}
|
||||
|
||||
|
@@ -16,14 +16,14 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Patch index for triangle, -1 if not subdivision triangle */
|
||||
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
ccl_device_inline uint subd_triangle_patch(KernelGlobals kg, int prim)
|
||||
{
|
||||
return (sd->prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, sd->prim) : ~0;
|
||||
return (prim != PRIM_NONE) ? kernel_data_fetch(tri_patch, prim) : ~0;
|
||||
}
|
||||
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, ccl_private const ShaderData *sd)
|
||||
ccl_device_inline uint attribute_primitive_type(KernelGlobals kg, int prim, int type)
|
||||
{
|
||||
if ((sd->type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, sd) != ~0) {
|
||||
if ((type & PRIMITIVE_TRIANGLE) && subd_triangle_patch(kg, prim) != ~0) {
|
||||
return ATTR_PRIM_SUBD;
|
||||
}
|
||||
else {
|
||||
@@ -45,17 +45,16 @@ ccl_device_inline uint object_attribute_map_offset(KernelGlobals kg, int object)
|
||||
return kernel_data_fetch(objects, object).attribute_map_offset;
|
||||
}
|
||||
|
||||
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
uint id)
|
||||
ccl_device_inline AttributeDescriptor
|
||||
find_attribute(KernelGlobals kg, int object, int prim, int type, uint64_t id)
|
||||
{
|
||||
if (sd->object == OBJECT_NONE) {
|
||||
if (object == OBJECT_NONE) {
|
||||
return attribute_not_found();
|
||||
}
|
||||
|
||||
/* for SVM, find attribute by unique id */
|
||||
uint attr_offset = object_attribute_map_offset(kg, sd->object);
|
||||
attr_offset += attribute_primitive_type(kg, sd);
|
||||
uint attr_offset = object_attribute_map_offset(kg, object);
|
||||
attr_offset += attribute_primitive_type(kg, prim, type);
|
||||
AttributeMap attr_map = kernel_data_fetch(attributes_map, attr_offset);
|
||||
|
||||
while (attr_map.id != id) {
|
||||
@@ -77,7 +76,7 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
AttributeDescriptor desc;
|
||||
desc.element = (AttributeElement)attr_map.element;
|
||||
|
||||
if (sd->prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
|
||||
if (prim == PRIM_NONE && desc.element != ATTR_ELEMENT_MESH &&
|
||||
desc.element != ATTR_ELEMENT_VOXEL && desc.element != ATTR_ELEMENT_OBJECT) {
|
||||
return attribute_not_found();
|
||||
}
|
||||
@@ -91,11 +90,16 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
return desc;
|
||||
}
|
||||
|
||||
ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
uint64_t id)
|
||||
{
|
||||
return find_attribute(kg, sd->object, sd->prim, sd->type, id);
|
||||
}
|
||||
|
||||
/* Transform matrix attribute on meshes */
|
||||
|
||||
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
const AttributeDescriptor desc)
|
||||
ccl_device Transform primitive_attribute_matrix(KernelGlobals kg, const AttributeDescriptor desc)
|
||||
{
|
||||
Transform tfm;
|
||||
|
||||
|
@@ -25,7 +25,7 @@ ccl_device_forceinline float primitive_surface_attribute_float(KernelGlobals kg,
|
||||
ccl_private float *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float(kg, sd, desc, dx, dy);
|
||||
@@ -56,7 +56,7 @@ ccl_device_forceinline float2 primitive_surface_attribute_float2(KernelGlobals k
|
||||
ccl_private float2 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float2(kg, sd, desc, dx, dy);
|
||||
@@ -87,7 +87,7 @@ ccl_device_forceinline float3 primitive_surface_attribute_float3(KernelGlobals k
|
||||
ccl_private float3 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float3(kg, sd, desc, dx, dy);
|
||||
@@ -118,7 +118,7 @@ ccl_device_forceinline float4 primitive_surface_attribute_float4(KernelGlobals k
|
||||
ccl_private float4 *dy)
|
||||
{
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
if (subd_triangle_patch(kg, sd) == ~0)
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0)
|
||||
return triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
else
|
||||
return subd_triangle_attribute_float4(kg, sd, desc, dx, dy);
|
||||
@@ -320,7 +320,7 @@ ccl_device_forceinline float4 primitive_motion_vector(KernelGlobals kg,
|
||||
#endif
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
/* Triangle */
|
||||
if (subd_triangle_patch(kg, sd) == ~0) {
|
||||
if (subd_triangle_patch(kg, sd->prim) == ~0) {
|
||||
motion_pre = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
desc.offset += numverts;
|
||||
motion_post = triangle_attribute_float3(kg, sd, desc, NULL, NULL);
|
||||
|
@@ -7,6 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kernel/util/differential.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* ShaderData setup from incoming ray */
|
||||
|
@@ -87,7 +87,7 @@ ccl_device_noinline float subd_triangle_attribute_float(KernelGlobals kg,
|
||||
ccl_private float *dx,
|
||||
ccl_private float *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
@@ -226,7 +226,7 @@ ccl_device_noinline float2 subd_triangle_attribute_float2(KernelGlobals kg,
|
||||
ccl_private float2 *dx,
|
||||
ccl_private float2 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
@@ -368,7 +368,7 @@ ccl_device_noinline float3 subd_triangle_attribute_float3(KernelGlobals kg,
|
||||
ccl_private float3 *dx,
|
||||
ccl_private float3 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
@@ -509,7 +509,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals kg,
|
||||
ccl_private float4 *dx,
|
||||
ccl_private float4 *dy)
|
||||
{
|
||||
int patch = subd_triangle_patch(kg, sd);
|
||||
int patch = subd_triangle_patch(kg, sd->prim);
|
||||
|
||||
#ifdef __PATCH_EVAL__
|
||||
if (desc.flags & ATTR_SUBDIVIDED) {
|
||||
|
@@ -29,7 +29,7 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals kg,
|
||||
object_inverse_position_transform(kg, sd, &P);
|
||||
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, sd, desc);
|
||||
Transform tfm = primitive_attribute_matrix(kg, desc);
|
||||
P = transform_point(&tfm, P);
|
||||
}
|
||||
|
||||
|
@@ -5,10 +5,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "kernel/svm/svm.h"
|
||||
|
||||
#ifdef __SVM__
|
||||
# include "kernel/svm/svm.h"
|
||||
#endif
|
||||
#ifdef __OSL__
|
||||
# include "kernel/osl/shader.h"
|
||||
# include "kernel/osl/osl.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -22,17 +23,18 @@ ccl_device void displacement_shader_eval(KernelGlobals kg,
|
||||
sd->num_closure_left = 0;
|
||||
|
||||
/* this will modify sd->P */
|
||||
#ifdef __SVM__
|
||||
# ifdef __OSL__
|
||||
if (kg->osl)
|
||||
#ifdef __OSL__
|
||||
if (kg->osl) {
|
||||
OSLShader::eval_displacement(kg, state, sd);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
#endif
|
||||
{
|
||||
#ifdef __SVM__
|
||||
svm_eval_nodes<KERNEL_FEATURE_NODE_MASK_DISPLACEMENT, SHADER_TYPE_DISPLACEMENT>(
|
||||
kg, state, sd, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -12,8 +12,6 @@
|
||||
|
||||
#include "kernel/light/light.h"
|
||||
|
||||
#include "kernel/util/differential.h"
|
||||
|
||||
#include "kernel/geom/geom.h"
|
||||
|
||||
#include "kernel/bvh/bvh.h"
|
||||
|
@@ -62,8 +62,7 @@ ccl_device_inline void integrate_light(KernelGlobals kg,
|
||||
/* multiple importance sampling, get regular light pdf,
|
||||
* and compute weight with respect to BSDF pdf */
|
||||
const float mis_ray_pdf = INTEGRATOR_STATE(state, path, mis_ray_pdf);
|
||||
const float mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
light_eval *= mis_weight;
|
||||
mis_weight = light_sample_mis_weight_forward(kg, mis_ray_pdf, ls.pdf);
|
||||
}
|
||||
|
||||
/* Write to render buffer. */
|
||||
|
@@ -10,10 +10,11 @@
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/svm/svm.h"
|
||||
|
||||
#ifdef __SVM__
|
||||
# include "kernel/svm/svm.h"
|
||||
#endif
|
||||
#ifdef __OSL__
|
||||
# include "kernel/osl/shader.h"
|
||||
# include "kernel/osl/osl.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@@ -10,10 +10,11 @@
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/svm/svm.h"
|
||||
|
||||
#ifdef __SVM__
|
||||
# include "kernel/svm/svm.h"
|
||||
#endif
|
||||
#ifdef __OSL__
|
||||
# include "kernel/osl/shader.h"
|
||||
# include "kernel/osl/osl.h"
|
||||
#endif
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
@@ -326,18 +327,18 @@ ccl_device_inline void volume_shader_eval(KernelGlobals kg,
|
||||
}
|
||||
|
||||
/* evaluate shader */
|
||||
# ifdef __SVM__
|
||||
# ifdef __OSL__
|
||||
# ifdef __OSL__
|
||||
if (kg->osl) {
|
||||
OSLShader::eval_volume(kg, state, sd, path_flag);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
# endif
|
||||
{
|
||||
# ifdef __SVM__
|
||||
svm_eval_nodes<KERNEL_FEATURE_NODE_MASK_VOLUME, SHADER_TYPE_VOLUME>(
|
||||
kg, state, sd, NULL, path_flag);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Merge closures to avoid exceeding number of closures limit. */
|
||||
if (!shadow) {
|
||||
|
@@ -10,21 +10,18 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
background.cpp
|
||||
bsdf_diffuse_ramp.cpp
|
||||
bsdf_phong_ramp.cpp
|
||||
emissive.cpp
|
||||
bssrdf.cpp
|
||||
closures.cpp
|
||||
globals.cpp
|
||||
services.cpp
|
||||
shader.cpp
|
||||
)
|
||||
|
||||
set(HEADER_SRC
|
||||
closures.h
|
||||
closures_setup.h
|
||||
closures_template.h
|
||||
globals.h
|
||||
osl.h
|
||||
services.h
|
||||
shader.h
|
||||
types.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
|
@@ -1,77 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
/// Generic background closure
|
||||
///
|
||||
/// We only have a background closure for the shaders
|
||||
/// to return a color in background shaders. No methods,
|
||||
/// only the weight is taking into account
|
||||
///
|
||||
class GenericBackgroundClosure : public CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
background_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
};
|
||||
|
||||
/// Holdout closure
|
||||
///
|
||||
/// This will be used by the shader to mark the
|
||||
/// amount of holdout for the current shading
|
||||
/// point. No parameters, only the weight will be
|
||||
/// used
|
||||
///
|
||||
class HoldoutClosure : CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
closure_alloc(sd, sizeof(ShaderClosure), CLOSURE_HOLDOUT_ID, rgb_to_spectrum(weight));
|
||||
sd->flag |= SD_HOLDOUT;
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_background_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_STRING_KEYPARAM(GenericBackgroundClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(GenericBackgroundClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_background_prepare, GenericBackgroundClosure)
|
||||
|
||||
ClosureParam *closure_holdout_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FINISH_PARAM(HoldoutClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,68 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_diffuse_ramp.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
class DiffuseRampClosure : public CBSDFClosure {
|
||||
public:
|
||||
DiffuseRampBsdf params;
|
||||
Color3 colors[8];
|
||||
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
DiffuseRampBsdf *bsdf = (DiffuseRampBsdf *)bsdf_alloc_osl(
|
||||
sd, sizeof(DiffuseRampBsdf), rgb_to_spectrum(weight), ¶ms);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
|
||||
|
||||
if (bsdf->colors) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
bsdf->colors[i] = TO_FLOAT3(colors[i]);
|
||||
|
||||
sd->flag |= bsdf_diffuse_ramp_setup(bsdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_diffuse_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(DiffuseRampClosure, params.N),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(DiffuseRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM(DiffuseRampClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(DiffuseRampClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bsdf_diffuse_ramp_prepare, DiffuseRampClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,69 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_phong_ramp.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
class PhongRampClosure : public CBSDFClosure {
|
||||
public:
|
||||
PhongRampBsdf params;
|
||||
Color3 colors[8];
|
||||
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
PhongRampBsdf *bsdf = (PhongRampBsdf *)bsdf_alloc_osl(
|
||||
sd, sizeof(PhongRampBsdf), rgb_to_spectrum(weight), ¶ms);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8);
|
||||
|
||||
if (bsdf->colors) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
bsdf->colors[i] = TO_FLOAT3(colors[i]);
|
||||
|
||||
sd->flag |= bsdf_phong_ramp_setup(bsdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bsdf_phong_ramp_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_FLOAT3_PARAM(PhongRampClosure, params.N),
|
||||
CLOSURE_FLOAT_PARAM(PhongRampClosure, params.exponent),
|
||||
CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
|
||||
CLOSURE_STRING_KEYPARAM(PhongRampClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(PhongRampClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -1,105 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/bsdf_util.h"
|
||||
#include "kernel/closure/bsdf_diffuse.h"
|
||||
#include "kernel/closure/bsdf_principled_diffuse.h"
|
||||
#include "kernel/closure/bssrdf.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
static ustring u_burley("burley");
|
||||
static ustring u_random_walk_fixed_radius("random_walk_fixed_radius");
|
||||
static ustring u_random_walk("random_walk");
|
||||
|
||||
class CBSSRDFClosure : public CClosurePrimitive {
|
||||
public:
|
||||
Bssrdf params;
|
||||
float ior;
|
||||
ustring method;
|
||||
|
||||
CBSSRDFClosure()
|
||||
{
|
||||
params.roughness = FLT_MAX;
|
||||
params.anisotropy = 1.0f;
|
||||
ior = 1.4f;
|
||||
}
|
||||
|
||||
void setup(ShaderData *sd, uint32_t path_flag, float3 weight)
|
||||
{
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N);
|
||||
|
||||
if (method == u_burley) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_BURLEY_ID);
|
||||
}
|
||||
else if (method == u_random_walk_fixed_radius) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_FIXED_RADIUS_ID);
|
||||
}
|
||||
else if (method == u_random_walk) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void alloc(ShaderData *sd, uint32_t path_flag, float3 weight, ClosureType type)
|
||||
{
|
||||
Bssrdf *bssrdf = bssrdf_alloc(sd, rgb_to_spectrum(weight));
|
||||
|
||||
if (bssrdf) {
|
||||
/* disable in case of diffuse ancestor, can't see it well then and
|
||||
* adds considerably noise due to probabilities of continuing path
|
||||
* getting lower and lower */
|
||||
if (path_flag & PATH_RAY_DIFFUSE_ANCESTOR) {
|
||||
params.radius = zero_spectrum();
|
||||
}
|
||||
|
||||
/* create one closure per color channel */
|
||||
bssrdf->radius = params.radius;
|
||||
bssrdf->albedo = params.albedo;
|
||||
bssrdf->N = params.N;
|
||||
bssrdf->roughness = params.roughness;
|
||||
bssrdf->anisotropy = clamp(params.anisotropy, 0.0f, 0.9f);
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type, clamp(ior, 1.01f, 3.8f));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_bssrdf_params()
|
||||
{
|
||||
static ClosureParam params[] = {
|
||||
CLOSURE_STRING_PARAM(CBSSRDFClosure, method),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.N),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.radius),
|
||||
CLOSURE_FLOAT3_PARAM(CBSSRDFClosure, params.albedo),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.roughness, "roughness"),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, ior, "ior"),
|
||||
CLOSURE_FLOAT_KEYPARAM(CBSSRDFClosure, params.anisotropy, "anisotropy"),
|
||||
CLOSURE_STRING_KEYPARAM(CBSSRDFClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(CBSSRDFClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_bssrdf_prepare, CBSSRDFClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
File diff suppressed because it is too large
Load Diff
@@ -1,142 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#ifndef __OSL_CLOSURES_H__
|
||||
#define __OSL_CLOSURES_H__
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "util/types.h"
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
#include <OSL/oslclosure.h>
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
OSL::ClosureParam *closure_emission_params();
|
||||
OSL::ClosureParam *closure_background_params();
|
||||
OSL::ClosureParam *closure_holdout_params();
|
||||
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
|
||||
OSL::ClosureParam *closure_bsdf_transparent_params();
|
||||
OSL::ClosureParam *closure_bssrdf_params();
|
||||
OSL::ClosureParam *closure_absorption_params();
|
||||
OSL::ClosureParam *closure_henyey_greenstein_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_ggx_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_ggx_aniso_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_glass_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_microfacet_multi_ggx_aniso_fresnel_params();
|
||||
OSL::ClosureParam *closure_bsdf_principled_clearcoat_params();
|
||||
|
||||
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bssrdf_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_absorption_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_henyey_greenstein_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_glass_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_aniso_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_ggx_fresnel_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_microfacet_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_glass_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_microfacet_multi_ggx_aniso_fresnel_prepare(OSL::RendererServices *,
|
||||
int id,
|
||||
void *data);
|
||||
void closure_bsdf_principled_clearcoat_prepare(OSL::RendererServices *, int id, void *data);
|
||||
void closure_bsdf_principled_hair_prepare(OSL::RendererServices *, int id, void *data);
|
||||
|
||||
#define CCLOSURE_PREPARE(name, classname) \
|
||||
void name(RendererServices *, int id, void *data) \
|
||||
{ \
|
||||
memset(data, 0, sizeof(classname)); \
|
||||
new (data) classname(); \
|
||||
}
|
||||
|
||||
#define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname)
|
||||
|
||||
#define CLOSURE_FLOAT3_PARAM(st, fld) \
|
||||
{ \
|
||||
TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) \
|
||||
}
|
||||
|
||||
#define BSDF_CLOSURE_FLOAT_PARAM(st, fld) CLOSURE_FLOAT_PARAM(st, fld),
|
||||
#define BSDF_CLOSURE_FLOAT3_PARAM(st, fld) CLOSURE_FLOAT3_PARAM(st, fld),
|
||||
|
||||
#define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z)
|
||||
#define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z)
|
||||
#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
|
||||
|
||||
/* Closure */
|
||||
|
||||
class CClosurePrimitive {
|
||||
public:
|
||||
virtual void setup(ShaderData *sd, uint32_t path_flag, float3 weight) = 0;
|
||||
|
||||
OSL::ustring label;
|
||||
};
|
||||
|
||||
/* BSDF */
|
||||
|
||||
class CBSDFClosure : public CClosurePrimitive {
|
||||
public:
|
||||
bool skip(const ShaderData *sd, uint32_t path_flag, int scattering);
|
||||
};
|
||||
|
||||
#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, structname, TYPE) \
|
||||
\
|
||||
class Upper##Closure : public CBSDFClosure { \
|
||||
public: \
|
||||
structname params; \
|
||||
float3 unused; \
|
||||
\
|
||||
void setup(ShaderData *sd, uint32_t path_flag, float3 weight) \
|
||||
{ \
|
||||
if (!skip(sd, path_flag, TYPE)) { \
|
||||
params.N = ensure_valid_reflection(sd->Ng, sd->I, params.N); \
|
||||
structname *bsdf = (structname *)bsdf_alloc_osl( \
|
||||
sd, sizeof(structname), rgb_to_spectrum(weight), ¶ms); \
|
||||
sd->flag |= (bsdf) ? bsdf_##lower##_setup(bsdf) : 0; \
|
||||
} \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
static ClosureParam *bsdf_##lower##_params() \
|
||||
{ \
|
||||
static ClosureParam params[] = {
|
||||
|
||||
/* parameters */
|
||||
|
||||
#define BSDF_CLOSURE_CLASS_END(Upper, lower) \
|
||||
CLOSURE_STRING_KEYPARAM(Upper##Closure, label, "label"), CLOSURE_FINISH_PARAM(Upper##Closure) \
|
||||
} \
|
||||
; \
|
||||
return params; \
|
||||
} \
|
||||
\
|
||||
CCLOSURE_PREPARE_STATIC(bsdf_##lower##_prepare, Upper##Closure)
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif /* __OSL_CLOSURES_H__ */
|
1166
intern/cycles/kernel/osl/closures_setup.h
Normal file
1166
intern/cycles/kernel/osl/closures_setup.h
Normal file
File diff suppressed because it is too large
Load Diff
258
intern/cycles/kernel/osl/closures_template.h
Normal file
258
intern/cycles/kernel/osl/closures_template.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#ifndef OSL_CLOSURE_STRUCT_BEGIN
|
||||
# define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_END
|
||||
# define OSL_CLOSURE_STRUCT_END(Upper, lower)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_MEMBER
|
||||
# define OSL_CLOSURE_STRUCT_MEMBER(Upper, TYPE, type, name, key)
|
||||
#endif
|
||||
#ifndef OSL_CLOSURE_STRUCT_ARRAY_MEMBER
|
||||
# define OSL_CLOSURE_STRUCT_ARRAY_MEMBER(Upper, TYPE, type, name, key, size)
|
||||
#endif
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Diffuse, diffuse)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Diffuse, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Diffuse, diffuse)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(OrenNayar, oren_nayar)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(OrenNayar, FLOAT, float, roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(OrenNayar, oren_nayar)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Translucent, translucent)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Translucent, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Translucent, translucent)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Reflection, reflection)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Reflection, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Reflection, reflection)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Refraction, refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Refraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Refraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Refraction, refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Transparent, transparent)
|
||||
OSL_CLOSURE_STRUCT_END(Transparent, transparent)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Microfacet, microfacet)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, STRING, ustring, distribution, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(Microfacet, INT, int, refract, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(Microfacet, microfacet)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXIsotropic, microfacet_ggx)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXIsotropic, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXIsotropic, microfacet_ggx)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGX, microfacet_ggx_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGX, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGX, microfacet_ggx_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXRefraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGX, microfacet_multi_ggx)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGX, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGX, microfacet_multi_ggx)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlass, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlass, microfacet_multi_ggx_glass)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAniso, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAniso, microfacet_multi_ggx_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXFresnel, microfacet_ggx_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetGGXAnisoFresnel, microfacet_ggx_aniso_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXFresnel, microfacet_multi_ggx_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXGlassFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXGlassFresnel, microfacet_multi_ggx_glass_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, color, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetMultiGGXAnisoFresnel, VECTOR, packed_float3, cspec0, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetMultiGGXAnisoFresnel, microfacet_multi_ggx_aniso_fresnel)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannIsotropic, microfacet_beckmann)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannIsotropic, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannIsotropic, microfacet_beckmann)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmann, microfacet_beckmann_aniso)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmann, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmann, microfacet_beckmann_aniso)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(MicrofacetBeckmannRefraction, FLOAT, float, ior, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(AshikhminShirley, ashikhmin_shirley)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_x, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminShirley, FLOAT, float, alpha_y, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(AshikhminShirley, ashikhmin_shirley)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(AshikhminVelvet, ashikhmin_velvet)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(AshikhminVelvet, FLOAT, float, sigma, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(AshikhminVelvet, ashikhmin_velvet)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(DiffuseToon, diffuse_toon)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, size, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseToon, FLOAT, float, smooth, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(DiffuseToon, diffuse_toon)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GlossyToon, glossy_toon)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, size, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(GlossyToon, FLOAT, float, smooth, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(GlossyToon, glossy_toon)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledDiffuse, principled_diffuse)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledDiffuse, FLOAT, float, roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledDiffuse, principled_diffuse)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledSheen, principled_sheen)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledSheen, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledSheen, principled_sheen)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledClearcoat, principled_clearcoat)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledClearcoat, FLOAT, float, clearcoat_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledClearcoat, principled_clearcoat)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GenericEmissive, emission)
|
||||
OSL_CLOSURE_STRUCT_END(GenericEmissive, emission)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(GenericBackground, background)
|
||||
OSL_CLOSURE_STRUCT_END(GenericBackground, background)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(Holdout, holdout)
|
||||
OSL_CLOSURE_STRUCT_END(Holdout, holdout)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(DiffuseRamp, diffuse_ramp)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(DiffuseRamp, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_ARRAY_MEMBER(DiffuseRamp, COLOR, packed_float3, colors, NULL, 8)
|
||||
OSL_CLOSURE_STRUCT_END(DiffuseRamp, diffuse_ramp)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PhongRamp, phong_ramp)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PhongRamp, FLOAT, float, exponent, NULL)
|
||||
OSL_CLOSURE_STRUCT_ARRAY_MEMBER(PhongRamp, COLOR, packed_float3, colors, NULL, 8)
|
||||
OSL_CLOSURE_STRUCT_END(PhongRamp, phong_ramp)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(BSSRDF, bssrdf)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, STRING, ustring, method, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, radius, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, VECTOR, packed_float3, albedo, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, roughness, "roughness")
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, ior, "ior")
|
||||
OSL_CLOSURE_STRUCT_MEMBER(BSSRDF, FLOAT, float, anisotropy, "anisotropy")
|
||||
OSL_CLOSURE_STRUCT_END(BSSRDF, bssrdf)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(HairReflection, hair_reflection)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness1, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, roughness2, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(HairReflection, hair_reflection)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(HairTransmission, hair_transmission)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness1, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairTransmission, FLOAT, float, roughness2, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, VECTOR, packed_float3, T, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(HairReflection, FLOAT, float, offset, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(HairTransmission, hair_transmission)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, sigma, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, s, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, m0_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, alpha, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(VolumeAbsorption, absorption)
|
||||
OSL_CLOSURE_STRUCT_END(VolumeAbsorption, absorption)
|
||||
|
||||
OSL_CLOSURE_STRUCT_BEGIN(VolumeHenyeyGreenstein, henyey_greenstein)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(VolumeHenyeyGreenstein, FLOAT, float, g, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(VolumeHenyeyGreenstein, henyey_greenstein)
|
||||
|
||||
#undef OSL_CLOSURE_STRUCT_BEGIN
|
||||
#undef OSL_CLOSURE_STRUCT_END
|
||||
#undef OSL_CLOSURE_STRUCT_MEMBER
|
||||
#undef OSL_CLOSURE_STRUCT_ARRAY_MEMBER
|
@@ -1,54 +0,0 @@
|
||||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* Adapted from Open Shading Language
|
||||
* Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Modifications Copyright 2011-2022 Blender Foundation. */
|
||||
|
||||
#include <OpenImageIO/fmath.h>
|
||||
|
||||
#include <OSL/genclosure.h>
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/closure/alloc.h"
|
||||
#include "kernel/closure/emissive.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
// clang-format on
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
using namespace OSL;
|
||||
|
||||
/// Variable cone emissive closure
|
||||
///
|
||||
/// This primitive emits in a cone having a configurable
|
||||
/// penumbra area where the light decays to 0 reaching the
|
||||
/// outer_angle limit. It can also behave as a lambertian emitter
|
||||
/// if the provided angles are PI/2, which is the default
|
||||
///
|
||||
class GenericEmissiveClosure : public CClosurePrimitive {
|
||||
public:
|
||||
void setup(ShaderData *sd, uint32_t /* path_flag */, float3 weight)
|
||||
{
|
||||
emission_setup(sd, rgb_to_spectrum(weight));
|
||||
}
|
||||
};
|
||||
|
||||
ClosureParam *closure_emission_params()
|
||||
{
|
||||
static ClosureParam params[] = {CLOSURE_STRING_KEYPARAM(GenericEmissiveClosure, label, "label"),
|
||||
CLOSURE_FINISH_PARAM(GenericEmissiveClosure)};
|
||||
return params;
|
||||
}
|
||||
|
||||
CCLOSURE_PREPARE(closure_emission_prepare, GenericEmissiveClosure)
|
||||
|
||||
CCL_NAMESPACE_END
|
59
intern/cycles/kernel/osl/globals.cpp
Normal file
59
intern/cycles/kernel/osl/globals.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/osl/globals.h"
|
||||
#include "kernel/osl/services.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
void OSLGlobals::thread_init(KernelGlobalsCPU *kg, OSLGlobals *osl_globals)
|
||||
{
|
||||
/* no osl used? */
|
||||
if (!osl_globals->use) {
|
||||
kg->osl = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Per thread kernel data init. */
|
||||
kg->osl = osl_globals;
|
||||
|
||||
OSL::ShadingSystem *ss = kg->osl->ss;
|
||||
OSLThreadData *tdata = new OSLThreadData();
|
||||
|
||||
memset((void *)&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
|
||||
tdata->globals.tracedata = &tdata->tracedata;
|
||||
tdata->osl_thread_info = ss->create_thread_info();
|
||||
tdata->context = ss->get_context(tdata->osl_thread_info);
|
||||
|
||||
tdata->oiio_thread_info = osl_globals->ts->get_perthread_info();
|
||||
|
||||
kg->osl_ss = (OSLShadingSystem *)ss;
|
||||
kg->osl_tdata = tdata;
|
||||
}
|
||||
|
||||
void OSLGlobals::thread_free(KernelGlobalsCPU *kg)
|
||||
{
|
||||
if (!kg->osl)
|
||||
return;
|
||||
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
ss->release_context(tdata->context);
|
||||
|
||||
ss->destroy_thread_info(tdata->osl_thread_info);
|
||||
|
||||
delete tdata;
|
||||
|
||||
kg->osl = NULL;
|
||||
kg->osl_ss = NULL;
|
||||
kg->osl_tdata = NULL;
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -41,6 +41,10 @@ struct OSLGlobals {
|
||||
use = false;
|
||||
}
|
||||
|
||||
/* per thread data */
|
||||
static void thread_init(struct KernelGlobalsCPU *kg, OSLGlobals *osl_globals);
|
||||
static void thread_free(struct KernelGlobalsCPU *kg);
|
||||
|
||||
bool use;
|
||||
|
||||
/* shading system */
|
||||
@@ -56,16 +60,8 @@ struct OSLGlobals {
|
||||
OSL::ShaderGroupRef background_state;
|
||||
|
||||
/* attributes */
|
||||
struct Attribute {
|
||||
TypeDesc type;
|
||||
AttributeDescriptor desc;
|
||||
ParamValue value;
|
||||
};
|
||||
|
||||
typedef unordered_map<ustring, Attribute, ustringHash> AttributeMap;
|
||||
typedef unordered_map<ustring, int, ustringHash> ObjectNameMap;
|
||||
|
||||
vector<AttributeMap> attribute_map;
|
||||
ObjectNameMap object_name_map;
|
||||
vector<ustring> object_names;
|
||||
};
|
||||
|
@@ -1,10 +1,7 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#ifndef __OSL_SHADER_H__
|
||||
#define __OSL_SHADER_H__
|
||||
|
||||
#ifdef WITH_OSL
|
||||
#pragma once
|
||||
|
||||
/* OSL Shader Engine
|
||||
*
|
||||
@@ -16,30 +13,12 @@
|
||||
* This means no thread state must be passed along in the kernel itself.
|
||||
*/
|
||||
|
||||
# include "kernel/types.h"
|
||||
#include "kernel/osl/types.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
class Scene;
|
||||
|
||||
struct ShaderClosure;
|
||||
struct ShaderData;
|
||||
struct IntegratorStateCPU;
|
||||
struct differential3;
|
||||
struct KernelGlobalsCPU;
|
||||
|
||||
struct OSLGlobals;
|
||||
struct OSLShadingSystem;
|
||||
|
||||
class OSLShader {
|
||||
public:
|
||||
/* init */
|
||||
static void register_closures(OSLShadingSystem *ss);
|
||||
|
||||
/* per thread data */
|
||||
static void thread_init(KernelGlobalsCPU *kg, OSLGlobals *osl_globals);
|
||||
static void thread_free(KernelGlobalsCPU *kg);
|
||||
|
||||
/* eval */
|
||||
static void eval_surface(const KernelGlobalsCPU *kg,
|
||||
const void *state,
|
||||
@@ -54,16 +33,6 @@ class OSLShader {
|
||||
ShaderData *sd,
|
||||
uint32_t path_flag);
|
||||
static void eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd);
|
||||
|
||||
/* attributes */
|
||||
static int find_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
uint id,
|
||||
AttributeDescriptor *desc);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __OSL_SHADER_H__ */
|
@@ -18,10 +18,8 @@
|
||||
#include "scene/pointcloud.h"
|
||||
#include "scene/scene.h"
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
#include "kernel/osl/services.h"
|
||||
#include "kernel/osl/shader.h"
|
||||
|
||||
#include "util/foreach.h"
|
||||
#include "util/log.h"
|
||||
@@ -31,8 +29,6 @@
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
#include "kernel/device/cpu/image.h"
|
||||
|
||||
#include "kernel/util/differential.h"
|
||||
|
||||
#include "kernel/integrator/state.h"
|
||||
#include "kernel/integrator/state_flow.h"
|
||||
|
||||
@@ -124,14 +120,14 @@ ustring OSLRenderServices::u_v("v");
|
||||
ustring OSLRenderServices::u_empty;
|
||||
|
||||
OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system)
|
||||
: texture_system(texture_system)
|
||||
: OSL::RendererServices(texture_system)
|
||||
{
|
||||
}
|
||||
|
||||
OSLRenderServices::~OSLRenderServices()
|
||||
{
|
||||
if (texture_system) {
|
||||
VLOG_INFO << "OSL texture system stats:\n" << texture_system->getstats();
|
||||
if (m_texturesys) {
|
||||
VLOG_INFO << "OSL texture system stats:\n" << m_texturesys->getstats();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,6 +447,7 @@ static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, v
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool set_attribute_float2(float2 f, TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
float2 fv[3];
|
||||
@@ -461,6 +458,7 @@ static bool set_attribute_float2(float2 f, TypeDesc type, bool derivatives, void
|
||||
|
||||
return set_attribute_float2(fv, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
@@ -589,6 +587,7 @@ static bool set_attribute_float4(float4 f[3], TypeDesc type, bool derivatives, v
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static bool set_attribute_float4(float4 f, TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
float4 fv[3];
|
||||
@@ -599,6 +598,7 @@ static bool set_attribute_float4(float4 f, TypeDesc type, bool derivatives, void
|
||||
|
||||
return set_attribute_float4(fv, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val)
|
||||
{
|
||||
@@ -740,115 +740,76 @@ static bool set_attribute_matrix(const Transform &tfm, TypeDesc type, void *val)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool get_primitive_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
const OSLGlobals::Attribute &attr,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
||||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
|
||||
float3 fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
fval[0] = primitive_volume_attribute_float3(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_surface_attribute_float3(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeFloat2) {
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
assert(!"Float2 attribute not support for volumes");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
float2 fval[3];
|
||||
fval[0] = primitive_surface_attribute_float2(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat) {
|
||||
float fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
fval[0] = primitive_surface_attribute_float(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float(fval, type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat4 || attr.type == TypeRGBA) {
|
||||
float4 fval[3];
|
||||
if (primitive_is_volume_attribute(sd, attr.desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float4(kg, sd, attr.desc);
|
||||
}
|
||||
else {
|
||||
fval[0] = primitive_surface_attribute_float4(
|
||||
kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float4(fval, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_mesh_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
const OSLGlobals::Attribute &attr,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypeMatrix) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, sd, attr.desc);
|
||||
return set_attribute_matrix(tfm, type, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_object_attribute(const OSLGlobals::Attribute &attr,
|
||||
TypeDesc type,
|
||||
static bool get_object_attribute(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
const AttributeDescriptor &desc,
|
||||
const TypeDesc &type,
|
||||
bool derivatives,
|
||||
void *val)
|
||||
{
|
||||
if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
|
||||
attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float3(make_float3(data[0], data[1], data[2]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeFloat2) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float2(make_float2(data[0], data[1]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeDesc::TypeFloat) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float(data[0], type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == TypeRGBA || attr.type == TypeDesc::TypeFloat4) {
|
||||
const float *data = (const float *)attr.value.data();
|
||||
return set_attribute_float4(
|
||||
make_float4(data[0], data[1], data[2], data[3]), type, derivatives, val);
|
||||
}
|
||||
else if (attr.type == type) {
|
||||
size_t datasize = attr.value.datasize();
|
||||
|
||||
memcpy(val, attr.value.data(), datasize);
|
||||
if (derivatives) {
|
||||
memset((char *)val + datasize, 0, datasize * 2);
|
||||
if (desc.type == NODE_ATTR_FLOAT3) {
|
||||
float3 fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
fval[0] = primitive_volume_attribute_float3(kg, sd, desc);
|
||||
}
|
||||
|
||||
return true;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_surface_attribute_float3(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float3(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT2) {
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
assert(!"Float2 attribute not support for volumes");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
float2 fval[3];
|
||||
fval[0] = primitive_surface_attribute_float2(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
return set_attribute_float2(fval, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT) {
|
||||
float fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float(kg, sd, desc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fval[0] = primitive_surface_attribute_float(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) {
|
||||
float4 fval[3];
|
||||
#ifdef __VOLUME__
|
||||
if (primitive_is_volume_attribute(sd, desc)) {
|
||||
memset(fval, 0, sizeof(fval));
|
||||
fval[0] = primitive_volume_attribute_float4(kg, sd, desc);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
fval[0] = primitive_surface_attribute_float4(
|
||||
kg, sd, desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
|
||||
}
|
||||
return set_attribute_float4(fval, type, derivatives, val);
|
||||
}
|
||||
else if (desc.type == NODE_ATTR_MATRIX) {
|
||||
Transform tfm = primitive_attribute_matrix(kg, desc);
|
||||
return set_attribute_matrix(tfm, type, val);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
@@ -979,6 +940,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#ifdef __HAIR__
|
||||
/* Hair Attributes */
|
||||
else if (name == u_is_curve) {
|
||||
float f = (sd->type & PRIMITIVE_CURVE) != 0;
|
||||
@@ -996,6 +958,8 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
float f = curve_random(kg, sd);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
#ifdef __POINTCLOUD__
|
||||
/* point attributes */
|
||||
else if (name == u_is_point) {
|
||||
float f = (sd->type & PRIMITIVE_POINT) != 0;
|
||||
@@ -1013,6 +977,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
float f = point_random(kg, sd);
|
||||
return set_attribute_float(f, type, derivatives, val);
|
||||
}
|
||||
#endif
|
||||
else if (name == u_normal_map_normal) {
|
||||
if (sd->type & PRIMITIVE_TRIANGLE) {
|
||||
float3 f = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v);
|
||||
@@ -1023,7 +988,7 @@ bool OSLRenderServices::get_object_standard_attribute(const KernelGlobalsCPU *kg
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1131,7 +1096,6 @@ bool OSLRenderServices::get_attribute(
|
||||
ShaderData *sd, bool derivatives, ustring object_name, TypeDesc type, ustring name, void *val)
|
||||
{
|
||||
const KernelGlobalsCPU *kg = sd->osl_globals;
|
||||
int prim_type = 0;
|
||||
int object;
|
||||
|
||||
/* lookup of attribute on another object */
|
||||
@@ -1145,44 +1109,18 @@ bool OSLRenderServices::get_attribute(
|
||||
}
|
||||
else {
|
||||
object = sd->object;
|
||||
prim_type = attribute_primitive_type(kg, sd);
|
||||
|
||||
if (object == OBJECT_NONE)
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
|
||||
/* find attribute on object */
|
||||
object = object * ATTR_PRIM_TYPES + prim_type;
|
||||
OSLGlobals::AttributeMap &attribute_map = kg->osl->attribute_map[object];
|
||||
OSLGlobals::AttributeMap::iterator it = attribute_map.find(name);
|
||||
|
||||
if (it != attribute_map.end()) {
|
||||
const OSLGlobals::Attribute &attr = it->second;
|
||||
|
||||
if (attr.desc.element != ATTR_ELEMENT_OBJECT) {
|
||||
/* triangle and vertex attributes */
|
||||
if (get_primitive_attribute(kg, sd, attr, type, derivatives, val))
|
||||
return true;
|
||||
else
|
||||
return get_mesh_attribute(kg, sd, attr, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
/* object attribute */
|
||||
return get_object_attribute(attr, type, derivatives, val);
|
||||
}
|
||||
const AttributeDescriptor desc = find_attribute(
|
||||
kg, object, sd->prim, object == sd->object ? sd->type : PRIMITIVE_NONE, name.hash());
|
||||
if (desc.offset != ATTR_STD_NOT_FOUND) {
|
||||
return get_object_attribute(kg, sd, desc, type, derivatives, val);
|
||||
}
|
||||
else {
|
||||
/* not found in attribute, check standard object info */
|
||||
bool is_std_object_attribute = get_object_standard_attribute(
|
||||
kg, sd, name, type, derivatives, val);
|
||||
|
||||
if (is_std_object_attribute)
|
||||
return true;
|
||||
|
||||
return get_background_attribute(kg, sd, name, type, derivatives, val);
|
||||
return get_object_standard_attribute(kg, sd, name, type, derivatives, val);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OSLRenderServices::get_userdata(
|
||||
@@ -1209,7 +1147,7 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file
|
||||
}
|
||||
|
||||
/* Get handle from OpenImageIO. */
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
TextureSystem::TextureHandle *handle = ts->get_texture_handle(filename);
|
||||
if (handle == NULL) {
|
||||
return NULL;
|
||||
@@ -1231,7 +1169,7 @@ bool OSLRenderServices::good(TextureSystem::TextureHandle *texture_handle)
|
||||
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
||||
|
||||
if (handle->oiio_handle) {
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
return ts->good(handle->oiio_handle);
|
||||
}
|
||||
else {
|
||||
@@ -1353,7 +1291,7 @@ bool OSLRenderServices::texture(ustring filename,
|
||||
}
|
||||
case OSLTextureHandle::OIIO: {
|
||||
/* OpenImageIO texture cache. */
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
|
||||
if (handle && handle->oiio_handle) {
|
||||
if (texture_thread_info == NULL) {
|
||||
@@ -1457,7 +1395,7 @@ bool OSLRenderServices::texture3d(ustring filename,
|
||||
}
|
||||
case OSLTextureHandle::OIIO: {
|
||||
/* OpenImageIO texture cache. */
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
|
||||
if (handle && handle->oiio_handle) {
|
||||
if (texture_thread_info == NULL) {
|
||||
@@ -1541,7 +1479,7 @@ bool OSLRenderServices::environment(ustring filename,
|
||||
ustring *errormessage)
|
||||
{
|
||||
OSLTextureHandle *handle = (OSLTextureHandle *)texture_handle;
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
bool status = false;
|
||||
|
||||
if (handle && handle->oiio_handle) {
|
||||
@@ -1613,7 +1551,7 @@ bool OSLRenderServices::get_texture_info(OSL::ShaderGlobals *sg,
|
||||
}
|
||||
|
||||
/* Get texture info from OpenImageIO. */
|
||||
OSL::TextureSystem *ts = texture_system;
|
||||
OSL::TextureSystem *ts = m_texturesys;
|
||||
return ts->get_texture_info(filename, subimage, dataname, datatype, data);
|
||||
}
|
||||
|
||||
@@ -1667,8 +1605,8 @@ bool OSLRenderServices::trace(TraceOpt &options,
|
||||
/* setup ray */
|
||||
Ray ray;
|
||||
|
||||
ray.P = TO_FLOAT3(P);
|
||||
ray.D = TO_FLOAT3(R);
|
||||
ray.P = make_float3(P.x, P.y, P.z);
|
||||
ray.D = make_float3(R.x, R.y, R.z);
|
||||
ray.tmin = 0.0f;
|
||||
ray.tmax = (options.maxdist == 1.0e30f) ? FLT_MAX : options.maxdist - options.mindist;
|
||||
ray.time = sd->time;
|
||||
@@ -1691,12 +1629,12 @@ bool OSLRenderServices::trace(TraceOpt &options,
|
||||
|
||||
/* ray differentials */
|
||||
differential3 dP;
|
||||
dP.dx = TO_FLOAT3(dPdx);
|
||||
dP.dy = TO_FLOAT3(dPdy);
|
||||
dP.dx = make_float3(dPdx.x, dPdx.y, dPdx.z);
|
||||
dP.dy = make_float3(dPdy.x, dPdy.y, dPdy.z);
|
||||
ray.dP = differential_make_compact(dP);
|
||||
differential3 dD;
|
||||
dD.dx = TO_FLOAT3(dRdx);
|
||||
dD.dy = TO_FLOAT3(dRdy);
|
||||
dD.dx = make_float3(dRdx.x, dRdx.y, dRdx.z);
|
||||
dD.dy = make_float3(dRdy.x, dRdy.y, dRdy.z);
|
||||
ray.dD = differential_make_compact(dD);
|
||||
|
||||
/* allocate trace data */
|
||||
|
@@ -76,6 +76,8 @@ class OSLRenderServices : public OSL::RendererServices {
|
||||
OSLRenderServices(OSL::TextureSystem *texture_system);
|
||||
~OSLRenderServices();
|
||||
|
||||
static void register_closures(OSL::ShadingSystem *ss);
|
||||
|
||||
bool get_matrix(OSL::ShaderGlobals *sg,
|
||||
OSL::Matrix44 &result,
|
||||
OSL::TransformationPtr xform,
|
||||
@@ -321,7 +323,6 @@ class OSLRenderServices : public OSL::RendererServices {
|
||||
* globals to be shared between different render sessions. This saves memory,
|
||||
* and is required because texture handles are cached as part of the shared
|
||||
* shading system. */
|
||||
OSL::TextureSystem *texture_system;
|
||||
OSLTextureHandleMap textures;
|
||||
};
|
||||
|
||||
|
@@ -1,425 +0,0 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
// clang-format off
|
||||
#include "kernel/device/cpu/compat.h"
|
||||
#include "kernel/device/cpu/globals.h"
|
||||
|
||||
#include "kernel/types.h"
|
||||
|
||||
#include "kernel/geom/object.h"
|
||||
|
||||
#include "kernel/integrator/state.h"
|
||||
|
||||
#include "kernel/osl/closures.h"
|
||||
#include "kernel/osl/globals.h"
|
||||
#include "kernel/osl/services.h"
|
||||
#include "kernel/osl/shader.h"
|
||||
|
||||
#include "kernel/util/differential.h"
|
||||
// clang-format on
|
||||
|
||||
#include "scene/attribute.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Threads */
|
||||
|
||||
void OSLShader::thread_init(KernelGlobalsCPU *kg, OSLGlobals *osl_globals)
|
||||
{
|
||||
/* no osl used? */
|
||||
if (!osl_globals->use) {
|
||||
kg->osl = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Per thread kernel data init. */
|
||||
kg->osl = osl_globals;
|
||||
|
||||
OSL::ShadingSystem *ss = kg->osl->ss;
|
||||
OSLThreadData *tdata = new OSLThreadData();
|
||||
|
||||
memset((void *)&tdata->globals, 0, sizeof(OSL::ShaderGlobals));
|
||||
tdata->globals.tracedata = &tdata->tracedata;
|
||||
tdata->globals.flipHandedness = false;
|
||||
tdata->osl_thread_info = ss->create_thread_info();
|
||||
tdata->context = ss->get_context(tdata->osl_thread_info);
|
||||
|
||||
tdata->oiio_thread_info = osl_globals->ts->get_perthread_info();
|
||||
|
||||
kg->osl_ss = (OSLShadingSystem *)ss;
|
||||
kg->osl_tdata = tdata;
|
||||
}
|
||||
|
||||
void OSLShader::thread_free(KernelGlobalsCPU *kg)
|
||||
{
|
||||
if (!kg->osl)
|
||||
return;
|
||||
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
ss->release_context(tdata->context);
|
||||
|
||||
ss->destroy_thread_info(tdata->osl_thread_info);
|
||||
|
||||
delete tdata;
|
||||
|
||||
kg->osl = NULL;
|
||||
kg->osl_ss = NULL;
|
||||
kg->osl_tdata = NULL;
|
||||
}
|
||||
|
||||
/* Globals */
|
||||
|
||||
static void shaderdata_to_shaderglobals(const KernelGlobalsCPU *kg,
|
||||
ShaderData *sd,
|
||||
const void *state,
|
||||
uint32_t path_flag,
|
||||
OSLThreadData *tdata)
|
||||
{
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
|
||||
const differential3 dP = differential_from_compact(sd->Ng, sd->dP);
|
||||
const differential3 dI = differential_from_compact(sd->I, sd->dI);
|
||||
|
||||
/* copy from shader data to shader globals */
|
||||
globals->P = TO_VEC3(sd->P);
|
||||
globals->dPdx = TO_VEC3(dP.dx);
|
||||
globals->dPdy = TO_VEC3(dP.dy);
|
||||
globals->I = TO_VEC3(sd->I);
|
||||
globals->dIdx = TO_VEC3(dI.dx);
|
||||
globals->dIdy = TO_VEC3(dI.dy);
|
||||
globals->N = TO_VEC3(sd->N);
|
||||
globals->Ng = TO_VEC3(sd->Ng);
|
||||
globals->u = sd->u;
|
||||
globals->dudx = sd->du.dx;
|
||||
globals->dudy = sd->du.dy;
|
||||
globals->v = sd->v;
|
||||
globals->dvdx = sd->dv.dx;
|
||||
globals->dvdy = sd->dv.dy;
|
||||
globals->dPdu = TO_VEC3(sd->dPdu);
|
||||
globals->dPdv = TO_VEC3(sd->dPdv);
|
||||
globals->surfacearea = 1.0f;
|
||||
globals->time = sd->time;
|
||||
|
||||
/* booleans */
|
||||
globals->raytype = path_flag;
|
||||
globals->backfacing = (sd->flag & SD_BACKFACING);
|
||||
|
||||
/* shader data to be used in services callbacks */
|
||||
globals->renderstate = sd;
|
||||
|
||||
/* hacky, we leave it to services to fetch actual object matrix */
|
||||
globals->shader2common = sd;
|
||||
globals->object2common = sd;
|
||||
|
||||
/* must be set to NULL before execute */
|
||||
globals->Ci = NULL;
|
||||
|
||||
/* clear trace data */
|
||||
tdata->tracedata.init = false;
|
||||
|
||||
/* Used by render-services. */
|
||||
sd->osl_globals = kg;
|
||||
if (path_flag & PATH_RAY_SHADOW) {
|
||||
sd->osl_path_state = nullptr;
|
||||
sd->osl_shadow_path_state = (const IntegratorShadowStateCPU *)state;
|
||||
}
|
||||
else {
|
||||
sd->osl_path_state = (const IntegratorStateCPU *)state;
|
||||
sd->osl_shadow_path_state = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Surface */
|
||||
|
||||
static void flatten_surface_closure_tree(ShaderData *sd,
|
||||
uint32_t path_flag,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
/* OSL gives us a closure tree, we flatten it into arrays per
|
||||
* closure type, for evaluation, sampling, etc later on. */
|
||||
|
||||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_surface_closure_tree(sd, path_flag, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
flatten_surface_closure_tree(sd, path_flag, add->closureA, weight);
|
||||
flatten_surface_closure_tree(sd, path_flag, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, path_flag, weight);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSLShader::eval_surface(const KernelGlobalsCPU *kg,
|
||||
const void *state,
|
||||
ShaderData *sd,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
/* setup shader globals from shader data */
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
|
||||
|
||||
/* execute shader for this point */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context;
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
/* automatic bump shader */
|
||||
if (kg->osl->bump_state[shader]) {
|
||||
/* save state */
|
||||
const float3 P = sd->P;
|
||||
const float dP = sd->dP;
|
||||
const OSL::Vec3 dPdx = globals->dPdx;
|
||||
const OSL::Vec3 dPdy = globals->dPdy;
|
||||
|
||||
/* set state as if undisplaced */
|
||||
if (sd->flag & SD_HAS_DISPLACEMENT) {
|
||||
float data[9];
|
||||
bool found = kg->osl->services->get_attribute(sd,
|
||||
true,
|
||||
OSLRenderServices::u_empty,
|
||||
TypeDesc::TypeVector,
|
||||
OSLRenderServices::u_geom_undisplaced,
|
||||
data);
|
||||
(void)found;
|
||||
assert(found);
|
||||
|
||||
differential3 tmp_dP;
|
||||
memcpy(&sd->P, data, sizeof(float) * 3);
|
||||
memcpy(&tmp_dP.dx, data + 3, sizeof(float) * 3);
|
||||
memcpy(&tmp_dP.dy, data + 6, sizeof(float) * 3);
|
||||
|
||||
object_position_transform(kg, sd, &sd->P);
|
||||
object_dir_transform(kg, sd, &tmp_dP.dx);
|
||||
object_dir_transform(kg, sd, &tmp_dP.dy);
|
||||
|
||||
sd->dP = differential_make_compact(tmp_dP);
|
||||
|
||||
globals->P = TO_VEC3(sd->P);
|
||||
globals->dPdx = TO_VEC3(tmp_dP.dx);
|
||||
globals->dPdy = TO_VEC3(tmp_dP.dy);
|
||||
}
|
||||
|
||||
/* execute bump shader */
|
||||
ss->execute(octx, *(kg->osl->bump_state[shader]), *globals);
|
||||
|
||||
/* reset state */
|
||||
sd->P = P;
|
||||
sd->dP = dP;
|
||||
|
||||
globals->P = TO_VEC3(P);
|
||||
globals->dPdx = TO_VEC3(dPdx);
|
||||
globals->dPdy = TO_VEC3(dPdy);
|
||||
}
|
||||
|
||||
/* surface shader */
|
||||
if (kg->osl->surface_state[shader]) {
|
||||
ss->execute(octx, *(kg->osl->surface_state[shader]), *globals);
|
||||
}
|
||||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci)
|
||||
flatten_surface_closure_tree(sd, path_flag, globals->Ci);
|
||||
}
|
||||
|
||||
/* Background */
|
||||
|
||||
static void flatten_background_closure_tree(ShaderData *sd,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
/* OSL gives us a closure tree, if we are shading for background there
|
||||
* is only one supported closure type at the moment, which has no evaluation
|
||||
* functions, so we just sum the weights */
|
||||
|
||||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_background_closure_tree(sd, mul->closure, weight * TO_FLOAT3(mul->weight));
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
|
||||
flatten_background_closure_tree(sd, add->closureA, weight);
|
||||
flatten_background_closure_tree(sd, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, 0, weight);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSLShader::eval_background(const KernelGlobalsCPU *kg,
|
||||
const void *state,
|
||||
ShaderData *sd,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
/* setup shader globals from shader data */
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
|
||||
|
||||
/* execute shader for this point */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context;
|
||||
|
||||
if (kg->osl->background_state) {
|
||||
ss->execute(octx, *(kg->osl->background_state), *globals);
|
||||
}
|
||||
|
||||
/* return background color immediately */
|
||||
if (globals->Ci)
|
||||
flatten_background_closure_tree(sd, globals->Ci);
|
||||
}
|
||||
|
||||
/* Volume */
|
||||
|
||||
static void flatten_volume_closure_tree(ShaderData *sd,
|
||||
const OSL::ClosureColor *closure,
|
||||
float3 weight = make_float3(1.0f, 1.0f, 1.0f))
|
||||
{
|
||||
/* OSL gives us a closure tree, we flatten it into arrays per
|
||||
* closure type, for evaluation, sampling, etc later on. */
|
||||
|
||||
switch (closure->id) {
|
||||
case OSL::ClosureColor::MUL: {
|
||||
OSL::ClosureMul *mul = (OSL::ClosureMul *)closure;
|
||||
flatten_volume_closure_tree(sd, mul->closure, TO_FLOAT3(mul->weight) * weight);
|
||||
break;
|
||||
}
|
||||
case OSL::ClosureColor::ADD: {
|
||||
OSL::ClosureAdd *add = (OSL::ClosureAdd *)closure;
|
||||
flatten_volume_closure_tree(sd, add->closureA, weight);
|
||||
flatten_volume_closure_tree(sd, add->closureB, weight);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
OSL::ClosureComponent *comp = (OSL::ClosureComponent *)closure;
|
||||
CClosurePrimitive *prim = (CClosurePrimitive *)comp->data();
|
||||
|
||||
if (prim) {
|
||||
#ifdef OSL_SUPPORTS_WEIGHTED_CLOSURE_COMPONENTS
|
||||
weight = weight * TO_FLOAT3(comp->w);
|
||||
#endif
|
||||
prim->setup(sd, 0, weight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OSLShader::eval_volume(const KernelGlobalsCPU *kg,
|
||||
const void *state,
|
||||
ShaderData *sd,
|
||||
uint32_t path_flag)
|
||||
{
|
||||
/* setup shader globals from shader data */
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
shaderdata_to_shaderglobals(kg, sd, state, path_flag, tdata);
|
||||
|
||||
/* execute shader */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context;
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
if (kg->osl->volume_state[shader]) {
|
||||
ss->execute(octx, *(kg->osl->volume_state[shader]), *globals);
|
||||
}
|
||||
|
||||
/* flatten closure tree */
|
||||
if (globals->Ci)
|
||||
flatten_volume_closure_tree(sd, globals->Ci);
|
||||
}
|
||||
|
||||
/* Displacement */
|
||||
|
||||
void OSLShader::eval_displacement(const KernelGlobalsCPU *kg, const void *state, ShaderData *sd)
|
||||
{
|
||||
/* setup shader globals from shader data */
|
||||
OSLThreadData *tdata = kg->osl_tdata;
|
||||
|
||||
shaderdata_to_shaderglobals(kg, sd, state, 0, tdata);
|
||||
|
||||
/* execute shader */
|
||||
OSL::ShadingSystem *ss = (OSL::ShadingSystem *)kg->osl_ss;
|
||||
OSL::ShaderGlobals *globals = &tdata->globals;
|
||||
OSL::ShadingContext *octx = tdata->context;
|
||||
int shader = sd->shader & SHADER_MASK;
|
||||
|
||||
if (kg->osl->displacement_state[shader]) {
|
||||
ss->execute(octx, *(kg->osl->displacement_state[shader]), *globals);
|
||||
}
|
||||
|
||||
/* get back position */
|
||||
sd->P = TO_FLOAT3(globals->P);
|
||||
}
|
||||
|
||||
/* Attributes */
|
||||
|
||||
int OSLShader::find_attribute(const KernelGlobalsCPU *kg,
|
||||
const ShaderData *sd,
|
||||
uint id,
|
||||
AttributeDescriptor *desc)
|
||||
{
|
||||
/* for OSL, a hash map is used to lookup the attribute by name. */
|
||||
int object = sd->object * ATTR_PRIM_TYPES;
|
||||
|
||||
OSLGlobals::AttributeMap &attr_map = kg->osl->attribute_map[object];
|
||||
ustring stdname(std::string("geom:") +
|
||||
std::string(Attribute::standard_name((AttributeStandard)id)));
|
||||
OSLGlobals::AttributeMap::const_iterator it = attr_map.find(stdname);
|
||||
|
||||
if (it != attr_map.end()) {
|
||||
const OSLGlobals::Attribute &osl_attr = it->second;
|
||||
*desc = osl_attr.desc;
|
||||
|
||||
if (sd->prim == PRIM_NONE && (AttributeElement)osl_attr.desc.element != ATTR_ELEMENT_MESH) {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
return ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* return result */
|
||||
if (osl_attr.desc.element == ATTR_ELEMENT_NONE) {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
return desc->offset;
|
||||
}
|
||||
else {
|
||||
desc->offset = ATTR_STD_NOT_FOUND;
|
||||
return (int)ATTR_STD_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
20
intern/cycles/kernel/osl/types.h
Normal file
20
intern/cycles/kernel/osl/types.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#pragma once
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Closure */
|
||||
|
||||
enum ClosureTypeOSL {
|
||||
OSL_CLOSURE_MUL_ID = -1,
|
||||
OSL_CLOSURE_ADD_ID = -2,
|
||||
|
||||
OSL_CLOSURE_NONE_ID = 0,
|
||||
|
||||
#define OSL_CLOSURE_STRUCT_BEGIN(Upper, lower) OSL_CLOSURE_##Upper##_ID,
|
||||
#include "closures_template.h"
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
@@ -655,12 +655,11 @@ typedef struct AttributeDescriptor {
|
||||
|
||||
/* For looking up attributes on objects and geometry. */
|
||||
typedef struct AttributeMap {
|
||||
uint id; /* Global unique identifier. */
|
||||
uint element; /* AttributeElement. */
|
||||
int offset; /* Offset into __attributes global arrays. */
|
||||
uint8_t type; /* NodeAttributeType. */
|
||||
uint8_t flags; /* AttributeFlag. */
|
||||
uint8_t pad[2];
|
||||
uint64_t id; /* Global unique identifier. */
|
||||
int offset; /* Offset into __attributes global arrays. */
|
||||
uint16_t element; /* AttributeElement. */
|
||||
uint8_t type; /* NodeAttributeType. */
|
||||
uint8_t flags; /* AttributeFlag. */
|
||||
} AttributeMap;
|
||||
|
||||
/* Closure data */
|
||||
|
@@ -302,111 +302,32 @@ GeometryManager::~GeometryManager()
|
||||
{
|
||||
}
|
||||
|
||||
void GeometryManager::update_osl_attributes(Device *device,
|
||||
Scene *scene,
|
||||
vector<AttributeRequestSet> &geom_attributes)
|
||||
void GeometryManager::update_osl_globals(Device *device, Scene *scene)
|
||||
{
|
||||
#ifdef WITH_OSL
|
||||
/* for OSL, a hash map is used to lookup the attribute by name. */
|
||||
OSLGlobals *og = (OSLGlobals *)device->get_cpu_osl_memory();
|
||||
|
||||
og->object_name_map.clear();
|
||||
og->attribute_map.clear();
|
||||
og->object_names.clear();
|
||||
|
||||
og->attribute_map.resize(scene->objects.size() * ATTR_PRIM_TYPES);
|
||||
|
||||
for (size_t i = 0; i < scene->objects.size(); i++) {
|
||||
/* set object name to object index map */
|
||||
Object *object = scene->objects[i];
|
||||
og->object_name_map[object->name] = i;
|
||||
og->object_names.push_back(object->name);
|
||||
|
||||
/* set object attributes */
|
||||
foreach (ParamValue &attr, object->attributes) {
|
||||
OSLGlobals::Attribute osl_attr;
|
||||
|
||||
osl_attr.type = attr.type();
|
||||
osl_attr.desc.element = ATTR_ELEMENT_OBJECT;
|
||||
osl_attr.value = attr;
|
||||
osl_attr.desc.offset = 0;
|
||||
osl_attr.desc.flags = 0;
|
||||
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][attr.name()] = osl_attr;
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][attr.name()] = osl_attr;
|
||||
}
|
||||
|
||||
/* find geometry attributes */
|
||||
size_t j = object->geometry->index;
|
||||
assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry);
|
||||
|
||||
AttributeRequestSet &attributes = geom_attributes[j];
|
||||
|
||||
/* set mesh attributes */
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
OSLGlobals::Attribute osl_attr;
|
||||
|
||||
if (req.desc.element != ATTR_ELEMENT_NONE) {
|
||||
osl_attr.desc = req.desc;
|
||||
|
||||
if (req.type == TypeDesc::TypeFloat)
|
||||
osl_attr.type = TypeDesc::TypeFloat;
|
||||
else if (req.type == TypeDesc::TypeMatrix)
|
||||
osl_attr.type = TypeDesc::TypeMatrix;
|
||||
else if (req.type == TypeFloat2)
|
||||
osl_attr.type = TypeFloat2;
|
||||
else if (req.type == TypeRGBA)
|
||||
osl_attr.type = TypeRGBA;
|
||||
else
|
||||
osl_attr.type = TypeDesc::TypeColor;
|
||||
|
||||
if (req.std != ATTR_STD_NONE) {
|
||||
/* if standard attribute, add lookup by geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][stdname] = osl_attr;
|
||||
}
|
||||
else if (req.name != ustring()) {
|
||||
/* add lookup by geometry attribute name */
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_GEOMETRY][req.name] = osl_attr;
|
||||
}
|
||||
}
|
||||
|
||||
if (req.subd_desc.element != ATTR_ELEMENT_NONE) {
|
||||
osl_attr.desc = req.subd_desc;
|
||||
|
||||
if (req.subd_type == TypeDesc::TypeFloat)
|
||||
osl_attr.type = TypeDesc::TypeFloat;
|
||||
else if (req.subd_type == TypeDesc::TypeMatrix)
|
||||
osl_attr.type = TypeDesc::TypeMatrix;
|
||||
else if (req.subd_type == TypeFloat2)
|
||||
osl_attr.type = TypeFloat2;
|
||||
else if (req.subd_type == TypeRGBA)
|
||||
osl_attr.type = TypeRGBA;
|
||||
else
|
||||
osl_attr.type = TypeDesc::TypeColor;
|
||||
|
||||
if (req.std != ATTR_STD_NONE) {
|
||||
/* if standard attribute, add lookup by geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(req.std)));
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][stdname] = osl_attr;
|
||||
}
|
||||
else if (req.name != ustring()) {
|
||||
/* add lookup by geometry attribute name */
|
||||
og->attribute_map[i * ATTR_PRIM_TYPES + ATTR_PRIM_SUBD][req.name] = osl_attr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)device;
|
||||
(void)scene;
|
||||
(void)geom_attributes;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Generate a normal attribute map entry from an attribute descriptor. */
|
||||
static void emit_attribute_map_entry(
|
||||
AttributeMap *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc)
|
||||
static void emit_attribute_map_entry(AttributeMap *attr_map,
|
||||
size_t index,
|
||||
uint64_t id,
|
||||
TypeDesc type,
|
||||
const AttributeDescriptor &desc)
|
||||
{
|
||||
attr_map[index].id = id;
|
||||
attr_map[index].element = desc.element;
|
||||
@@ -431,7 +352,7 @@ static void emit_attribute_map_entry(
|
||||
/* Generate an attribute map end marker, optionally including a link to another map.
|
||||
* Links are used to connect object attribute maps to mesh attribute maps. */
|
||||
static void emit_attribute_map_terminator(AttributeMap *attr_map,
|
||||
int index,
|
||||
size_t index,
|
||||
bool chain,
|
||||
uint chain_link)
|
||||
{
|
||||
@@ -446,15 +367,8 @@ static void emit_attribute_map_terminator(AttributeMap *attr_map,
|
||||
|
||||
/* Generate all necessary attribute map entries from the attribute request. */
|
||||
static void emit_attribute_mapping(
|
||||
AttributeMap *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom)
|
||||
AttributeMap *attr_map, size_t index, uint64_t id, AttributeRequest &req, Geometry *geom)
|
||||
{
|
||||
uint id;
|
||||
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_map_entry(attr_map, index, id, req.type, req.desc);
|
||||
|
||||
if (geom->is_mesh()) {
|
||||
@@ -475,12 +389,26 @@ void GeometryManager::update_svm_attributes(Device *,
|
||||
* attribute, based on a unique shader attribute id. */
|
||||
|
||||
/* compute array stride */
|
||||
int attr_map_size = 0;
|
||||
size_t attr_map_size = 0;
|
||||
|
||||
for (size_t i = 0; i < scene->geometry.size(); i++) {
|
||||
Geometry *geom = scene->geometry[i];
|
||||
geom->attr_map_offset = attr_map_size;
|
||||
attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
size_t attr_count = 0;
|
||||
foreach (AttributeRequest &req, geom_attributes[i].requests) {
|
||||
if (req.std != ATTR_STD_NONE &&
|
||||
scene->shader_manager->get_attribute_id(req.std) != (uint64_t)req.std)
|
||||
attr_count += 2;
|
||||
else
|
||||
attr_count += 1;
|
||||
}
|
||||
#else
|
||||
const size_t attr_count = geom_attributes[i].size();
|
||||
#endif
|
||||
|
||||
attr_map_size += (attr_count + 1) * ATTR_PRIM_TYPES;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < scene->objects.size(); i++) {
|
||||
@@ -512,11 +440,26 @@ void GeometryManager::update_svm_attributes(Device *,
|
||||
AttributeRequestSet &attributes = geom_attributes[i];
|
||||
|
||||
/* set geometry attributes */
|
||||
int index = geom->attr_map_offset;
|
||||
size_t index = geom->attr_map_offset;
|
||||
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
emit_attribute_mapping(attr_map, index, scene, req, geom);
|
||||
uint64_t id;
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_mapping(attr_map, index, id, req, geom);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
|
||||
#ifdef WITH_OSL
|
||||
/* Some standard attributes are explicitly referenced via their standard ID, so add those
|
||||
* again in case they were added under a different attribute ID. */
|
||||
if (req.std != ATTR_STD_NONE && id != (uint64_t)req.std) {
|
||||
emit_attribute_mapping(attr_map, index, (uint64_t)req.std, req, geom);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
emit_attribute_map_terminator(attr_map, index, false, 0);
|
||||
@@ -528,10 +471,16 @@ void GeometryManager::update_svm_attributes(Device *,
|
||||
|
||||
/* set object attributes */
|
||||
if (attributes.size() > 0) {
|
||||
int index = object->attr_map_offset;
|
||||
size_t index = object->attr_map_offset;
|
||||
|
||||
foreach (AttributeRequest &req, attributes.requests) {
|
||||
emit_attribute_mapping(attr_map, index, scene, req, object->geometry);
|
||||
uint64_t id;
|
||||
if (req.std == ATTR_STD_NONE)
|
||||
id = scene->shader_manager->get_attribute_id(req.name);
|
||||
else
|
||||
id = scene->shader_manager->get_attribute_id(req.std);
|
||||
|
||||
emit_attribute_mapping(attr_map, index, id, req, object->geometry);
|
||||
index += ATTR_PRIM_TYPES;
|
||||
}
|
||||
|
||||
@@ -982,7 +931,7 @@ void GeometryManager::device_update_attributes(Device *device,
|
||||
|
||||
/* create attribute lookup maps */
|
||||
if (scene->shader_manager->use_osl())
|
||||
update_osl_attributes(device, scene, geom_attributes);
|
||||
update_osl_globals(device, scene);
|
||||
|
||||
update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes);
|
||||
|
||||
@@ -2188,7 +2137,6 @@ void GeometryManager::device_free(Device *device, DeviceScene *dscene, bool forc
|
||||
|
||||
if (og) {
|
||||
og->object_name_map.clear();
|
||||
og->attribute_map.clear();
|
||||
og->object_names.clear();
|
||||
}
|
||||
#else
|
||||
|
@@ -219,9 +219,7 @@ class GeometryManager {
|
||||
void create_volume_mesh(const Scene *scene, Volume *volume, Progress &progress);
|
||||
|
||||
/* Attributes */
|
||||
void update_osl_attributes(Device *device,
|
||||
Scene *scene,
|
||||
vector<AttributeRequestSet> &geom_attributes);
|
||||
void update_osl_globals(Device *device, Scene *scene);
|
||||
void update_svm_attributes(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
|
@@ -17,7 +17,6 @@
|
||||
|
||||
# include "kernel/osl/globals.h"
|
||||
# include "kernel/osl/services.h"
|
||||
# include "kernel/osl/shader.h"
|
||||
|
||||
# include "util/aligned_malloc.h"
|
||||
# include "util/foreach.h"
|
||||
@@ -78,6 +77,18 @@ void OSLShaderManager::reset(Scene * /*scene*/)
|
||||
shading_system_init();
|
||||
}
|
||||
|
||||
uint64_t OSLShaderManager::get_attribute_id(ustring name)
|
||||
{
|
||||
return name.hash();
|
||||
}
|
||||
|
||||
uint64_t OSLShaderManager::get_attribute_id(AttributeStandard std)
|
||||
{
|
||||
/* if standard attribute, use geom: name convention */
|
||||
ustring stdname(string("geom:") + string(Attribute::standard_name(std)));
|
||||
return stdname.hash();
|
||||
}
|
||||
|
||||
void OSLShaderManager::device_update_specific(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
@@ -286,7 +297,7 @@ void OSLShaderManager::shading_system_init()
|
||||
const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]);
|
||||
ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
|
||||
|
||||
OSLShader::register_closures((OSLShadingSystem *)ss_shared);
|
||||
OSLRenderServices::register_closures(ss_shared);
|
||||
|
||||
loaded_shaders.clear();
|
||||
}
|
||||
|
@@ -66,6 +66,9 @@ class OSLShaderManager : public ShaderManager {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t get_attribute_id(ustring name) override;
|
||||
uint64_t get_attribute_id(AttributeStandard std) override;
|
||||
|
||||
void device_update_specific(Device *device,
|
||||
DeviceScene *dscene,
|
||||
Scene *scene,
|
||||
|
@@ -414,7 +414,7 @@ ShaderManager *ShaderManager::create(int shadingsystem)
|
||||
return manager;
|
||||
}
|
||||
|
||||
uint ShaderManager::get_attribute_id(ustring name)
|
||||
uint64_t ShaderManager::get_attribute_id(ustring name)
|
||||
{
|
||||
thread_scoped_spin_lock lock(attribute_lock_);
|
||||
|
||||
@@ -424,14 +424,14 @@ uint ShaderManager::get_attribute_id(ustring name)
|
||||
if (it != unique_attribute_id.end())
|
||||
return it->second;
|
||||
|
||||
uint id = (uint)ATTR_STD_NUM + unique_attribute_id.size();
|
||||
uint64_t id = ATTR_STD_NUM + unique_attribute_id.size();
|
||||
unique_attribute_id[name] = id;
|
||||
return id;
|
||||
}
|
||||
|
||||
uint ShaderManager::get_attribute_id(AttributeStandard std)
|
||||
uint64_t ShaderManager::get_attribute_id(AttributeStandard std)
|
||||
{
|
||||
return (uint)std;
|
||||
return (uint64_t)std;
|
||||
}
|
||||
|
||||
int ShaderManager::get_shader_id(Shader *shader, bool smooth)
|
||||
|
@@ -192,8 +192,8 @@ class ShaderManager {
|
||||
void device_free_common(Device *device, DeviceScene *dscene, Scene *scene);
|
||||
|
||||
/* get globally unique id for a type of attribute */
|
||||
uint get_attribute_id(ustring name);
|
||||
uint get_attribute_id(AttributeStandard std);
|
||||
virtual uint64_t get_attribute_id(ustring name);
|
||||
virtual uint64_t get_attribute_id(AttributeStandard std);
|
||||
|
||||
/* get shader id for mesh faces */
|
||||
int get_shader_id(Shader *shader, bool smooth = false);
|
||||
@@ -223,7 +223,7 @@ class ShaderManager {
|
||||
|
||||
uint32_t update_flags;
|
||||
|
||||
typedef unordered_map<ustring, uint, ustringHash> AttributeIDMap;
|
||||
typedef unordered_map<ustring, uint64_t, ustringHash> AttributeIDMap;
|
||||
AttributeIDMap unique_attribute_id;
|
||||
|
||||
static thread_mutex lookup_table_mutex;
|
||||
|
@@ -281,7 +281,7 @@ class GHOST_ISystem {
|
||||
const bool stereoVisual) = 0;
|
||||
|
||||
/**
|
||||
* Updates the resolution while in fullscreen mode.
|
||||
* Updates the resolution while in full-screen mode.
|
||||
* \param setting: The new setting of the display.
|
||||
* \param window: Window displayed in full screen.
|
||||
*
|
||||
|
@@ -121,7 +121,8 @@ typedef enum {
|
||||
GHOST_kModifierKeyRightAlt,
|
||||
GHOST_kModifierKeyLeftControl,
|
||||
GHOST_kModifierKeyRightControl,
|
||||
GHOST_kModifierKeyOS,
|
||||
GHOST_kModifierKeyLeftOS,
|
||||
GHOST_kModifierKeyRightOS,
|
||||
GHOST_kModifierKeyNum
|
||||
} GHOST_TModifierKey;
|
||||
|
||||
@@ -320,13 +321,17 @@ typedef enum {
|
||||
GHOST_kKeyBackslash = 0x5C,
|
||||
GHOST_kKeyAccentGrave = '`',
|
||||
|
||||
/* Modifiers: See #GHOST_KEY_IS_MODIFIER. */
|
||||
GHOST_kKeyLeftShift = 0x100,
|
||||
GHOST_kKeyRightShift,
|
||||
GHOST_kKeyLeftControl,
|
||||
GHOST_kKeyRightControl,
|
||||
GHOST_kKeyLeftAlt,
|
||||
GHOST_kKeyRightAlt,
|
||||
GHOST_kKeyOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyLeftOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyRightOS,
|
||||
/* End modifiers. */
|
||||
|
||||
GHOST_kKeyGrLess, /* German PC only! */
|
||||
GHOST_kKeyApp, /* Also known as menu key. */
|
||||
|
||||
@@ -400,6 +405,8 @@ typedef enum {
|
||||
GHOST_kKeyMediaLast
|
||||
} GHOST_TKey;
|
||||
|
||||
#define GHOST_KEY_IS_MODIFIER(key) (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightOS);
|
||||
|
||||
typedef enum {
|
||||
/** Grab not set. */
|
||||
GHOST_kGrabDisable = 0,
|
||||
|
@@ -220,8 +220,11 @@ void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
|
||||
case GHOST_kKeyRightAlt:
|
||||
tstr = "RightAlt";
|
||||
break;
|
||||
case GHOST_kKeyOS:
|
||||
tstr = "OS";
|
||||
case GHOST_kKeyLeftOS:
|
||||
tstr = "LeftOS";
|
||||
break;
|
||||
case GHOST_kKeyRightOS:
|
||||
tstr = "RightOS";
|
||||
break;
|
||||
case GHOST_kKeyApp:
|
||||
tstr = "App";
|
||||
|
@@ -42,8 +42,11 @@ GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKey mask)
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
key = GHOST_kKeyRightControl;
|
||||
break;
|
||||
case GHOST_kModifierKeyOS:
|
||||
key = GHOST_kKeyOS;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
key = GHOST_kKeyLeftOS;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
key = GHOST_kKeyRightOS;
|
||||
break;
|
||||
default:
|
||||
// Should not happen
|
||||
@@ -68,8 +71,10 @@ bool GHOST_ModifierKeys::get(GHOST_TModifierKey mask) const
|
||||
return m_LeftControl;
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
return m_RightControl;
|
||||
case GHOST_kModifierKeyOS:
|
||||
return m_OS;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
return m_LeftOS;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
return m_RightOS;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -96,8 +101,11 @@ void GHOST_ModifierKeys::set(GHOST_TModifierKey mask, bool down)
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
m_RightControl = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyOS:
|
||||
m_OS = down;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
m_LeftOS = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
m_RightOS = down;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -112,7 +120,8 @@ void GHOST_ModifierKeys::clear()
|
||||
m_RightAlt = false;
|
||||
m_LeftControl = false;
|
||||
m_RightControl = false;
|
||||
m_OS = false;
|
||||
m_LeftOS = false;
|
||||
m_RightOS = false;
|
||||
}
|
||||
|
||||
bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
@@ -120,5 +129,5 @@ bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
return (m_LeftShift == keys.m_LeftShift) && (m_RightShift == keys.m_RightShift) &&
|
||||
(m_LeftAlt == keys.m_LeftAlt) && (m_RightAlt == keys.m_RightAlt) &&
|
||||
(m_LeftControl == keys.m_LeftControl) && (m_RightControl == keys.m_RightControl) &&
|
||||
(m_OS == keys.m_OS);
|
||||
(m_LeftOS == keys.m_LeftOS) && (m_RightOS == keys.m_RightOS);
|
||||
}
|
||||
|
@@ -68,5 +68,6 @@ struct GHOST_ModifierKeys {
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
uint8_t m_RightControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
uint8_t m_OS : 1;
|
||||
uint8_t m_LeftOS : 1;
|
||||
uint8_t m_RightOS : 1;
|
||||
};
|
||||
|
@@ -123,7 +123,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
const bool stereoVisual);
|
||||
|
||||
/**
|
||||
* Updates the resolution while in fullscreen mode.
|
||||
* Updates the resolution while in full-screen mode.
|
||||
* \param setting: The new setting of the display.
|
||||
* \param window: Window displayed in full screen.
|
||||
*
|
||||
@@ -369,7 +369,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
virtual GHOST_TSuccess exit();
|
||||
|
||||
/**
|
||||
* Creates a fullscreen window.
|
||||
* Creates a full-screen window.
|
||||
* \param window: The window created.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
@@ -399,7 +399,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
GHOST_EventPrinter *m_eventPrinter;
|
||||
#endif // WITH_GHOST_DEBUG
|
||||
|
||||
/** Settings of the display before the display went fullscreen. */
|
||||
/** Settings of the display before the display went full-screen. */
|
||||
GHOST_DisplaySetting m_preFullScreenSetting;
|
||||
|
||||
/** Which tablet API to use. */
|
||||
|
@@ -79,7 +79,7 @@ class GHOST_SystemCocoa : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent (embedder) window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -856,7 +856,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(int32_t x, int32_t y)
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
{
|
||||
keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSEventModifierFlagOption) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftShift,
|
||||
(m_modifierMask & NSEventModifierFlagShift) ? true : false);
|
||||
@@ -1020,7 +1020,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
|
||||
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown :
|
||||
GHOST_kEventKeyUp,
|
||||
window,
|
||||
GHOST_kKeyOS,
|
||||
GHOST_kKeyLeftOS,
|
||||
false));
|
||||
}
|
||||
|
||||
@@ -1123,6 +1123,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
case GHOST_kEventDraggingEntered:
|
||||
case GHOST_kEventDraggingUpdated:
|
||||
case GHOST_kEventDraggingExited:
|
||||
window->clientToScreenIntern(mouseX, mouseY, mouseX, mouseY);
|
||||
pushEvent(new GHOST_EventDragnDrop(
|
||||
getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, NULL));
|
||||
break;
|
||||
@@ -1331,6 +1332,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
return GHOST_kFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
window->clientToScreenIntern(mouseX, mouseY, mouseX, mouseY);
|
||||
pushEvent(new GHOST_EventDragnDrop(
|
||||
getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, eventData));
|
||||
|
||||
@@ -1898,7 +1901,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
|
||||
[event timestamp] * 1000,
|
||||
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
|
||||
window,
|
||||
GHOST_kKeyOS,
|
||||
GHOST_kKeyLeftOS,
|
||||
false));
|
||||
}
|
||||
|
||||
|
@@ -161,7 +161,8 @@ GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
|
||||
keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftOS, (mod & KMOD_LGUI) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightOS, (mod & KMOD_RGUI) != 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -219,8 +220,8 @@ static GHOST_TKey convertSDLKey(SDL_Scancode key)
|
||||
GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
|
||||
GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
|
||||
GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
|
||||
GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
|
||||
GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyLeftOS);
|
||||
GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyRightOS);
|
||||
GXMAP(type, SDL_SCANCODE_APPLICATION, GHOST_kKeyApp);
|
||||
|
||||
GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
|
||||
|
@@ -613,8 +613,8 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
||||
GXMAP(gkey, XKB_KEY_Control_R, GHOST_kKeyRightControl);
|
||||
GXMAP(gkey, XKB_KEY_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(gkey, XKB_KEY_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyRightOS);
|
||||
GXMAP(gkey, XKB_KEY_Menu, GHOST_kKeyApp);
|
||||
|
||||
GXMAP(gkey, XKB_KEY_Caps_Lock, GHOST_kKeyCapsLock);
|
||||
@@ -2185,8 +2185,8 @@ static void keyboard_handle_enter(void *data,
|
||||
MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl);
|
||||
MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt);
|
||||
MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyLeftOS, logo);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyRightOS, logo);
|
||||
}
|
||||
|
||||
#undef MOD_TEST
|
||||
@@ -3069,7 +3069,8 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co
|
||||
keys.set(GHOST_kModifierKeyRightControl, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.logo);
|
||||
keys.set(GHOST_kModifierKeyOS, val);
|
||||
keys.set(GHOST_kModifierKeyLeftOS, val);
|
||||
keys.set(GHOST_kModifierKeyRightOS, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.num);
|
||||
keys.set(GHOST_kModifierKeyNum, val);
|
||||
|
@@ -456,14 +456,11 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) cons
|
||||
down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightControl, down);
|
||||
|
||||
bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
|
||||
bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
|
||||
if (lwindown || rwindown) {
|
||||
keys.set(GHOST_kModifierKeyOS, true);
|
||||
}
|
||||
else {
|
||||
keys.set(GHOST_kModifierKeyOS, false);
|
||||
}
|
||||
down = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftOS, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightOS, down);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@@ -751,8 +748,10 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten
|
||||
key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt;
|
||||
break;
|
||||
case VK_LWIN:
|
||||
key = GHOST_kKeyLeftOS;
|
||||
break;
|
||||
case VK_RWIN:
|
||||
key = GHOST_kKeyOS;
|
||||
key = GHOST_kKeyRightOS;
|
||||
break;
|
||||
case VK_APPS:
|
||||
key = GHOST_kKeyApp;
|
||||
@@ -1137,12 +1136,18 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
||||
GHOST_TKey key = system->hardKey(raw, &key_down);
|
||||
GHOST_EventKey *event;
|
||||
|
||||
/* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys.
|
||||
* Check for this case and filter out modifier-repeat.
|
||||
* Typically keyboard events are *not* filtered as part of GHOST's event handling.
|
||||
* As other GHOST back-ends don't have the behavior, it's simplest not to send them through.
|
||||
* Ideally it would be possible to check the key-map for keys that repeat but this doesn't look
|
||||
* to be supported. */
|
||||
bool is_repeat = false;
|
||||
bool is_repeated_modifier = false;
|
||||
if (key_down) {
|
||||
if (system->m_keycode_last_repeat_key == vk) {
|
||||
is_repeat = true;
|
||||
is_repeated_modifier = (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt);
|
||||
is_repeated_modifier = GHOST_KEY_IS_MODIFIER(key);
|
||||
}
|
||||
system->m_keycode_last_repeat_key = vk;
|
||||
}
|
||||
|
@@ -105,7 +105,7 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -1065,7 +1065,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
case GHOST_kKeyLeftShift:
|
||||
case GHOST_kKeyRightControl:
|
||||
case GHOST_kKeyLeftControl:
|
||||
case GHOST_kKeyOS:
|
||||
case GHOST_kKeyLeftOS:
|
||||
case GHOST_kKeyRightOS:
|
||||
case GHOST_kKey0:
|
||||
case GHOST_kKey1:
|
||||
case GHOST_kKey2:
|
||||
@@ -1600,9 +1601,10 @@ GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
|
||||
/* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
|
||||
keys.set(GHOST_kModifierKeyOS,
|
||||
(((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftOS,
|
||||
((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightOS,
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) != 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -1818,8 +1820,8 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
|
||||
GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
|
||||
GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(type, XK_Super_L, GHOST_kKeyOS);
|
||||
GXMAP(type, XK_Super_R, GHOST_kKeyOS);
|
||||
GXMAP(type, XK_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(type, XK_Super_R, GHOST_kKeyRightOS);
|
||||
|
||||
GXMAP(type, XK_Insert, GHOST_kKeyInsert);
|
||||
GXMAP(type, XK_Delete, GHOST_kKeyDelete);
|
||||
|
@@ -115,7 +115,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param stereoVisual: Create a stereo visual for quad buffered stereo.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used full*screen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent (embedder) window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -29,7 +29,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param height: The height of the window.
|
||||
* \param state: The state the window is initially opened with.
|
||||
* \param wantStereoVisual: Stereo visual for quad buffered stereo.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used full-screen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
*/
|
||||
GHOST_Window(uint32_t width,
|
||||
uint32_t height,
|
||||
|
@@ -719,7 +719,7 @@ void GHOST_WindowCocoa::setNativePixelSize(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Fullscreen switch is not actual fullscreen with display capture.
|
||||
* \note Full-screen switch is not actual fullscreen with display capture.
|
||||
* As this capture removes all OS X window manager features.
|
||||
*
|
||||
* Instead, the menu bar and the dock are hidden, and the window is made border-less and enlarged.
|
||||
|
@@ -113,13 +113,13 @@ class GHOST_WindowManager {
|
||||
/** The list of windows managed */
|
||||
std::vector<GHOST_IWindow *> m_windows;
|
||||
|
||||
/** Window in fullscreen state. There can be only one of this which is not in or window list. */
|
||||
/** Window in full-screen state. There can be only one of this which is not in or window list. */
|
||||
GHOST_IWindow *m_fullScreenWindow;
|
||||
|
||||
/** The active window. */
|
||||
GHOST_IWindow *m_activeWindow;
|
||||
|
||||
/** Window that was active before entering fullscreen state. */
|
||||
/** Window that was active before entering full-screen state. */
|
||||
GHOST_IWindow *m_activeWindowBeforeFullScreen;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
|
@@ -226,7 +226,7 @@
|
||||
[super drawRect:rect];
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
|
||||
|
||||
/* For some cases like entering fullscreen we need to redraw immediately
|
||||
/* For some cases like entering full-screen we need to redraw immediately
|
||||
* so our window does not show blank during the animation */
|
||||
if (associatedWindow->getImmediateDraw())
|
||||
systemCocoa->dispatchEvents();
|
||||
|
@@ -123,27 +123,44 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
void initFromGhostContext(GHOST_Context &ghost_ctx) override
|
||||
{
|
||||
#if defined(WITH_GHOST_X11) || defined(WITH_GHOST_WAYLAND)
|
||||
if (dynamic_cast<GHOST_ContextEGL *>(&ghost_ctx)) {
|
||||
/* WAYLAND/X11 may be dynamically selected at load time but both may also be
|
||||
* supported at compile time individually.
|
||||
* Without `is_ctx_egl` & `is_wayland` preprocessor checks become an unmanageable soup. */
|
||||
const bool is_ctx_egl = dynamic_cast<GHOST_ContextEGL *>(&ghost_ctx) != nullptr;
|
||||
if (is_ctx_egl) {
|
||||
GHOST_ContextEGL &ctx_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
|
||||
|
||||
const bool is_wayland = (
|
||||
# if defined(WITH_GHOST_WAYLAND)
|
||||
if (dynamic_cast<const GHOST_SystemWayland *const>(ctx_egl.m_system)) {
|
||||
dynamic_cast<const GHOST_SystemWayland *const>(ctx_egl.m_system) != nullptr
|
||||
# else
|
||||
false
|
||||
# endif
|
||||
);
|
||||
|
||||
if (is_wayland) {
|
||||
# if defined(WITH_GHOST_WAYLAND)
|
||||
/* #GHOST_SystemWayland */
|
||||
oxr_binding.wl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WAYLAND_KHR;
|
||||
oxr_binding.wl.display = (struct wl_display *)ctx_egl.m_nativeDisplay;
|
||||
# else
|
||||
GHOST_ASSERT(false, "Unexpected State: logical error, unreachable!");
|
||||
# endif /* !WITH_GHOST_WAYLAND */
|
||||
}
|
||||
else
|
||||
# endif
|
||||
else { /* `!is_wayland` */
|
||||
# if defined(WITH_GHOST_X11)
|
||||
{
|
||||
/* SystemX11. */
|
||||
/* #GHOST_SystemX11. */
|
||||
oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
|
||||
oxr_binding.egl.getProcAddress = eglGetProcAddress;
|
||||
oxr_binding.egl.display = ctx_egl.getDisplay();
|
||||
oxr_binding.egl.config = ctx_egl.getConfig();
|
||||
oxr_binding.egl.context = ctx_egl.getContext();
|
||||
# else
|
||||
GHOST_ASSERT(false, "Unexpected State: built with only WAYLAND and no System found!");
|
||||
# endif /* !WITH_GHOST_X11 */
|
||||
}
|
||||
}
|
||||
else {
|
||||
else { /* `!is_ctx_egl` */
|
||||
# if defined(WITH_GHOST_X11)
|
||||
GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx);
|
||||
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig);
|
||||
|
||||
@@ -155,7 +172,9 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
oxr_binding.glx.visualid = visual_info->visualid;
|
||||
|
||||
XFree(visual_info);
|
||||
# endif
|
||||
# else
|
||||
GHOST_ASSERT(false, "Unexpected State: built without X11 and no EGL context is available!");
|
||||
# endif /* !WITH_GHOST_X11 */
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
|
||||
@@ -163,7 +182,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
oxr_binding.wgl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR;
|
||||
oxr_binding.wgl.hDC = ctx_wgl.m_hDC;
|
||||
oxr_binding.wgl.hGLRC = ctx_wgl.m_hGLRC;
|
||||
#endif
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Generate a frame-buffer to use for blitting into the texture. */
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
|
@@ -315,7 +315,7 @@ bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
|
||||
} break;
|
||||
case GHOST_kKeyF:
|
||||
if (!GHOST_GetFullScreen(shSystem)) {
|
||||
/* Begin fullscreen mode */
|
||||
/* Begin full-screen mode. */
|
||||
setting.bpp = 24;
|
||||
setting.frequency = 85;
|
||||
setting.xPixels = 640;
|
||||
|
@@ -18,3 +18,9 @@ set(LIB
|
||||
add_c_flag(-ffast-math)
|
||||
|
||||
blender_add_lib(bf_intern_libc_compat "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
if(WITH_LIBC_MALLOC_HOOK_WORKAROUND)
|
||||
target_compile_definitions(bf_intern_libc_compat
|
||||
PRIVATE WITH_LIBC_MALLOC_HOOK_WORKAROUND
|
||||
)
|
||||
endif()
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#ifdef __linux__
|
||||
# include <features.h>
|
||||
# include <math.h>
|
||||
# include <stdlib.h>
|
||||
|
||||
# if defined(__GLIBC_PREREQ)
|
||||
# if __GLIBC_PREREQ(2, 31)
|
||||
@@ -114,5 +115,20 @@ float __powf_finite(float x, float y)
|
||||
}
|
||||
|
||||
# endif /* __GLIBC_PREREQ(2, 31) */
|
||||
# endif /* __GLIBC_PREREQ */
|
||||
#endif /* __linux__ */
|
||||
|
||||
# if __GLIBC_PREREQ(2, 34) && defined(WITH_LIBC_MALLOC_HOOK_WORKAROUND)
|
||||
|
||||
extern void *(*__malloc_hook)(size_t __size, const void *);
|
||||
extern void *(*__realloc_hook)(void *__ptr, size_t __size, const void *);
|
||||
extern void *(*__memalign_hook)(size_t __alignment, size_t __size, const void *);
|
||||
extern void (*__free_hook)(void *__ptr, const void *);
|
||||
|
||||
void *(*__malloc_hook)(size_t __size, const void *) = NULL;
|
||||
void *(*__realloc_hook)(void *__ptr, size_t __size, const void *) = NULL;
|
||||
void *(*__memalign_hook)(size_t __alignment, size_t __size, const void *) = NULL;
|
||||
void (*__free_hook)(void *__ptr, const void *) = NULL;
|
||||
|
||||
# endif /* __GLIBC_PREREQ(2, 34) */
|
||||
|
||||
# endif /* __GLIBC_PREREQ */
|
||||
#endif /* __linux__ */
|
||||
|
@@ -108,7 +108,7 @@ void radixsort(std::vector<T> &data, std::vector<T> &data2, KeyGetter getKey)
|
||||
static_assert(datasize % 2 == 0);
|
||||
static_assert(std::is_integral<key_t>::value);
|
||||
|
||||
uint bins[datasize][257] = {0};
|
||||
uint bins[datasize][257] = {{0}};
|
||||
|
||||
/* Count number of elements per bin. */
|
||||
for (const T &item : data) {
|
||||
|
@@ -401,7 +401,7 @@ template<typename Mesh> class Mikktspace {
|
||||
});
|
||||
|
||||
std::stable_partition(triangles.begin(), triangles.end(), [](const Triangle &tri) {
|
||||
return tri.markDegenerate;
|
||||
return !tri.markDegenerate;
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -72,7 +72,7 @@ class TriMesh:
|
||||
@staticmethod
|
||||
def _tri_copy_from_object(ob):
|
||||
import bmesh
|
||||
assert(ob.type in OBJECTS_TYPES_MESH_COMPATIBLE)
|
||||
assert ob.type in OBJECTS_TYPES_MESH_COMPATIBLE
|
||||
bm = bmesh.new()
|
||||
bm.from_mesh(ob.to_mesh())
|
||||
bmesh.ops.triangulate(bm, faces=bm.faces)
|
||||
@@ -143,7 +143,7 @@ def mesh_data_lists_from_mesh(me, material_colors):
|
||||
i1 = 1
|
||||
|
||||
# we only write tris now
|
||||
assert(len(loops_poly) == 3)
|
||||
assert len(loops_poly) == 3
|
||||
|
||||
for i2 in range(2, l_len):
|
||||
l0 = loops_poly[i0]
|
||||
@@ -217,7 +217,7 @@ def mesh_data_lists_from_objects(ob_parent, ob_children):
|
||||
def write_mesh_to_py(fh, ob, ob_children):
|
||||
|
||||
def float_as_byte(f, axis_range):
|
||||
assert(axis_range <= 255)
|
||||
assert axis_range <= 255
|
||||
# -1..1 -> 0..255
|
||||
f = (f + 1.0) * 0.5
|
||||
f = round(f * axis_range)
|
||||
@@ -238,7 +238,7 @@ def write_mesh_to_py(fh, ob, ob_children):
|
||||
if 0:
|
||||
# make as large as we can, keeping alignment
|
||||
def size_scale_up(size):
|
||||
assert(size != 0)
|
||||
assert size != 0
|
||||
while size * 2 <= 255:
|
||||
size *= 2
|
||||
return size
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user