Compare commits
47 Commits
temp-geome
...
retopo_tra
Author | SHA1 | Date | |
---|---|---|---|
6485941d7a | |||
eee25a175a | |||
4f33dcff78 | |||
fd39da1df6 | |||
dbdab681cf | |||
66c6cf0d71 | |||
8ab91edd91 | |||
3ac5a52d6e | |||
60a8ade18a | |||
d57ce54e30 | |||
a735b2c335 | |||
73aa6b8185 | |||
698efac59e | |||
afe11eff8a | |||
4ebe1c3e69 | |||
887713d08d | |||
cc761cdae6 | |||
a2938c86ca | |||
a66e20f984 | |||
db317f070e | |||
7502bc583c | |||
089870ab3a | |||
298711d158 | |||
8d284d4854 | |||
9e88cfbe0c | |||
405bbb06f2 | |||
ed8f2bbf5c | |||
ddce8e9ea3 | |||
1b9e31f004 | |||
8791762af0 | |||
8d813f2eed | |||
af29d103c6 | |||
ca336c600b | |||
491ada0a38 | |||
62f813754d | |||
cbeb70bdae | |||
139a651434 | |||
add307d429 | |||
59e6dc8a93 | |||
6410fe0492 | |||
b818008ddf | |||
af9c969768 | |||
0b25d923e5 | |||
a863ba191d | |||
f606393522 | |||
f8b389b121 | |||
![]() |
59adee83e7 |
@@ -266,7 +266,6 @@ ForEachMacros:
|
||||
- MAP_SLOT_PROBING_BEGIN
|
||||
- VECTOR_SET_SLOT_PROBING_BEGIN
|
||||
- WL_ARRAY_FOR_EACH
|
||||
- FOREACH_SPECTRUM_CHANNEL
|
||||
|
||||
StatementMacros:
|
||||
- PyObject_HEAD
|
||||
|
294
CMakeLists.txt
294
CMakeLists.txt
@@ -25,6 +25,13 @@ endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# Prefer LEGACY OpenGL to be compatible with all the existing releases and
|
||||
# platforms which don't have GLVND yet. Only do it if preference was not set
|
||||
# externally.
|
||||
if(NOT DEFINED OpenGL_GL_PREFERENCE)
|
||||
set(OpenGL_GL_PREFERENCE "LEGACY")
|
||||
endif()
|
||||
|
||||
if(NOT EXECUTABLE_OUTPUT_PATH)
|
||||
set(FIRST_RUN TRUE)
|
||||
else()
|
||||
@@ -105,12 +112,6 @@ blender_project_hack_post()
|
||||
|
||||
enable_testing()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test compiler/library features.
|
||||
|
||||
include(build_files/cmake/have_features.cmake)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Redirect output files
|
||||
|
||||
@@ -195,7 +196,7 @@ endif()
|
||||
option(WITH_GMP "Enable features depending on GMP (Exact Boolean)" ON)
|
||||
|
||||
# Compositor
|
||||
option(WITH_COMPOSITOR_CPU "Enable the tile based CPU nodal compositor" ON)
|
||||
option(WITH_COMPOSITOR "Enable the tile based nodal compositor" ON)
|
||||
option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ON)
|
||||
|
||||
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ON)
|
||||
@@ -222,7 +223,7 @@ if(UNIX AND NOT (APPLE OR HAIKU))
|
||||
option(WITH_GHOST_WAYLAND "Enable building Blender against Wayland for windowing (under development)" OFF)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND)
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
if (WITH_GHOST_WAYLAND)
|
||||
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" OFF)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
|
||||
@@ -261,6 +262,7 @@ if(WITH_GHOST_X11)
|
||||
option(WITH_X11_XINPUT "Enable X11 Xinput (tablet support and unicode input)" ON)
|
||||
option(WITH_X11_XF86VMODE "Enable X11 video mode switching" ON)
|
||||
option(WITH_X11_XFIXES "Enable X11 XWayland cursor warping workaround" ON)
|
||||
option(WITH_X11_ALPHA "Enable X11 transparent background" ON)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
@@ -364,7 +366,7 @@ if(WIN32 OR APPLE)
|
||||
endif()
|
||||
option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
|
||||
if(UNIX AND NOT APPLE)
|
||||
option(WITH_INSTALL_PORTABLE "Install redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
|
||||
option(WITH_INSTALL_PORTABLE "Install redistributeable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON)
|
||||
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
|
||||
if(WITH_STATIC_LIBS)
|
||||
option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF)
|
||||
@@ -435,16 +437,10 @@ if(NOT APPLE)
|
||||
option(WITH_CYCLES_CUBIN_COMPILER "Build cubins with nvrtc based compiler instead of nvcc" OFF)
|
||||
option(WITH_CYCLES_CUDA_BUILD_SERIAL "Build cubins one after another (useful on machines with limited RAM)" OFF)
|
||||
option(WITH_CUDA_DYNLOAD "Dynamically load CUDA libraries at runtime (for developers, makes cuda-gdb work)" ON)
|
||||
|
||||
set(OPTIX_ROOT_DIR "" CACHE PATH "Path to the OptiX SDK root directory, for building Cycles OptiX kernels.")
|
||||
set(CYCLES_RUNTIME_OPTIX_ROOT_DIR "" CACHE PATH "Path to the OptiX SDK root directory. When set, this path will be used at runtime to compile OptiX kernels.")
|
||||
|
||||
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
|
||||
mark_as_advanced(WITH_CYCLES_CUBIN_COMPILER)
|
||||
mark_as_advanced(WITH_CYCLES_CUDA_BUILD_SERIAL)
|
||||
mark_as_advanced(WITH_CUDA_DYNLOAD)
|
||||
mark_as_advanced(OPTIX_ROOT_DIR)
|
||||
mark_as_advanced(CYCLES_RUNTIME_OPTIX_ROOT_DIR)
|
||||
endif()
|
||||
|
||||
# AMD HIP
|
||||
@@ -468,8 +464,8 @@ if(NOT APPLE)
|
||||
option(WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED "Enable use of SYCL host (CPU) device execution by oneAPI implementation. This option is for debugging purposes and impacts GPU execution." OFF)
|
||||
|
||||
# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compilation/ahead-of-time-compilation.html
|
||||
set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "dg2" CACHE STRING "oneAPI Intel GPU architectures to build binaries for")
|
||||
set(CYCLES_ONEAPI_SYCL_TARGETS spir64 spir64_gen CACHE STRING "oneAPI targets to build AOT binaries for")
|
||||
SET (CYCLES_ONEAPI_SPIR64_GEN_DEVICES "dg2" CACHE STRING "oneAPI Intel GPU architectures to build binaries for")
|
||||
SET (CYCLES_ONEAPI_SYCL_TARGETS spir64 spir64_gen CACHE STRING "oneAPI targets to build AOT binaries for")
|
||||
|
||||
mark_as_advanced(WITH_CYCLES_ONEAPI_SYCL_HOST_ENABLED)
|
||||
mark_as_advanced(CYCLES_ONEAPI_SPIR64_GEN_DEVICES)
|
||||
@@ -540,27 +536,71 @@ endif()
|
||||
|
||||
# OpenGL
|
||||
|
||||
# Experimental EGL option.
|
||||
option(WITH_GL_EGL "Use the EGL OpenGL system library instead of the platform specific OpenGL system library (CGL, GLX or WGL)" OFF)
|
||||
mark_as_advanced(WITH_GL_EGL)
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
# Wayland can only use EGL to create OpenGL contexts, not GLX.
|
||||
set(WITH_GL_EGL ON)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(WITH_GL_EGL)
|
||||
# GLEW can only be built with either GLX or EGL support. Most binary distributions are
|
||||
# built with GLX support and we have no automated way to detect this. So always build
|
||||
# GLEW from source to be sure it has EGL support.
|
||||
set(WITH_SYSTEM_GLEW OFF)
|
||||
else()
|
||||
option(WITH_SYSTEM_GLEW "Use GLEW OpenGL wrapper library provided by the operating system" OFF)
|
||||
endif()
|
||||
|
||||
option(WITH_SYSTEM_GLES "Use OpenGL ES library provided by the operating system" ON)
|
||||
else()
|
||||
# System GLEW and GLES not an option on other platforms.
|
||||
set(WITH_SYSTEM_GLEW OFF)
|
||||
set(WITH_SYSTEM_GLES OFF)
|
||||
endif()
|
||||
|
||||
option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON)
|
||||
option(WITH_GLEW_ES "Switches to experimental copy of GLEW that has support for OpenGL ES. (temporary option for development purposes)" OFF)
|
||||
option(WITH_GL_PROFILE_ES20 "Support using OpenGL ES 2.0. (through either EGL or the AGL/WGL/XGL 'es20' profile)" OFF)
|
||||
option(WITH_GPU_BUILDTIME_SHADER_BUILDER "Shader builder is a developer option enabling linting on GLSL during compilation" OFF)
|
||||
|
||||
mark_as_advanced(
|
||||
WITH_OPENGL
|
||||
WITH_GLEW_ES
|
||||
WITH_GL_PROFILE_ES20
|
||||
WITH_GPU_BUILDTIME_SHADER_BUILDER
|
||||
)
|
||||
|
||||
if(WITH_HEADLESS)
|
||||
set(WITH_OPENGL OFF)
|
||||
endif()
|
||||
|
||||
# Metal
|
||||
|
||||
if(APPLE)
|
||||
if (APPLE)
|
||||
option(WITH_METAL_BACKEND "Use Metal for graphics instead of (or as well as) OpenGL on macOS." OFF)
|
||||
mark_as_advanced(WITH_METAL_BACKEND)
|
||||
else()
|
||||
set(WITH_METAL_BACKEND OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_METAL_BACKEND)
|
||||
if (WITH_METAL_BACKEND)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
option(WITH_GL_ANGLE "Link with the ANGLE library, an OpenGL ES 2.0 implementation based on Direct3D, instead of the system OpenGL library." OFF)
|
||||
mark_as_advanced(WITH_GL_ANGLE)
|
||||
endif()
|
||||
|
||||
if(WITH_GLEW_ES AND WITH_SYSTEM_GLEW)
|
||||
message(WARNING Ignoring WITH_SYSTEM_GLEW and using WITH_GLEW_ES)
|
||||
set(WITH_SYSTEM_GLEW OFF)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
getDefaultWindowsPrefixBase(CMAKE_GENERIC_PROGRAM_FILES)
|
||||
set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${})
|
||||
@@ -737,13 +777,6 @@ if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Effective install path including config folder, as a generator expression.
|
||||
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" CMAKE_INSTALL_PREFIX_WITH_CONFIG ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
string(REPLACE "\${BUILD_TYPE}" "" CMAKE_INSTALL_PREFIX_WITH_CONFIG ${CMAKE_INSTALL_PREFIX})
|
||||
endif()
|
||||
|
||||
|
||||
# Apple
|
||||
@@ -864,6 +897,7 @@ if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_XFIXES OFF)
|
||||
set(WITH_X11_ALPHA OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_INPUT_IME OFF)
|
||||
set(WITH_XR_OPENXR OFF)
|
||||
@@ -1162,8 +1196,7 @@ if(WITH_OPENVDB)
|
||||
list(APPEND OPENVDB_INCLUDE_DIRS
|
||||
${BOOST_INCLUDE_DIR}
|
||||
${TBB_INCLUDE_DIRS}
|
||||
${OPENEXR_INCLUDE_DIRS}
|
||||
)
|
||||
${OPENEXR_INCLUDE_DIRS})
|
||||
|
||||
list(APPEND OPENVDB_LIBRARIES ${OPENEXR_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
|
||||
@@ -1178,13 +1211,142 @@ endif()
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure OpenGL.
|
||||
|
||||
find_package(OpenGL)
|
||||
blender_include_dirs_sys("${OPENGL_INCLUDE_DIR}")
|
||||
|
||||
if(WITH_OPENGL)
|
||||
add_definitions(-DWITH_OPENGL)
|
||||
endif()
|
||||
|
||||
if(WITH_SYSTEM_GLES)
|
||||
find_package_wrapper(OpenGLES)
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
if(WITH_SYSTEM_GLES)
|
||||
if(NOT OPENGLES_LIBRARY)
|
||||
message(FATAL_ERROR
|
||||
"Unable to find OpenGL ES libraries. "
|
||||
"Install them or disable WITH_SYSTEM_GLES."
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}")
|
||||
|
||||
else()
|
||||
set(OPENGLES_LIBRARY "" CACHE FILEPATH "OpenGL ES 2.0 library file")
|
||||
mark_as_advanced(OPENGLES_LIBRARY)
|
||||
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}")
|
||||
|
||||
if(NOT OPENGLES_LIBRARY)
|
||||
message(FATAL_ERROR
|
||||
"To compile WITH_GL_EGL you need to set OPENGLES_LIBRARY "
|
||||
"to the file path of an OpenGL ES 2.0 library."
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Setup paths to files needed to install and redistribute Windows Blender with OpenGL ES
|
||||
|
||||
set(OPENGLES_DLL "" CACHE FILEPATH "OpenGL ES 2.0 redistributable DLL file")
|
||||
mark_as_advanced(OPENGLES_DLL)
|
||||
|
||||
if(NOT OPENGLES_DLL)
|
||||
message(FATAL_ERROR
|
||||
"To compile WITH_GL_PROFILE_ES20 you need to set OPENGLES_DLL to the file "
|
||||
"path of an OpenGL ES 2.0 runtime dynamic link library (DLL)."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GL_ANGLE)
|
||||
list(APPEND GL_DEFINITIONS -DWITH_ANGLE)
|
||||
|
||||
set(D3DCOMPILER_DLL "" CACHE FILEPATH "Direct3D Compiler redistributable DLL file (needed by ANGLE)")
|
||||
|
||||
get_filename_component(D3DCOMPILER_FILENAME "${D3DCOMPILER_DLL}" NAME)
|
||||
list(APPEND GL_DEFINITIONS "-DD3DCOMPILER=\"\\\"${D3DCOMPILER_FILENAME}\\\"\"")
|
||||
|
||||
mark_as_advanced(D3DCOMPILER_DLL)
|
||||
|
||||
if(D3DCOMPILER_DLL STREQUAL "")
|
||||
message(FATAL_ERROR
|
||||
"To compile WITH_GL_ANGLE you need to set D3DCOMPILER_DLL to the file "
|
||||
"path of a copy of the DirectX redistributable DLL file: D3DCompiler_46.dll"
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
else()
|
||||
if(OpenGL_GL_PREFERENCE STREQUAL "LEGACY" AND OPENGL_gl_LIBRARY)
|
||||
list(APPEND BLENDER_GL_LIBRARIES ${OPENGL_gl_LIBRARY})
|
||||
else()
|
||||
list(APPEND BLENDER_GL_LIBRARIES ${OPENGL_opengl_LIBRARY} ${OPENGL_glx_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_GL_EGL)
|
||||
find_package(OpenGL REQUIRED EGL)
|
||||
list(APPEND BLENDER_GL_LIBRARIES OpenGL::EGL)
|
||||
|
||||
list(APPEND GL_DEFINITIONS -DWITH_GL_EGL -DGLEW_EGL -DGLEW_INC_EGL)
|
||||
|
||||
if(WITH_SYSTEM_GLES)
|
||||
if(NOT OPENGLES_EGL_LIBRARY)
|
||||
message(FATAL_ERROR
|
||||
"Unable to find OpenGL ES libraries. "
|
||||
"Install them or disable WITH_SYSTEM_GLES."
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND BLENDER_GL_LIBRARIES ${OPENGLES_EGL_LIBRARY})
|
||||
|
||||
else()
|
||||
set(OPENGLES_EGL_LIBRARY "" CACHE FILEPATH "EGL library file")
|
||||
mark_as_advanced(OPENGLES_EGL_LIBRARY)
|
||||
|
||||
list(APPEND BLENDER_GL_LIBRARIES "${OPENGLES_LIBRARY}" "${OPENGLES_EGL_LIBRARY}")
|
||||
|
||||
if(NOT OPENGLES_EGL_LIBRARY)
|
||||
message(FATAL_ERROR
|
||||
"To compile WITH_GL_EGL you need to set OPENGLES_EGL_LIBRARY "
|
||||
"to the file path of an EGL library."
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Setup paths to files needed to install and redistribute Windows Blender with OpenGL ES
|
||||
|
||||
set(OPENGLES_EGL_DLL "" CACHE FILEPATH "EGL redistributable DLL file")
|
||||
mark_as_advanced(OPENGLES_EGL_DLL)
|
||||
|
||||
if(NOT OPENGLES_EGL_DLL)
|
||||
message(FATAL_ERROR
|
||||
"To compile WITH_GL_EGL you need to set OPENGLES_EGL_DLL "
|
||||
"to the file path of an EGL runtime dynamic link library (DLL)."
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_ES20)
|
||||
else()
|
||||
list(APPEND GL_DEFINITIONS -DWITH_GL_PROFILE_CORE)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Metal.
|
||||
if(WITH_METAL_BACKEND)
|
||||
if (WITH_METAL_BACKEND)
|
||||
add_definitions(-DWITH_METAL_BACKEND)
|
||||
|
||||
# No need to add frameworks here, all the ones we need for Metal and
|
||||
@@ -1225,6 +1387,66 @@ if(WITH_OPENMP)
|
||||
)
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure GLEW
|
||||
|
||||
if(WITH_SYSTEM_GLEW)
|
||||
find_package(GLEW)
|
||||
|
||||
# Note: There is an assumption here that the system GLEW is not a static library.
|
||||
|
||||
if(NOT GLEW_FOUND)
|
||||
message(FATAL_ERROR "GLEW is required to build Blender. Install it or disable WITH_SYSTEM_GLEW.")
|
||||
endif()
|
||||
|
||||
set(GLEW_INCLUDE_PATH "${GLEW_INCLUDE_DIR}")
|
||||
set(BLENDER_GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
else()
|
||||
if(WITH_GLEW_ES)
|
||||
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew-es/include")
|
||||
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_STATIC -DWITH_GLEW_ES)
|
||||
|
||||
# These definitions remove APIs from glew.h, making GLEW smaller, and catching unguarded API usage
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_ES_ONLY)
|
||||
else()
|
||||
# No ES functions are needed
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_NO_ES)
|
||||
endif()
|
||||
|
||||
if(WITH_GL_PROFILE_ES20)
|
||||
if(WITH_GL_EGL)
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_USE_LIB_ES20)
|
||||
endif()
|
||||
|
||||
# ToDo: This is an experiment to eliminate ES 1 symbols,
|
||||
# GLEW doesn't really properly provide this level of control
|
||||
# (for example, without modification it eliminates too many symbols)
|
||||
# so there are lots of modifications to GLEW to make this work,
|
||||
# and no attempt to make it work beyond Blender at this point.
|
||||
list(APPEND GL_DEFINITIONS -DGL_ES_VERSION_1_0=0 -DGL_ES_VERSION_CL_1_1=0 -DGL_ES_VERSION_CM_1_1=0)
|
||||
endif()
|
||||
|
||||
set(BLENDER_GLEW_LIBRARIES extern_glew_es bf_intern_glew_mx)
|
||||
|
||||
else()
|
||||
set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include")
|
||||
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_STATIC)
|
||||
|
||||
# This won't affect the non-experimental glew library,
|
||||
# but is used for conditional compilation elsewhere.
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_NO_ES)
|
||||
|
||||
set(BLENDER_GLEW_LIBRARIES extern_glew)
|
||||
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
list(APPEND GL_DEFINITIONS -DGLEW_NO_GLU)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Configure Bullet
|
||||
|
||||
@@ -1750,6 +1972,7 @@ if(WITH_BLENDER)
|
||||
# internal and external library information first, for test linking
|
||||
add_subdirectory(source)
|
||||
elseif(WITH_CYCLES_STANDALONE OR WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
add_subdirectory(intern/glew-mx)
|
||||
add_subdirectory(intern/guardedalloc)
|
||||
add_subdirectory(intern/libc_compat)
|
||||
add_subdirectory(intern/sky)
|
||||
@@ -1767,6 +1990,9 @@ elseif(WITH_CYCLES_STANDALONE OR WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
if(WITH_HIP_DYNLOAD)
|
||||
add_subdirectory(extern/hipew)
|
||||
endif()
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
add_subdirectory(extern/glew)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
@@ -1859,6 +2085,8 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_INSTALL_PORTABLE)
|
||||
info_cfg_option(WITH_MEM_JEMALLOC)
|
||||
info_cfg_option(WITH_MEM_VALGRIND)
|
||||
info_cfg_option(WITH_SYSTEM_GLEW)
|
||||
info_cfg_option(WITH_X11_ALPHA)
|
||||
info_cfg_option(WITH_X11_XF86VMODE)
|
||||
info_cfg_option(WITH_X11_XFIXES)
|
||||
info_cfg_option(WITH_X11_XINPUT)
|
||||
@@ -1905,6 +2133,14 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_MOD_OCEANSIM)
|
||||
info_cfg_option(WITH_MOD_REMESH)
|
||||
|
||||
info_cfg_text("OpenGL:")
|
||||
if(WIN32)
|
||||
info_cfg_option(WITH_GL_ANGLE)
|
||||
endif()
|
||||
info_cfg_option(WITH_GL_EGL)
|
||||
info_cfg_option(WITH_GL_PROFILE_ES20)
|
||||
info_cfg_option(WITH_GLEW_ES)
|
||||
|
||||
info_cfg_text("")
|
||||
|
||||
message("${_config_msg}")
|
||||
|
@@ -53,8 +53,8 @@ include(cmake/imath.cmake)
|
||||
include(cmake/openexr.cmake)
|
||||
include(cmake/brotli.cmake)
|
||||
include(cmake/freetype.cmake)
|
||||
include(cmake/epoxy.cmake)
|
||||
include(cmake/freeglut.cmake)
|
||||
include(cmake/glew.cmake)
|
||||
include(cmake/alembic.cmake)
|
||||
include(cmake/opensubdiv.cmake)
|
||||
include(cmake/sdl.cmake)
|
||||
|
@@ -12,13 +12,21 @@ if(UNIX)
|
||||
automake
|
||||
bison
|
||||
${_libtoolize_name}
|
||||
meson
|
||||
ninja
|
||||
pkg-config
|
||||
tclsh
|
||||
yasm
|
||||
)
|
||||
|
||||
if(NOT APPLE)
|
||||
set(_required_software
|
||||
${_required_software}
|
||||
|
||||
# Needed for Mesa.
|
||||
meson
|
||||
ninja
|
||||
)
|
||||
endif()
|
||||
|
||||
foreach(_software ${_required_software})
|
||||
find_program(_software_find NAMES ${_software})
|
||||
if(NOT _software_find)
|
||||
@@ -49,7 +57,7 @@ if(UNIX)
|
||||
" apt install autoconf automake libtool yasm tcl ninja-build meson python3-mako\n"
|
||||
"\n"
|
||||
"On macOS (with homebrew):\n"
|
||||
" brew install autoconf automake bison flex libtool meson ninja pkg-config yasm\n"
|
||||
" brew install autoconf automake bison flex libtool pkg-config yasm\n"
|
||||
"\n"
|
||||
"Other platforms:\n"
|
||||
" Install equivalent packages.\n")
|
||||
|
@@ -36,7 +36,7 @@ download_source(BLOSC)
|
||||
download_source(PTHREADS)
|
||||
download_source(OPENEXR)
|
||||
download_source(FREETYPE)
|
||||
download_source(EPOXY)
|
||||
download_source(GLEW)
|
||||
download_source(FREEGLUT)
|
||||
download_source(ALEMBIC)
|
||||
download_source(OPENSUBDIV)
|
||||
@@ -94,7 +94,6 @@ download_source(GMP)
|
||||
download_source(POTRACE)
|
||||
download_source(HARU)
|
||||
download_source(ZSTD)
|
||||
download_source(SSE2NEON)
|
||||
download_source(FLEX)
|
||||
download_source(BROTLI)
|
||||
download_source(FMT)
|
||||
|
@@ -1,25 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
if(WIN32)
|
||||
set(EPOXY_LIB_TYPE shared)
|
||||
else()
|
||||
set(EPOXY_LIB_TYPE static)
|
||||
endif()
|
||||
ExternalProject_Add(external_epoxy
|
||||
URL file://${PACKAGE_DIR}/${EPOXY_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${EPOXY_HASH_TYPE}=${EPOXY_HASH}
|
||||
PREFIX ${BUILD_DIR}/epoxy
|
||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/epoxy/src/external_epoxy/ < ${PATCH_DIR}/epoxy.diff
|
||||
CONFIGURE_COMMAND ${CONFIGURE_ENV} && meson setup --prefix ${LIBDIR}/epoxy --default-library ${EPOXY_LIB_TYPE} --libdir lib ${BUILD_DIR}/epoxy/src/external_epoxy-build ${BUILD_DIR}/epoxy/src/external_epoxy -Dtests=false
|
||||
BUILD_COMMAND ninja
|
||||
INSTALL_COMMAND ninja install
|
||||
)
|
||||
|
||||
if(BUILD_MODE STREQUAL Release AND WIN32)
|
||||
ExternalProject_Add_Step(external_epoxy after_install
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/epoxy/include ${HARVEST_TARGET}/epoxy/include
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/epoxy/bin/epoxy-0.dll ${HARVEST_TARGET}/epoxy/bin/epoxy-0.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/epoxy/lib/epoxy.lib ${HARVEST_TARGET}/epoxy/lib/epoxy.lib
|
||||
DEPENDEES install
|
||||
)
|
||||
endif()
|
16
build_files/build_environment/cmake/glew.cmake
Normal file
16
build_files/build_environment/cmake/glew.cmake
Normal file
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
set(GLEW_EXTRA_ARGS
|
||||
-DBUILD_UTILS=Off
|
||||
-DBUILD_SHARED_LIBS=Off
|
||||
)
|
||||
|
||||
ExternalProject_Add(external_glew
|
||||
URL file://${PACKAGE_DIR}/${GLEW_FILE}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${GLEW_HASH_TYPE}=${GLEW_HASH}
|
||||
PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_glew.txt ${BUILD_DIR}/glew/src/external_glew/CMakeLists.txt
|
||||
PREFIX ${BUILD_DIR}/glew
|
||||
CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=${LIBDIR}/glew ${DEFAULT_CMAKE_FLAGS} ${GLEW_EXTRA_ARGS}
|
||||
INSTALL_DIR ${LIBDIR}/glew
|
||||
)
|
@@ -22,6 +22,9 @@ if(BUILD_MODE STREQUAL Release)
|
||||
# freeglut-> opengl
|
||||
${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ &&
|
||||
# glew-> opengl
|
||||
${CMAKE_COMMAND} -E copy ${LIBDIR}/glew/lib/libglew32.lib ${HARVEST_TARGET}/opengl/lib/glew.lib &&
|
||||
${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/glew/include/ ${HARVEST_TARGET}/opengl/include/ &&
|
||||
DEPENDS
|
||||
)
|
||||
endif()
|
||||
@@ -40,8 +43,7 @@ function(harvest from to)
|
||||
install(
|
||||
FILES ${LIBDIR}/${from}
|
||||
DESTINATION ${HARVEST_TARGET}/${dirpath}
|
||||
RENAME ${filename}
|
||||
)
|
||||
RENAME ${filename})
|
||||
else()
|
||||
install(
|
||||
DIRECTORY ${LIBDIR}/${from}/
|
||||
@@ -51,8 +53,7 @@ function(harvest from to)
|
||||
PATTERN "pkgconfig" EXCLUDE
|
||||
PATTERN "cmake" EXCLUDE
|
||||
PATTERN "__pycache__" EXCLUDE
|
||||
PATTERN "tests" EXCLUDE
|
||||
)
|
||||
PATTERN "tests" EXCLUDE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -72,8 +73,8 @@ harvest(fftw3/lib fftw3/lib "*.a")
|
||||
harvest(flac/lib sndfile/lib "libFLAC.a")
|
||||
harvest(freetype/include freetype/include "*.h")
|
||||
harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a)
|
||||
harvest(epoxy/include epoxy/include "*.h")
|
||||
harvest(epoxy/lib epoxy/lib "*.a")
|
||||
harvest(glew/include glew/include "*.h")
|
||||
harvest(glew/lib glew/lib "*.a")
|
||||
harvest(gmp/include gmp/include "*.h")
|
||||
harvest(gmp/lib gmp/lib "*.a")
|
||||
harvest(jemalloc/include jemalloc/include "*.h")
|
||||
|
@@ -27,7 +27,6 @@ if(WIN32)
|
||||
PREFIX ${BUILD_DIR}/python
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p x64 -c ${BUILD_MODE}
|
||||
PATCH_COMMAND ${PATCH_CMD} --verbose -p1 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_windows.diff
|
||||
INSTALL_COMMAND ${PYTHON_BINARY_INTERNAL} ${PYTHON_SRC}/PC/layout/main.py -b ${PYTHON_SRC}/PCbuild/amd64 -s ${PYTHON_SRC} -t ${PYTHON_SRC}/tmp/ --include-stable --include-pip --include-dev --include-launchers --include-venv --include-symbols ${PYTHON_EXTRA_INSTLAL_FLAGS} --copy ${LIBDIR}/python
|
||||
)
|
||||
|
||||
|
@@ -1,9 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
ExternalProject_Add(external_sse2neon
|
||||
URL file://${PACKAGE_DIR}/${SSE2NEON_FILE}
|
||||
GIT_REPOSITORY ${SSE2NEON_GIT}
|
||||
GIT_TAG ${SSE2NEON_GIT_HASH}
|
||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||
URL_HASH ${SSE2NEON_HASH_TYPE}=${SSE2NEON_HASH}
|
||||
PREFIX ${BUILD_DIR}/sse2neon
|
||||
CONFIGURE_COMMAND echo sse2neon - Nothing to configure
|
||||
BUILD_COMMAND echo sse2neon - nothing to build
|
||||
|
@@ -80,11 +80,11 @@ set(FREETYPE_HASH bd4e3b007474319909a6b79d50908e85)
|
||||
set(FREETYPE_HASH_TYPE MD5)
|
||||
set(FREETYPE_FILE freetype-${FREETYPE_VERSION}.tar.gz)
|
||||
|
||||
set(EPOXY_VERSION 1.5.10)
|
||||
set(EPOXY_URI https://github.com/anholt/libepoxy/archive/refs/tags/${EPOXY_VERSION}.tar.gz)
|
||||
set(EPOXY_HASH f0730aad115c952e77591fcc805b1dc1)
|
||||
set(EPOXY_HASH_TYPE MD5)
|
||||
set(EPOXY_FILE libepoxy-${EPOXY_VERSION}.tar.gz)
|
||||
set(GLEW_VERSION 1.13.0)
|
||||
set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz)
|
||||
set(GLEW_HASH 7cbada3166d2aadfc4169c4283701066)
|
||||
set(GLEW_HASH_TYPE MD5)
|
||||
set(GLEW_FILE glew-${GLEW_VERSION}.tgz)
|
||||
|
||||
set(FREEGLUT_VERSION 3.0.0)
|
||||
set(FREEGLUT_URI http://prdownloads.sourceforge.net/freeglut/freeglut/${FREEGLUT_VERSION}/freeglut-${FREEGLUT_VERSION}.tar.gz)
|
||||
@@ -488,11 +488,8 @@ set(ZSTD_HASH 5194fbfa781fcf45b98c5e849651aa7b3b0a008c6b72d4a0db760f3002291e94)
|
||||
set(ZSTD_HASH_TYPE SHA256)
|
||||
set(ZSTD_FILE zstd-${ZSTD_VERSION}.tar.gz)
|
||||
|
||||
set(SSE2NEON_VERSION fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
|
||||
set(SSE2NEON_URI https://github.com/DLTcollab/sse2neon/archive/${SSE2NEON_VERSION}.tar.gz)
|
||||
set(SSE2NEON_HASH 0780253525d299c31775ef95853698d03db9c7739942af8570000f4a25a5d605)
|
||||
set(SSE2NEON_HASH_TYPE SHA256)
|
||||
set(SSE2NEON_FILE sse2neon-${SSE2NEON_VERSION}.tar.gz)
|
||||
set(SSE2NEON_GIT https://github.com/DLTcollab/sse2neon.git)
|
||||
set(SSE2NEON_GIT_HASH fe5ff00bb8d19b327714a3c290f3e2ce81ba3525)
|
||||
|
||||
set(BROTLI_VERSION v1.0.9)
|
||||
set(BROTLI_URI https://github.com/google/brotli/archive/refs/tags/${BROTLI_VERSION}.tar.gz)
|
||||
@@ -506,9 +503,9 @@ set(LEVEL_ZERO_HASH c39bb05a8e5898aa6c444e1704105b93d3f1888b9c333f8e7e73825ffbfb
|
||||
set(LEVEL_ZERO_HASH_TYPE SHA256)
|
||||
set(LEVEL_ZERO_FILE level-zero-${LEVEL_ZERO_VERSION}.tar.gz)
|
||||
|
||||
set(DPCPP_VERSION 20220812)
|
||||
set(DPCPP_VERSION 20220620)
|
||||
set(DPCPP_URI https://github.com/intel/llvm/archive/refs/tags/sycl-nightly/${DPCPP_VERSION}.tar.gz)
|
||||
set(DPCPP_HASH 0e3c95346c295f5cf80f3a42d80b1c49481955898530242636ddc002627248d6)
|
||||
set(DPCPP_HASH a5f41abd5229d28afa92cbd8a5d8d786ee698bf239f722929fd686276bad692c)
|
||||
set(DPCPP_HASH_TYPE SHA256)
|
||||
set(DPCPP_FILE DPCPP-${DPCPP_VERSION}.tar.gz)
|
||||
|
||||
|
@@ -1193,7 +1193,7 @@ Those libraries should be available as packages in all recent distributions (opt
|
||||
* libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed).
|
||||
* libwayland-client0, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland)
|
||||
* libsqlite3, libzstd, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp, flex.
|
||||
* libsdl2, libepoxy, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf].\""
|
||||
* libsdl2, libglew, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf].\""
|
||||
|
||||
DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES:
|
||||
|
||||
@@ -4062,7 +4062,7 @@ install_DEB() {
|
||||
libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \
|
||||
libwayland-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \
|
||||
libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \
|
||||
libopenal-dev libepoxy-dev yasm \
|
||||
libopenal-dev libglew-dev yasm \
|
||||
libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \
|
||||
libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev libzstd-dev libpystring-dev"
|
||||
|
||||
@@ -4772,7 +4772,7 @@ install_RPM() {
|
||||
libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \
|
||||
wayland-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \
|
||||
wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \
|
||||
libepoxy-devel yasm patch \
|
||||
glew-devel yasm patch \
|
||||
libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \
|
||||
gmp-devel pugixml-devel potrace-devel libharu-devel libzstd-devel pystring-devel"
|
||||
|
||||
@@ -5412,7 +5412,7 @@ install_ARCH() {
|
||||
fi
|
||||
|
||||
_packages="$BASE_DEVEL git cmake fontconfig flex \
|
||||
libxi libxcursor libxrandr libxinerama libepoxy libpng libtiff wget openal \
|
||||
libxi libxcursor libxrandr libxinerama glew libpng libtiff wget openal \
|
||||
$OPENJPEG_DEV yasm sdl2 fftw \
|
||||
libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml libharu \
|
||||
zstd pystring"
|
||||
|
@@ -0,0 +1,2 @@
|
||||
cmake_minimum_required (VERSION 2.4)
|
||||
add_subdirectory(build/cmake)
|
@@ -1,3 +1,21 @@
|
||||
diff -Naur external_dpcpp.orig/sycl/source/CMakeLists.txt external_dpcpp/sycl/source/CMakeLists.txt
|
||||
--- external_dpcpp.orig/sycl/source/CMakeLists.txt 2022-05-20 04:19:45.067771362 +0000
|
||||
+++ external_dpcpp/sycl/source/CMakeLists.txt 2022-05-20 04:21:49.708025048 +0000
|
||||
@@ -66,10 +66,10 @@
|
||||
target_compile_options(${LIB_OBJ_NAME} PUBLIC
|
||||
-fvisibility=hidden -fvisibility-inlines-hidden)
|
||||
set(linker_script "${CMAKE_CURRENT_SOURCE_DIR}/ld-version-script.txt")
|
||||
- set(abi_linker_script "${CMAKE_CURRENT_SOURCE_DIR}/abi_replacements_linux.txt")
|
||||
- target_link_libraries(
|
||||
- ${LIB_NAME} PRIVATE "-Wl,${abi_linker_script}")
|
||||
- set_target_properties(${LIB_NAME} PROPERTIES LINK_DEPENDS ${abi_linker_script})
|
||||
+# set(abi_linker_script "${CMAKE_CURRENT_SOURCE_DIR}/abi_replacements_linux.txt")
|
||||
+# target_link_libraries(
|
||||
+# ${LIB_NAME} PRIVATE "-Wl,${abi_linker_script}")
|
||||
+# set_target_properties(${LIB_NAME} PROPERTIES LINK_DEPENDS ${abi_linker_script})
|
||||
target_link_libraries(
|
||||
${LIB_NAME} PRIVATE "-Wl,--version-script=${linker_script}")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES LINK_DEPENDS ${linker_script})
|
||||
diff -Naur llvm-sycl-nightly-20220501.orig\opencl/CMakeLists.txt llvm-sycl-nightly-20220501\opencl/CMakeLists.txt
|
||||
--- llvm-sycl-nightly-20220501.orig/opencl/CMakeLists.txt 2022-04-29 13:47:11 -0600
|
||||
+++ llvm-sycl-nightly-20220501/opencl/CMakeLists.txt 2022-05-21 15:25:06 -0600
|
||||
|
@@ -1,19 +0,0 @@
|
||||
--- a/src/dispatch_wgl.c 2022-08-04 17:45:13.144924705 +0200
|
||||
+++ b/src/dispatch_wgl.c 2022-08-04 17:45:47.657482971 +0200
|
||||
@@ -78,6 +78,8 @@
|
||||
if (!first_context_current) {
|
||||
first_context_current = true;
|
||||
} else {
|
||||
+ /* BLENDER: disable slow dispatch table switching. */
|
||||
+#if 0
|
||||
if (!already_switched_to_dispatch_table) {
|
||||
already_switched_to_dispatch_table = true;
|
||||
gl_switch_to_dispatch_table();
|
||||
@@ -86,6 +88,7 @@
|
||||
|
||||
gl_init_dispatch_table();
|
||||
wgl_init_dispatch_table();
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
@@ -1,24 +0,0 @@
|
||||
diff -Naur orig/PCbuild/get_externals.bat Python-3.10.2/PCbuild/get_externals.bat
|
||||
--- orig/PCbuild/get_externals.bat 2022-01-13 11:52:14 -0700
|
||||
+++ Python-3.10.2/PCbuild/get_externals.bat 2022-08-17 11:24:42 -0600
|
||||
@@ -51,7 +51,7 @@
|
||||
echo.Fetching external libraries...
|
||||
|
||||
set libraries=
|
||||
-set libraries=%libraries% bzip2-1.0.6
|
||||
+set libraries=%libraries% bzip2-1.0.8
|
||||
if NOT "%IncludeLibffiSrc%"=="false" set libraries=%libraries% libffi-3.3.0
|
||||
if NOT "%IncludeSSLSrc%"=="false" set libraries=%libraries% openssl-1.1.1m
|
||||
set libraries=%libraries% sqlite-3.35.5.0
|
||||
diff -Naur orig/PCbuild/python.props external_python/PCbuild/python.props
|
||||
--- orig/PCbuild/python.props 2022-01-13 11:52:14 -0700
|
||||
+++ external_python/PCbuild/python.props 2022-08-17 11:38:38 -0600
|
||||
@@ -58,7 +58,7 @@
|
||||
<ExternalsDir Condition="$(ExternalsDir) == ''">$([System.IO.Path]::GetFullPath(`$(PySourcePath)externals`))</ExternalsDir>
|
||||
<ExternalsDir Condition="!HasTrailingSlash($(ExternalsDir))">$(ExternalsDir)\</ExternalsDir>
|
||||
<sqlite3Dir>$(ExternalsDir)sqlite-3.35.5.0\</sqlite3Dir>
|
||||
- <bz2Dir>$(ExternalsDir)bzip2-1.0.6\</bz2Dir>
|
||||
+ <bz2Dir>$(ExternalsDir)bzip2-1.0.8\</bz2Dir>
|
||||
<lzmaDir>$(ExternalsDir)xz-5.2.2\</lzmaDir>
|
||||
<libffiDir>$(ExternalsDir)libffi-3.3.0\</libffiDir>
|
||||
<libffiOutDir>$(ExternalsDir)libffi-3.3.0\$(ArchName)\</libffiOutDir>
|
@@ -1,47 +0,0 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright 2022 Blender Foundation.
|
||||
|
||||
# This module defines
|
||||
# Epoxy_INCLUDE_DIRS, where to find epoxy/gl.h
|
||||
# Epoxy_LIBRARY, where to find the epoxy library.
|
||||
# Epoxy_ROOT_DIR, The base directory to search for epoxy.
|
||||
# This can also be an environment variable.
|
||||
# Epoxy_FOUND, If false, do not try to use epoxy.
|
||||
|
||||
IF(NOT EPOXY_ROOT_DIR AND NOT $ENV{EPOXY_ROOT_DIR} STREQUAL "")
|
||||
SET(EPOXY_ROOT_DIR $ENV{EPOXY_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(Epoxy_INCLUDE_DIR
|
||||
NAMES
|
||||
epoxy/gl.h
|
||||
HINTS
|
||||
${EPOXY_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(Epoxy_LIBRARY
|
||||
NAMES
|
||||
epoxy
|
||||
HINTS
|
||||
${EPOXY_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set Epoxy_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Epoxy DEFAULT_MSG
|
||||
Epoxy_LIBRARY Epoxy_INCLUDE_DIR)
|
||||
|
||||
IF(Epoxy_FOUND)
|
||||
SET(Epoxy_INCLUDE_DIRS ${Epoxy_INCLUDE_DIR})
|
||||
SET(Epoxy_LIBRARIES ${Epoxy_LIBRARY})
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
Epoxy_INCLUDE_DIR
|
||||
Epoxy_LIBRARY
|
||||
)
|
58
build_files/cmake/Modules/FindGLEW.cmake
Normal file
58
build_files/cmake/Modules/FindGLEW.cmake
Normal file
@@ -0,0 +1,58 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright 2014 Blender Foundation.
|
||||
|
||||
# - Find GLEW library
|
||||
# Find the native Glew includes and library
|
||||
# This module defines
|
||||
# GLEW_INCLUDE_DIRS, where to find glew.h, Set when
|
||||
# GLEW_INCLUDE_DIR is found.
|
||||
# GLEW_ROOT_DIR, The base directory to search for Glew.
|
||||
# This can also be an environment variable.
|
||||
# GLEW_FOUND, If false, do not try to use Glew.
|
||||
#
|
||||
# also defined,
|
||||
# GLEW_LIBRARY, where to find the Glew library.
|
||||
|
||||
# If GLEW_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT GLEW_ROOT_DIR AND NOT $ENV{GLEW_ROOT_DIR} STREQUAL "")
|
||||
SET(GLEW_ROOT_DIR $ENV{GLEW_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_glew_SEARCH_DIRS
|
||||
${GLEW_ROOT_DIR}
|
||||
)
|
||||
|
||||
FIND_PATH(GLEW_INCLUDE_DIR
|
||||
NAMES
|
||||
GL/glew.h
|
||||
HINTS
|
||||
${_glew_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(GLEW_LIBRARY
|
||||
NAMES
|
||||
GLEW
|
||||
HINTS
|
||||
${_glew_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set GLEW_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLEW DEFAULT_MSG
|
||||
GLEW_LIBRARY GLEW_INCLUDE_DIR)
|
||||
|
||||
IF(GLEW_FOUND)
|
||||
SET(GLEW_INCLUDE_DIRS ${GLEW_INCLUDE_DIR})
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
GLEW_INCLUDE_DIR
|
||||
GLEW_LIBRARY
|
||||
)
|
||||
|
||||
UNSET(_glew_SEARCH_DIRS)
|
@@ -1,47 +0,0 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright 2022 Blender Foundation.
|
||||
|
||||
# This module defines
|
||||
# LibEpoxy_INCLUDE_DIRS, where to find epoxy/gl.h
|
||||
# LibEpoxy_LIBRARY, where to find the epoxy library.
|
||||
# LibEpoxy_ROOT_DIR, The base directory to search for libepoxy.
|
||||
# This can also be an environment variable.
|
||||
# LibEpoxy_FOUND, If false, do not try to use libepoxy.
|
||||
|
||||
IF(NOT EPOXY_ROOT_DIR AND NOT $ENV{EPOXY_ROOT_DIR} STREQUAL "")
|
||||
SET(EPOXY_ROOT_DIR $ENV{EPOXY_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(LibEpoxy_INCLUDE_DIR
|
||||
NAMES
|
||||
epoxy/gl.h
|
||||
HINTS
|
||||
${EPOXY_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
include
|
||||
)
|
||||
|
||||
FIND_LIBRARY(LibEpoxy_LIBRARY
|
||||
NAMES
|
||||
epoxy
|
||||
HINTS
|
||||
${EPOXY_ROOT_DIR}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LibEpoxy_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibEpoxy DEFAULT_MSG
|
||||
LibEpoxy_LIBRARY LibEpoxy_INCLUDE_DIR)
|
||||
|
||||
IF(LibEpoxy_FOUND)
|
||||
SET(LibEpoxy_INCLUDE_DIRS ${LibEpoxy_INCLUDE_DIR})
|
||||
SET(LibEpoxy_LIBRARIES ${LibEpoxy_LIBRARY})
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
LibEpoxy_INCLUDE_DIR
|
||||
LibEpoxy_LIBRARY
|
||||
)
|
80
build_files/cmake/Modules/FindOpenGLES.cmake
Normal file
80
build_files/cmake/Modules/FindOpenGLES.cmake
Normal file
@@ -0,0 +1,80 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Copyright 2014 Blender Foundation.
|
||||
|
||||
# - Try to find OpenGLES
|
||||
# Once done this will define
|
||||
#
|
||||
# OPENGLES_FOUND - system has OpenGLES and EGL
|
||||
# OPENGL_EGL_FOUND - system has EGL
|
||||
# OPENGLES_INCLUDE_DIR - the GLES include directory
|
||||
# OPENGLES_LIBRARY - the GLES library
|
||||
# OPENGLES_EGL_INCLUDE_DIR - the EGL include directory
|
||||
# OPENGLES_EGL_LIBRARY - the EGL library
|
||||
# OPENGLES_LIBRARIES - all libraries needed for OpenGLES
|
||||
# OPENGLES_INCLUDES - all includes needed for OpenGLES
|
||||
|
||||
# If OPENGLES_ROOT_DIR was defined in the environment, use it.
|
||||
IF(NOT OPENGLES_ROOT_DIR AND NOT $ENV{OPENGLES_ROOT_DIR} STREQUAL "")
|
||||
SET(OPENGLES_ROOT_DIR $ENV{OPENGLES_ROOT_DIR})
|
||||
ENDIF()
|
||||
|
||||
SET(_opengles_SEARCH_DIRS
|
||||
${OPENGLES_ROOT_DIR}
|
||||
)
|
||||
|
||||
FIND_PATH(OPENGLES_INCLUDE_DIR
|
||||
NAMES
|
||||
GLES2/gl2.h
|
||||
HINTS
|
||||
${_opengles_SEARCH_DIRS}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENGLES_LIBRARY
|
||||
NAMES
|
||||
GLESv2
|
||||
PATHS
|
||||
${_opengles_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
FIND_PATH(OPENGLES_EGL_INCLUDE_DIR
|
||||
NAMES
|
||||
EGL/egl.h
|
||||
HINTS
|
||||
${_opengles_SEARCH_DIRS}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(OPENGLES_EGL_LIBRARY
|
||||
NAMES
|
||||
EGL
|
||||
HINTS
|
||||
${_opengles_SEARCH_DIRS}
|
||||
PATH_SUFFIXES
|
||||
lib64 lib
|
||||
)
|
||||
|
||||
IF(OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR)
|
||||
SET(OPENGL_EGL_FOUND "YES")
|
||||
ELSE()
|
||||
SET(OPENGL_EGL_FOUND "NO")
|
||||
ENDIF()
|
||||
|
||||
IF(OPENGLES_LIBRARY AND OPENGLES_INCLUDE_DIR AND
|
||||
OPENGLES_EGL_LIBRARY AND OPENGLES_EGL_INCLUDE_DIR)
|
||||
SET(OPENGLES_LIBRARIES ${OPENGLES_LIBRARY} ${OPENGLES_LIBRARIES}
|
||||
${OPENGLES_EGL_LIBRARY})
|
||||
SET(OPENGLES_INCLUDES ${OPENGLES_INCLUDE_DIR} ${OPENGLES_EGL_INCLUDE_DIR})
|
||||
SET(OPENGLES_FOUND "YES")
|
||||
ELSE()
|
||||
SET(OPENGLES_FOUND "NO")
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPENGLES_EGL_INCLUDE_DIR
|
||||
OPENGLES_EGL_LIBRARY
|
||||
OPENGLES_LIBRARY
|
||||
OPENGLES_INCLUDE_DIR
|
||||
)
|
||||
|
||||
UNSET(_opengles_SEARCH_DIRS)
|
@@ -10,77 +10,40 @@ import tempfile
|
||||
from typing import (
|
||||
Any,
|
||||
List,
|
||||
Tuple,
|
||||
)
|
||||
|
||||
USE_VERBOSE = (os.environ.get("VERBOSE", None) is not None)
|
||||
# Could make configurable.
|
||||
USE_VERBOSE_PROGRESS = True
|
||||
|
||||
CHECKER_BIN = "cppcheck"
|
||||
USE_QUIET = (os.environ.get("QUIET", None) is not None)
|
||||
|
||||
CHECKER_IGNORE_PREFIX = [
|
||||
"extern",
|
||||
]
|
||||
|
||||
CHECKER_EXCLUDE_SOURCE_FILES = set(os.path.join(*f.split("/")) for f in (
|
||||
# These files hang (taking longer than 5min with v2.8.2 at time of writing).
|
||||
# All other files process in under around 10seconds.
|
||||
"source/blender/editors/space_text/text_format_pov.c",
|
||||
"source/blender/editors/space_text/text_format_pov_ini.c",
|
||||
))
|
||||
CHECKER_BIN = "cppcheck"
|
||||
|
||||
CHECKER_ARGS = [
|
||||
# Speed up execution.
|
||||
# As Blender has many defines, the total number of configurations is large making execution unreasonably slow.
|
||||
# This could be increased but do so with care.
|
||||
"--max-configs=1",
|
||||
|
||||
# Enable this when includes are missing.
|
||||
# "--check-config",
|
||||
|
||||
# Shows many pedantic issues, some are quite useful.
|
||||
"--enable=all",
|
||||
|
||||
# Also shows useful messages, even if some are false-positives.
|
||||
"--inconclusive",
|
||||
# not sure why this is needed, but it is.
|
||||
"-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"),
|
||||
"--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR,
|
||||
"--max-configs=1", # speeds up execution
|
||||
# "--check-config", # when includes are missing
|
||||
"--enable=all", # if you want sixty hundred pedantic suggestions
|
||||
|
||||
# Quiet output, otherwise all defines/includes are printed (overly verbose).
|
||||
# Only enable this for troubleshooting (if defines are not set as expected for example).
|
||||
*(() if USE_VERBOSE else ("--quiet",))
|
||||
"--quiet",
|
||||
|
||||
# NOTE: `--cppcheck-build-dir=<dir>` is added later as a temporary directory.
|
||||
]
|
||||
|
||||
|
||||
def source_info_filter(
|
||||
source_info: List[Tuple[str, List[str], List[str]]],
|
||||
) -> List[Tuple[str, List[str], List[str]]]:
|
||||
source_dir = project_source_info.SOURCE_DIR
|
||||
if not source_dir.endswith(os.sep):
|
||||
source_dir += os.sep
|
||||
source_info_result = []
|
||||
for i, item in enumerate(source_info):
|
||||
c = item[0]
|
||||
if c.startswith(source_dir):
|
||||
c_relative = c[len(source_dir):]
|
||||
if c_relative in CHECKER_EXCLUDE_SOURCE_FILES:
|
||||
CHECKER_EXCLUDE_SOURCE_FILES.remove(c_relative)
|
||||
continue
|
||||
source_info_result.append(item)
|
||||
if CHECKER_EXCLUDE_SOURCE_FILES:
|
||||
sys.stderr.write("Error: exclude file(s) are missing: %r\n" % list(sorted(CHECKER_EXCLUDE_SOURCE_FILES)))
|
||||
sys.exit(1)
|
||||
return source_info_result
|
||||
if USE_QUIET:
|
||||
CHECKER_ARGS.append("--quiet")
|
||||
|
||||
|
||||
def cppcheck() -> None:
|
||||
source_info = project_source_info.build_info(ignore_prefix_list=CHECKER_IGNORE_PREFIX)
|
||||
source_defines = project_source_info.build_defines_as_args()
|
||||
|
||||
# Apply exclusion.
|
||||
source_info = source_info_filter(source_info)
|
||||
|
||||
check_commands = []
|
||||
for c, inc_dirs, defs in source_info:
|
||||
cmd = (
|
||||
@@ -97,7 +60,7 @@ def cppcheck() -> None:
|
||||
process_functions = []
|
||||
|
||||
def my_process(i: int, c: str, cmd: List[str]) -> subprocess.Popen[Any]:
|
||||
if USE_VERBOSE_PROGRESS:
|
||||
if not USE_QUIET:
|
||||
percent = 100.0 * (i / len(check_commands))
|
||||
percent_str = "[" + ("%.2f]" % percent).rjust(7) + " %:"
|
||||
|
||||
|
@@ -13,7 +13,7 @@ set(WITH_BULLET ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR_CPU ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
|
@@ -18,7 +18,7 @@ set(WITH_BULLET OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_AVI OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR_CPU OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_COREAUDIO OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_DRACO OFF CACHE BOOL "" FORCE)
|
||||
@@ -35,7 +35,6 @@ set(WITH_IMAGE_OPENEXR OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_OPENJPEG OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_TIFF OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_IMAGE_WEBP OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_INPUT_IME OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_INPUT_NDOF OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_INTERNATIONAL OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_IO_STL OFF CACHE BOOL "" FORCE)
|
||||
|
@@ -14,7 +14,7 @@ set(WITH_BULLET ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_AVI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_FFMPEG ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_SNDFILE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR_CPU ON CACHE BOOL "" FORCE)
|
||||
set(WITH_COMPOSITOR ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_EMBREE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_OSL ON CACHE BOOL "" FORCE)
|
||||
@@ -87,5 +87,7 @@ if(NOT APPLE)
|
||||
set(WITH_CYCLES_CUBIN_COMPILER OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_HIP_BINARIES ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_DEVICE_ONEAPI ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CYCLES_ONEAPI_BINARIES ON CACHE BOOL "" FORCE)
|
||||
|
||||
# Disable AoT kernels compilations until buildbot can deliver them in a reasonable time.
|
||||
set(WITH_CYCLES_ONEAPI_BINARIES OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
@@ -1,33 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2022 Blender Foundation. All rights reserved.
|
||||
|
||||
# This file is used to test the system for headers & symbols.
|
||||
# Variables should use the `HAVE_` prefix.
|
||||
# Defines should use the same name as the CMAKE variable.
|
||||
|
||||
include(CheckSymbolExists)
|
||||
|
||||
# Used for: `intern/guardedalloc/intern/mallocn_intern.h`.
|
||||
# Function `malloc_stats` is only available on GLIBC,
|
||||
# so check that before defining `HAVE_MALLOC_STATS`.
|
||||
check_symbol_exists(malloc_stats "malloc.h" HAVE_MALLOC_STATS_H)
|
||||
|
||||
# Used for: `source/creator/creator_signals.c`.
|
||||
# The function `feenableexcept` is not present non-GLIBC systems,
|
||||
# hence we need to check if it's available in the `fenv.h` file.
|
||||
set(HAVE_FEENABLEEXCEPT OFF)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
check_symbol_exists(feenableexcept "fenv.h" HAVE_FEENABLEEXCEPT)
|
||||
endif()
|
||||
|
||||
# Used for: `source/blender/blenlib/intern/system.c`.
|
||||
# `execinfo` is not available on non-GLIBC systems (at least not on MUSL-LIBC),
|
||||
# so check the presence of the header before including it and using the it for back-trace.
|
||||
set(HAVE_EXECINFO_H OFF)
|
||||
if(NOT MSVC)
|
||||
include(CheckIncludeFiles)
|
||||
check_include_files("execinfo.h" HAVE_EXECINFO_H)
|
||||
if(HAVE_EXECINFO_H)
|
||||
add_definitions(-DHAVE_EXECINFO_H)
|
||||
endif()
|
||||
endif()
|
@@ -21,18 +21,6 @@ function(print_found_status
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Utility to install precompiled shared libraries.
|
||||
macro(add_bundled_libraries library)
|
||||
if(EXISTS ${LIBDIR})
|
||||
set(_library_dir ${LIBDIR}/${library}/lib)
|
||||
file(GLOB _all_library_versions ${_library_dir}/*\.dylib*)
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_all_library_versions})
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARY_DIRS ${_library_dir})
|
||||
unset(_all_library_versions)
|
||||
unset(_library_dir)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ------------------------------------------------------------------------
|
||||
# Find system provided libraries.
|
||||
|
||||
@@ -238,9 +226,6 @@ if(WITH_SDL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(EPOXY_ROOT_DIR ${LIBDIR}/epoxy)
|
||||
find_package(Epoxy REQUIRED)
|
||||
|
||||
set(PNG_ROOT ${LIBDIR}/png)
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
@@ -427,7 +412,6 @@ if(WITH_OPENMP)
|
||||
set(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/")
|
||||
set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp")
|
||||
set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib")
|
||||
add_bundled_libraries(openmp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -517,27 +501,17 @@ if(WITH_COMPILER_CCACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_COMPILER_ASAN)
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${COMPILER_ASAN_LIBRARY})
|
||||
endif()
|
||||
# For binaries that are built but not installed (also not distributed) (datatoc,
|
||||
# makesdna, tests, etc.), we add an rpath to the OpenMP library dir through
|
||||
# CMAKE_BUILD_RPATH. This avoids having to make many copies of the dylib next to each binary.
|
||||
#
|
||||
# For the installed Python module and installed Blender executable, CMAKE_INSTALL_RPATH
|
||||
# is modified to find the dylib in an adjacent folder. Install step puts the libraries there.
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
list(APPEND CMAKE_BUILD_RPATH "${OpenMP_LIBRARY_DIR}")
|
||||
|
||||
if(PLATFORM_BUNDLED_LIBRARIES)
|
||||
# For the installed Python module and installed Blender executable, we set the
|
||||
# rpath to the location where install step will copy the shared libraries.
|
||||
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
|
||||
if(WITH_PYTHON_MODULE)
|
||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/lib")
|
||||
else()
|
||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/lib")
|
||||
endif()
|
||||
|
||||
# For binaries that are built but not installed (like makesdan or tests), we add
|
||||
# the original directory of all shared libraries to the rpath. This is needed because
|
||||
# these can be in different folders, and because the build and install folder may be
|
||||
# different.
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
list(APPEND CMAKE_BUILD_RPATH ${PLATFORM_BUNDLED_LIBRARY_DIRS})
|
||||
endif()
|
||||
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
|
||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/../Resources/${BLENDER_VERSION}/lib")
|
||||
|
||||
# Same as `CFBundleIdentifier` in Info.plist.
|
||||
set(CMAKE_XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "org.blenderfoundation.blender")
|
||||
|
@@ -81,15 +81,6 @@ macro(find_package_wrapper)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Utility to install precompiled shared libraries.
|
||||
macro(add_bundled_libraries library)
|
||||
if(EXISTS ${LIBDIR})
|
||||
file(GLOB _all_library_versions ${LIBDIR}/${library}/lib/*\.so*)
|
||||
list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_all_library_versions})
|
||||
unset(_all_library_versions)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Precompiled Libraries
|
||||
#
|
||||
@@ -104,19 +95,6 @@ find_package_wrapper(JPEG REQUIRED)
|
||||
find_package_wrapper(PNG REQUIRED)
|
||||
find_package_wrapper(ZLIB REQUIRED)
|
||||
find_package_wrapper(Zstd REQUIRED)
|
||||
find_package_wrapper(Epoxy REQUIRED)
|
||||
|
||||
function(check_freetype_for_brotli)
|
||||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${FREETYPE_INCLUDE_DIRS})
|
||||
check_symbol_exists(FT_CONFIG_OPTION_USE_BROTLI "freetype/config/ftconfig.h" HAVE_BROTLI)
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
if(NOT HAVE_BROTLI)
|
||||
unset(HAVE_BROTLI CACHE)
|
||||
message(FATAL_ERROR "Freetype needs to be compiled with brotli support!")
|
||||
endif()
|
||||
unset(HAVE_BROTLI CACHE)
|
||||
endfunction()
|
||||
|
||||
if(NOT WITH_SYSTEM_FREETYPE)
|
||||
# FreeType compiled with Brotli compression for woff2.
|
||||
@@ -132,7 +110,6 @@ if(NOT WITH_SYSTEM_FREETYPE)
|
||||
# ${BROTLI_LIBRARIES}
|
||||
# )
|
||||
endif()
|
||||
check_freetype_for_brotli()
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON)
|
||||
@@ -610,7 +587,6 @@ if(WITH_SYSTEM_FREETYPE)
|
||||
if(NOT FREETYPE_FOUND)
|
||||
message(FATAL_ERROR "Failed finding system FreeType version!")
|
||||
endif()
|
||||
check_freetype_for_brotli()
|
||||
endif()
|
||||
|
||||
if(WITH_LZO AND WITH_SYSTEM_LZO)
|
||||
@@ -653,92 +629,46 @@ endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(wayland-client wayland-client>=1.12)
|
||||
pkg_check_modules(wayland-egl wayland-egl)
|
||||
pkg_check_modules(wayland-scanner wayland-scanner)
|
||||
pkg_check_modules(xkbcommon xkbcommon)
|
||||
pkg_check_modules(wayland-cursor wayland-cursor)
|
||||
pkg_check_modules(wayland-protocols wayland-protocols>=1.15)
|
||||
pkg_check_modules(wayland-client REQUIRED wayland-client>=1.12)
|
||||
pkg_check_modules(wayland-egl REQUIRED wayland-egl)
|
||||
pkg_check_modules(wayland-scanner REQUIRED wayland-scanner)
|
||||
pkg_check_modules(xkbcommon REQUIRED xkbcommon)
|
||||
pkg_check_modules(wayland-cursor REQUIRED wayland-cursor)
|
||||
|
||||
if(${wayland-protocols_FOUND})
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||
else()
|
||||
# CentOS 7 packages have too old a version, a newer version exist in the
|
||||
# precompiled libraries.
|
||||
find_path(WAYLAND_PROTOCOLS_DIR
|
||||
NAMES unstable/xdg-decoration/xdg-decoration-unstable-v1.xml
|
||||
PATH_SUFFIXES share/wayland-protocols
|
||||
PATHS ${LIBDIR}/wayland-protocols
|
||||
)
|
||||
|
||||
if(EXISTS ${WAYLAND_PROTOCOLS_DIR})
|
||||
set(wayland-protocols_FOUND ON)
|
||||
endif()
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
pkg_check_modules(dbus REQUIRED dbus-1)
|
||||
endif()
|
||||
|
||||
if (NOT ${wayland-client_FOUND})
|
||||
message(STATUS "wayland-client not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
endif()
|
||||
if (NOT ${wayland-egl_FOUND})
|
||||
message(STATUS "wayland-egl not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
endif()
|
||||
if (NOT ${wayland-scanner_FOUND})
|
||||
message(STATUS "wayland-scanner not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
endif()
|
||||
if (NOT ${wayland-cursor_FOUND})
|
||||
message(STATUS "wayland-cursor not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
endif()
|
||||
if (NOT ${wayland-protocols_FOUND})
|
||||
message(STATUS "wayland-protocols not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
endif()
|
||||
if (NOT ${xkbcommon_FOUND})
|
||||
message(STATUS "xkbcommon not found, disabling WITH_GHOST_WAYLAND")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
pkg_check_modules(dbus REQUIRED dbus-1)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
pkg_check_modules(libdecor REQUIRED libdecor-0>=0.1)
|
||||
endif()
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${xkbcommon_LINK_LIBRARIES}
|
||||
)
|
||||
|
||||
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${xkbcommon_LINK_LIBRARIES}
|
||||
${wayland-client_LINK_LIBRARIES}
|
||||
${wayland-egl_LINK_LIBRARIES}
|
||||
${wayland-cursor_LINK_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${dbus_LINK_LIBRARIES}
|
||||
)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_DBUS)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${wayland-client_LINK_LIBRARIES}
|
||||
${wayland-egl_LINK_LIBRARIES}
|
||||
${wayland-cursor_LINK_LIBRARIES}
|
||||
${libdecor_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${dbus_LINK_LIBRARIES}
|
||||
)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_DBUS)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
if(NOT WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
list(APPEND PLATFORM_LINKLIBS
|
||||
${libdecor_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
|
||||
endif()
|
||||
|
||||
pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -859,8 +789,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
"The mold linker could not find the directory containing the linker command "
|
||||
"(typically "
|
||||
"\"${MOLD_PREFIX}/libexec/mold/ld\") or "
|
||||
"\"${MOLD_PREFIX}/lib/mold/ld\") using system linker."
|
||||
)
|
||||
"\"${MOLD_PREFIX}/lib/mold/ld\") using system linker.")
|
||||
set(WITH_LINKER_MOLD OFF)
|
||||
endif()
|
||||
unset(MOLD_PREFIX)
|
||||
@@ -999,8 +928,7 @@ function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
|
||||
int main(int argc, char **argv) {
|
||||
std::atomic<uint64_t> uint64; uint64++;
|
||||
return 0;
|
||||
}"
|
||||
)
|
||||
}")
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles("${_source}" ATOMIC_OPS_WITHOUT_LIBATOMIC)
|
||||
@@ -1012,7 +940,6 @@ function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES atomic)
|
||||
check_cxx_source_compiles("${_source}" ATOMIC_OPS_WITH_LIBATOMIC)
|
||||
unset(CMAKE_REQUIRED_LIBRARIES)
|
||||
|
||||
if(ATOMIC_OPS_WITH_LIBATOMIC)
|
||||
set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -latomic" PARENT_SCOPE)
|
||||
@@ -1026,16 +953,3 @@ function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
|
||||
endfunction()
|
||||
|
||||
CONFIGURE_ATOMIC_LIB_IF_NEEDED()
|
||||
|
||||
if(PLATFORM_BUNDLED_LIBRARIES)
|
||||
# For the installed Python module and installed Blender executable, we set the
|
||||
# rpath to the relative path where the install step will copy the shared libraries.
|
||||
set(CMAKE_SKIP_INSTALL_RPATH FALSE)
|
||||
list(APPEND CMAKE_INSTALL_RPATH $ORIGIN/lib)
|
||||
|
||||
# For executables that are built but not installed (mainly tests) we set an absolute
|
||||
# rpath to the lib folder. This is needed because these can be in different folders,
|
||||
# and because the build and install folder may be different.
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
list(APPEND CMAKE_BUILD_RPATH $ORIGIN/lib ${CMAKE_INSTALL_PREFIX_WITH_CONFIG}/lib)
|
||||
endif()
|
||||
|
@@ -146,7 +146,7 @@ endif()
|
||||
if(WITH_COMPILER_ASAN AND MSVC AND NOT MSVC_CLANG)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.28.29828)
|
||||
#set a flag so we don't have to do this comparison all the time
|
||||
set(MSVC_ASAN ON)
|
||||
SET(MSVC_ASAN ON)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fsanitize=address")
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /INCREMENTAL:NO")
|
||||
@@ -185,20 +185,20 @@ endif()
|
||||
|
||||
|
||||
if(WITH_WINDOWS_SCCACHE)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER sccache)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER sccache)
|
||||
set(SYMBOL_FORMAT /Z7)
|
||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
||||
else()
|
||||
unset(CMAKE_C_COMPILER_LAUNCHER)
|
||||
unset(CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
if(MSVC_ASAN)
|
||||
set(CMAKE_C_COMPILER_LAUNCHER sccache)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER sccache)
|
||||
set(SYMBOL_FORMAT /Z7)
|
||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
||||
else()
|
||||
set(SYMBOL_FORMAT /ZI)
|
||||
set(SYMBOL_FORMAT_RELEASE /Zi)
|
||||
endif()
|
||||
else()
|
||||
unset(CMAKE_C_COMPILER_LAUNCHER)
|
||||
unset(CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
if(MSVC_ASAN)
|
||||
set(SYMBOL_FORMAT /Z7)
|
||||
set(SYMBOL_FORMAT_RELEASE /Z7)
|
||||
else()
|
||||
set(SYMBOL_FORMAT /ZI)
|
||||
set(SYMBOL_FORMAT_RELEASE /Zi)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_WINDOWS_PDB)
|
||||
@@ -323,13 +323,6 @@ if(NOT JPEG_FOUND)
|
||||
set(JPEG_LIBRARIES ${LIBDIR}/jpeg/lib/libjpeg.lib)
|
||||
endif()
|
||||
|
||||
set(EPOXY_ROOT_DIR ${LIBDIR}/epoxy)
|
||||
windows_find_package(Epoxy REQUIRED)
|
||||
if(NOT EPOXY_FOUND)
|
||||
set(Epoxy_INCLUDE_DIRS ${LIBDIR}/epoxy/include)
|
||||
set(Epoxy_LIBRARIES ${LIBDIR}/epoxy/lib/epoxy.lib)
|
||||
endif()
|
||||
|
||||
set(PTHREADS_INCLUDE_DIRS ${LIBDIR}/pthreads/include)
|
||||
set(PTHREADS_LIBRARIES ${LIBDIR}/pthreads/lib/pthreadVC3.lib)
|
||||
|
||||
@@ -423,7 +416,7 @@ if(WITH_CODEC_FFMPEG)
|
||||
${LIBDIR}/ffmpeg/lib/avdevice.lib
|
||||
${LIBDIR}/ffmpeg/lib/avutil.lib
|
||||
${LIBDIR}/ffmpeg/lib/swscale.lib
|
||||
)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -572,14 +565,12 @@ if(WITH_BOOST)
|
||||
if(WITH_CYCLES AND WITH_CYCLES_OSL)
|
||||
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
|
||||
optimized ${BOOST_LIBPATH}/libboost_wave-${BOOST_POSTFIX}
|
||||
debug ${BOOST_LIBPATH}/libboost_wave-${BOOST_DEBUG_POSTFIX}
|
||||
)
|
||||
debug ${BOOST_LIBPATH}/libboost_wave-${BOOST_DEBUG_POSTFIX})
|
||||
endif()
|
||||
if(WITH_INTERNATIONAL)
|
||||
set(BOOST_LIBRARIES ${BOOST_LIBRARIES}
|
||||
optimized ${BOOST_LIBPATH}/libboost_locale-${BOOST_POSTFIX}
|
||||
debug ${BOOST_LIBPATH}/libboost_locale-${BOOST_DEBUG_POSTFIX}
|
||||
)
|
||||
debug ${BOOST_LIBPATH}/libboost_locale-${BOOST_DEBUG_POSTFIX})
|
||||
endif()
|
||||
else() # we found boost using find_package
|
||||
set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS})
|
||||
@@ -686,8 +677,7 @@ if(WITH_OPENIMAGEDENOISE)
|
||||
optimized ${OPENIMAGEDENOISE_LIBPATH}/dnnl.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/OpenImageDenoise_d.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/common_d.lib
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/dnnl_d.lib
|
||||
)
|
||||
debug ${OPENIMAGEDENOISE_LIBPATH}/dnnl_d.lib)
|
||||
set(OPENIMAGEDENOISE_DEFINITIONS)
|
||||
endif()
|
||||
|
||||
@@ -842,8 +832,7 @@ if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
|
||||
debug ${LIBDIR}/embree/lib/math_d.lib
|
||||
debug ${LIBDIR}/embree/lib/simd_d.lib
|
||||
debug ${LIBDIR}/embree/lib/sys_d.lib
|
||||
debug ${LIBDIR}/embree/lib/tasking_d.lib
|
||||
)
|
||||
debug ${LIBDIR}/embree/lib/tasking_d.lib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@@ -110,9 +110,6 @@ def svn_update(args, release_version):
|
||||
if not make_utils.command_missing(args.svn_command):
|
||||
call(svn_non_interactive + ["cleanup", lib_dirpath])
|
||||
continue
|
||||
elif dirname.startswith("."):
|
||||
# Temporary paths such as ".mypy_cache" will report a warning, skip hidden directories.
|
||||
continue
|
||||
|
||||
svn_dirpath = os.path.join(dirpath, ".svn")
|
||||
svn_root_dirpath = os.path.join(lib_dirpath, ".svn")
|
||||
|
@@ -6,10 +6,6 @@ It can be useful to perform an action when a property is changed and can be
|
||||
used to update other properties or synchronize with external data.
|
||||
|
||||
All properties define update functions except for CollectionProperty.
|
||||
|
||||
.. warning::
|
||||
Remember that these callbacks may be executed in threaded context.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
@@ -6,10 +6,6 @@ Getter/setter functions can be used for boolean, int, float, string and enum pro
|
||||
If these callbacks are defined the property will not be stored in the ID properties
|
||||
automatically. Instead, the `get` and `set` functions will be called when the property
|
||||
is respectively read or written from the API.
|
||||
|
||||
.. warning::
|
||||
Remember that these callbacks may be executed in threaded context.
|
||||
|
||||
"""
|
||||
import bpy
|
||||
|
||||
|
@@ -7,15 +7,6 @@ Custom properties can be added to any subclass of an :class:`ID`,
|
||||
|
||||
These properties can be animated, accessed by the user interface and python
|
||||
like Blender's existing properties.
|
||||
|
||||
.. warning::
|
||||
|
||||
Access to these properties might happen in threaded context, on a per-data-block level.
|
||||
This has to be carefully considered when using accessors or update callbacks.
|
||||
|
||||
Typically, these callbacks should not affect any other data that the one owned by their data-block.
|
||||
When accessing external non-Blender data, thread safety mechanisms should be considered.
|
||||
|
||||
"""
|
||||
|
||||
import bpy
|
||||
|
@@ -3,8 +3,8 @@ Extending the Button Context Menu
|
||||
+++++++++++++++++++++++++++++++++
|
||||
|
||||
This example enables you to insert your own menu entry into the common
|
||||
right click menu that you get while hovering over a UI button (e.g. operator,
|
||||
value field, color, string, etc.)
|
||||
right click menu that you get while hovering over a value field,
|
||||
color, string, etc.
|
||||
|
||||
To make the example work, you have to first select an object
|
||||
then right click on an user interface element (maybe a color in the
|
||||
@@ -14,6 +14,7 @@ Executing the operator will then print all values.
|
||||
"""
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
|
||||
|
||||
def dump(obj, text):
|
||||
@@ -46,20 +47,36 @@ class WM_OT_button_context_test(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def draw_menu(self, context):
|
||||
# This class has to be exactly named like that to insert an entry in the right click menu
|
||||
class WM_MT_button_context(Menu):
|
||||
bl_label = "Unused"
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
def menu_func(self, context):
|
||||
layout = self.layout
|
||||
layout.separator()
|
||||
layout.operator(WM_OT_button_context_test.bl_idname)
|
||||
|
||||
|
||||
classes = (
|
||||
WM_OT_button_context_test,
|
||||
WM_MT_button_context,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.utils.register_class(WM_OT_button_context_test)
|
||||
bpy.types.UI_MT_button_context_menu.append(draw_menu)
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
bpy.types.WM_MT_button_context.append(menu_func)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.UI_MT_button_context_menu.remove(draw_menu)
|
||||
bpy.utils.unregister_class(WM_OT_button_context_test)
|
||||
for cls in classes:
|
||||
bpy.utils.unregister_class(cls)
|
||||
bpy.types.WM_MT_button_context.remove(menu_func)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -1,6 +1,4 @@
|
||||
"""
|
||||
.. _modal_operator:
|
||||
|
||||
Modal Execution
|
||||
+++++++++++++++
|
||||
|
||||
|
@@ -14,36 +14,33 @@ from random import random
|
||||
from mathutils import Vector
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
||||
vert_out.smooth('FLOAT', "v_ArcLength")
|
||||
vertex_shader = '''
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
|
||||
shader_info = gpu.types.GPUShaderCreateInfo()
|
||||
shader_info.push_constant('MAT4', "u_ViewProjectionMatrix")
|
||||
shader_info.push_constant('FLOAT', "u_Scale")
|
||||
shader_info.vertex_in(0, 'VEC3', "position")
|
||||
shader_info.vertex_in(1, 'FLOAT', "arcLength")
|
||||
shader_info.vertex_out(vert_out)
|
||||
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
||||
in vec3 position;
|
||||
in float arcLength;
|
||||
|
||||
shader_info.vertex_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" v_ArcLength = arcLength;"
|
||||
" gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f);"
|
||||
"}"
|
||||
)
|
||||
out float v_ArcLength;
|
||||
|
||||
shader_info.fragment_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard;"
|
||||
" FragColor = vec4(1.0);"
|
||||
"}"
|
||||
)
|
||||
void main()
|
||||
{
|
||||
v_ArcLength = arcLength;
|
||||
gl_Position = u_ViewProjectionMatrix * vec4(position, 1.0f);
|
||||
}
|
||||
'''
|
||||
|
||||
shader = gpu.shader.create_from_info(shader_info)
|
||||
del vert_out
|
||||
del shader_info
|
||||
fragment_shader = '''
|
||||
uniform float u_Scale;
|
||||
|
||||
in float v_ArcLength;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (step(sin(v_ArcLength * u_Scale), 0.5) == 1) discard;
|
||||
FragColor = vec4(1.0);
|
||||
}
|
||||
'''
|
||||
|
||||
coords = [Vector((random(), random(), random())) * 5 for _ in range(5)]
|
||||
|
||||
@@ -51,6 +48,7 @@ arc_lengths = [0]
|
||||
for a, b in zip(coords[:-1], coords[1:]):
|
||||
arc_lengths.append(arc_lengths[-1] + (a - b).length)
|
||||
|
||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
batch = batch_for_shader(
|
||||
shader, 'LINE_STRIP',
|
||||
{"position": coords, "arcLength": arc_lengths},
|
||||
|
@@ -6,37 +6,33 @@ import bpy
|
||||
import gpu
|
||||
from gpu_extras.batch import batch_for_shader
|
||||
|
||||
vertex_shader = '''
|
||||
uniform mat4 viewProjectionMatrix;
|
||||
|
||||
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
||||
vert_out.smooth('VEC3', "pos")
|
||||
in vec3 position;
|
||||
out vec3 pos;
|
||||
|
||||
shader_info = gpu.types.GPUShaderCreateInfo()
|
||||
shader_info.push_constant('MAT4', "viewProjectionMatrix")
|
||||
shader_info.push_constant('FLOAT', "brightness")
|
||||
shader_info.vertex_in(0, 'VEC3', "position")
|
||||
shader_info.vertex_out(vert_out)
|
||||
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
||||
void main()
|
||||
{
|
||||
pos = position;
|
||||
gl_Position = viewProjectionMatrix * vec4(position, 1.0f);
|
||||
}
|
||||
'''
|
||||
|
||||
shader_info.vertex_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" pos = position;"
|
||||
" gl_Position = viewProjectionMatrix * vec4(position, 1.0f);"
|
||||
"}"
|
||||
)
|
||||
fragment_shader = '''
|
||||
uniform float brightness;
|
||||
|
||||
shader_info.fragment_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" FragColor = vec4(pos * brightness, 1.0);"
|
||||
"}"
|
||||
)
|
||||
in vec3 pos;
|
||||
out vec4 FragColor;
|
||||
|
||||
shader = gpu.shader.create_from_info(shader_info)
|
||||
del vert_out
|
||||
del shader_info
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(pos * brightness, 1.0);
|
||||
}
|
||||
'''
|
||||
|
||||
coords = [(1, 1, 1), (2, 0, 0), (-2, -1, 3)]
|
||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
batch = batch_for_shader(shader, 'TRIS', {"position": coords})
|
||||
|
||||
|
||||
|
@@ -35,37 +35,35 @@ with offscreen.bind():
|
||||
# Drawing the generated texture in 3D space
|
||||
#############################################
|
||||
|
||||
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
||||
vert_out.smooth('VEC2', "uvInterp")
|
||||
vertex_shader = '''
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 viewProjectionMatrix;
|
||||
|
||||
shader_info = gpu.types.GPUShaderCreateInfo()
|
||||
shader_info.push_constant('MAT4', "viewProjectionMatrix")
|
||||
shader_info.push_constant('MAT4', "modelMatrix")
|
||||
shader_info.sampler(0, 'FLOAT_2D', "image")
|
||||
shader_info.vertex_in(0, 'VEC2', "position")
|
||||
shader_info.vertex_in(1, 'VEC2', "uv")
|
||||
shader_info.vertex_out(vert_out)
|
||||
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
||||
in vec2 position;
|
||||
in vec2 uv;
|
||||
|
||||
shader_info.vertex_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" uvInterp = uv;"
|
||||
" gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0);"
|
||||
"}"
|
||||
)
|
||||
out vec2 uvInterp;
|
||||
|
||||
shader_info.fragment_source(
|
||||
"void main()"
|
||||
"{"
|
||||
" FragColor = texture(image, uvInterp);"
|
||||
"}"
|
||||
)
|
||||
void main()
|
||||
{
|
||||
uvInterp = uv;
|
||||
gl_Position = viewProjectionMatrix * modelMatrix * vec4(position, 0.0, 1.0);
|
||||
}
|
||||
'''
|
||||
|
||||
shader = gpu.shader.create_from_info(shader_info)
|
||||
del vert_out
|
||||
del shader_info
|
||||
fragment_shader = '''
|
||||
uniform sampler2D image;
|
||||
|
||||
in vec2 uvInterp;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = texture(image, uvInterp);
|
||||
}
|
||||
'''
|
||||
|
||||
shader = gpu.types.GPUShader(vertex_shader, fragment_shader)
|
||||
batch = batch_for_shader(
|
||||
shader, 'TRI_FAN',
|
||||
{
|
||||
|
@@ -86,8 +86,7 @@ No updates after setting values
|
||||
Sometimes you want to modify values from Python and immediately access the updated values, e.g:
|
||||
Once changing the objects :class:`bpy.types.Object.location`
|
||||
you may want to access its transformation right after from :class:`bpy.types.Object.matrix_world`,
|
||||
but this doesn't work as you might expect. There are similar issues with changes to the UI, that
|
||||
are covered in the next section.
|
||||
but this doesn't work as you might expect.
|
||||
|
||||
Consider the calculations that might contribute to the object's final transformation, this includes:
|
||||
|
||||
@@ -111,35 +110,6 @@ Now all dependent data (child objects, modifiers, drivers, etc.)
|
||||
have been recalculated and are available to the script within the active view layer.
|
||||
|
||||
|
||||
No updates after changing UI context
|
||||
------------------------------------
|
||||
|
||||
Similar to the previous issue, some changes to the UI may also not have an immediate effect. For example, setting
|
||||
:class:`bpy.types.Window.workspace` doesn't seem to cause an observable effect in the immediately following code
|
||||
(:class:`bpy.types.Window.workspace` is still the same), but the UI will in fact reflect the change. Some of the
|
||||
properties that behave that way are:
|
||||
|
||||
- :class:`bpy.types.Window.workspace`
|
||||
- :class:`bpy.types.Window.screen`
|
||||
- :class:`bpy.types.Window.scene`
|
||||
- :class:`bpy.types.Area.type`
|
||||
- :class:`bpy.types.Area.uitype`
|
||||
|
||||
Such changes impact the UI, and with that the context (:class:`bpy.context`) quite drastically. This can break
|
||||
Blender's context management. So Blender delays this change until after operators have run and just before the UI is
|
||||
redrawn, making sure that context can be changed safely.
|
||||
|
||||
If you rely on executing code with an updated context this can be worked around by executing the code in a delayed
|
||||
fashion as well. Possible options include:
|
||||
|
||||
- :ref:`Modal Operator <modal_operator>`.
|
||||
- :class:`bpy.app.handlers`.
|
||||
- :class:`bpy.app.timer`.
|
||||
|
||||
It's also possible to depend on drawing callbacks although these should generally be avoided as failure to draw a
|
||||
hidden panel, region, cursor, etc. could cause your script to be unreliable
|
||||
|
||||
|
||||
Can I redraw during script execution?
|
||||
-------------------------------------
|
||||
|
||||
|
12
extern/CMakeLists.txt
vendored
12
extern/CMakeLists.txt
vendored
@@ -32,6 +32,14 @@ if(WITH_BINRELOC)
|
||||
add_subdirectory(binreloc)
|
||||
endif()
|
||||
|
||||
if(NOT WITH_SYSTEM_GLEW)
|
||||
if(WITH_GLEW_ES)
|
||||
add_subdirectory(glew-es)
|
||||
else()
|
||||
add_subdirectory(glew)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_LZO AND NOT WITH_SYSTEM_LZO)
|
||||
add_subdirectory(lzo)
|
||||
endif()
|
||||
@@ -40,7 +48,7 @@ if(WITH_LZMA)
|
||||
add_subdirectory(lzma)
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES OR WITH_COMPOSITOR_CPU OR WITH_OPENSUBDIV)
|
||||
if(WITH_CYCLES OR WITH_COMPOSITOR OR WITH_OPENSUBDIV)
|
||||
add_subdirectory(clew)
|
||||
if((WITH_CYCLES_DEVICE_CUDA OR WITH_CYCLES_DEVICE_OPTIX) AND WITH_CUDA_DYNLOAD)
|
||||
add_subdirectory(cuew)
|
||||
@@ -88,6 +96,6 @@ if(WITH_MOD_FLUID)
|
||||
add_subdirectory(mantaflow)
|
||||
endif()
|
||||
|
||||
if(WITH_COMPOSITOR_CPU)
|
||||
if(WITH_COMPOSITOR)
|
||||
add_subdirectory(smaa_areatex)
|
||||
endif()
|
||||
|
@@ -363,8 +363,8 @@ int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
|
||||
|
||||
long long size = std::min(static_cast<long long>(buf_size), reader->m_membuffer->getSize() - reader->m_membufferpos);
|
||||
|
||||
if(size <= 0)
|
||||
return AVERROR_EOF;
|
||||
if(size < 0)
|
||||
return -1;
|
||||
|
||||
std::memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
|
||||
reader->m_membufferpos += size;
|
||||
|
33
extern/glew-es/CMakeLists.txt
vendored
Normal file
33
extern/glew-es/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2013 Blender Foundation. All rights reserved.
|
||||
|
||||
set(INC
|
||||
include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
list(APPEND INC_SYS
|
||||
${X11_X11_INCLUDE_PATH}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
src/glew.c
|
||||
|
||||
include/GL/eglew.h
|
||||
include/GL/glesew.h
|
||||
include/GL/glew.h
|
||||
include/GL/glxew.h
|
||||
include/GL/wglew.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(extern_glew_es "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
73
extern/glew-es/LICENSE.txt
vendored
Normal file
73
extern/glew-es/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
The OpenGL Extension Wrangler Library
|
||||
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
|
||||
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
|
||||
Copyright (C) 2002, Lev Povalahev
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* The name of the author may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Mesa 3-D graphics library
|
||||
Version: 7.0
|
||||
|
||||
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 2007 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
5
extern/glew-es/README.blender
vendored
Normal file
5
extern/glew-es/README.blender
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Project: The OpenGL Extension Wrangler Library
|
||||
URL: http://glew.sourceforge.net/
|
||||
License: Check LICENSE.txt
|
||||
Upstream version: 2.0.0
|
||||
Local modifications: None
|
20525
extern/glew-es/include/GL/glew.h
vendored
Normal file
20525
extern/glew-es/include/GL/glew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1649
extern/glew-es/include/GL/glxew.h
vendored
Normal file
1649
extern/glew-es/include/GL/glxew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1424
extern/glew-es/include/GL/wglew.h
vendored
Normal file
1424
extern/glew-es/include/GL/wglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
22401
extern/glew-es/src/glew.c
vendored
Normal file
22401
extern/glew-es/src/glew.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
54
extern/glew/CMakeLists.txt
vendored
Normal file
54
extern/glew/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright 2006 Blender Foundation. All rights reserved.
|
||||
|
||||
# avoid noisy warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
add_c_flag(
|
||||
"-Wno-strict-prototypes"
|
||||
)
|
||||
endif()
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "12.1"))
|
||||
add_c_flag(
|
||||
"-Wno-address"
|
||||
)
|
||||
endif()
|
||||
|
||||
# MSVC's inliner is not having a happy time with glewIsSupported
|
||||
# causing this to be one of the most expensive things to build
|
||||
# in blender. Optimize for size rather than speed sidesteps this
|
||||
# problem, more details at
|
||||
# https://developercommunity.visualstudio.com/content/problem/732941/slow-compilation-of-glewc-for-visual-studio-2019-x.html
|
||||
|
||||
if(MSVC)
|
||||
add_c_flag("/Os")
|
||||
endif()
|
||||
|
||||
set(INC
|
||||
include
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
list(APPEND INC_SYS
|
||||
${X11_X11_INCLUDE_PATH}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
src/glew.c
|
||||
|
||||
include/GL/eglew.h
|
||||
include/GL/glew.h
|
||||
include/GL/glxew.h
|
||||
include/GL/wglew.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
blender_add_lib(extern_glew "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
73
extern/glew/LICENSE.txt
vendored
Normal file
73
extern/glew/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
The OpenGL Extension Wrangler Library
|
||||
Copyright (C) 2002-2007, Milan Ikits <milan ikits[]ieee org>
|
||||
Copyright (C) 2002-2007, Marcelo E. Magallon <mmagallo[]debian org>
|
||||
Copyright (C) 2002, Lev Povalahev
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
* The name of the author may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
Mesa 3-D graphics library
|
||||
Version: 7.0
|
||||
|
||||
Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
Copyright (c) 2007 The Khronos Group Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and/or associated documentation files (the
|
||||
"Materials"), to deal in the Materials without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
permit persons to whom the Materials are furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Materials.
|
||||
|
||||
THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
5
extern/glew/README.blender
vendored
Normal file
5
extern/glew/README.blender
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
Project: The OpenGL Extension Wrangler Library
|
||||
URL: http://glew.sourceforge.net/
|
||||
License: Check LICENSE.txt
|
||||
Upstream version: 2.0.0
|
||||
Local modifications: None
|
2261
extern/glew/include/GL/eglew.h
vendored
Normal file
2261
extern/glew/include/GL/eglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
20113
extern/glew/include/GL/glew.h
vendored
Normal file
20113
extern/glew/include/GL/glew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1769
extern/glew/include/GL/glxew.h
vendored
Normal file
1769
extern/glew/include/GL/glxew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1427
extern/glew/include/GL/wglew.h
vendored
Normal file
1427
extern/glew/include/GL/wglew.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23952
extern/glew/src/glew.c
vendored
Normal file
23952
extern/glew/src/glew.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ add_subdirectory(memutil)
|
||||
add_subdirectory(opencolorio)
|
||||
add_subdirectory(opensubdiv)
|
||||
add_subdirectory(mikktspace)
|
||||
add_subdirectory(glew-mx)
|
||||
add_subdirectory(eigen)
|
||||
add_subdirectory(sky)
|
||||
|
||||
|
@@ -43,8 +43,9 @@ else()
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI)
|
||||
list(APPEND INC_SYS ${Epoxy_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
|
||||
list(APPEND LIB ${Epoxy_LIBRARIES} ${SDL2_LIBRARIES})
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
list(APPEND INC_SYS ${GLEW_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS})
|
||||
list(APPEND LIB ${CYCLES_GL_LIBRARIES} ${CYCLES_GLEW_LIBRARIES} ${SDL2_LIBRARIES})
|
||||
endif()
|
||||
|
||||
cycles_external_libraries_append(LIB)
|
||||
|
@@ -7,8 +7,8 @@
|
||||
#include "util/log.h"
|
||||
#include "util/string.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <SDL.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -6,7 +6,7 @@
|
||||
#include "util/log.h"
|
||||
#include "util/string.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <GL/glew.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
|
@@ -11,8 +11,8 @@
|
||||
#include "util/time.h"
|
||||
#include "util/version.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <SDL.h>
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -294,6 +294,7 @@ void window_main_loop(const char *title,
|
||||
SDL_RaiseWindow(V.window);
|
||||
|
||||
V.gl_context = SDL_GL_CreateContext(V.window);
|
||||
glewInit();
|
||||
SDL_GL_MakeCurrent(V.window, nullptr);
|
||||
|
||||
window_reshape(width, height);
|
||||
|
@@ -3,19 +3,18 @@
|
||||
|
||||
set(INC
|
||||
..
|
||||
../../glew-mx
|
||||
../../guardedalloc
|
||||
../../mikktspace
|
||||
../../../source/blender/makesdna
|
||||
../../../source/blender/makesrna
|
||||
../../../source/blender/blenlib
|
||||
../../../source/blender/gpu
|
||||
../../../source/blender/render
|
||||
${CMAKE_BINARY_DIR}/source/blender/makesrna/intern
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${Epoxy_INCLUDE_DIRS}
|
||||
${PYTHON_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
@@ -65,9 +64,6 @@ set(LIB
|
||||
cycles_subd
|
||||
cycles_util
|
||||
|
||||
bf_intern_mikktspace
|
||||
|
||||
${Epoxy_LIBRARIES}
|
||||
${PYTHON_LINKFLAGS}
|
||||
${PYTHON_LIBRARIES}
|
||||
)
|
||||
@@ -91,6 +87,8 @@ set(ADDON_FILES
|
||||
addon/version_update.py
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_CYCLES_DEVICE_HIP)
|
||||
add_definitions(-DWITH_HIP)
|
||||
endif()
|
||||
@@ -103,10 +101,6 @@ if(WITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_FLUID)
|
||||
endif()
|
||||
|
||||
if(WITH_TBB)
|
||||
add_definitions(-DWITH_TBB)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
|
||||
list(APPEND INC_SYS
|
||||
|
@@ -81,7 +81,7 @@ enum_use_layer_samples = (
|
||||
)
|
||||
|
||||
enum_sampling_pattern = (
|
||||
('SOBOL', "Sobol-Burley", "Use Sobol-Burley random sampling pattern", 0),
|
||||
('SOBOL', "Sobol", "Use Sobol random sampling pattern", 0),
|
||||
('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1),
|
||||
)
|
||||
|
||||
@@ -381,7 +381,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
|
||||
|
||||
sampling_pattern: EnumProperty(
|
||||
name="Sampling Pattern",
|
||||
description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol-Burley",
|
||||
description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol",
|
||||
items=enum_sampling_pattern,
|
||||
default='PROGRESSIVE_MULTI_JITTER',
|
||||
)
|
||||
@@ -1558,7 +1558,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
import sys
|
||||
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
|
||||
if sys.platform.startswith("win"):
|
||||
col.label(text="and Windows driver version 101.3268 or newer", icon='BLANK1')
|
||||
col.label(text="and Windows driver version 101.1660 or newer", icon='BLANK1')
|
||||
elif sys.platform.startswith("linux"):
|
||||
col.label(text="and Linux driver version xx.xx.23570 or newer", icon='BLANK1')
|
||||
elif device_type == 'METAL':
|
||||
|
@@ -296,6 +296,7 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
row.prop(cscene, "use_animated_seed", text="", icon='TIME')
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not (cscene.use_adaptive_sampling and cscene.use_preview_adaptive_sampling)
|
||||
col.prop(cscene, "sampling_pattern", text="Pattern")
|
||||
|
||||
col = layout.column(align=True)
|
||||
@@ -304,7 +305,6 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel):
|
||||
layout.separator()
|
||||
|
||||
heading = layout.column(align=True, heading="Scrambling Distance")
|
||||
heading.active = cscene.sampling_pattern != 'SOBOL'
|
||||
heading.prop(cscene, "auto_scrambling_distance", text="Automatic")
|
||||
heading.prop(cscene, "preview_scrambling_distance", text="Viewport")
|
||||
heading.prop(cscene, "scrambling_distance", text="Multiplier")
|
||||
|
@@ -707,21 +707,6 @@ static void attr_create_motion(Hair *hair, BL::Attribute &b_attribute, const flo
|
||||
}
|
||||
}
|
||||
|
||||
static void attr_create_uv(AttributeSet &attributes,
|
||||
BL::Curves &b_curves,
|
||||
BL::Attribute &b_attribute,
|
||||
const ustring name)
|
||||
{
|
||||
BL::Float2Attribute b_float2_attribute{b_attribute};
|
||||
Attribute *attr = attributes.add(ATTR_STD_UV, name);
|
||||
|
||||
float2 *data = attr->data_float2();
|
||||
fill_generic_attribute(b_curves, data, ATTR_ELEMENT_CURVE, [&](int i) {
|
||||
BL::Array<float, 2> v = b_float2_attribute.data[i].vector();
|
||||
return make_float2(v[0], v[1]);
|
||||
});
|
||||
}
|
||||
|
||||
static void attr_create_generic(Scene *scene,
|
||||
Hair *hair,
|
||||
BL::Curves &b_curves,
|
||||
@@ -730,26 +715,12 @@ static void attr_create_generic(Scene *scene,
|
||||
{
|
||||
AttributeSet &attributes = hair->attributes;
|
||||
static const ustring u_velocity("velocity");
|
||||
const bool need_uv = hair->need_attribute(scene, ATTR_STD_UV);
|
||||
bool have_uv = false;
|
||||
|
||||
for (BL::Attribute &b_attribute : b_curves.attributes) {
|
||||
const ustring name{b_attribute.name().c_str()};
|
||||
|
||||
const BL::Attribute::domain_enum b_domain = b_attribute.domain();
|
||||
const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
|
||||
|
||||
if (need_motion && name == u_velocity) {
|
||||
attr_create_motion(hair, b_attribute, motion_scale);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Weak, use first float2 attribute as standard UV. */
|
||||
if (need_uv && !have_uv && b_data_type == BL::Attribute::data_type_FLOAT2 &&
|
||||
b_domain == BL::Attribute::domain_CURVE) {
|
||||
attr_create_uv(attributes, b_curves, b_attribute, name);
|
||||
have_uv = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!hair->need_attribute(scene, name)) {
|
||||
@@ -759,6 +730,9 @@ static void attr_create_generic(Scene *scene,
|
||||
continue;
|
||||
}
|
||||
|
||||
const BL::Attribute::domain_enum b_domain = b_attribute.domain();
|
||||
const BL::Attribute::data_type_enum b_data_type = b_attribute.data_type();
|
||||
|
||||
AttributeElement element = ATTR_ELEMENT_NONE;
|
||||
switch (b_domain) {
|
||||
case BL::Attribute::domain_POINT:
|
||||
@@ -843,7 +817,7 @@ static float4 hair_point_as_float4(BL::FloatVectorAttribute b_attr_position,
|
||||
const int index)
|
||||
{
|
||||
float4 mP = float3_to_float4(get_float3(b_attr_position.data[index].vector()));
|
||||
mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.005f;
|
||||
mP.w = b_attr_radius ? b_attr_radius->data[index].value() : 0.0f;
|
||||
return mP;
|
||||
}
|
||||
|
||||
@@ -870,84 +844,79 @@ static void export_hair_curves(Scene *scene,
|
||||
{
|
||||
/* TODO: optimize so we can straight memcpy arrays from Blender? */
|
||||
|
||||
/* Add requested attributes. */
|
||||
Attribute *attr_intercept = NULL;
|
||||
Attribute *attr_length = NULL;
|
||||
Attribute *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT);
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
|
||||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH);
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM);
|
||||
}
|
||||
|
||||
/* Reserve memory. */
|
||||
const int num_keys = b_curves.points.length();
|
||||
const int num_curves = b_curves.curves.length();
|
||||
|
||||
hair->resize_curves(num_curves, num_keys);
|
||||
|
||||
float3 *curve_keys = hair->get_curve_keys().data();
|
||||
float *curve_radius = hair->get_curve_radius().data();
|
||||
int *curve_first_key = hair->get_curve_first_key().data();
|
||||
int *curve_shader = hair->get_curve_shader().data();
|
||||
|
||||
/* Add requested attributes. */
|
||||
float *attr_intercept = NULL;
|
||||
float *attr_length = NULL;
|
||||
float *attr_random = NULL;
|
||||
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_INTERCEPT)) {
|
||||
attr_intercept = hair->attributes.add(ATTR_STD_CURVE_INTERCEPT)->data_float();
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_LENGTH)) {
|
||||
attr_length = hair->attributes.add(ATTR_STD_CURVE_LENGTH)->data_float();
|
||||
}
|
||||
if (hair->need_attribute(scene, ATTR_STD_CURVE_RANDOM)) {
|
||||
attr_random = hair->attributes.add(ATTR_STD_CURVE_RANDOM)->data_float();
|
||||
}
|
||||
hair->reserve_curves(num_curves, num_keys);
|
||||
|
||||
BL::FloatVectorAttribute b_attr_position = find_curves_position_attribute(b_curves);
|
||||
std::optional<BL::FloatAttribute> b_attr_radius = find_curves_radius_attribute(b_curves);
|
||||
|
||||
/* Export curves and points. */
|
||||
vector<float> points_length;
|
||||
|
||||
for (int i = 0; i < num_curves; i++) {
|
||||
const int first_point_index = b_curves.curve_offset_data[i].value();
|
||||
const int num_points = b_curves.curve_offset_data[i + 1].value() - first_point_index;
|
||||
|
||||
float3 prev_co = zero_float3();
|
||||
float length = 0.0f;
|
||||
if (attr_intercept) {
|
||||
points_length.clear();
|
||||
points_length.reserve(num_points);
|
||||
}
|
||||
|
||||
/* Position and radius. */
|
||||
for (int j = 0; j < num_points; j++) {
|
||||
const int point_offset = first_point_index + j;
|
||||
const float3 co = get_float3(b_attr_position.data[point_offset].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[point_offset].value() : 0.005f;
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
const float3 co = get_float3(b_attr_position.data[first_point_index + i].vector());
|
||||
const float radius = b_attr_radius ? b_attr_radius->data[first_point_index + i].value() :
|
||||
0.005f;
|
||||
hair->add_curve_key(co, radius);
|
||||
|
||||
curve_keys[point_offset] = co;
|
||||
curve_radius[point_offset] = radius;
|
||||
|
||||
if (attr_length || attr_intercept) {
|
||||
if (j > 0) {
|
||||
if (attr_intercept) {
|
||||
if (i > 0) {
|
||||
length += len(co - prev_co);
|
||||
points_length.push_back(length);
|
||||
}
|
||||
prev_co = co;
|
||||
|
||||
if (attr_intercept) {
|
||||
attr_intercept[point_offset] = length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Normalized 0..1 attribute along curve. */
|
||||
if (attr_intercept && length > 0.0f) {
|
||||
for (int j = 1; j < num_points; j++) {
|
||||
const int point_offset = first_point_index + j;
|
||||
attr_intercept[point_offset] /= length;
|
||||
if (attr_intercept) {
|
||||
for (int i = 0; i < num_points; i++) {
|
||||
attr_intercept->add((length == 0.0f) ? 0.0f : points_length[i] / length);
|
||||
}
|
||||
}
|
||||
|
||||
/* Curve length. */
|
||||
if (attr_length) {
|
||||
attr_length[i] = length;
|
||||
attr_length->add(length);
|
||||
}
|
||||
|
||||
/* Random number per curve. */
|
||||
if (attr_random != NULL) {
|
||||
attr_random[i] = hash_uint2_to_float(i, 0);
|
||||
attr_random->add(hash_uint2_to_float(i, 0));
|
||||
}
|
||||
|
||||
/* Curve. */
|
||||
curve_shader[i] = 0;
|
||||
curve_first_key[i] = first_point_index;
|
||||
const int shader_index = 0;
|
||||
hair->add_curve(first_point_index, shader_index);
|
||||
}
|
||||
|
||||
attr_create_generic(scene, hair, b_curves, need_motion, motion_scale);
|
||||
|
@@ -7,9 +7,21 @@
|
||||
#include "util/log.h"
|
||||
#include "util/opengl.h"
|
||||
|
||||
#include "GPU_platform.h"
|
||||
extern "C" {
|
||||
struct RenderEngine;
|
||||
|
||||
#include "RE_engine.h"
|
||||
bool RE_engine_has_render_context(struct RenderEngine *engine);
|
||||
void RE_engine_render_context_enable(struct RenderEngine *engine);
|
||||
void RE_engine_render_context_disable(struct RenderEngine *engine);
|
||||
|
||||
bool DRW_opengl_context_release();
|
||||
void DRW_opengl_context_activate(bool drw_state);
|
||||
|
||||
void *WM_opengl_context_create();
|
||||
void WM_opengl_context_activate(void *gl_context);
|
||||
void WM_opengl_context_dispose(void *gl_context);
|
||||
void WM_opengl_context_release(void *context);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -495,7 +507,6 @@ class DrawTileAndPBO {
|
||||
|
||||
DrawTile tile;
|
||||
GLPixelBufferObject buffer_object;
|
||||
bool need_update_texture_pixels = false;
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@@ -545,21 +556,18 @@ struct BlenderDisplayDriver::Tiles {
|
||||
}
|
||||
};
|
||||
|
||||
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine,
|
||||
BL::Scene &b_scene,
|
||||
const bool background)
|
||||
BlenderDisplayDriver::BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene)
|
||||
: b_engine_(b_engine),
|
||||
background_(background),
|
||||
display_shader_(BlenderDisplayShader::create(b_engine, b_scene)),
|
||||
tiles_(make_unique<Tiles>())
|
||||
{
|
||||
/* Create context while on the main thread. */
|
||||
gpu_context_create();
|
||||
gl_context_create();
|
||||
}
|
||||
|
||||
BlenderDisplayDriver::~BlenderDisplayDriver()
|
||||
{
|
||||
gpu_resources_destroy();
|
||||
gl_resources_destroy();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@@ -577,8 +585,6 @@ void BlenderDisplayDriver::next_tile_begin()
|
||||
/* Moving to the next tile without giving render data for the current tile is not an expected
|
||||
* situation. */
|
||||
DCHECK(!need_clear_);
|
||||
/* Texture should have been updated from the PBO at this point. */
|
||||
DCHECK(!tiles_->current_tile.need_update_texture_pixels);
|
||||
|
||||
tiles_->finished_tiles.tiles.emplace_back(std::move(tiles_->current_tile.tile));
|
||||
}
|
||||
@@ -590,12 +596,12 @@ bool BlenderDisplayDriver::update_begin(const Params ¶ms,
|
||||
/* Note that it's the responsibility of BlenderDisplayDriver to ensure updating and drawing
|
||||
* the texture does not happen at the same time. This is achieved indirectly.
|
||||
*
|
||||
* When enabling the OpenGL context, it uses an internal mutex lock DST.gpu_context_lock.
|
||||
* When enabling the OpenGL context, it uses an internal mutex lock DST.gl_context_lock.
|
||||
* This same lock is also held when do_draw() is called, which together ensure mutual
|
||||
* exclusion.
|
||||
*
|
||||
* This locking is not performed on the Cycles side, because that would cause lock inversion. */
|
||||
if (!gpu_context_enable()) {
|
||||
if (!gl_context_enable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -616,13 +622,13 @@ bool BlenderDisplayDriver::update_begin(const Params ¶ms,
|
||||
|
||||
if (!tiles_->gl_resources_ensure()) {
|
||||
tiles_->gl_resources_destroy();
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tiles_->current_tile.gl_resources_ensure()) {
|
||||
tiles_->current_tile.gl_resources_destroy();
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -696,23 +702,13 @@ void BlenderDisplayDriver::update_end()
|
||||
* One concern with this approach is that if the update happens more often than drawing then
|
||||
* doing the unpack here occupies GPU transfer for no good reason. However, the render scheduler
|
||||
* takes care of ensuring updates don't happen that often. In regular applications redraw will
|
||||
* happen much more often than this update.
|
||||
*
|
||||
* On some older GPUs on macOS, there is a driver crash when updating the texture for viewport
|
||||
* renders while Blender is drawing. As a workaround update texture during draw, under assumption
|
||||
* that there is no graphics interop on macOS and viewport render has a single tile. */
|
||||
if (!background_ &&
|
||||
GPU_type_matches_ex(GPU_DEVICE_NVIDIA, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_ANY)) {
|
||||
tiles_->current_tile.need_update_texture_pixels = true;
|
||||
}
|
||||
else {
|
||||
update_tile_texture_pixels(tiles_->current_tile);
|
||||
}
|
||||
* happen much more often than this update. */
|
||||
update_tile_texture_pixels(tiles_->current_tile);
|
||||
|
||||
gl_upload_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@@ -760,12 +756,12 @@ BlenderDisplayDriver::GraphicsInterop BlenderDisplayDriver::graphics_interop_get
|
||||
|
||||
void BlenderDisplayDriver::graphics_interop_activate()
|
||||
{
|
||||
gpu_context_enable();
|
||||
gl_context_enable();
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::graphics_interop_deactivate()
|
||||
{
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------
|
||||
@@ -899,7 +895,7 @@ void BlenderDisplayDriver::flush()
|
||||
* If we don't do this, the NVIDIA driver hangs for a few seconds for when ending 3D viewport
|
||||
* rendering, for unknown reasons. This was found with NVIDIA driver version 470.73 and a Quadro
|
||||
* RTX 6000 on Linux. */
|
||||
if (!gpu_context_enable()) {
|
||||
if (!gl_context_enable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -911,12 +907,17 @@ void BlenderDisplayDriver::flush()
|
||||
glWaitSync((GLsync)gl_render_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
{
|
||||
gpu_context_lock();
|
||||
/* See do_update_begin() for why no locking is required here. */
|
||||
const bool transparent = true; // TODO(sergey): Derive this from Film.
|
||||
|
||||
if (use_gl_context_) {
|
||||
gl_context_mutex_.lock();
|
||||
}
|
||||
|
||||
if (need_clear_) {
|
||||
/* Texture is requested to be cleared and was not yet cleared.
|
||||
@@ -924,7 +925,9 @@ void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
* Do early return which should be equivalent of drawing all-zero texture.
|
||||
* Watch out for the lock though so that the clear happening during update is properly
|
||||
* synchronized here. */
|
||||
gpu_context_unlock();
|
||||
if (use_gl_context_) {
|
||||
gl_context_mutex_.unlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -932,8 +935,10 @@ void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
glWaitSync((GLsync)gl_upload_sync_, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
if (transparent) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@@ -952,11 +957,6 @@ void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
glEnableVertexAttribArray(texcoord_attribute);
|
||||
glEnableVertexAttribArray(position_attribute);
|
||||
|
||||
if (tiles_->current_tile.need_update_texture_pixels) {
|
||||
update_tile_texture_pixels(tiles_->current_tile);
|
||||
tiles_->current_tile.need_update_texture_pixels = false;
|
||||
}
|
||||
|
||||
draw_tile(zoom_,
|
||||
texcoord_attribute,
|
||||
position_attribute,
|
||||
@@ -975,60 +975,101 @@ void BlenderDisplayDriver::draw(const Params ¶ms)
|
||||
|
||||
glDeleteVertexArrays(1, &vertex_array_object);
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
if (transparent) {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
gl_render_sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
|
||||
gpu_context_unlock();
|
||||
|
||||
VLOG_DEVICE_STATS << "Display driver number of textures: " << GLTexture::num_used;
|
||||
VLOG_DEVICE_STATS << "Display driver number of PBOs: " << GLPixelBufferObject::num_used;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_context_create()
|
||||
{
|
||||
if (!RE_engine_gpu_context_create(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data))) {
|
||||
LOG(ERROR) << "Error creating OpenGL context.";
|
||||
if (use_gl_context_) {
|
||||
gl_context_mutex_.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool BlenderDisplayDriver::gpu_context_enable()
|
||||
void BlenderDisplayDriver::gl_context_create()
|
||||
{
|
||||
return RE_engine_gpu_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
/* When rendering in viewport there is no render context available via engine.
|
||||
* Check whether own context is to be created here.
|
||||
*
|
||||
* NOTE: If the `b_engine_`'s context is not available, we are expected to be on a main thread
|
||||
* here. */
|
||||
use_gl_context_ = !RE_engine_has_render_context(
|
||||
reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
|
||||
if (use_gl_context_) {
|
||||
const bool drw_state = DRW_opengl_context_release();
|
||||
gl_context_ = WM_opengl_context_create();
|
||||
if (gl_context_) {
|
||||
/* On Windows an old context is restored after creation, and subsequent release of context
|
||||
* generates a Win32 error. Harmless for users, but annoying to have possible misleading
|
||||
* error prints in the console. */
|
||||
#ifndef _WIN32
|
||||
WM_opengl_context_release(gl_context_);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
LOG(ERROR) << "Error creating OpenGL context.";
|
||||
}
|
||||
|
||||
DRW_opengl_context_activate(drw_state);
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_context_disable()
|
||||
bool BlenderDisplayDriver::gl_context_enable()
|
||||
{
|
||||
RE_engine_gpu_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
if (use_gl_context_) {
|
||||
if (!gl_context_) {
|
||||
return false;
|
||||
}
|
||||
gl_context_mutex_.lock();
|
||||
WM_opengl_context_activate(gl_context_);
|
||||
return true;
|
||||
}
|
||||
|
||||
RE_engine_render_context_enable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
return true;
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_context_destroy()
|
||||
void BlenderDisplayDriver::gl_context_disable()
|
||||
{
|
||||
RE_engine_gpu_context_destroy(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
if (use_gl_context_) {
|
||||
if (gl_context_) {
|
||||
WM_opengl_context_release(gl_context_);
|
||||
gl_context_mutex_.unlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
RE_engine_render_context_disable(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_context_lock()
|
||||
void BlenderDisplayDriver::gl_context_dispose()
|
||||
{
|
||||
RE_engine_gpu_context_lock(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
if (gl_context_) {
|
||||
const bool drw_state = DRW_opengl_context_release();
|
||||
|
||||
WM_opengl_context_activate(gl_context_);
|
||||
WM_opengl_context_dispose(gl_context_);
|
||||
|
||||
DRW_opengl_context_activate(drw_state);
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_context_unlock()
|
||||
void BlenderDisplayDriver::gl_resources_destroy()
|
||||
{
|
||||
RE_engine_gpu_context_unlock(reinterpret_cast<RenderEngine *>(b_engine_.ptr.data));
|
||||
}
|
||||
|
||||
void BlenderDisplayDriver::gpu_resources_destroy()
|
||||
{
|
||||
gpu_context_enable();
|
||||
gl_context_enable();
|
||||
|
||||
tiles_->current_tile.gl_resources_destroy();
|
||||
tiles_->finished_tiles.gl_resources_destroy_and_clear();
|
||||
tiles_->gl_resources_destroy();
|
||||
|
||||
gpu_context_disable();
|
||||
gl_context_disable();
|
||||
|
||||
gpu_context_destroy();
|
||||
gl_context_dispose();
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -89,7 +89,7 @@ class BlenderDisplaySpaceShader : public BlenderDisplayShader {
|
||||
/* Display driver implementation which is specific for Blender viewport integration. */
|
||||
class BlenderDisplayDriver : public DisplayDriver {
|
||||
public:
|
||||
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene, const bool background);
|
||||
BlenderDisplayDriver(BL::RenderEngine &b_engine, BL::Scene &b_scene);
|
||||
~BlenderDisplayDriver();
|
||||
|
||||
virtual void graphics_interop_activate() override;
|
||||
@@ -115,18 +115,23 @@ class BlenderDisplayDriver : public DisplayDriver {
|
||||
virtual void flush() override;
|
||||
|
||||
/* Helper function which allocates new GPU context. */
|
||||
void gpu_context_create();
|
||||
bool gpu_context_enable();
|
||||
void gpu_context_disable();
|
||||
void gpu_context_destroy();
|
||||
void gpu_context_lock();
|
||||
void gpu_context_unlock();
|
||||
void gl_context_create();
|
||||
bool gl_context_enable();
|
||||
void gl_context_disable();
|
||||
void gl_context_dispose();
|
||||
|
||||
/* Destroy all GPU resources which are being used by this object. */
|
||||
void gpu_resources_destroy();
|
||||
void gl_resources_destroy();
|
||||
|
||||
BL::RenderEngine b_engine_;
|
||||
bool background_;
|
||||
|
||||
/* OpenGL context which is used the render engine doesn't have its own. */
|
||||
void *gl_context_ = nullptr;
|
||||
/* The when Blender RenderEngine side context is not available and the DisplayDriver is to create
|
||||
* its own context. */
|
||||
bool use_gl_context_ = false;
|
||||
/* Mutex used to guard the `gl_context_`. */
|
||||
thread_mutex gl_context_mutex_;
|
||||
|
||||
/* Content of the display is to be filled with zeroes. */
|
||||
std::atomic<bool> need_clear_ = true;
|
||||
|
@@ -1,8 +1,6 @@
|
||||
/* SPDX-License-Identifier: Apache-2.0
|
||||
* Copyright 2011-2022 Blender Foundation */
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "blender/session.h"
|
||||
#include "blender/sync.h"
|
||||
#include "blender/util.h"
|
||||
@@ -24,23 +22,22 @@
|
||||
#include "util/log.h"
|
||||
#include "util/math.h"
|
||||
|
||||
#include "mikktspace.hh"
|
||||
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "mikktspace.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Tangent Space */
|
||||
|
||||
template<bool is_subd> struct MikkMeshWrapper {
|
||||
MikkMeshWrapper(const BL::Mesh &b_mesh,
|
||||
const char *layer_name,
|
||||
const Mesh *mesh,
|
||||
float3 *tangent,
|
||||
float *tangent_sign)
|
||||
struct MikkUserData {
|
||||
MikkUserData(const BL::Mesh &b_mesh,
|
||||
const char *layer_name,
|
||||
const Mesh *mesh,
|
||||
float3 *tangent,
|
||||
float *tangent_sign)
|
||||
: mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign)
|
||||
{
|
||||
const AttributeSet &attributes = is_subd ? mesh->subd_attributes : mesh->attributes;
|
||||
const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes :
|
||||
mesh->attributes;
|
||||
|
||||
Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
|
||||
vertex_normal = attr_vN->data_float3();
|
||||
@@ -50,9 +47,7 @@ template<bool is_subd> struct MikkMeshWrapper {
|
||||
|
||||
if (attr_orco) {
|
||||
orco = attr_orco->data_float3();
|
||||
float3 orco_size;
|
||||
mesh_texture_space(*(BL::Mesh *)&b_mesh, orco_loc, orco_size);
|
||||
inv_orco_size = 1.0f / orco_size;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -63,126 +58,160 @@ template<bool is_subd> struct MikkMeshWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
int GetNumFaces()
|
||||
{
|
||||
if constexpr (is_subd) {
|
||||
return mesh->get_num_subd_faces();
|
||||
}
|
||||
else {
|
||||
return mesh->num_triangles();
|
||||
}
|
||||
}
|
||||
|
||||
int GetNumVerticesOfFace(const int face_num)
|
||||
{
|
||||
if constexpr (is_subd) {
|
||||
return mesh->get_subd_num_corners()[face_num];
|
||||
}
|
||||
else {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
int CornerIndex(const int face_num, const int vert_num)
|
||||
{
|
||||
if constexpr (is_subd) {
|
||||
const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
|
||||
return face.start_corner + vert_num;
|
||||
}
|
||||
else {
|
||||
return face_num * 3 + vert_num;
|
||||
}
|
||||
}
|
||||
|
||||
int VertexIndex(const int face_num, const int vert_num)
|
||||
{
|
||||
int corner = CornerIndex(face_num, vert_num);
|
||||
if constexpr (is_subd) {
|
||||
return mesh->get_subd_face_corners()[corner];
|
||||
}
|
||||
else {
|
||||
return mesh->get_triangles()[corner];
|
||||
}
|
||||
}
|
||||
|
||||
mikk::float3 GetPosition(const int face_num, const int vert_num)
|
||||
{
|
||||
const float3 vP = mesh->get_verts()[VertexIndex(face_num, vert_num)];
|
||||
return mikk::float3(vP.x, vP.y, vP.z);
|
||||
}
|
||||
|
||||
mikk::float3 GetTexCoord(const int face_num, const int vert_num)
|
||||
{
|
||||
/* TODO: Check whether introducing a template boolean in order to
|
||||
* turn this into a constexpr is worth it. */
|
||||
if (texface != NULL) {
|
||||
const int corner_index = CornerIndex(face_num, vert_num);
|
||||
float2 tfuv = texface[corner_index];
|
||||
return mikk::float3(tfuv.x, tfuv.y, 1.0f);
|
||||
}
|
||||
else if (orco != NULL) {
|
||||
const int vertex_index = VertexIndex(face_num, vert_num);
|
||||
const float2 uv = map_to_sphere((orco[vertex_index] + orco_loc) * inv_orco_size);
|
||||
return mikk::float3(uv.x, uv.y, 1.0f);
|
||||
}
|
||||
else {
|
||||
return mikk::float3(0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
mikk::float3 GetNormal(const int face_num, const int vert_num)
|
||||
{
|
||||
float3 vN;
|
||||
if (is_subd) {
|
||||
const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
|
||||
if (face.smooth) {
|
||||
const int vertex_index = VertexIndex(face_num, vert_num);
|
||||
vN = vertex_normal[vertex_index];
|
||||
}
|
||||
else {
|
||||
vN = face.normal(mesh);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mesh->get_smooth()[face_num]) {
|
||||
const int vertex_index = VertexIndex(face_num, vert_num);
|
||||
vN = vertex_normal[vertex_index];
|
||||
}
|
||||
else {
|
||||
const Mesh::Triangle tri = mesh->get_triangle(face_num);
|
||||
vN = tri.compute_normal(&mesh->get_verts()[0]);
|
||||
}
|
||||
}
|
||||
return mikk::float3(vN.x, vN.y, vN.z);
|
||||
}
|
||||
|
||||
void SetTangentSpace(const int face_num, const int vert_num, mikk::float3 T, bool orientation)
|
||||
{
|
||||
const int corner_index = CornerIndex(face_num, vert_num);
|
||||
tangent[corner_index] = make_float3(T.x, T.y, T.z);
|
||||
if (tangent_sign != NULL) {
|
||||
tangent_sign[corner_index] = orientation ? 1.0f : -1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
const Mesh *mesh;
|
||||
int num_faces;
|
||||
|
||||
float3 *vertex_normal;
|
||||
float2 *texface;
|
||||
float3 *orco;
|
||||
float3 orco_loc, inv_orco_size;
|
||||
float3 orco_loc, orco_size;
|
||||
|
||||
float3 *tangent;
|
||||
float *tangent_sign;
|
||||
};
|
||||
|
||||
static int mikk_get_num_faces(const SMikkTSpaceContext *context)
|
||||
{
|
||||
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||
if (userdata->mesh->get_num_subd_faces()) {
|
||||
return userdata->mesh->get_num_subd_faces();
|
||||
}
|
||||
else {
|
||||
return userdata->mesh->num_triangles();
|
||||
}
|
||||
}
|
||||
|
||||
static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
|
||||
{
|
||||
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||
if (userdata->mesh->get_num_subd_faces()) {
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
return mesh->get_subd_num_corners()[face_num];
|
||||
}
|
||||
else {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num)
|
||||
{
|
||||
if (mesh->get_num_subd_faces()) {
|
||||
const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
|
||||
return mesh->get_subd_face_corners()[face.start_corner + vert_num];
|
||||
}
|
||||
else {
|
||||
return mesh->get_triangles()[face_num * 3 + vert_num];
|
||||
}
|
||||
}
|
||||
|
||||
static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num)
|
||||
{
|
||||
if (mesh->get_num_subd_faces()) {
|
||||
const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
|
||||
return face.start_corner + vert_num;
|
||||
}
|
||||
else {
|
||||
return face_num * 3 + vert_num;
|
||||
}
|
||||
}
|
||||
|
||||
static void mikk_get_position(const SMikkTSpaceContext *context,
|
||||
float P[3],
|
||||
const int face_num,
|
||||
const int vert_num)
|
||||
{
|
||||
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
|
||||
const float3 vP = mesh->get_verts()[vertex_index];
|
||||
P[0] = vP.x;
|
||||
P[1] = vP.y;
|
||||
P[2] = vP.z;
|
||||
}
|
||||
|
||||
static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context,
|
||||
float uv[2],
|
||||
const int face_num,
|
||||
const int vert_num)
|
||||
{
|
||||
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
if (userdata->texface != NULL) {
|
||||
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
|
||||
float2 tfuv = userdata->texface[corner_index];
|
||||
uv[0] = tfuv.x;
|
||||
uv[1] = tfuv.y;
|
||||
}
|
||||
else if (userdata->orco != NULL) {
|
||||
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
|
||||
const float3 orco_loc = userdata->orco_loc;
|
||||
const float3 orco_size = userdata->orco_size;
|
||||
const float3 orco = (userdata->orco[vertex_index] + orco_loc) / orco_size;
|
||||
|
||||
const float2 tmp = map_to_sphere(orco);
|
||||
uv[0] = tmp.x;
|
||||
uv[1] = tmp.y;
|
||||
}
|
||||
else {
|
||||
uv[0] = 0.0f;
|
||||
uv[1] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void mikk_get_normal(const SMikkTSpaceContext *context,
|
||||
float N[3],
|
||||
const int face_num,
|
||||
const int vert_num)
|
||||
{
|
||||
const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData;
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
float3 vN;
|
||||
if (mesh->get_num_subd_faces()) {
|
||||
const Mesh::SubdFace &face = mesh->get_subd_face(face_num);
|
||||
if (face.smooth) {
|
||||
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
|
||||
vN = userdata->vertex_normal[vertex_index];
|
||||
}
|
||||
else {
|
||||
vN = face.normal(mesh);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mesh->get_smooth()[face_num]) {
|
||||
const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num);
|
||||
vN = userdata->vertex_normal[vertex_index];
|
||||
}
|
||||
else {
|
||||
const Mesh::Triangle tri = mesh->get_triangle(face_num);
|
||||
vN = tri.compute_normal(&mesh->get_verts()[0]);
|
||||
}
|
||||
}
|
||||
N[0] = vN.x;
|
||||
N[1] = vN.y;
|
||||
N[2] = vN.z;
|
||||
}
|
||||
|
||||
static void mikk_set_tangent_space(const SMikkTSpaceContext *context,
|
||||
const float T[],
|
||||
const float sign,
|
||||
const int face_num,
|
||||
const int vert_num)
|
||||
{
|
||||
MikkUserData *userdata = (MikkUserData *)context->m_pUserData;
|
||||
const Mesh *mesh = userdata->mesh;
|
||||
const int corner_index = mikk_corner_index(mesh, face_num, vert_num);
|
||||
userdata->tangent[corner_index] = make_float3(T[0], T[1], T[2]);
|
||||
if (userdata->tangent_sign != NULL) {
|
||||
userdata->tangent_sign[corner_index] = sign;
|
||||
}
|
||||
}
|
||||
|
||||
static void mikk_compute_tangents(
|
||||
const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render)
|
||||
{
|
||||
/* Create tangent attributes. */
|
||||
const bool is_subd = mesh->get_num_subd_faces();
|
||||
AttributeSet &attributes = is_subd ? mesh->subd_attributes : mesh->attributes;
|
||||
AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes :
|
||||
mesh->attributes;
|
||||
Attribute *attr;
|
||||
ustring name;
|
||||
if (layer_name != NULL) {
|
||||
@@ -218,18 +247,24 @@ static void mikk_compute_tangents(
|
||||
}
|
||||
tangent_sign = attr_sign->data_float();
|
||||
}
|
||||
|
||||
/* Setup userdata. */
|
||||
if (is_subd) {
|
||||
MikkMeshWrapper<true> userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
|
||||
/* Compute tangents. */
|
||||
mikk::Mikktspace(userdata).genTangSpace();
|
||||
}
|
||||
else {
|
||||
MikkMeshWrapper<false> userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
|
||||
/* Compute tangents. */
|
||||
mikk::Mikktspace(userdata).genTangSpace();
|
||||
}
|
||||
MikkUserData userdata(b_mesh, layer_name, mesh, tangent, tangent_sign);
|
||||
/* Setup interface. */
|
||||
SMikkTSpaceInterface sm_interface;
|
||||
memset(&sm_interface, 0, sizeof(sm_interface));
|
||||
sm_interface.m_getNumFaces = mikk_get_num_faces;
|
||||
sm_interface.m_getNumVerticesOfFace = mikk_get_num_verts_of_face;
|
||||
sm_interface.m_getPosition = mikk_get_position;
|
||||
sm_interface.m_getTexCoord = mikk_get_texture_coordinate;
|
||||
sm_interface.m_getNormal = mikk_get_normal;
|
||||
sm_interface.m_setTSpaceBasic = mikk_set_tangent_space;
|
||||
/* Setup context. */
|
||||
SMikkTSpaceContext context;
|
||||
memset(&context, 0, sizeof(context));
|
||||
context.m_pUserData = &userdata;
|
||||
context.m_pInterface = &sm_interface;
|
||||
/* Compute tangents. */
|
||||
genTangSpaceDefault(&context);
|
||||
}
|
||||
|
||||
template<typename TypeInCycles, typename GetValueAtIndex>
|
||||
@@ -242,15 +277,10 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
|
||||
switch (b_domain) {
|
||||
case BL::Attribute::domain_CORNER: {
|
||||
if (subdivision) {
|
||||
const int polys_num = b_mesh.polygons.length();
|
||||
if (polys_num == 0) {
|
||||
return;
|
||||
}
|
||||
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
|
||||
for (int i = 0; i < polys_num; i++) {
|
||||
const MPoly &b_poly = polys[i];
|
||||
for (int j = 0; j < b_poly.totloop; j++) {
|
||||
*data = get_value_at_index(b_poly.loopstart + j);
|
||||
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||
int n = p.loop_total();
|
||||
for (int i = 0; i < n; i++) {
|
||||
*data = get_value_at_index(p.loop_start() + i);
|
||||
data++;
|
||||
}
|
||||
}
|
||||
@@ -267,32 +297,27 @@ static void fill_generic_attribute(BL::Mesh &b_mesh,
|
||||
break;
|
||||
}
|
||||
case BL::Attribute::domain_EDGE: {
|
||||
const size_t edges_num = b_mesh.edges.length();
|
||||
if (edges_num == 0) {
|
||||
return;
|
||||
}
|
||||
if constexpr (std::is_same_v<TypeInCycles, uchar4>) {
|
||||
/* uchar4 edge attributes do not exist, and averaging in place
|
||||
* would not work. */
|
||||
assert(0);
|
||||
}
|
||||
else {
|
||||
const MEdge *edges = static_cast<const MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
const size_t verts_num = b_mesh.vertices.length();
|
||||
vector<int> count(verts_num, 0);
|
||||
|
||||
/* Average edge attributes at vertices. */
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
TypeInCycles value = get_value_at_index(i);
|
||||
const size_t num_verts = b_mesh.vertices.length();
|
||||
vector<int> count(num_verts, 0);
|
||||
|
||||
const MEdge &b_edge = edges[i];
|
||||
data[b_edge.v1] += value;
|
||||
data[b_edge.v2] += value;
|
||||
count[b_edge.v1]++;
|
||||
count[b_edge.v2]++;
|
||||
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||
BL::Array<int, 2> vertices = e.vertices();
|
||||
TypeInCycles value = get_value_at_index(e.index());
|
||||
|
||||
data[vertices[0]] += value;
|
||||
data[vertices[1]] += value;
|
||||
count[vertices[0]]++;
|
||||
count[vertices[1]]++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < verts_num; i++) {
|
||||
for (size_t i = 0; i < num_verts; i++) {
|
||||
if (count[i] > 1) {
|
||||
data[i] /= (float)count[i];
|
||||
}
|
||||
@@ -576,12 +601,6 @@ static void attr_create_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh)
|
||||
|
||||
static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, bool subdivide_uvs)
|
||||
{
|
||||
const int polys_num = b_mesh.polygons.length();
|
||||
if (polys_num == 0) {
|
||||
return;
|
||||
}
|
||||
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
|
||||
|
||||
if (!b_mesh.uv_layers.empty()) {
|
||||
BL::Mesh::uv_layers_iterator l;
|
||||
int i = 0;
|
||||
@@ -615,10 +634,10 @@ static void attr_create_subd_uv_map(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh,
|
||||
|
||||
float2 *fdata = uv_attr->data_float2();
|
||||
|
||||
for (int i = 0; i < polys_num; i++) {
|
||||
const MPoly &b_poly = polys[i];
|
||||
for (int j = 0; j < b_poly.totloop; j++) {
|
||||
*(fdata++) = get_float2(l->data[b_poly.loopstart + j].uv());
|
||||
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||
int n = p.loop_total();
|
||||
for (int j = 0; j < n; j++) {
|
||||
*(fdata++) = get_float2(l->data[p.loop_start() + j].uv());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -681,8 +700,6 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
|
||||
if (num_verts == 0) {
|
||||
return;
|
||||
}
|
||||
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
|
||||
|
||||
/* STEP 1: Find out duplicated vertices and point duplicates to a single
|
||||
* original vertex.
|
||||
*/
|
||||
@@ -735,12 +752,10 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
|
||||
*/
|
||||
vector<float3> vert_normal(num_verts, zero_float3());
|
||||
/* First we accumulate all vertex normals in the original index. */
|
||||
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
|
||||
b_mesh.vertex_normals[0].ptr.data);
|
||||
for (int vert_index = 0; vert_index < num_verts; ++vert_index) {
|
||||
const float *b_vert_normal = b_vert_normals[vert_index];
|
||||
const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
|
||||
const int orig_index = vert_orig_index[vert_index];
|
||||
vert_normal[orig_index] += make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
|
||||
vert_normal[orig_index] += normal;
|
||||
}
|
||||
/* Then we normalize the accumulated result and flush it to all duplicates
|
||||
* as well.
|
||||
@@ -753,24 +768,18 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
|
||||
vector<int> counter(num_verts, 0);
|
||||
vector<float> raw_data(num_verts, 0.0f);
|
||||
vector<float3> edge_accum(num_verts, zero_float3());
|
||||
BL::Mesh::edges_iterator e;
|
||||
EdgeMap visited_edges;
|
||||
int edge_index = 0;
|
||||
memset(&counter[0], 0, sizeof(int) * counter.size());
|
||||
|
||||
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
const int edges_num = b_mesh.edges.length();
|
||||
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
const int v0 = vert_orig_index[b_edge.v1];
|
||||
const int v1 = vert_orig_index[b_edge.v2];
|
||||
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
|
||||
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
|
||||
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
|
||||
if (visited_edges.exists(v0, v1)) {
|
||||
continue;
|
||||
}
|
||||
visited_edges.insert(v0, v1);
|
||||
const MVert &b_vert_0 = verts[v0];
|
||||
const MVert &b_vert_1 = verts[v1];
|
||||
float3 co0 = make_float3(b_vert_0.co[0], b_vert_0.co[1], b_vert_0.co[2]);
|
||||
float3 co1 = make_float3(b_vert_1.co[0], b_vert_1.co[1], b_vert_1.co[2]);
|
||||
float3 co0 = get_float3(b_mesh.vertices[v0].co()), co1 = get_float3(b_mesh.vertices[v1].co());
|
||||
float3 edge = normalize(co1 - co0);
|
||||
edge_accum[v0] += edge;
|
||||
edge_accum[v1] += -edge;
|
||||
@@ -798,11 +807,11 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b
|
||||
float *data = attr->data_float();
|
||||
memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
|
||||
memset(&counter[0], 0, sizeof(int) * counter.size());
|
||||
edge_index = 0;
|
||||
visited_edges.clear();
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
const int v0 = vert_orig_index[b_edge.v1];
|
||||
const int v1 = vert_orig_index[b_edge.v2];
|
||||
for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
|
||||
const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
|
||||
v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
|
||||
if (visited_edges.exists(v0, v1)) {
|
||||
continue;
|
||||
}
|
||||
@@ -841,7 +850,6 @@ static void attr_create_random_per_island(Scene *scene,
|
||||
return;
|
||||
}
|
||||
|
||||
const int polys_num = b_mesh.polygons.length();
|
||||
int number_of_vertices = b_mesh.vertices.length();
|
||||
if (number_of_vertices == 0) {
|
||||
return;
|
||||
@@ -849,11 +857,8 @@ static void attr_create_random_per_island(Scene *scene,
|
||||
|
||||
DisjointSet vertices_sets(number_of_vertices);
|
||||
|
||||
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
const int edges_num = b_mesh.edges.length();
|
||||
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
vertices_sets.join(edges[i].v1, edges[i].v2);
|
||||
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||
vertices_sets.join(e.vertices()[0], e.vertices()[1]);
|
||||
}
|
||||
|
||||
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
|
||||
@@ -866,37 +871,14 @@ static void attr_create_random_per_island(Scene *scene,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (polys_num != 0) {
|
||||
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
|
||||
const MLoop *loops = static_cast<const MLoop *>(b_mesh.loops[0].ptr.data);
|
||||
for (int i = 0; i < polys_num; i++) {
|
||||
const MPoly &b_poly = polys[i];
|
||||
const MLoop &b_loop = loops[b_poly.loopstart];
|
||||
data[i] = hash_uint_to_float(vertices_sets.find(b_loop.v));
|
||||
}
|
||||
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||
data[p.index()] = hash_uint_to_float(vertices_sets.find(p.vertices()[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create Mesh */
|
||||
|
||||
static std::optional<BL::IntAttribute> find_material_index_attribute(BL::Mesh b_mesh)
|
||||
{
|
||||
for (BL::Attribute &b_attribute : b_mesh.attributes) {
|
||||
if (b_attribute.domain() != BL::Attribute::domain_FACE) {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.data_type() != BL::Attribute::data_type_INT) {
|
||||
continue;
|
||||
}
|
||||
if (b_attribute.name() != "material_index") {
|
||||
continue;
|
||||
}
|
||||
return BL::IntAttribute{b_attribute};
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static void create_mesh(Scene *scene,
|
||||
Mesh *mesh,
|
||||
BL::Mesh &b_mesh,
|
||||
@@ -908,7 +890,6 @@ static void create_mesh(Scene *scene,
|
||||
{
|
||||
/* count vertices and faces */
|
||||
int numverts = b_mesh.vertices.length();
|
||||
const int polys_num = b_mesh.polygons.length();
|
||||
int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.length();
|
||||
int numtris = 0;
|
||||
int numcorners = 0;
|
||||
@@ -921,17 +902,13 @@ static void create_mesh(Scene *scene,
|
||||
return;
|
||||
}
|
||||
|
||||
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
|
||||
|
||||
if (!subdivision) {
|
||||
numtris = numfaces;
|
||||
}
|
||||
else {
|
||||
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
|
||||
for (int i = 0; i < polys_num; i++) {
|
||||
const MPoly &b_poly = polys[i];
|
||||
numngons += (b_poly.totloop == 4) ? 0 : 1;
|
||||
numcorners += b_poly.totloop;
|
||||
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||
numngons += (p.loop_total() == 4) ? 0 : 1;
|
||||
numcorners += p.loop_total();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -943,23 +920,17 @@ static void create_mesh(Scene *scene,
|
||||
mesh->reserve_mesh(numverts, numtris);
|
||||
|
||||
/* create vertex coordinates and normals */
|
||||
for (int i = 0; i < numverts; i++) {
|
||||
const MVert &b_vert = verts[i];
|
||||
mesh->add_vertex(make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2]));
|
||||
}
|
||||
BL::Mesh::vertices_iterator v;
|
||||
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
|
||||
mesh->add_vertex(get_float3(v->co()));
|
||||
|
||||
AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes;
|
||||
Attribute *attr_N = attributes.add(ATTR_STD_VERTEX_NORMAL);
|
||||
float3 *N = attr_N->data_float3();
|
||||
|
||||
if (subdivision || !use_loop_normals) {
|
||||
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
|
||||
b_mesh.vertex_normals[0].ptr.data);
|
||||
for (int i = 0; i < numverts; i++) {
|
||||
const float *b_vert_normal = b_vert_normals[i];
|
||||
N[i] = make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
|
||||
}
|
||||
}
|
||||
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N)
|
||||
*N = get_float3(v->normal());
|
||||
N = attr_N->data_float3();
|
||||
|
||||
/* create generated coordinates from undeformed coordinates */
|
||||
const bool need_default_tangent = (subdivision == false) && (b_mesh.uv_layers.empty()) &&
|
||||
@@ -974,30 +945,19 @@ static void create_mesh(Scene *scene,
|
||||
float3 *generated = attr->data_float3();
|
||||
size_t i = 0;
|
||||
|
||||
BL::Mesh::vertices_iterator v;
|
||||
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) {
|
||||
generated[i++] = get_float3(v->undeformed_co()) * size - loc;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<BL::IntAttribute> material_indices = find_material_index_attribute(b_mesh);
|
||||
auto get_material_index = [&](const int poly_index) -> int {
|
||||
if (material_indices) {
|
||||
return clamp(material_indices->data[poly_index].value(), 0, used_shaders.size() - 1);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
/* create faces */
|
||||
const MPoly *polys = static_cast<const MPoly *>(b_mesh.polygons[0].ptr.data);
|
||||
if (!subdivision) {
|
||||
for (BL::MeshLoopTriangle &t : b_mesh.loop_triangles) {
|
||||
const int poly_index = t.polygon_index();
|
||||
const MPoly &b_poly = polys[poly_index];
|
||||
BL::MeshPolygon p = b_mesh.polygons[t.polygon_index()];
|
||||
int3 vi = get_int3(t.vertices());
|
||||
|
||||
int shader = get_material_index(poly_index);
|
||||
bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals;
|
||||
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
|
||||
bool smooth = p.use_smooth() || use_loop_normals;
|
||||
|
||||
if (use_loop_normals) {
|
||||
BL::Array<float, 9> loop_normals = t.split_normals();
|
||||
@@ -1017,19 +977,15 @@ static void create_mesh(Scene *scene,
|
||||
else {
|
||||
vector<int> vi;
|
||||
|
||||
const MLoop *loops = static_cast<const MLoop *>(b_mesh.loops[0].ptr.data);
|
||||
|
||||
for (int i = 0; i < numfaces; i++) {
|
||||
const MPoly &b_poly = polys[i];
|
||||
int n = b_poly.totloop;
|
||||
int shader = get_material_index(i);
|
||||
bool smooth = (b_poly.flag & ME_SMOOTH) || use_loop_normals;
|
||||
for (BL::MeshPolygon &p : b_mesh.polygons) {
|
||||
int n = p.loop_total();
|
||||
int shader = clamp(p.material_index(), 0, used_shaders.size() - 1);
|
||||
bool smooth = p.use_smooth() || use_loop_normals;
|
||||
|
||||
vi.resize(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
/* NOTE: Autosmooth is already taken care about. */
|
||||
|
||||
vi[i] = loops[b_poly.loopstart + i].v;
|
||||
vi[i] = b_mesh.loops[p.loop_start() + i].vertex_index();
|
||||
}
|
||||
|
||||
/* create subd faces */
|
||||
@@ -1082,33 +1038,27 @@ static void create_subd_mesh(Scene *scene,
|
||||
|
||||
create_mesh(scene, mesh, b_mesh, used_shaders, need_motion, motion_scale, true, subdivide_uvs);
|
||||
|
||||
const int edges_num = b_mesh.edges.length();
|
||||
/* export creases */
|
||||
size_t num_creases = 0;
|
||||
|
||||
if (edges_num != 0) {
|
||||
size_t num_creases = 0;
|
||||
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
if (b_edge.crease != 0) {
|
||||
num_creases++;
|
||||
}
|
||||
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||
if (e.crease() != 0.0f) {
|
||||
num_creases++;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->reserve_subd_creases(num_creases);
|
||||
mesh->reserve_subd_creases(num_creases);
|
||||
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
if (b_edge.crease != 0) {
|
||||
mesh->add_edge_crease(b_edge.v1, b_edge.v2, float(b_edge.crease) / 255.0f);
|
||||
}
|
||||
for (BL::MeshEdge &e : b_mesh.edges) {
|
||||
if (e.crease() != 0.0f) {
|
||||
mesh->add_edge_crease(e.vertices()[0], e.vertices()[1], e.crease());
|
||||
}
|
||||
}
|
||||
|
||||
for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) {
|
||||
for (int i = 0; i < c.data.length(); ++i) {
|
||||
if (c.data[i].value() != 0.0f) {
|
||||
mesh->add_vertex_crease(i, c.data[i].value());
|
||||
}
|
||||
for (BL::MeshVertexCreaseLayer &c : b_mesh.vertex_creases) {
|
||||
for (int i = 0; i < c.data.length(); ++i) {
|
||||
if (c.data[i].value() != 0.0f) {
|
||||
mesh->add_vertex_crease(i, c.data[i].value());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1229,12 +1179,6 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
||||
|
||||
/* TODO(sergey): Perform preliminary check for number of vertices. */
|
||||
if (b_mesh) {
|
||||
const int b_verts_num = b_mesh.vertices.length();
|
||||
if (b_verts_num == 0) {
|
||||
free_object_to_mesh(b_data, b_ob_info, b_mesh);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Export deformed coordinates. */
|
||||
/* Find attributes. */
|
||||
Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
|
||||
@@ -1252,30 +1196,22 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
||||
/* Load vertex data from mesh. */
|
||||
float3 *mP = attr_mP->data_float3() + motion_step * numverts;
|
||||
float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL;
|
||||
|
||||
const MVert *verts = static_cast<const MVert *>(b_mesh.vertices[0].ptr.data);
|
||||
|
||||
/* NOTE: We don't copy more that existing amount of vertices to prevent
|
||||
* possible memory corruption.
|
||||
*/
|
||||
for (int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
|
||||
const MVert &b_vert = verts[i];
|
||||
mP[i] = make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2]);
|
||||
}
|
||||
if (mN) {
|
||||
const float(*b_vert_normals)[3] = static_cast<const float(*)[3]>(
|
||||
b_mesh.vertex_normals[0].ptr.data);
|
||||
for (int i = 0; i < std::min<size_t>(b_verts_num, numverts); i++) {
|
||||
const float *b_vert_normal = b_vert_normals[i];
|
||||
mN[i] = make_float3(b_vert_normal[0], b_vert_normal[1], b_vert_normal[2]);
|
||||
}
|
||||
BL::Mesh::vertices_iterator v;
|
||||
int i = 0;
|
||||
for (b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < numverts; ++v, ++i) {
|
||||
mP[i] = get_float3(v->co());
|
||||
if (mN)
|
||||
mN[i] = get_float3(v->normal());
|
||||
}
|
||||
if (new_attribute) {
|
||||
/* In case of new attribute, we verify if there really was any motion. */
|
||||
if (b_verts_num != numverts ||
|
||||
if (b_mesh.vertices.length() != numverts ||
|
||||
memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) {
|
||||
/* no motion, remove attributes again */
|
||||
if (b_verts_num != numverts) {
|
||||
if (b_mesh.vertices.length() != numverts) {
|
||||
VLOG_WARNING << "Topology differs, disabling motion blur for object " << ob_name;
|
||||
}
|
||||
else {
|
||||
@@ -1299,7 +1235,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph,
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (b_verts_num != numverts) {
|
||||
if (b_mesh.vertices.length() != numverts) {
|
||||
VLOG_WARNING << "Topology differs, discarding motion blur for object " << ob_name
|
||||
<< " at time " << motion_step;
|
||||
memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts);
|
||||
|
@@ -66,6 +66,12 @@ bool BlenderSync::object_is_geometry(BObjectInfo &b_ob_info)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Other object types that are not meshes but evaluate to meshes are presented to render engines
|
||||
* as separate instance objects. Metaballs have not been affected by that change yet. */
|
||||
if (type == BL::Object::type_META) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return b_ob_data.is_a(&RNA_Mesh);
|
||||
}
|
||||
|
||||
|
@@ -59,6 +59,8 @@ static void debug_flags_sync_from_scene(BL::Scene b_scene)
|
||||
{
|
||||
DebugFlagsRef flags = DebugFlags();
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
/* Synchronize shared flags. */
|
||||
flags.viewport_static_bvh = get_enum(cscene, "debug_bvh_type");
|
||||
/* Synchronize CPU flags. */
|
||||
flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2");
|
||||
flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx");
|
||||
@@ -138,6 +140,8 @@ static PyObject *init_func(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
BlenderSession::headless = headless;
|
||||
|
||||
DebugFlags().running_inside_blender = true;
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@@ -110,8 +110,7 @@ void BlenderSession::create_session()
|
||||
{
|
||||
const SessionParams session_params = BlenderSync::get_session_params(
|
||||
b_engine, b_userpref, b_scene, background);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(
|
||||
b_scene, background, use_developer_ui);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
|
||||
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
|
||||
|
||||
/* reset status/progress */
|
||||
@@ -197,8 +196,7 @@ void BlenderSession::reset_session(BL::BlendData &b_data, BL::Depsgraph &b_depsg
|
||||
|
||||
const SessionParams session_params = BlenderSync::get_session_params(
|
||||
b_engine, b_userpref, b_scene, background);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(
|
||||
b_scene, background, use_developer_ui);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
|
||||
|
||||
if (scene->params.modified(scene_params) || session->params.modified(session_params) ||
|
||||
!this->b_render.use_persistent_data()) {
|
||||
@@ -659,7 +657,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
|
||||
session->set_display_driver(nullptr);
|
||||
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
|
||||
session->full_buffer_written_cb = [&](string_view filename) { full_buffer_written(filename); };
|
||||
|
||||
/* Sync scene. */
|
||||
BL::Object b_camera_override(b_engine.camera_override());
|
||||
@@ -701,10 +698,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
BufferParams buffer_params;
|
||||
buffer_params.width = bake_width;
|
||||
buffer_params.height = bake_height;
|
||||
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());
|
||||
|
||||
/* Update session. */
|
||||
session->reset(session_params, buffer_params);
|
||||
@@ -718,6 +711,8 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
|
||||
session->start();
|
||||
session->wait();
|
||||
}
|
||||
|
||||
session->set_output_driver(nullptr);
|
||||
}
|
||||
|
||||
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
||||
@@ -729,8 +724,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)
|
||||
/* on session/scene parameter changes, we recreate session entirely */
|
||||
const SessionParams session_params = BlenderSync::get_session_params(
|
||||
b_engine, b_userpref, b_scene, background);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(
|
||||
b_scene, background, use_developer_ui);
|
||||
const SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
|
||||
const bool session_pause = BlenderSync::get_session_pause(b_scene, background);
|
||||
|
||||
if (session->params.modified(session_params) || scene->params.modified(scene_params)) {
|
||||
@@ -1062,8 +1056,8 @@ void BlenderSession::ensure_display_driver_if_needed()
|
||||
return;
|
||||
}
|
||||
|
||||
unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(
|
||||
b_engine, b_scene, background);
|
||||
unique_ptr<BlenderDisplayDriver> display_driver = make_unique<BlenderDisplayDriver>(b_engine,
|
||||
b_scene);
|
||||
display_driver_ = display_driver.get();
|
||||
session->set_display_driver(move(display_driver));
|
||||
}
|
||||
|
@@ -248,13 +248,6 @@ static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping)
|
||||
mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z());
|
||||
}
|
||||
|
||||
static bool is_image_animated(BL::Image::source_enum b_image_source, BL::ImageUser &b_image_user)
|
||||
{
|
||||
return (b_image_source == BL::Image::source_MOVIE ||
|
||||
b_image_source == BL::Image::source_SEQUENCE) &&
|
||||
b_image_user.use_auto_refresh();
|
||||
}
|
||||
|
||||
static ShaderNode *add_node(Scene *scene,
|
||||
BL::RenderEngine &b_engine,
|
||||
BL::BlendData &b_data,
|
||||
@@ -350,33 +343,6 @@ static ShaderNode *add_node(Scene *scene,
|
||||
mix->set_use_clamp(b_mix_node.use_clamp());
|
||||
node = mix;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
||||
BL::ShaderNodeMix b_mix_node(b_node);
|
||||
if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_VECTOR) {
|
||||
if (b_mix_node.factor_mode() == BL::ShaderNodeMix::factor_mode_UNIFORM) {
|
||||
MixVectorNode *mix_node = graph->create_node<MixVectorNode>();
|
||||
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
||||
node = mix_node;
|
||||
}
|
||||
else {
|
||||
MixVectorNonUniformNode *mix_node = graph->create_node<MixVectorNonUniformNode>();
|
||||
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
||||
node = mix_node;
|
||||
}
|
||||
}
|
||||
else if (b_mix_node.data_type() == BL::ShaderNodeMix::data_type_RGBA) {
|
||||
MixColorNode *mix_node = graph->create_node<MixColorNode>();
|
||||
mix_node->set_blend_type((NodeMix)b_mix_node.blend_type());
|
||||
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
||||
mix_node->set_use_clamp_result(b_mix_node.clamp_result());
|
||||
node = mix_node;
|
||||
}
|
||||
else {
|
||||
MixFloatNode *mix_node = graph->create_node<MixFloatNode>();
|
||||
mix_node->set_use_clamp(b_mix_node.clamp_factor());
|
||||
node = mix_node;
|
||||
}
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
|
||||
node = graph->create_node<SeparateRGBNode>();
|
||||
}
|
||||
@@ -782,11 +748,10 @@ static ShaderNode *add_node(Scene *scene,
|
||||
get_tex_mapping(image, b_texture_mapping);
|
||||
|
||||
if (b_image) {
|
||||
BL::Image::source_enum b_image_source = b_image.source();
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
|
||||
|
||||
image->set_animated(is_image_animated(b_image_source, b_image_user));
|
||||
image->set_animated(b_image_node.image_user().use_auto_refresh());
|
||||
image->set_alpha_type(get_image_alpha_type(b_image));
|
||||
|
||||
array<int> tiles;
|
||||
@@ -798,9 +763,9 @@ static ShaderNode *add_node(Scene *scene,
|
||||
/* builtin images will use callback-based reading because
|
||||
* they could only be loaded correct from blender side
|
||||
*/
|
||||
bool is_builtin = b_image.packed_file() || b_image_source == BL::Image::source_GENERATED ||
|
||||
b_image_source == BL::Image::source_MOVIE ||
|
||||
(b_engine.is_preview() && b_image_source != BL::Image::source_SEQUENCE);
|
||||
bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
|
||||
b_image.source() == BL::Image::source_MOVIE ||
|
||||
(b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
|
||||
|
||||
if (is_builtin) {
|
||||
/* for builtin images we're using image datablock name to find an image to
|
||||
@@ -811,7 +776,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
*/
|
||||
int scene_frame = b_scene.frame_current();
|
||||
int image_frame = image_user_frame_number(b_image_user, b_image, scene_frame);
|
||||
if (b_image_source != BL::Image::source_TILED) {
|
||||
if (b_image.source() != BL::Image::source_TILED) {
|
||||
image->handle = scene->image_manager->add_image(
|
||||
new BlenderImageLoader(b_image, image_frame, 0, b_engine.is_preview()),
|
||||
image->image_params());
|
||||
@@ -829,7 +794,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
}
|
||||
else {
|
||||
ustring filename = ustring(
|
||||
image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current()));
|
||||
image_user_file_path(b_image_user, b_image, b_scene.frame_current()));
|
||||
image->set_filename(filename);
|
||||
}
|
||||
}
|
||||
@@ -847,15 +812,15 @@ static ShaderNode *add_node(Scene *scene,
|
||||
get_tex_mapping(env, b_texture_mapping);
|
||||
|
||||
if (b_image) {
|
||||
BL::Image::source_enum b_image_source = b_image.source();
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name")));
|
||||
env->set_animated(is_image_animated(b_image_source, b_image_user));
|
||||
|
||||
env->set_animated(b_env_node.image_user().use_auto_refresh());
|
||||
env->set_alpha_type(get_image_alpha_type(b_image));
|
||||
|
||||
bool is_builtin = b_image.packed_file() || b_image_source == BL::Image::source_GENERATED ||
|
||||
b_image_source == BL::Image::source_MOVIE ||
|
||||
(b_engine.is_preview() && b_image_source != BL::Image::source_SEQUENCE);
|
||||
bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED ||
|
||||
b_image.source() == BL::Image::source_MOVIE ||
|
||||
(b_engine.is_preview() && b_image.source() != BL::Image::source_SEQUENCE);
|
||||
|
||||
if (is_builtin) {
|
||||
int scene_frame = b_scene.frame_current();
|
||||
@@ -866,7 +831,7 @@ static ShaderNode *add_node(Scene *scene,
|
||||
}
|
||||
else {
|
||||
env->set_filename(
|
||||
ustring(image_user_file_path(b_data, b_image_user, b_image, b_scene.frame_current())));
|
||||
ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current())));
|
||||
}
|
||||
}
|
||||
node = env;
|
||||
@@ -1099,9 +1064,7 @@ static bool node_use_modified_socket_name(ShaderNode *node)
|
||||
return true;
|
||||
}
|
||||
|
||||
static ShaderInput *node_find_input_by_name(BL::Node b_node,
|
||||
ShaderNode *node,
|
||||
BL::NodeSocket &b_socket)
|
||||
static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::NodeSocket &b_socket)
|
||||
{
|
||||
string name = b_socket.identifier();
|
||||
ShaderInput *input = node->input(name.c_str());
|
||||
@@ -1111,35 +1074,6 @@ static ShaderInput *node_find_input_by_name(BL::Node b_node,
|
||||
if (string_startswith(name, "Shader")) {
|
||||
string_replace(name, "Shader", "Closure");
|
||||
}
|
||||
|
||||
/* Map mix node internal name for shader. */
|
||||
if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
||||
if (string_endswith(name, "Factor_Float")) {
|
||||
string_replace(name, "Factor_Float", "Factor");
|
||||
}
|
||||
else if (string_endswith(name, "Factor_Vector")) {
|
||||
string_replace(name, "Factor_Vector", "Factor");
|
||||
}
|
||||
else if (string_endswith(name, "A_Float")) {
|
||||
string_replace(name, "A_Float", "A");
|
||||
}
|
||||
else if (string_endswith(name, "B_Float")) {
|
||||
string_replace(name, "B_Float", "B");
|
||||
}
|
||||
else if (string_endswith(name, "A_Color")) {
|
||||
string_replace(name, "A_Color", "A");
|
||||
}
|
||||
else if (string_endswith(name, "B_Color")) {
|
||||
string_replace(name, "B_Color", "B");
|
||||
}
|
||||
else if (string_endswith(name, "A_Vector")) {
|
||||
string_replace(name, "A_Vector", "A");
|
||||
}
|
||||
else if (string_endswith(name, "B_Vector")) {
|
||||
string_replace(name, "B_Vector", "B");
|
||||
}
|
||||
}
|
||||
|
||||
input = node->input(name.c_str());
|
||||
|
||||
if (!input) {
|
||||
@@ -1169,9 +1103,7 @@ static ShaderInput *node_find_input_by_name(BL::Node b_node,
|
||||
return input;
|
||||
}
|
||||
|
||||
static ShaderOutput *node_find_output_by_name(BL::Node b_node,
|
||||
ShaderNode *node,
|
||||
BL::NodeSocket &b_socket)
|
||||
static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::NodeSocket &b_socket)
|
||||
{
|
||||
string name = b_socket.identifier();
|
||||
ShaderOutput *output = node->output(name.c_str());
|
||||
@@ -1182,21 +1114,6 @@ static ShaderOutput *node_find_output_by_name(BL::Node b_node,
|
||||
name = "Closure";
|
||||
output = node->output(name.c_str());
|
||||
}
|
||||
/* Map internal name for shader. */
|
||||
if (b_node.is_a(&RNA_ShaderNodeMix)) {
|
||||
if (string_endswith(name, "Result_Float")) {
|
||||
string_replace(name, "Result_Float", "Result");
|
||||
output = node->output(name.c_str());
|
||||
}
|
||||
else if (string_endswith(name, "Result_Color")) {
|
||||
string_replace(name, "Result_Color", "Result");
|
||||
output = node->output(name.c_str());
|
||||
}
|
||||
else if (string_endswith(name, "Result_Vector")) {
|
||||
string_replace(name, "Result_Vector", "Result");
|
||||
output = node->output(name.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
@@ -1342,11 +1259,7 @@ static void add_nodes(Scene *scene,
|
||||
if (node) {
|
||||
/* map node sockets for linking */
|
||||
for (BL::NodeSocket &b_input : b_node.inputs) {
|
||||
if (b_input.is_unavailable()) {
|
||||
/* Skip unavailable sockets. */
|
||||
continue;
|
||||
}
|
||||
ShaderInput *input = node_find_input_by_name(b_node, node, b_input);
|
||||
ShaderInput *input = node_find_input_by_name(node, b_input);
|
||||
if (!input) {
|
||||
/* XXX should not happen, report error? */
|
||||
continue;
|
||||
@@ -1356,11 +1269,7 @@ static void add_nodes(Scene *scene,
|
||||
set_default_value(input, b_input, b_data, b_ntree);
|
||||
}
|
||||
for (BL::NodeSocket &b_output : b_node.outputs) {
|
||||
if (b_output.is_unavailable()) {
|
||||
/* Skip unavailable sockets. */
|
||||
continue;
|
||||
}
|
||||
ShaderOutput *output = node_find_output_by_name(b_node, node, b_output);
|
||||
ShaderOutput *output = node_find_output_by_name(node, b_output);
|
||||
if (!output) {
|
||||
/* XXX should not happen, report error? */
|
||||
continue;
|
||||
|
@@ -343,7 +343,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold"));
|
||||
|
||||
SamplingPattern sampling_pattern = (SamplingPattern)get_enum(
|
||||
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_PMJ);
|
||||
cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL);
|
||||
integrator->set_sampling_pattern(sampling_pattern);
|
||||
|
||||
int samples = 1;
|
||||
@@ -385,8 +385,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
|
||||
/* Only use scrambling distance in the viewport if user wants to. */
|
||||
bool preview_scrambling_distance = get_boolean(cscene, "preview_scrambling_distance");
|
||||
if ((preview && !preview_scrambling_distance) ||
|
||||
sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) {
|
||||
if (preview && !preview_scrambling_distance) {
|
||||
scrambling_distance = 1.0f;
|
||||
}
|
||||
|
||||
@@ -413,15 +412,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background)
|
||||
integrator->set_direct_light_sampling_type(direct_light_sampling_type);
|
||||
#endif
|
||||
|
||||
DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
|
||||
|
||||
/* No denoising support for vertex color baking, vertices packed into image
|
||||
* buffer have no relation to neighbors. */
|
||||
if (scene->bake_manager->get_baking() &&
|
||||
b_scene.render().bake().target() != BL::BakeSettings::target_IMAGE_TEXTURES) {
|
||||
denoise_params.use = false;
|
||||
}
|
||||
|
||||
const DenoiseParams denoise_params = get_denoise_params(b_scene, b_view_layer, background);
|
||||
integrator->set_use_denoise(denoise_params.use);
|
||||
|
||||
/* Only update denoiser parameters if the denoiser is actually used. This allows to tweak
|
||||
@@ -680,18 +671,14 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
}
|
||||
|
||||
/* Cryptomatte stores two ID/weight pairs per RGBA layer.
|
||||
* User facing parameter is the number of pairs.
|
||||
*
|
||||
* NOTE: Name channels lowercase RGBA so that compression rules check in OpenEXR DWA code uses
|
||||
* lossless compression. Reportedly this naming is the only one which works good from the
|
||||
* interoperability point of view. Using XYZW naming is not portable. */
|
||||
* User facing parameter is the number of pairs. */
|
||||
int crypto_depth = divide_up(min(16, b_view_layer.pass_cryptomatte_depth()), 2);
|
||||
scene->film->set_cryptomatte_depth(crypto_depth);
|
||||
CryptomatteType cryptomatte_passes = CRYPT_NONE;
|
||||
if (b_view_layer.use_pass_cryptomatte_object()) {
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Object%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT);
|
||||
@@ -699,7 +686,7 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
if (b_view_layer.use_pass_cryptomatte_material()) {
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Material%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL);
|
||||
@@ -707,7 +694,7 @@ void BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::ViewLayer &b_v
|
||||
if (b_view_layer.use_pass_cryptomatte_asset()) {
|
||||
for (int i = 0; i < crypto_depth; i++) {
|
||||
string passname = cryptomatte_prefix + string_printf("Asset%02d", i);
|
||||
b_engine.add_pass(passname.c_str(), 4, "rgba", b_view_layer.name().c_str());
|
||||
b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str());
|
||||
pass_add(scene, PASS_CRYPTOMATTE, passname.c_str());
|
||||
}
|
||||
cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET);
|
||||
@@ -806,9 +793,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
||||
|
||||
/* Scene Parameters */
|
||||
|
||||
SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene,
|
||||
const bool background,
|
||||
const bool use_developer_ui)
|
||||
SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background)
|
||||
{
|
||||
SceneParams params;
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
@@ -819,7 +804,7 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene,
|
||||
else if (shadingsystem == 1)
|
||||
params.shadingsystem = SHADINGSYSTEM_OSL;
|
||||
|
||||
if (background || (use_developer_ui && get_enum(cscene, "debug_bvh_type")))
|
||||
if (background || DebugFlags().viewport_static_bvh)
|
||||
params.bvh_type = BVH_TYPE_STATIC;
|
||||
else
|
||||
params.bvh_type = BVH_TYPE_DYNAMIC;
|
||||
|
@@ -84,9 +84,7 @@ class BlenderSync {
|
||||
}
|
||||
|
||||
/* get parameters */
|
||||
static SceneParams get_scene_params(BL::Scene &b_scene,
|
||||
const bool background,
|
||||
const bool use_developer_ui);
|
||||
static SceneParams get_scene_params(BL::Scene &b_scene, bool background);
|
||||
static SessionParams get_session_params(BL::RenderEngine &b_engine,
|
||||
BL::Preferences &b_userpref,
|
||||
BL::Scene &b_scene,
|
||||
|
@@ -21,8 +21,7 @@
|
||||
|
||||
extern "C" {
|
||||
void BKE_image_user_frame_calc(void *ima, void *iuser, int cfra);
|
||||
void BKE_image_user_file_path_ex(
|
||||
void *bmain, void *iuser, void *ima, char *path, bool resolve_udim, bool resolve_multiview);
|
||||
void BKE_image_user_file_path_ex(void *iuser, void *ima, char *path, bool resolve_udim);
|
||||
unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame, int tile);
|
||||
float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile);
|
||||
}
|
||||
@@ -282,15 +281,12 @@ static inline int render_resolution_y(BL::RenderSettings &b_render)
|
||||
return b_render.resolution_y() * b_render.resolution_percentage() / 100;
|
||||
}
|
||||
|
||||
static inline string image_user_file_path(BL::BlendData &data,
|
||||
BL::ImageUser &iuser,
|
||||
BL::Image &ima,
|
||||
int cfra)
|
||||
static inline string image_user_file_path(BL::ImageUser &iuser, BL::Image &ima, int cfra)
|
||||
{
|
||||
char filepath[1024];
|
||||
iuser.tile(0);
|
||||
BKE_image_user_frame_calc(ima.ptr.data, iuser.ptr.data, cfra);
|
||||
BKE_image_user_file_path_ex(data.ptr.data, iuser.ptr.data, ima.ptr.data, filepath, false, true);
|
||||
BKE_image_user_file_path_ex(iuser.ptr.data, ima.ptr.data, filepath, false);
|
||||
|
||||
return string(filepath);
|
||||
}
|
||||
|
@@ -74,13 +74,6 @@ class BVH {
|
||||
{
|
||||
}
|
||||
|
||||
virtual void replace_geometry(const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects)
|
||||
{
|
||||
this->geometry = geometry;
|
||||
this->objects = objects;
|
||||
}
|
||||
|
||||
protected:
|
||||
BVH(const BVHParams ¶ms,
|
||||
const vector<Geometry *> &geometry,
|
||||
|
@@ -21,12 +21,4 @@ BVHMulti::~BVHMulti()
|
||||
}
|
||||
}
|
||||
|
||||
void BVHMulti::replace_geometry(const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects)
|
||||
{
|
||||
foreach (BVH *bvh, sub_bvhs) {
|
||||
bvh->replace_geometry(geometry, objects);
|
||||
}
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -19,9 +19,6 @@ class BVHMulti : public BVH {
|
||||
const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
virtual ~BVHMulti();
|
||||
|
||||
virtual void replace_geometry(const vector<Geometry *> &geometry,
|
||||
const vector<Object *> &objects);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -39,10 +39,10 @@ enum BVHType {
|
||||
BVH_NUM_TYPES,
|
||||
};
|
||||
|
||||
/* Names bit-flag type to denote which BVH layouts are supported by
|
||||
/* Names bitflag type to denote which BVH layouts are supported by
|
||||
* particular area.
|
||||
*
|
||||
* Bit-flags are the BVH_LAYOUT_* values.
|
||||
* Bitflags are the BVH_LAYOUT_* values.
|
||||
*/
|
||||
typedef int BVHLayoutMask;
|
||||
|
||||
|
@@ -505,19 +505,26 @@ if(CYCLES_STANDALONE_REPOSITORY)
|
||||
endif()
|
||||
|
||||
###########################################################################
|
||||
# Epoxy
|
||||
# GLEW
|
||||
###########################################################################
|
||||
|
||||
if(CYCLES_STANDALONE_REPOSITORY)
|
||||
if((WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) OR
|
||||
WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
if(MSVC AND EXISTS ${_cycles_lib_dir})
|
||||
set(Epoxy_LIBRARIES "${_cycles_lib_dir}/epoxy/lib/epoxy.lib")
|
||||
set(Epoxy_INCLUDE_DIRS "${_cycles_lib_dir}/epoxy/include")
|
||||
set(GLEW_LIBRARY "${_cycles_lib_dir}/opengl/lib/glew.lib")
|
||||
set(GLEW_INCLUDE_DIR "${_cycles_lib_dir}/opengl/include")
|
||||
add_definitions(-DGLEW_STATIC)
|
||||
else()
|
||||
find_package(Epoxy REQUIRED)
|
||||
find_package(GLEW REQUIRED)
|
||||
endif()
|
||||
|
||||
set(CYCLES_GLEW_LIBRARIES ${GLEW_LIBRARY})
|
||||
endif()
|
||||
else()
|
||||
# Workaround for unconventional variable name use in Blender.
|
||||
set(GLEW_INCLUDE_DIR "${GLEW_INCLUDE_PATH}")
|
||||
set(CYCLES_GLEW_LIBRARIES bf_intern_glew_mx ${BLENDER_GLEW_LIBRARIES})
|
||||
endif()
|
||||
|
||||
###########################################################################
|
||||
@@ -549,6 +556,25 @@ if(EXISTS ${_cycles_lib_dir})
|
||||
unset(_cycles_lib_dir)
|
||||
endif()
|
||||
|
||||
###########################################################################
|
||||
# OpenGL
|
||||
###########################################################################
|
||||
|
||||
if((WITH_CYCLES_STANDALONE AND WITH_CYCLES_STANDALONE_GUI) OR
|
||||
WITH_CYCLES_HYDRA_RENDER_DELEGATE)
|
||||
if(CYCLES_STANDALONE_REPOSITORY)
|
||||
if(NOT DEFINED OpenGL_GL_PREFERENCE)
|
||||
set(OpenGL_GL_PREFERENCE "LEGACY")
|
||||
endif()
|
||||
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
set(CYCLES_GL_LIBRARIES ${OPENGL_gl_LIBRARY})
|
||||
else()
|
||||
set(CYCLES_GL_LIBRARIES ${BLENDER_GL_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
###########################################################################
|
||||
# SDL
|
||||
###########################################################################
|
||||
@@ -628,29 +654,15 @@ endif()
|
||||
# oneAPI
|
||||
###########################################################################
|
||||
|
||||
if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if (WITH_CYCLES_DEVICE_ONEAPI)
|
||||
find_package(SYCL)
|
||||
find_package(LevelZero)
|
||||
|
||||
if(SYCL_FOUND AND LEVEL_ZERO_FOUND)
|
||||
if (SYCL_FOUND AND LEVEL_ZERO_FOUND)
|
||||
message(STATUS "Found oneAPI: ${SYCL_LIBRARY}")
|
||||
message(STATUS "Found Level Zero: ${LEVEL_ZERO_LIBRARY}")
|
||||
|
||||
if(WITH_CYCLES_ONEAPI_BINARIES)
|
||||
if(NOT OCLOC_INSTALL_DIR)
|
||||
get_filename_component(_sycl_compiler_root ${SYCL_COMPILER} DIRECTORY)
|
||||
get_filename_component(OCLOC_INSTALL_DIR "${_sycl_compiler_root}/../lib/ocloc" ABSOLUTE)
|
||||
unset(_sycl_compiler_root)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS ${OCLOC_INSTALL_DIR})
|
||||
message(STATUS "oneAPI ocloc not found in ${OCLOC_INSTALL_DIR}, disabling WITH_CYCLES_ONEAPI_BINARIES."
|
||||
" A different ocloc directory can be set using OCLOC_INSTALL_DIR cmake variable.")
|
||||
set(WITH_CYCLES_ONEAPI_BINARIES OFF)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "oneAPI or Level Zero not found, disabling WITH_CYCLES_DEVICE_ONEAPI")
|
||||
message(STATUS "oneAPI or Level Zero not found, disabling oneAPI device from Cycles")
|
||||
set(WITH_CYCLES_DEVICE_ONEAPI OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -3,9 +3,12 @@
|
||||
|
||||
set(INC
|
||||
..
|
||||
../../glew-mx
|
||||
)
|
||||
|
||||
set(INC_SYS )
|
||||
set(INC_SYS
|
||||
${GLEW_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA)
|
||||
if(WITH_CUDA_DYNLOAD)
|
||||
@@ -19,8 +22,6 @@ if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA)
|
||||
)
|
||||
add_definitions(-DCYCLES_CUDA_NVCC_EXECUTABLE="${CUDA_NVCC_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DCYCLES_RUNTIME_OPTIX_ROOT_DIR="${CYCLES_RUNTIME_OPTIX_ROOT_DIR}")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
|
||||
@@ -149,6 +150,7 @@ set(SRC
|
||||
set(LIB
|
||||
cycles_kernel
|
||||
cycles_util
|
||||
${CYCLES_GL_LIBRARIES}
|
||||
)
|
||||
|
||||
if(WITH_CYCLES_DEVICE_OPTIX OR WITH_CYCLES_DEVICE_CUDA)
|
||||
@@ -169,6 +171,8 @@ if(WITH_CYCLES_DEVICE_HIP AND WITH_HIP_DYNLOAD)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_CYCLES_DEVICE_CUDA)
|
||||
add_definitions(-DWITH_CUDA)
|
||||
endif()
|
||||
|
@@ -1202,11 +1202,11 @@ bool CUDADevice::should_use_graphics_interop()
|
||||
}
|
||||
|
||||
vector<CUdevice> gl_devices(num_all_devices);
|
||||
uint num_gl_devices = 0;
|
||||
uint num_gl_devices;
|
||||
cuGLGetDevices(&num_gl_devices, gl_devices.data(), num_all_devices, CU_GL_DEVICE_LIST_ALL);
|
||||
|
||||
for (uint i = 0; i < num_gl_devices; ++i) {
|
||||
if (gl_devices[i] == cuDevice) {
|
||||
for (CUdevice gl_device : gl_devices) {
|
||||
if (gl_device == cuDevice) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -16,6 +16,7 @@
|
||||
# include "util/log.h"
|
||||
# include "util/map.h"
|
||||
# include "util/md5.h"
|
||||
# include "util/opengl.h"
|
||||
# include "util/path.h"
|
||||
# include "util/string.h"
|
||||
# include "util/system.h"
|
||||
|
@@ -65,8 +65,6 @@ OneapiDevice::OneapiDevice(const DeviceInfo &info,
|
||||
kg_memory_device_ = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, globals_segment_size);
|
||||
|
||||
kg_memory_size_ = globals_segment_size;
|
||||
|
||||
max_memory_on_device_ = oneapi_dll_.oneapi_get_memcapacity(device_queue_);
|
||||
}
|
||||
|
||||
OneapiDevice::~OneapiDevice()
|
||||
@@ -136,16 +134,17 @@ void OneapiDevice::generic_alloc(device_memory &mem)
|
||||
* because Cycles already uses two different pointer for host activity and device activity, and
|
||||
* also has to perform all needed memory transfer operations. So, USM device memory
|
||||
* type has been used for oneAPI device in order to better fit in Cycles architecture. */
|
||||
void *device_pointer = nullptr;
|
||||
if (mem.memory_size() + stats.mem_used < max_memory_on_device_)
|
||||
device_pointer = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, memory_size);
|
||||
void *device_pointer = oneapi_dll_.oneapi_usm_alloc_device(device_queue_, memory_size);
|
||||
if (device_pointer == nullptr) {
|
||||
size_t max_memory_on_device = oneapi_dll_.oneapi_get_memcapacity(device_queue_);
|
||||
set_error("oneAPI kernel - device memory allocation error for " +
|
||||
string_human_readable_size(mem.memory_size()) +
|
||||
", possibly caused by lack of available memory space on the device: " +
|
||||
string_human_readable_size(stats.mem_used) + " of " +
|
||||
string_human_readable_size(max_memory_on_device_) + " is already allocated");
|
||||
string_human_readable_size(max_memory_on_device) + " is already allocated");
|
||||
return;
|
||||
}
|
||||
assert(device_pointer);
|
||||
|
||||
mem.device_pointer = reinterpret_cast<ccl::device_ptr>(device_pointer);
|
||||
mem.device_size = memory_size;
|
||||
@@ -155,9 +154,6 @@ void OneapiDevice::generic_alloc(device_memory &mem)
|
||||
|
||||
void OneapiDevice::generic_copy_to(device_memory &mem)
|
||||
{
|
||||
if (!mem.device_pointer) {
|
||||
return;
|
||||
}
|
||||
size_t memory_size = mem.memory_size();
|
||||
|
||||
/* Copy operation from host shouldn't be requested if there is no memory allocated on host. */
|
||||
@@ -190,10 +186,7 @@ void *OneapiDevice::kernel_globals_device_pointer()
|
||||
|
||||
void OneapiDevice::generic_free(device_memory &mem)
|
||||
{
|
||||
if (!mem.device_pointer) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(mem.device_pointer);
|
||||
stats.mem_free(mem.device_size);
|
||||
mem.device_size = 0;
|
||||
|
||||
@@ -263,15 +256,14 @@ void OneapiDevice::mem_copy_from(device_memory &mem, size_t y, size_t w, size_t
|
||||
assert(device_queue_);
|
||||
|
||||
assert(size != 0);
|
||||
if (mem.device_pointer) {
|
||||
char *shifted_host = reinterpret_cast<char *>(mem.host_pointer) + offset;
|
||||
char *shifted_device = reinterpret_cast<char *>(mem.device_pointer) + offset;
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_usm_memcpy(
|
||||
device_queue_, shifted_host, shifted_device, size);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI memory operation error: got runtime exception \"" +
|
||||
oneapi_error_string_ + "\"");
|
||||
}
|
||||
assert(mem.device_pointer);
|
||||
char *shifted_host = reinterpret_cast<char *>(mem.host_pointer) + offset;
|
||||
char *shifted_device = reinterpret_cast<char *>(mem.device_pointer) + offset;
|
||||
bool is_finished_ok = oneapi_dll_.oneapi_usm_memcpy(
|
||||
device_queue_, shifted_host, shifted_device, size);
|
||||
if (is_finished_ok == false) {
|
||||
set_error("oneAPI memory operation error: got runtime exception \"" + oneapi_error_string_ +
|
||||
"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -24,7 +24,6 @@ class OneapiDevice : public Device {
|
||||
void *kg_memory_;
|
||||
void *kg_memory_device_;
|
||||
size_t kg_memory_size_ = (size_t)0;
|
||||
size_t max_memory_on_device_ = (size_t)0;
|
||||
OneAPIDLLInterface oneapi_dll_;
|
||||
std::string oneapi_error_string_;
|
||||
|
||||
|
@@ -39,9 +39,6 @@ CCL_NAMESPACE_BEGIN
|
||||
// The original code is Copyright NVIDIA Corporation, BSD-3-Clause.
|
||||
namespace {
|
||||
|
||||
# if OPTIX_ABI_VERSION >= 60
|
||||
using ::optixUtilDenoiserInvokeTiled;
|
||||
# else
|
||||
static OptixResult optixUtilDenoiserSplitImage(const OptixImage2D &input,
|
||||
const OptixImage2D &output,
|
||||
unsigned int overlapWindowSizeInPixels,
|
||||
@@ -218,7 +215,6 @@ static OptixResult optixUtilDenoiserInvokeTiled(OptixDenoiser denoiser,
|
||||
}
|
||||
return OPTIX_SUCCESS;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if OPTIX_ABI_VERSION >= 55
|
||||
static void execute_optix_task(TaskPool &pool, OptixTask task, OptixResult &failure_reason)
|
||||
@@ -342,29 +338,15 @@ BVHLayoutMask OptiXDevice::get_bvh_layout_mask() const
|
||||
return BVH_LAYOUT_OPTIX;
|
||||
}
|
||||
|
||||
static string get_optix_include_dir()
|
||||
{
|
||||
const char *env_dir = getenv("OPTIX_ROOT_DIR");
|
||||
const char *default_dir = CYCLES_RUNTIME_OPTIX_ROOT_DIR;
|
||||
|
||||
if (env_dir && env_dir[0]) {
|
||||
const string env_include_dir = path_join(env_dir, "include");
|
||||
return env_include_dir;
|
||||
}
|
||||
else if (default_dir[0]) {
|
||||
const string default_include_dir = path_join(default_dir, "include");
|
||||
return default_include_dir;
|
||||
}
|
||||
|
||||
return string();
|
||||
}
|
||||
|
||||
string OptiXDevice::compile_kernel_get_common_cflags(const uint kernel_features)
|
||||
{
|
||||
string common_cflags = CUDADevice::compile_kernel_get_common_cflags(kernel_features);
|
||||
|
||||
/* Add OptiX SDK include directory to include paths. */
|
||||
common_cflags += string_printf(" -I\"%s\"", get_optix_include_dir().c_str());
|
||||
const char *optix_sdk_path = getenv("OPTIX_ROOT_DIR");
|
||||
if (optix_sdk_path) {
|
||||
common_cflags += string_printf(" -I\"%s/include\"", optix_sdk_path);
|
||||
}
|
||||
|
||||
/* Specialization for shader raytracing. */
|
||||
if (kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
|
||||
@@ -474,19 +456,10 @@ bool OptiXDevice::load_kernels(const uint kernel_features)
|
||||
"lib/kernel_optix_shader_raytrace.ptx" :
|
||||
"lib/kernel_optix.ptx");
|
||||
if (use_adaptive_compilation() || path_file_size(ptx_filename) == -1) {
|
||||
std::string optix_include_dir = get_optix_include_dir();
|
||||
if (optix_include_dir.empty()) {
|
||||
if (!getenv("OPTIX_ROOT_DIR")) {
|
||||
set_error(
|
||||
"Unable to compile OptiX kernels at runtime. Set OPTIX_ROOT_DIR environment variable "
|
||||
"to a directory containing the OptiX SDK.");
|
||||
return false;
|
||||
}
|
||||
else if (!path_is_directory(optix_include_dir)) {
|
||||
set_error(string_printf(
|
||||
"OptiX headers not found at %s, unable to compile OptiX kernels at runtime. Install "
|
||||
"OptiX SDK in the specified location, or set OPTIX_ROOT_DIR environment variable to a "
|
||||
"directory containing the OptiX SDK.",
|
||||
optix_include_dir.c_str()));
|
||||
"Missing OPTIX_ROOT_DIR environment variable (which must be set with the path to "
|
||||
"the Optix SDK to be able to compile Optix kernels on demand).");
|
||||
return false;
|
||||
}
|
||||
ptx_filename = compile_kernel(
|
||||
@@ -1416,7 +1389,7 @@ bool OptiXDevice::build_optix_bvh(BVHOptiX *bvh,
|
||||
options.operation = operation;
|
||||
if (use_fast_trace_bvh ||
|
||||
/* The build flags have to match the ones used to query the built-in curve intersection
|
||||
* program (see optixBuiltinISModuleGet above) */
|
||||
program (see optixBuiltinISModuleGet above) */
|
||||
build_input.type == OPTIX_BUILD_INPUT_TYPE_CURVES) {
|
||||
VLOG_INFO << "Using fast to trace OptiX BVH";
|
||||
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
|
||||
|
@@ -171,7 +171,7 @@ struct NodeType {
|
||||
#define SOCKET_DEFINE(name, ui_name, default_value, datatype, TYPE, flags, ...) \
|
||||
{ \
|
||||
static datatype defval = default_value; \
|
||||
static_assert(std::is_same_v<decltype(T::name), datatype>); \
|
||||
CHECK_TYPE(T::name, datatype); \
|
||||
type->register_input(ustring(#name), \
|
||||
ustring(ui_name), \
|
||||
TYPE, \
|
||||
|
@@ -10,18 +10,18 @@ set(INC
|
||||
)
|
||||
set(INC_SYS
|
||||
${USD_INCLUDE_DIRS}
|
||||
${Epoxy_INCLUDE_DIRS}
|
||||
${GLEW_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
set(LIB
|
||||
cycles_scene
|
||||
cycles_session
|
||||
cycles_graph
|
||||
${Epoxy_LIBRARIES}
|
||||
${CYCLES_GLEW_LIBRARIES}
|
||||
)
|
||||
cycles_external_libraries_append(LIB)
|
||||
|
||||
set(SRC_HD_CYCLES_HEADERS
|
||||
set(INC_HD_CYCLES
|
||||
attribute.h
|
||||
camera.h
|
||||
config.h
|
||||
@@ -64,6 +64,8 @@ set(SRC_HD_CYCLES
|
||||
volume.cpp
|
||||
)
|
||||
|
||||
add_definitions(${GL_DEFINITIONS})
|
||||
|
||||
if(WITH_OPENVDB)
|
||||
add_definitions(-DWITH_OPENVDB ${OPENVDB_DEFINITIONS})
|
||||
list(APPEND INC_SYS
|
||||
@@ -75,7 +77,7 @@ endif()
|
||||
if(EXISTS ${USD_INCLUDE_DIR}/pxr/imaging/hgiGL)
|
||||
add_definitions(-DWITH_HYDRA_DISPLAY_DRIVER)
|
||||
list(APPEND SRC_HD_CYCLES display_driver.cpp)
|
||||
list(APPEND SRC_HD_CYCLES_HEADERS display_driver.h)
|
||||
list(APPEND INC_HD_CYCLES display_driver.h)
|
||||
endif()
|
||||
|
||||
include_directories(${INC})
|
||||
@@ -83,7 +85,7 @@ include_directories(SYSTEM ${INC_SYS})
|
||||
|
||||
add_library(cycles_hydra STATIC
|
||||
${SRC_HD_CYCLES}
|
||||
${SRC_HD_CYCLES_HEADERS}
|
||||
${INC_HD_CYCLES}
|
||||
)
|
||||
|
||||
target_compile_options(cycles_hydra
|
||||
|
@@ -11,7 +11,7 @@
|
||||
#include "hydra/render_buffer.h"
|
||||
#include "hydra/session.h"
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <GL/glew.h>
|
||||
#include <pxr/imaging/hgiGL/texture.h>
|
||||
|
||||
HDCYCLES_NAMESPACE_OPEN_SCOPE
|
||||
|
@@ -101,17 +101,10 @@ static Device *find_best_device(Device *device, DenoiserType type)
|
||||
if ((sub_device->info.denoisers & type) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!best_device) {
|
||||
best_device = sub_device;
|
||||
}
|
||||
else {
|
||||
/* Prefer a device that can use graphics interop for faster display update. */
|
||||
if (sub_device->should_use_graphics_interop() &&
|
||||
!best_device->should_use_graphics_interop()) {
|
||||
best_device = sub_device;
|
||||
}
|
||||
|
||||
/* TODO(sergey): Choose fastest device from available ones. Taking into account performance
|
||||
* of the device and data transfer cost. */
|
||||
}
|
||||
|
@@ -191,12 +191,6 @@ bool PassAccessor::get_render_tile_pixels(const RenderBuffers *render_buffers,
|
||||
* had the computation done. */
|
||||
if (pass_info.num_components == 3) {
|
||||
get_pass_float3(render_buffers, buffer_params, destination);
|
||||
|
||||
/* Use alpha for colors passes. */
|
||||
if (type == PASS_DIFFUSE_COLOR || type == PASS_GLOSSY_COLOR ||
|
||||
type == PASS_TRANSMISSION_COLOR) {
|
||||
num_written_components = destination.num_components;
|
||||
}
|
||||
}
|
||||
else if (pass_info.num_components == 4) {
|
||||
if (destination.num_components == 3) {
|
||||
|
@@ -26,7 +26,6 @@ PathTrace::PathTrace(Device *device,
|
||||
RenderScheduler &render_scheduler,
|
||||
TileManager &tile_manager)
|
||||
: device_(device),
|
||||
film_(film),
|
||||
device_scene_(device_scene),
|
||||
render_scheduler_(render_scheduler),
|
||||
tile_manager_(tile_manager)
|
||||
@@ -61,17 +60,7 @@ PathTrace::~PathTrace()
|
||||
void PathTrace::load_kernels()
|
||||
{
|
||||
if (denoiser_) {
|
||||
/* Activate graphics interop while denoiser device is created, so that it can choose a device
|
||||
* that supports interop for faster display updates. */
|
||||
if (display_ && path_trace_works_.size() > 1) {
|
||||
display_->graphics_interop_activate();
|
||||
}
|
||||
|
||||
denoiser_->load_kernels(progress_);
|
||||
|
||||
if (display_ && path_trace_works_.size() > 1) {
|
||||
display_->graphics_interop_deactivate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,29 +506,27 @@ void PathTrace::denoise(const RenderWork &render_work)
|
||||
const double start_time = time_dt();
|
||||
|
||||
RenderBuffers *buffer_to_denoise = nullptr;
|
||||
|
||||
unique_ptr<RenderBuffers> multi_device_buffers;
|
||||
bool allow_inplace_modification = false;
|
||||
|
||||
Device *denoiser_device = denoiser_->get_denoiser_device();
|
||||
if (path_trace_works_.size() > 1 && denoiser_device && !big_tile_denoise_work_) {
|
||||
big_tile_denoise_work_ = PathTraceWork::create(denoiser_device, film_, device_scene_, nullptr);
|
||||
}
|
||||
|
||||
if (big_tile_denoise_work_) {
|
||||
big_tile_denoise_work_->set_effective_buffer_params(render_state_.effective_big_tile_params,
|
||||
render_state_.effective_big_tile_params,
|
||||
render_state_.effective_big_tile_params);
|
||||
|
||||
buffer_to_denoise = big_tile_denoise_work_->get_render_buffers();
|
||||
buffer_to_denoise->reset(render_state_.effective_big_tile_params);
|
||||
|
||||
copy_to_render_buffers(buffer_to_denoise);
|
||||
|
||||
allow_inplace_modification = true;
|
||||
if (path_trace_works_.size() == 1) {
|
||||
buffer_to_denoise = path_trace_works_.front()->get_render_buffers();
|
||||
}
|
||||
else {
|
||||
DCHECK_EQ(path_trace_works_.size(), 1);
|
||||
Device *denoiser_device = denoiser_->get_denoiser_device();
|
||||
if (!denoiser_device) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_to_denoise = path_trace_works_.front()->get_render_buffers();
|
||||
multi_device_buffers = make_unique<RenderBuffers>(denoiser_device);
|
||||
multi_device_buffers->reset(render_state_.effective_big_tile_params);
|
||||
|
||||
buffer_to_denoise = multi_device_buffers.get();
|
||||
|
||||
copy_to_render_buffers(multi_device_buffers.get());
|
||||
|
||||
allow_inplace_modification = true;
|
||||
}
|
||||
|
||||
if (denoiser_->denoise_buffer(render_state_.effective_big_tile_params,
|
||||
@@ -549,6 +536,14 @@ void PathTrace::denoise(const RenderWork &render_work)
|
||||
render_state_.has_denoised_result = true;
|
||||
}
|
||||
|
||||
if (multi_device_buffers) {
|
||||
multi_device_buffers->copy_from_device();
|
||||
parallel_for_each(
|
||||
path_trace_works_, [&multi_device_buffers](unique_ptr<PathTraceWork> &path_trace_work) {
|
||||
path_trace_work->copy_from_denoised_render_buffers(multi_device_buffers.get());
|
||||
});
|
||||
}
|
||||
|
||||
render_scheduler_.report_denoise_time(render_work, time_dt() - start_time);
|
||||
}
|
||||
|
||||
@@ -640,13 +635,8 @@ void PathTrace::update_display(const RenderWork &render_work)
|
||||
/* TODO(sergey): When using multi-device rendering map the GPUDisplay once and copy data from
|
||||
* all works in parallel. */
|
||||
const int num_samples = get_num_samples_in_buffer();
|
||||
if (big_tile_denoise_work_ && render_state_.has_denoised_result) {
|
||||
big_tile_denoise_work_->copy_to_display(display_.get(), pass_mode, num_samples);
|
||||
}
|
||||
else {
|
||||
for (auto &&path_trace_work : path_trace_works_) {
|
||||
path_trace_work->copy_to_display(display_.get(), pass_mode, num_samples);
|
||||
}
|
||||
for (auto &&path_trace_work : path_trace_works_) {
|
||||
path_trace_work->copy_to_display(display_.get(), pass_mode, num_samples);
|
||||
}
|
||||
|
||||
display_->update_end();
|
||||
@@ -731,10 +721,11 @@ void PathTrace::write_tile_buffer(const RenderWork &render_work)
|
||||
VLOG_WORK << "Write tile result via buffer write callback.";
|
||||
tile_buffer_write();
|
||||
}
|
||||
|
||||
/* Write tile to disk, so that the render work's render buffer can be re-used for the next tile.
|
||||
*/
|
||||
else {
|
||||
VLOG_WORK << "Write tile result to disk.";
|
||||
if (has_multiple_tiles) {
|
||||
VLOG_WORK << "Write tile result into .";
|
||||
tile_buffer_write_to_disk();
|
||||
}
|
||||
}
|
||||
@@ -910,10 +901,6 @@ bool PathTrace::copy_render_tile_from_device()
|
||||
return true;
|
||||
}
|
||||
|
||||
if (big_tile_denoise_work_ && render_state_.has_denoised_result) {
|
||||
return big_tile_denoise_work_->copy_render_buffers_from_device();
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
|
||||
@@ -1015,10 +1002,6 @@ bool PathTrace::get_render_tile_pixels(const PassAccessor &pass_accessor,
|
||||
return pass_accessor.get_render_tile_pixels(full_frame_state_.render_buffers, destination);
|
||||
}
|
||||
|
||||
if (big_tile_denoise_work_ && render_state_.has_denoised_result) {
|
||||
return big_tile_denoise_work_->get_render_tile_pixels(pass_accessor, destination);
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) {
|
||||
@@ -1099,10 +1082,6 @@ void PathTrace::destroy_gpu_resources()
|
||||
for (auto &&path_trace_work : path_trace_works_) {
|
||||
path_trace_work->destroy_gpu_resources(display_.get());
|
||||
}
|
||||
|
||||
if (big_tile_denoise_work_) {
|
||||
big_tile_denoise_work_->destroy_gpu_resources(display_.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -236,7 +236,6 @@ class PathTrace {
|
||||
/* CPU device for creating temporary render buffers on the CPU side. */
|
||||
unique_ptr<Device> cpu_device_;
|
||||
|
||||
Film *film_;
|
||||
DeviceScene *device_scene_;
|
||||
|
||||
RenderScheduler &render_scheduler_;
|
||||
@@ -262,9 +261,6 @@ class PathTrace {
|
||||
/* Denoiser which takes care of denoising the big tile. */
|
||||
unique_ptr<Denoiser> denoiser_;
|
||||
|
||||
/* Denoiser device descriptor which holds the denoised big tile for multi-device workloads. */
|
||||
unique_ptr<PathTraceWork> big_tile_denoise_work_;
|
||||
|
||||
/* State which is common for all the steps of the render work.
|
||||
* Is brought up to date in the `render()` call and is accessed from all the steps involved into
|
||||
* rendering the work. */
|
||||
|
@@ -33,7 +33,7 @@ bool PathTraceTile::get_pass_pixels(const string_view pass_name,
|
||||
if (!copied_from_device_) {
|
||||
/* Copy from device on demand. */
|
||||
path_trace_.copy_render_tile_from_device();
|
||||
copied_from_device_ = true;
|
||||
const_cast<PathTraceTile *>(this)->copied_from_device_ = true;
|
||||
}
|
||||
|
||||
const BufferParams &buffer_params = path_trace_.get_render_tile_params();
|
||||
|
@@ -24,7 +24,7 @@ class PathTraceTile : public OutputDriver::Tile {
|
||||
|
||||
private:
|
||||
PathTrace &path_trace_;
|
||||
mutable bool copied_from_device_;
|
||||
bool copied_from_device_;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -204,26 +204,22 @@ void PathTraceWorkGPU::alloc_integrator_sorting()
|
||||
integrator_state_gpu_.sort_key_counter[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE] =
|
||||
(int *)integrator_shader_sort_counter_.device_pointer;
|
||||
|
||||
integrator_shader_sort_prefix_sum_.alloc(sort_buckets);
|
||||
integrator_shader_sort_prefix_sum_.zero_to_device();
|
||||
}
|
||||
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
|
||||
if (integrator_shader_raytrace_sort_counter_.size() < sort_buckets) {
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_NODE_RAYTRACE) {
|
||||
integrator_shader_raytrace_sort_counter_.alloc(sort_buckets);
|
||||
integrator_shader_raytrace_sort_counter_.zero_to_device();
|
||||
integrator_state_gpu_.sort_key_counter[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE] =
|
||||
(int *)integrator_shader_raytrace_sort_counter_.device_pointer;
|
||||
}
|
||||
}
|
||||
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_MNEE) {
|
||||
if (integrator_shader_mnee_sort_counter_.size() < sort_buckets) {
|
||||
if (device_scene_->data.kernel_features & KERNEL_FEATURE_MNEE) {
|
||||
integrator_shader_mnee_sort_counter_.alloc(sort_buckets);
|
||||
integrator_shader_mnee_sort_counter_.zero_to_device();
|
||||
integrator_state_gpu_.sort_key_counter[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_MNEE] =
|
||||
(int *)integrator_shader_mnee_sort_counter_.device_pointer;
|
||||
}
|
||||
|
||||
integrator_shader_sort_prefix_sum_.alloc(sort_buckets);
|
||||
integrator_shader_sort_prefix_sum_.zero_to_device();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -225,18 +225,15 @@ set(SRC_KERNEL_CAMERA_HEADERS
|
||||
)
|
||||
|
||||
set(SRC_KERNEL_FILM_HEADERS
|
||||
film/accumulate.h
|
||||
film/adaptive_sampling.h
|
||||
film/aov_passes.h
|
||||
film/data_passes.h
|
||||
film/denoising_passes.h
|
||||
film/cryptomatte_passes.h
|
||||
film/light_passes.h
|
||||
film/id_passes.h
|
||||
film/passes.h
|
||||
film/read.h
|
||||
film/write.h
|
||||
film/write_passes.h
|
||||
)
|
||||
|
||||
set(SRC_KERNEL_INTEGRATOR_HEADERS
|
||||
integrator/displacement_shader.h
|
||||
integrator/init_from_bake.h
|
||||
integrator/init_from_camera.h
|
||||
integrator/intersect_closest.h
|
||||
@@ -248,6 +245,7 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS
|
||||
integrator/path_state.h
|
||||
integrator/shade_background.h
|
||||
integrator/shade_light.h
|
||||
integrator/shader_eval.h
|
||||
integrator/shade_shadow.h
|
||||
integrator/shade_surface.h
|
||||
integrator/shade_volume.h
|
||||
@@ -260,8 +258,6 @@ set(SRC_KERNEL_INTEGRATOR_HEADERS
|
||||
integrator/subsurface_disk.h
|
||||
integrator/subsurface.h
|
||||
integrator/subsurface_random_walk.h
|
||||
integrator/surface_shader.h
|
||||
integrator/volume_shader.h
|
||||
integrator/volume_stack.h
|
||||
)
|
||||
|
||||
@@ -278,8 +274,6 @@ set(SRC_KERNEL_SAMPLE_HEADERS
|
||||
sample/mapping.h
|
||||
sample/mis.h
|
||||
sample/pattern.h
|
||||
sample/sobol_burley.h
|
||||
sample/util.h
|
||||
)
|
||||
|
||||
set(SRC_KERNEL_UTIL_HEADERS
|
||||
@@ -332,7 +326,6 @@ set(SRC_UTIL_HEADERS
|
||||
../util/rect.h
|
||||
../util/static_assert.h
|
||||
../util/transform.h
|
||||
../util/transform_inverse.h
|
||||
../util/texture.h
|
||||
../util/types.h
|
||||
../util/types_float2.h
|
||||
@@ -349,7 +342,6 @@ set(SRC_UTIL_HEADERS
|
||||
../util/types_int3_impl.h
|
||||
../util/types_int4.h
|
||||
../util/types_int4_impl.h
|
||||
../util/types_spectrum.h
|
||||
../util/types_uchar2.h
|
||||
../util/types_uchar2_impl.h
|
||||
../util/types_uchar3.h
|
||||
@@ -757,8 +749,10 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen)
|
||||
SET (CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "${CYCLES_ONEAPI_SYCL_OPTIONS_spir64}" CACHE STRING "Extra build options for spir64_gen target")
|
||||
endif()
|
||||
# Enable zebin, a graphics binary format with improved compatibility.
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ")
|
||||
# enabling zebin (graphics binary format with improved compatibility) on Windows only while support on Linux isn't available yet
|
||||
if(WIN32)
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ")
|
||||
endif()
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ")
|
||||
|
||||
if (WITH_CYCLES_ONEAPI_BINARIES)
|
||||
@@ -790,6 +784,14 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
get_filename_component(sycl_compiler_root ${SYCL_COMPILER} DIRECTORY)
|
||||
get_filename_component(sycl_compiler_compiler_name ${SYCL_COMPILER} NAME_WE)
|
||||
|
||||
if(NOT OCLOC_INSTALL_DIR)
|
||||
get_filename_component(OCLOC_INSTALL_DIR "${sycl_compiler_root}/../lib/ocloc" ABSOLUTE)
|
||||
endif()
|
||||
if(WITH_CYCLES_ONEAPI_BINARIES AND NOT EXISTS ${OCLOC_INSTALL_DIR})
|
||||
message(FATAL_ERROR "WITH_CYCLES_ONEAPI_BINARIES requires ocloc but ${OCLOC_INSTALL_DIR} directory doesn't exist."
|
||||
" A different ocloc directory can be set using OCLOC_INSTALL_DIR cmake variable.")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(NOT WITH_CXX11_ABI)
|
||||
check_library_exists(sycl
|
||||
|
@@ -4,13 +4,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "kernel/camera/projection.h"
|
||||
#include "kernel/integrator/displacement_shader.h"
|
||||
#include "kernel/integrator/surface_shader.h"
|
||||
#include "kernel/integrator/shader_eval.h"
|
||||
|
||||
#include "kernel/geom/geom.h"
|
||||
|
||||
#include "kernel/util/color.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
ccl_device void kernel_displace_evaluate(KernelGlobals kg,
|
||||
@@ -26,7 +23,7 @@ ccl_device void kernel_displace_evaluate(KernelGlobals kg,
|
||||
|
||||
/* Evaluate displacement shader. */
|
||||
const float3 P = sd.P;
|
||||
displacement_shader_eval(kg, INTEGRATOR_STATE_NULL, &sd);
|
||||
shader_eval_displacement(kg, INTEGRATOR_STATE_NULL, &sd);
|
||||
float3 D = sd.P - P;
|
||||
|
||||
object_inverse_dir_transform(kg, &sd, &D);
|
||||
@@ -65,10 +62,10 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg,
|
||||
/* Evaluate shader.
|
||||
* This is being evaluated for all BSDFs, so path flag does not contain a specific type. */
|
||||
const uint32_t path_flag = PATH_RAY_EMISSION;
|
||||
surface_shader_eval<KERNEL_FEATURE_NODE_MASK_SURFACE_LIGHT &
|
||||
shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_LIGHT &
|
||||
~(KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_NODE_LIGHT_PATH)>(
|
||||
kg, INTEGRATOR_STATE_NULL, &sd, NULL, path_flag);
|
||||
Spectrum color = surface_shader_background(&sd);
|
||||
float3 color = shader_background_eval(&sd);
|
||||
|
||||
#ifdef __KERNEL_DEBUG_NAN__
|
||||
if (!isfinite_safe(color)) {
|
||||
@@ -79,12 +76,10 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg,
|
||||
/* Ensure finite color, avoiding possible numerical instabilities in the path tracing kernels. */
|
||||
color = ensure_finite(color);
|
||||
|
||||
float3 color_rgb = spectrum_to_rgb(color);
|
||||
|
||||
/* Write output. */
|
||||
output[offset * 3 + 0] += color_rgb.x;
|
||||
output[offset * 3 + 1] += color_rgb.y;
|
||||
output[offset * 3 + 2] += color_rgb.z;
|
||||
output[offset * 3 + 0] += color.x;
|
||||
output[offset * 3 + 1] += color.y;
|
||||
output[offset * 3 + 2] += color.z;
|
||||
}
|
||||
|
||||
ccl_device void kernel_curve_shadow_transparency_evaluate(
|
||||
@@ -100,12 +95,12 @@ ccl_device void kernel_curve_shadow_transparency_evaluate(
|
||||
shader_setup_from_curve(kg, &sd, in.object, in.prim, __float_as_int(in.v), in.u);
|
||||
|
||||
/* Evaluate transparency. */
|
||||
surface_shader_eval<KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW &
|
||||
shader_eval_surface<KERNEL_FEATURE_NODE_MASK_SURFACE_SHADOW &
|
||||
~(KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_NODE_LIGHT_PATH)>(
|
||||
kg, INTEGRATOR_STATE_NULL, &sd, NULL, PATH_RAY_SHADOW);
|
||||
|
||||
/* Write output. */
|
||||
output[offset] = clamp(average(surface_shader_transparency(kg, &sd)), 0.0f, 1.0f);
|
||||
output[offset] = clamp(average(shader_bsdf_transparency(kg, &sd)), 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
@@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN
|
||||
*
|
||||
* Bounding volume hierarchy for ray tracing, when no native acceleration
|
||||
* structure is available for the device.
|
||||
*
|
||||
|
||||
* We compile different variations of the same BVH traversal function for
|
||||
* faster rendering when some types of primitives are not needed, using #includes
|
||||
* to work around the lack of C++ templates in OpenCL.
|
||||
|
@@ -33,30 +33,6 @@ ccl_device_forceinline float intersection_t_offset(const float t)
|
||||
return __uint_as_float(bits);
|
||||
}
|
||||
|
||||
/* Ray offset to avoid self intersection.
|
||||
*
|
||||
* This function can be used to compute a modified ray start position for rays
|
||||
* leaving from a surface. This is from:
|
||||
* "A Fast and Robust Method for Avoiding Self-Intersection"
|
||||
* Ray Tracing Gems, chapter 6.
|
||||
*/
|
||||
ccl_device_inline float3 ray_offset(const float3 P, const float3 Ng)
|
||||
{
|
||||
const float int_scale = 256.0f;
|
||||
const int3 of_i = make_int3(
|
||||
(int)(int_scale * Ng.x), (int)(int_scale * Ng.y), (int)(int_scale * Ng.z));
|
||||
|
||||
const float3 p_i = make_float3(
|
||||
__int_as_float(__float_as_int(P.x) + ((P.x < 0) ? -of_i.x : of_i.x)),
|
||||
__int_as_float(__float_as_int(P.y) + ((P.y < 0) ? -of_i.y : of_i.y)),
|
||||
__int_as_float(__float_as_int(P.z) + ((P.z < 0) ? -of_i.z : of_i.z)));
|
||||
const float origin = 1.0f / 32.0f;
|
||||
const float float_scale = 1.0f / 65536.0f;
|
||||
return make_float3(fabsf(P.x) < origin ? P.x + float_scale * Ng.x : p_i.x,
|
||||
fabsf(P.y) < origin ? P.y + float_scale * Ng.y : p_i.y,
|
||||
fabsf(P.z) < origin ? P.z + float_scale * Ng.z : p_i.z);
|
||||
}
|
||||
|
||||
#ifndef __KERNEL_GPU__
|
||||
ccl_device int intersections_compare(const void *a, const void *b)
|
||||
{
|
||||
|
@@ -45,6 +45,7 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
|
||||
float3 raster = make_float3(raster_x, raster_y, 0.0f);
|
||||
float3 Pcamera = transform_perspective(&rastertocamera, raster);
|
||||
|
||||
#ifdef __CAMERA_MOTION__
|
||||
if (kernel_data.cam.have_perspective_motion) {
|
||||
/* TODO(sergey): Currently we interpolate projected coordinate which
|
||||
* gives nice looking result and which is simple, but is in fact a bit
|
||||
@@ -62,6 +63,7 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
|
||||
Pcamera = interp(Pcamera, Pcamera_post, (ray->time - 0.5f) * 2.0f);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
float3 P = zero_float3();
|
||||
float3 D = Pcamera;
|
||||
@@ -85,12 +87,14 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
|
||||
/* transform ray from camera to world */
|
||||
Transform cameratoworld = kernel_data.cam.cameratoworld;
|
||||
|
||||
#ifdef __CAMERA_MOTION__
|
||||
if (kernel_data.cam.num_motion_steps) {
|
||||
transform_motion_array_interpolate(&cameratoworld,
|
||||
kernel_data_array(camera_motion),
|
||||
kernel_data.cam.num_motion_steps,
|
||||
ray->time);
|
||||
}
|
||||
#endif
|
||||
|
||||
P = transform_point(&cameratoworld, P);
|
||||
D = normalize(transform_direction(&cameratoworld, D));
|
||||
@@ -155,6 +159,7 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __CAMERA_CLIPPING__
|
||||
/* clipping */
|
||||
float z_inv = 1.0f / normalize(Pcamera).z;
|
||||
float nearclip = kernel_data.cam.nearclip * z_inv;
|
||||
@@ -162,6 +167,10 @@ ccl_device void camera_sample_perspective(KernelGlobals kg,
|
||||
ray->dP += nearclip * ray->dD;
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = kernel_data.cam.cliplength * z_inv;
|
||||
#else
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = FLT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Orthographic Camera */
|
||||
@@ -200,12 +209,14 @@ ccl_device void camera_sample_orthographic(KernelGlobals kg,
|
||||
/* transform ray from camera to world */
|
||||
Transform cameratoworld = kernel_data.cam.cameratoworld;
|
||||
|
||||
#ifdef __CAMERA_MOTION__
|
||||
if (kernel_data.cam.num_motion_steps) {
|
||||
transform_motion_array_interpolate(&cameratoworld,
|
||||
kernel_data_array(camera_motion),
|
||||
kernel_data.cam.num_motion_steps,
|
||||
ray->time);
|
||||
}
|
||||
#endif
|
||||
|
||||
ray->P = transform_point(&cameratoworld, P);
|
||||
ray->D = normalize(transform_direction(&cameratoworld, D));
|
||||
@@ -220,15 +231,22 @@ ccl_device void camera_sample_orthographic(KernelGlobals kg,
|
||||
ray->dD = differential_zero_compact();
|
||||
#endif
|
||||
|
||||
#ifdef __CAMERA_CLIPPING__
|
||||
/* clipping */
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = kernel_data.cam.cliplength;
|
||||
#else
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = FLT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Panorama Camera */
|
||||
|
||||
ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
||||
#ifdef __CAMERA_MOTION__
|
||||
ccl_global const DecomposedTransform *cam_motion,
|
||||
#endif
|
||||
float raster_x,
|
||||
float raster_y,
|
||||
float lens_u,
|
||||
@@ -272,10 +290,12 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
||||
/* transform ray from camera to world */
|
||||
Transform cameratoworld = cam->cameratoworld;
|
||||
|
||||
#ifdef __CAMERA_MOTION__
|
||||
if (cam->num_motion_steps) {
|
||||
transform_motion_array_interpolate(
|
||||
&cameratoworld, cam_motion, cam->num_motion_steps, ray->time);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Stereo transform */
|
||||
bool use_stereo = cam->interocular_offset != 0.0f;
|
||||
@@ -328,12 +348,17 @@ ccl_device_inline void camera_sample_panorama(ccl_constant KernelCamera *cam,
|
||||
ray->dP = differential_make_compact(dP);
|
||||
#endif
|
||||
|
||||
#ifdef __CAMERA_CLIPPING__
|
||||
/* clipping */
|
||||
float nearclip = cam->nearclip;
|
||||
ray->P += nearclip * ray->D;
|
||||
ray->dP += nearclip * ray->dD;
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = cam->cliplength;
|
||||
#else
|
||||
ray->tmin = 0.0f;
|
||||
ray->tmax = FLT_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Common */
|
||||
@@ -353,6 +378,7 @@ ccl_device_inline void camera_sample(KernelGlobals kg,
|
||||
float raster_x = x + lookup_table_read(kg, filter_u, filter_table_offset, FILTER_TABLE_SIZE);
|
||||
float raster_y = y + lookup_table_read(kg, filter_v, filter_table_offset, FILTER_TABLE_SIZE);
|
||||
|
||||
#ifdef __CAMERA_MOTION__
|
||||
/* motion blur */
|
||||
if (kernel_data.cam.shuttertime == -1.0f) {
|
||||
ray->time = 0.5f;
|
||||
@@ -390,6 +416,7 @@ ccl_device_inline void camera_sample(KernelGlobals kg,
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* sample */
|
||||
if (kernel_data.cam.type == CAMERA_PERSPECTIVE) {
|
||||
@@ -399,8 +426,12 @@ ccl_device_inline void camera_sample(KernelGlobals kg,
|
||||
camera_sample_orthographic(kg, raster_x, raster_y, lens_u, lens_v, ray);
|
||||
}
|
||||
else {
|
||||
#ifdef __CAMERA_MOTION__
|
||||
ccl_global const DecomposedTransform *cam_motion = kernel_data_array(camera_motion);
|
||||
camera_sample_panorama(&kernel_data.cam, cam_motion, raster_x, raster_y, lens_u, lens_v, ray);
|
||||
#else
|
||||
camera_sample_panorama(&kernel_data.cam, raster_x, raster_y, lens_u, lens_v, ray);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user