Node: Gabor Noise Texture #110802

Open
Charlie Jolly wants to merge 68 commits from CharlieJolly/blender:gabor into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
209 changed files with 6944 additions and 3518 deletions
Showing only changes of commit 98b2a67673 - Show all commits

View File

@ -119,11 +119,15 @@ enable_testing()
if(CMAKE_COMPILER_IS_GNUCC)
if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0")
message(FATAL_ERROR "The minimum supported version of GCC is 11.0.0, found ${CMAKE_C_COMPILER_VERSION}")
message(FATAL_ERROR "\
The minimum supported version of GCC is 11.0.0, found ${CMAKE_C_COMPILER_VERSION}"
)
endif()
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
if(CMAKE_COMPILER_IS_GNUCC AND ("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "8.0"))
message(FATAL_ERROR "The minimum supported version of CLANG is 8.0, found ${CMAKE_C_COMPILER_VERSION}")
message(FATAL_ERROR "\
The minimum supported version of CLANG is 8.0, found ${CMAKE_C_COMPILER_VERSION}"
)
endif()
elseif(CMAKE_CXX_COMPILER_ID MATCHES MSVC)
if(MSVC_VERSION VERSION_LESS "1928")
@ -208,7 +212,7 @@ endif()
option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON)
option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON)
option(WITH_PYTHON "Enable Embedded Python API (only disable for development)" ON)
option(WITH_PYTHON_SECURITY "Disables execution of scripts within blend files by default" ON)
# Don't want people disabling this unless they really know what they are doing.
mark_as_advanced(WITH_PYTHON)
@ -216,33 +220,63 @@ mark_as_advanced(WITH_PYTHON)
# make a build option.
mark_as_advanced(WITH_PYTHON_SECURITY)
option(WITH_PYTHON_SAFETY "Enable internal API error checking to track invalid data to prevent crash on access (at the expense of some efficiency, only enable for development)." OFF)
option(WITH_PYTHON_SAFETY "\
Enable internal API error checking to track invalid data to prevent crash on access \
(at the expense of some efficiency, only enable for development)."
OFF
)
mark_as_advanced(WITH_PYTHON_SAFETY)
option(WITH_PYTHON_MODULE "Enable building as a python module which runs without a user interface, like running regular blender in background mode (experimental, only enable for development), installs to PYTHON_SITE_PACKAGES (or CMAKE_INSTALL_PREFIX if WITH_INSTALL_PORTABLE is enabled)." OFF)
option(WITH_PYTHON_MODULE "\
Enable building as a python module which runs without a user interface, \
like running regular blender in background mode (only enable for development), \
installs to PYTHON_SITE_PACKAGES (or CMAKE_INSTALL_PREFIX if WITH_INSTALL_PORTABLE is enabled)."
OFF
)
option(WITH_BUILDINFO "Include extra build details (only disable for development & faster builds)" ON)
set(BUILDINFO_OVERRIDE_DATE "" CACHE STRING "Use instead of the current date for reproducible builds (empty string disables this option)")
set(BUILDINFO_OVERRIDE_TIME "" CACHE STRING "Use instead of the current time for reproducible builds (empty string disables this option)")
set(CPACK_OVERRIDE_PACKAGENAME "" CACHE STRING "Use instead of the standard packagename (empty string disables this option)")
option(WITH_BUILDINFO "\
Include extra build details (only disable for development & faster builds)"
ON
)
set(BUILDINFO_OVERRIDE_DATE "" CACHE STRING "\
Use instead of the current date for reproducible builds (empty string disables this option)"
)
set(BUILDINFO_OVERRIDE_TIME "" CACHE STRING "\
Use instead of the current time for reproducible builds (empty string disables this option)"
)
set(CPACK_OVERRIDE_PACKAGENAME "" CACHE STRING "\
Use instead of the standard packagename (empty string disables this option)"
)
mark_as_advanced(CPACK_OVERRIDE_PACKAGENAME)
mark_as_advanced(BUILDINFO_OVERRIDE_DATE)
mark_as_advanced(BUILDINFO_OVERRIDE_TIME)
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16")
option(WITH_UNITY_BUILD "Enable unity build for modules that support it to improve compile times" ON)
option(WITH_UNITY_BUILD "\
Enable unity build for modules that support it to improve compile times"
ON
)
mark_as_advanced(WITH_UNITY_BUILD)
else()
set(WITH_UNITY_BUILD OFF)
endif()
option(WITH_IK_ITASC "Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)" ON)
option(WITH_IK_SOLVER "Enable Legacy IK solver (only disable for development)" ON)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ON)
option(WITH_PUGIXML "Enable PugiXML support (Used for OpenImageIO, Grease Pencil SVG export)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" )
option(WITH_IK_ITASC "\
Enable ITASC IK solver (only disable for development & for incompatible C++ compilers)"
ON
)
option(WITH_IK_SOLVER "\
Enable Legacy IK solver (only disable for development)"
ON
)
option(WITH_FFTW3 "Enable FFTW3 support (Used for smoke, ocean sim, and audio effects)" ON)
option(WITH_PUGIXML "Enable PugiXML support (Used for OpenImageIO, Grease Pencil SVG export)" ON)
option(WITH_BULLET "Enable Bullet (Physics Engine)" ON)
option(WITH_SYSTEM_BULLET "\
Use the systems bullet library (currently unsupported due to missing features in upstream!)"
OFF
)
mark_as_advanced(WITH_SYSTEM_BULLET)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON)
set(_option_default ON)
if(APPLE)
@ -259,24 +293,33 @@ unset(_option_default)
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_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ON)
option(WITH_COMPOSITOR_CPU "Enable the tile based CPU nodal compositor" ON)
option(WITH_OPENIMAGEDENOISE "Enable the OpenImageDenoise compositing node" ON)
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ON)
option(WITH_OPENSUBDIV "Enable OpenSubdiv for surface subdivision" ON)
option(WITH_POTRACE "Enable features relying on potrace" ON)
option(WITH_OPENVDB "Enable features relying on OpenVDB" ON)
option(WITH_OPENVDB_BLOSC "Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support" ON)
option(WITH_OPENVDB_3_ABI_COMPATIBLE "Assume OpenVDB library has been compiled with version 3 ABI compatibility" OFF)
option(WITH_POTRACE "Enable features relying on potrace" ON)
option(WITH_OPENVDB "Enable features relying on OpenVDB" ON)
option(WITH_OPENVDB_BLOSC "\
Enable blosc compression for OpenVDB, only enable if OpenVDB was built with blosc support"
ON
)
option(WITH_OPENVDB_3_ABI_COMPATIBLE "\
Assume OpenVDB library has been compiled with version 3 ABI compatibility"
OFF
)
mark_as_advanced(WITH_OPENVDB_3_ABI_COMPATIBLE)
option(WITH_NANOVDB "Enable usage of NanoVDB data structure for rendering on the GPU" ON)
option(WITH_HARU "Enable features relying on Libharu (Grease pencil PDF export)" ON)
option(WITH_NANOVDB "Enable usage of NanoVDB data structure for rendering on the GPU" ON)
option(WITH_HARU "Enable features relying on Libharu (Grease pencil PDF export)" ON)
# GHOST Windowing Library Options
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
option(WITH_GHOST_DEBUG "Enable debugging output for the GHOST library" OFF)
mark_as_advanced(WITH_GHOST_DEBUG)
option(WITH_GHOST_SDL "Enable building Blender against SDL for windowing rather than the native APIs" OFF)
option(WITH_GHOST_SDL "\
Enable building Blender against SDL for windowing rather than the native APIs"
OFF
)
mark_as_advanced(WITH_GHOST_SDL)
if(UNIX AND NOT (APPLE OR HAIKU))
@ -290,10 +333,14 @@ if(UNIX AND NOT (APPLE OR HAIKU))
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
option(WITH_GHOST_WAYLAND_DBUS "Optionally build with DBUS support (used for Cursor themes). May hang on startup systems where DBUS is not used." OFF)
option(WITH_GHOST_WAYLAND_DBUS "\
Optionally build with DBUS support (used for Cursor themes). \
May hang on startup systems where DBUS is not used."
OFF
)
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
set(WITH_GHOST_WAYLAND_APP_ID "" CACHE STRING "\
@ -305,32 +352,39 @@ this can be used to differentiate Blender instances by version or branch for exa
endif()
if(WITH_GHOST_X11)
option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
option(WITH_GHOST_XDND "Enable drag'n'drop support on X11 using XDND protocol" ON)
endif()
# Misc...
option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
option(WITH_HEADLESS "Build without graphical support (renderfarm, server mode only)" OFF)
mark_as_advanced(WITH_HEADLESS)
option(WITH_QUADRIFLOW "Build with quadriflow remesher support" ON)
option(WITH_QUADRIFLOW "Build with quadriflow remesher support" ON)
option(WITH_AUDASPACE "Build with blenders audio library (only disable if you know what you're doing!)" ON)
option(WITH_SYSTEM_AUDASPACE "Build with external audaspace library installed on the system (only enable if you know what you're doing!)" OFF)
option(WITH_AUDASPACE "\
Build with blenders audio library (only disable if you know what you're doing!)"
ON
)
option(WITH_SYSTEM_AUDASPACE "\
Build with external audaspace library installed on the system \
(only enable if you know what you're doing!)"
OFF
)
mark_as_advanced(WITH_AUDASPACE)
mark_as_advanced(WITH_SYSTEM_AUDASPACE)
set_and_warn_dependency(WITH_AUDASPACE WITH_SYSTEM_AUDASPACE OFF)
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
option(WITH_OPENMP "Enable OpenMP (has to be supported by the compiler)" ON)
if(UNIX AND NOT APPLE)
option(WITH_OPENMP_STATIC "Link OpenMP statically (only used by the release environment)" OFF)
mark_as_advanced(WITH_OPENMP_STATIC)
endif()
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_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)
endif()
if(UNIX AND NOT APPLE)
@ -343,46 +397,46 @@ endif()
# Modifiers
option(WITH_MOD_FLUID "Enable Mantaflow Fluid Simulation Framework" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON)
option(WITH_MOD_FLUID "Enable Mantaflow Fluid Simulation Framework" ON)
option(WITH_MOD_REMESH "Enable Remesh Modifier" ON)
option(WITH_MOD_OCEANSIM "Enable Ocean Modifier" ON)
# Image format support
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_WEBP "Enable WebP Image Support" ON)
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
option(WITH_IMAGE_OPENJPEG "Enable OpenJpeg Support (http://www.openjpeg.org)" ON)
option(WITH_IMAGE_CINEON "Enable CINEON and DPX Image Support" ON)
option(WITH_IMAGE_WEBP "Enable WebP Image Support" ON)
# Audio/Video format support
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ON)
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" ON)
option(WITH_CODEC_AVI "Enable Blenders own AVI file support (raw/jpeg)" ON)
option(WITH_CODEC_FFMPEG "Enable FFMPeg Support (http://ffmpeg.org)" ON)
option(WITH_CODEC_SNDFILE "Enable libsndfile Support (http://www.mega-nerd.com/libsndfile)" ON)
# Alembic support
option(WITH_ALEMBIC "Enable Alembic Support" ON)
option(WITH_ALEMBIC "Enable Alembic Support" ON)
# Universal Scene Description support
option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
option(WITH_USD "Enable Universal Scene Description (USD) Support" ON)
# MaterialX
option(WITH_MATERIALX "Enable MaterialX Support" ON)
option(WITH_MATERIALX "Enable MaterialX Support" ON)
# Hydra render engine
option(WITH_HYDRA "Enable Hydra render engine" ON)
option(WITH_HYDRA "Enable Hydra render engine" ON)
# 3D format support
# Disable opencollada when we don't have precompiled libs
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
option(WITH_IO_WAVEFRONT_OBJ "Enable Wavefront-OBJ 3D file format support (*.obj)" ON)
option(WITH_IO_PLY "Enable PLY 3D file format support (*.ply)" ON)
option(WITH_IO_STL "Enable STL 3D file format support (*.stl)" ON)
option(WITH_IO_GPENCIL "Enable grease-pencil file format IO (*.svg, *.pdf)" ON)
option(WITH_OPENCOLLADA "Enable OpenCollada Support (http://www.opencollada.org)" ON)
option(WITH_IO_WAVEFRONT_OBJ "Enable Wavefront-OBJ 3D file format support (*.obj)" ON)
option(WITH_IO_PLY "Enable PLY 3D file format support (*.ply)" ON)
option(WITH_IO_STL "Enable STL 3D file format support (*.stl)" ON)
option(WITH_IO_GPENCIL "Enable grease-pencil file format IO (*.svg, *.pdf)" ON)
# Sound output
option(WITH_SDL "Enable SDL for sound" ON)
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
option(WITH_SDL "Enable SDL for sound" ON)
option(WITH_OPENAL "Enable OpenAL Support (http://www.openal.org)" ON)
if(APPLE)
option(WITH_COREAUDIO "Enable CoreAudio for audio support on macOS" ON)
option(WITH_COREAUDIO "Enable CoreAudio for audio support on macOS" ON)
else()
set(WITH_COREAUDIO OFF)
endif()
@ -398,41 +452,41 @@ else()
set(WITH_JACK OFF)
endif()
if(UNIX AND NOT APPLE)
option(WITH_SDL_DYNLOAD "Enable runtime dynamic SDL libraries loading" OFF)
option(WITH_SDL_DYNLOAD "Enable runtime dynamic SDL libraries loading" OFF)
endif()
if(UNIX AND NOT APPLE)
option(WITH_PULSEAUDIO "Enable PulseAudio for audio support on Linux" ON)
option(WITH_PULSEAUDIO_DYNLOAD "Enable runtime dynamic PulseAudio libraries loading" OFF)
option(WITH_PULSEAUDIO "Enable PulseAudio for audio support on Linux" ON)
option(WITH_PULSEAUDIO_DYNLOAD "Enable runtime dynamic PulseAudio libraries loading" OFF)
else()
set(WITH_PULSEAUDIO OFF)
endif()
if(WIN32)
option(WITH_WASAPI "Enable Windows Audio Sessions API for audio support on Windows" ON)
option(WITH_WASAPI "Enable Windows Audio Sessions API for audio support on Windows" ON)
else()
set(WITH_WASAPI OFF)
endif()
# Compression
option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON)
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
option(WITH_LZO "Enable fast LZO compression (used for pointcache)" ON)
option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)" ON)
if(UNIX AND NOT APPLE)
option(WITH_SYSTEM_LZO "Use the system LZO library" OFF)
option(WITH_SYSTEM_LZO "Use the system LZO library" OFF)
endif()
option(WITH_DRACO "Enable Draco mesh compression Python module (used for glTF)" ON)
option(WITH_DRACO "Enable Draco mesh compression Python module (used for glTF)" ON)
# Camera/motion tracking
option(WITH_LIBMV "Enable Libmv structure from motion library" ON)
option(WITH_LIBMV "Enable Libmv structure from motion library" ON)
option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
mark_as_advanced(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
# Logging/unbit test libraries.
option(WITH_SYSTEM_GFLAGS "Use system-wide Gflags instead of a bundled one" OFF)
option(WITH_SYSTEM_GLOG "Use system-wide Glog instead of a bundled one" OFF)
option(WITH_SYSTEM_GFLAGS "Use system-wide Gflags instead of a bundled one" OFF)
option(WITH_SYSTEM_GLOG "Use system-wide Glog instead of a bundled one" OFF)
mark_as_advanced(WITH_SYSTEM_GFLAGS)
mark_as_advanced(WITH_SYSTEM_GLOG)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
# Libraries.
if(UNIX AND NOT APPLE)
@ -447,9 +501,16 @@ that point to pre-compiled libraries will be left as-is."
)
mark_as_advanced(WITH_LIBS_PRECOMPILED)
option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF)
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)
option(WITH_BOOST_ICU "\
Boost uses ICU library (required for linking with static Boost built with libicu)."
OFF
)
mark_as_advanced(WITH_BOOST_ICU)
endif()
endif()
@ -460,61 +521,84 @@ 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 redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX"
ON
)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
option(WITH_INSTALL_COPYRIGHT "Copy the official Blender Foundation's copyright.txt into the Blender install folder" OFF)
option(WITH_INSTALL_COPYRIGHT "\
Copy the official Blender Foundation's copyright.txt into the Blender install folder"
OFF
)
mark_as_advanced(WITH_INSTALL_COPYRIGHT)
if((WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE) OR WITH_MOD_FLUID)
option(WITH_PYTHON_NUMPY "Include NumPy in Blender (used by Audaspace and Mantaflow)" ON)
option(WITH_PYTHON_NUMPY "Include NumPy in Blender (used by Audaspace and Mantaflow)" ON)
endif()
if(WIN32 OR APPLE)
# Windows and macOS have this bundled with Python libraries.
elseif(WITH_PYTHON_INSTALL OR WITH_PYTHON_NUMPY)
set(PYTHON_NUMPY_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'numpy' module")
set(PYTHON_NUMPY_PATH "" CACHE PATH "\
Path to python site-packages or dist-packages containing 'numpy' module"
)
mark_as_advanced(PYTHON_NUMPY_PATH)
set(PYTHON_NUMPY_INCLUDE_DIRS "" CACHE PATH "Path to the include directory of the NumPy module")
set(PYTHON_NUMPY_INCLUDE_DIRS "" CACHE PATH "Path to the include directory of the NumPy module")
mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
if(WITH_PYTHON_INSTALL)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system NumPy into the blender install folder" ON)
option(WITH_PYTHON_INSTALL_NUMPY "Copy system NumPy into the blender install folder" ON)
if(UNIX AND NOT APPLE)
option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
set(PYTHON_REQUESTS_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'requests' module")
set(PYTHON_REQUESTS_PATH "" CACHE PATH "\
Path to python site-packages or dist-packages containing 'requests' module"
)
mark_as_advanced(PYTHON_REQUESTS_PATH)
endif()
option(WITH_PYTHON_INSTALL_ZSTANDARD "Copy zstandard into the blender install folder" ON)
set(PYTHON_ZSTANDARD_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'zstandard' module")
set(PYTHON_ZSTANDARD_PATH "" CACHE PATH "\
Path to python site-packages or dist-packages containing 'zstandard' module"
)
mark_as_advanced(PYTHON_ZSTANDARD_PATH)
endif()
option(WITH_CPU_SIMD "Enable SIMD instruction if they're detected on the host machine" ON)
option(WITH_CPU_SIMD "Enable SIMD instruction if they're detected on the host machine" ON)
mark_as_advanced(WITH_CPU_SIMD)
# Cycles
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
option(WITH_CYCLES_PATH_GUIDING "Build Cycles with path guiding support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debugging (e.g., MIS)" OFF)
option(WITH_CYCLES "Enable Cycles Render Engine" ON)
option(WITH_CYCLES_OSL "Build Cycles with OpenShadingLanguage support" ON)
option(WITH_CYCLES_PATH_GUIDING "Build Cycles with path guiding support" ON)
option(WITH_CYCLES_EMBREE "Build Cycles with Embree support" ON)
option(WITH_CYCLES_LOGGING "Build Cycles with logging support" ON)
option(WITH_CYCLES_DEBUG "Build Cycles with options useful for debugging (e.g., MIS)" OFF)
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
option(WITH_CYCLES_PRECOMPUTE "Build Cycles data precomputation tool" OFF)
option(WITH_CYCLES_STANDALONE "Build Cycles standalone application" OFF)
option(WITH_CYCLES_STANDALONE_GUI "Build Cycles standalone with GUI" OFF)
option(WITH_CYCLES_PRECOMPUTE "Build Cycles data precomputation tool" OFF)
option(WITH_CYCLES_HYDRA_RENDER_DELEGATE "Build Cycles Hydra render delegate" OFF)
option(WITH_CYCLES_DEBUG_NAN "Build Cycles with additional asserts for detecting NaNs and invalid values" OFF)
option(WITH_CYCLES_NATIVE_ONLY "Build Cycles with native kernel only (which fits current CPU, use for development only)" OFF)
option(WITH_CYCLES_KERNEL_ASAN "Build Cycles kernels with address sanitizer when WITH_COMPILER_ASAN is on, even if it's very slow" OFF)
set(CYCLES_TEST_DEVICES CPU CACHE STRING "Run regression tests on the specified device types (CPU CUDA OPTIX HIP)" )
option(WITH_CYCLES_DEBUG_NAN "\
Build Cycles with additional asserts for detecting NaNs and invalid values"
OFF
)
option(WITH_CYCLES_NATIVE_ONLY "\
Build Cycles with native kernel only (which fits current CPU, use for development only)"
OFF
)
option(WITH_CYCLES_KERNEL_ASAN "\
Build Cycles kernels with address sanitizer when WITH_COMPILER_ASAN is on, even if it's very slow"
OFF
)
set(CYCLES_TEST_DEVICES CPU CACHE STRING "\
Run regression tests on the specified device types (CPU CUDA OPTIX HIP)"
)
mark_as_advanced(WITH_CYCLES_KERNEL_ASAN)
mark_as_advanced(WITH_CYCLES_LOGGING)
mark_as_advanced(WITH_CYCLES_DEBUG_NAN)
@ -524,17 +608,31 @@ mark_as_advanced(CYCLES_TEST_DEVICES)
# NVIDIA CUDA & OptiX
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
option(WITH_CYCLES_DEVICE_CUDA "Enable Cycles NVIDIA CUDA compute support" ON)
option(WITH_CYCLES_DEVICE_OPTIX "Enable Cycles NVIDIA OptiX support" ON)
mark_as_advanced(WITH_CYCLES_DEVICE_CUDA)
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles NVIDIA CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 sm_89 compute_75 CACHE STRING "CUDA architectures to build binaries for")
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)
option(WITH_CYCLES_CUDA_BINARIES "Build Cycles NVIDIA CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH
sm_30 sm_35 sm_37 sm_50 sm_52 sm_60 sm_61 sm_70 sm_75 sm_86 sm_89 compute_75
CACHE STRING "CUDA architectures to build binaries for"
)
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.")
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_CUDA_BUILD_SERIAL)
@ -545,35 +643,51 @@ endif()
# AMD HIP
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
# Radeon VII (gfx906) not currently working with HIP SDK, so left out of the list.
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
set(CYCLES_HIP_BINARIES_ARCH
gfx900 gfx90c gfx902
gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035
gfx1100 gfx1101 gfx1102
CACHE STRING "AMD HIP architectures to build binaries for"
)
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
# HIPRT is only available on Windows for now.
if(WIN32)
option(WITH_CYCLES_DEVICE_HIPRT "Enable Cycles AMD HIPRT support" OFF)
option(WITH_CYCLES_DEVICE_HIPRT "Enable Cycles AMD HIPRT support" OFF)
mark_as_advanced(WITH_CYCLES_DEVICE_HIPRT)
endif()
endif()
# Apple Metal
if(APPLE)
option(WITH_CYCLES_DEVICE_METAL "Enable Cycles Apple Metal compute support" ON)
option(WITH_CYCLES_DEVICE_METAL "Enable Cycles Apple Metal compute support" ON)
endif()
# oneAPI
if(NOT APPLE)
option(WITH_CYCLES_DEVICE_ONEAPI "Enable Cycles oneAPI compute support" OFF)
option(WITH_CYCLES_ONEAPI_BINARIES "Enable Ahead-Of-Time compilation for Cycles oneAPI device" OFF)
option(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION "Switch target of oneAPI implementation from SYCL devices to Host Task (single thread on CPU). This option is only for debugging purposes." OFF)
option(WITH_CYCLES_ONEAPI_BINARIES "\
Enable Ahead-Of-Time compilation for Cycles oneAPI device"
OFF
)
option(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION "\
Switch target of oneAPI implementation from SYCL devices to Host Task (single thread on CPU). \
This option is only for debugging purposes."
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
# acm-g10 is the target for the first Intel Arc Alchemist GPUs.
set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "acm-g10" 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 "acm-g10" 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_HOST_TASK_EXECUTION)
mark_as_advanced(CYCLES_ONEAPI_SPIR64_GEN_DEVICES)
@ -585,17 +699,18 @@ option(WITH_DRAW_DEBUG "Add extra debug capabilities to Draw Manager" OFF)
mark_as_advanced(WITH_DRAW_DEBUG)
# LLVM
option(WITH_LLVM "Use LLVM" OFF)
option(WITH_LLVM "Use LLVM" OFF)
if(APPLE)
option(LLVM_STATIC "Link with LLVM static libraries" ON) # we prefer static llvm build on Apple, dyn build possible though
# We prefer static llvm build on Apple, dyn build possible though.
option(LLVM_STATIC "Link with LLVM static libraries" ON)
else()
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
endif()
mark_as_advanced(LLVM_STATIC)
option(WITH_CLANG "Use Clang" OFF)
option(WITH_CLANG "Use Clang" OFF)
# disable for now, but plan to support on all platforms eventually
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" ON)
option(WITH_MEM_JEMALLOC "Enable malloc replacement (http://www.canonware.com/jemalloc)" ON)
mark_as_advanced(WITH_MEM_JEMALLOC)
# currently only used for BLI_mempool
@ -603,19 +718,29 @@ option(WITH_MEM_VALGRIND "Enable extended valgrind support for better reporting"
mark_as_advanced(WITH_MEM_VALGRIND)
# Debug
option(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)" OFF)
option(WITH_CXX_GUARDEDALLOC "\
Enable GuardedAlloc for C++ memory allocation tracking (only enable for development)"
OFF
)
mark_as_advanced(WITH_CXX_GUARDEDALLOC)
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" ON)
mark_as_advanced(WITH_ASSERT_ABORT)
if((UNIX AND NOT APPLE) OR (CMAKE_GENERATOR MATCHES "^Visual Studio.+"))
option(WITH_CLANG_TIDY "Use Clang Tidy to analyze the source code (only enable for development on Linux using Clang, or Windows using the Visual Studio IDE)" OFF)
option(WITH_CLANG_TIDY "\
Use Clang Tidy to analyze the source code \
(only enable for development on Linux using Clang, or Windows using the Visual Studio IDE)"
OFF
)
mark_as_advanced(WITH_CLANG_TIDY)
endif()
option(WITH_BOOST "Enable features depending on boost" ON)
option(WITH_TBB "Enable multithreading. TBB is also required for features such as Cycles, OpenVDB and USD" ON)
option(WITH_TBB "\
Enable multi-threading. TBB is also required for features such as Cycles, OpenVDB and USD"
ON
)
# TBB malloc is only supported on for windows currently
if(WIN32)
@ -644,7 +769,10 @@ endif()
# GPU Module
option(WITH_GPU_BUILDTIME_SHADER_BUILDER "Shader builder is a developer option enabling linting on GLSL during compilation" OFF)
option(WITH_GPU_BUILDTIME_SHADER_BUILDER "\
Shader builder is a developer option enabling linting on GLSL during compilation"
OFF
)
option(WITH_RENDERDOC "Use Renderdoc API to capture frames" OFF)
mark_as_advanced(
@ -662,7 +790,10 @@ endif()
# Vulkan
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF)
option(WITH_VULKAN_GUARDEDALLOC "\
Use guardedalloc for host allocations done inside Vulkan (development option)"
OFF
)
mark_as_advanced(
WITH_VULKAN_BACKEND
WITH_VULKAN_GUARDEDALLOC
@ -670,7 +801,10 @@ mark_as_advanced(
# Metal
if(APPLE)
option(WITH_METAL_BACKEND "Use Metal for graphics instead of (or as well as) OpenGL on macOS." ON)
option(WITH_METAL_BACKEND "\
Use Metal for graphics instead of (or as well as) OpenGL on macOS."
ON
)
mark_as_advanced(WITH_METAL_BACKEND)
else()
set(WITH_METAL_BACKEND OFF)
@ -701,7 +835,10 @@ if(UNIX)
endif()
endif()
option(WITH_COMPILER_ASAN "Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)." OFF)
option(WITH_COMPILER_ASAN "\
Build and link against address sanitizer (only for Debug & RelWithDebInfo targets)."
OFF
)
mark_as_advanced(WITH_COMPILER_ASAN)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
@ -780,7 +917,10 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
option(WITH_COMPILER_SHORT_FILE_MACRO "Make paths in macros like __FILE__ relative to top level source and build directories." ON)
option(WITH_COMPILER_SHORT_FILE_MACRO "\
Make paths in macros like __FILE__ relative to top level source and build directories."
ON
)
mark_as_advanced(WITH_COMPILER_SHORT_FILE_MACRO)
endif()
@ -789,7 +929,10 @@ if(WIN32)
option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF)
mark_as_advanced(WITH_WINDOWS_FIND_MODULES)
option(WINDOWS_PYTHON_DEBUG "Include the files needed for debugging python scripts with visual studio 2017+." OFF)
option(WINDOWS_PYTHON_DEBUG "\
Include the files needed for debugging python scripts with visual studio 2017+."
OFF
)
mark_as_advanced(WINDOWS_PYTHON_DEBUG)
option(WITH_WINDOWS_BUNDLE_CRT "Bundle the C runtime for install free distribution." ON)
@ -807,10 +950,16 @@ if(WIN32)
endif()
if(WIN32 OR XCODE)
option(IDE_GROUP_SOURCES_IN_FOLDERS "Organize the source files in filters matching the source folders." ON)
option(IDE_GROUP_SOURCES_IN_FOLDERS "\
Organize the source files in filters matching the source folders."
ON
)
mark_as_advanced(IDE_GROUP_SOURCES_IN_FOLDERS)
option(IDE_GROUP_PROJECTS_IN_FOLDERS "Organize the projects according to source folder structure." ON)
option(IDE_GROUP_PROJECTS_IN_FOLDERS "\
Organize the projects according to source folder structure."
ON
)
mark_as_advanced(IDE_GROUP_PROJECTS_IN_FOLDERS)
if(IDE_GROUP_PROJECTS_IN_FOLDERS)
@ -820,15 +969,20 @@ endif()
if(UNIX)
# See WITH_WINDOWS_SCCACHE for Windows.
option(WITH_COMPILER_CCACHE "Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)" OFF)
option(WITH_COMPILER_CCACHE "\
Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)"
OFF
)
mark_as_advanced(WITH_COMPILER_CCACHE)
endif()
# The following only works with the Ninja generator in CMake >= 3.0.
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
option(WITH_NINJA_POOL_JOBS
"Enable Ninja pools of jobs, to try to ease building on machines with 16GB of RAM or less (if not yet defined, will try to set best values based on detected machine specifications)."
OFF)
option(WITH_NINJA_POOL_JOBS "\
Enable Ninja pools of jobs, to try to ease building on machines with 16GB of RAM or less \
(if not yet defined, will try to set best values based on detected machine specifications)."
OFF
)
mark_as_advanced(WITH_NINJA_POOL_JOBS)
endif()
@ -836,7 +990,9 @@ endif()
set(POSTINSTALL_SCRIPT "" CACHE FILEPATH "Run given CMake script after installation process")
mark_as_advanced(POSTINSTALL_SCRIPT)
set(POSTCONFIGURE_SCRIPT "" CACHE FILEPATH "Run given CMake script as the last step of CMake configuration")
set(POSTCONFIGURE_SCRIPT "" CACHE FILEPATH "\
Run given CMake script as the last step of CMake configuration"
)
mark_as_advanced(POSTCONFIGURE_SCRIPT)
# end option(...)
@ -847,9 +1003,15 @@ mark_as_advanced(POSTCONFIGURE_SCRIPT)
# unless specified otherwise, which we currently do not allow
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if(WIN32)
set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "default install path" FORCE)
set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "\
default install path"
FORCE
)
elseif(APPLE)
set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "default install path" FORCE)
set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH}/\${BUILD_TYPE} CACHE PATH "\
default install path"
FORCE
)
else()
if(WITH_INSTALL_PORTABLE)
set(CMAKE_INSTALL_PREFIX ${EXECUTABLE_OUTPUT_PATH} CACHE PATH "default install path" FORCE)
@ -860,9 +1022,15 @@ 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})
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})
string(
REPLACE "\${BUILD_TYPE}" ""
CMAKE_INSTALL_PREFIX_WITH_CONFIG ${CMAKE_INSTALL_PREFIX}
)
endif()
@ -876,7 +1044,10 @@ endif()
# -----------------------------------------------------------------------------
# Check for Conflicting/Unsupported Configurations
option(WITH_STRICT_BUILD_OPTIONS "When requirements for a build option are not met, error instead of disabling the option" OFF)
option(WITH_STRICT_BUILD_OPTIONS "\
When requirements for a build option are not met, error instead of disabling the option."
OFF
)
if(NOT WITH_BLENDER AND NOT WITH_CYCLES_STANDALONE AND NOT WITH_CYCLES_HYDRA_RENDER_DELEGATE)
message(FATAL_ERROR
@ -973,8 +1144,13 @@ endif()
if(WITH_AUDASPACE)
if(NOT WITH_SYSTEM_AUDASPACE)
set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings/C" "${CMAKE_BINARY_DIR}/extern/audaspace")
set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings")
set(AUDASPACE_C_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/extern/audaspace/bindings/C"
"${CMAKE_BINARY_DIR}/extern/audaspace"
)
set(AUDASPACE_PY_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/extern/audaspace/bindings"
)
endif()
endif()
@ -1205,7 +1381,9 @@ if(MSVC)
# endianness-detection and auto-setting is counterproductive
# so we just set endianness according CMAKE_OSX_ARCHITECTURES
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR CMAKE_OSX_ARCHITECTURES MATCHES arm64)
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR
CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR
CMAKE_OSX_ARCHITECTURES MATCHES arm64)
add_definitions(-D__LITTLE_ENDIAN__)
elseif(CMAKE_OSX_ARCHITECTURES MATCHES ppc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc64)
add_definitions(-D__BIG_ENDIAN__)
@ -1410,8 +1588,11 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
set(_compile_heavy_jobs "")
endif()
set(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS "${_compile_heavy_jobs}" CACHE STRING
"Define the maximum number of concurrent heavy compilation jobs, for ninja build system (used for some targets which cpp files can take several GB each during compilation)." FORCE)
set(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS "${_compile_heavy_jobs}" CACHE STRING "\
Define the maximum number of concurrent heavy compilation jobs, for ninja build system \
(used for some targets which cpp files can take several GB each during compilation)."
FORCE
)
mark_as_advanced(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
set(_compile_heavy_jobs)
@ -1438,16 +1619,25 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja" AND WITH_NINJA_POOL_JOBS)
endif()
if(NINJA_MAX_NUM_PARALLEL_COMPILE_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_job_pool=${NINJA_MAX_NUM_PARALLEL_COMPILE_JOBS})
set_property(
GLOBAL APPEND PROPERTY
JOB_POOLS compile_job_pool=${NINJA_MAX_NUM_PARALLEL_COMPILE_JOBS}
)
set(CMAKE_JOB_POOL_COMPILE compile_job_pool)
endif()
if(NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS compile_heavy_job_pool=${NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS})
set_property(
GLOBAL APPEND PROPERTY
JOB_POOLS compile_heavy_job_pool=${NINJA_MAX_NUM_PARALLEL_COMPILE_HEAVY_JOBS}
)
endif()
if(NINJA_MAX_NUM_PARALLEL_LINK_JOBS)
set_property(GLOBAL APPEND PROPERTY JOB_POOLS link_job_pool=${NINJA_MAX_NUM_PARALLEL_LINK_JOBS})
set_property(
GLOBAL APPEND PROPERTY
JOB_POOLS link_job_pool=${NINJA_MAX_NUM_PARALLEL_LINK_JOBS}
)
set(CMAKE_JOB_POOL_LINK link_job_pool)
endif()
endif()

View File

@ -75,3 +75,18 @@ index 46e4529..8e86486 100644
return false;
}
diff --git a/src/liboslexec/CMakeLists.txt b/src/liboslexec/CMakeLists.txt
index 6bb0d175..19f13513 100644
--- a/src/liboslexec/CMakeLists.txt
+++ b/src/liboslexec/CMakeLists.txt
@@ -148,7 +148,9 @@ file (GLOB exec_headers "*.h")
file (GLOB compiler_headers "../liboslcomp/*.h")
FLEX_BISON ( osolex.l osogram.y oso lib_src exec_headers )
-FLEX_BISON ( ../liboslcomp/osllex.l ../liboslcomp/oslgram.y osl lib_src compiler_headers )
+if (BUILD_SHARED_LIBS)
+ FLEX_BISON ( ../liboslcomp/osllex.l ../liboslcomp/oslgram.y osl lib_src compiler_headers )
+endif()
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" )

View File

@ -26,6 +26,7 @@ set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
set(WITH_GMP OFF CACHE BOOL "" FORCE)
set(WITH_HARU OFF CACHE BOOL "" FORCE)
set(WITH_HYDRA OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
@ -55,6 +56,7 @@ set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
@ -71,3 +73,10 @@ if(UNIX AND NOT APPLE)
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
endif()
# These should not have any impact but are disabled so they don't
# appear to be enabled in the list of items (which are mostly OFF).
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_PATH_GUIDING OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC OFF CACHE BOOL "" FORCE)

View File

@ -48,6 +48,7 @@ import pxr.Sdf as Sdf
import pxr.Usd as Usd
import pxr.UsdShade as UsdShade
class USDHookExample(bpy.types.USDHook):
bl_idname = "usd_hook_example"
bl_label = "Example"
@ -97,10 +98,12 @@ class USDHookExample(bpy.types.USDHook):
def register():
bpy.utils.register_class(USDHookExample)
bpy.utils.register_class(USDHookExample)
def unregister():
bpy.utils.unregister_class(USDHookExample)
bpy.utils.unregister_class(USDHookExample)
if __name__ == "__main__":
register()

View File

@ -25,6 +25,8 @@
#include <cassert>
#include <vector>
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT_EDR = MTLPixelFormatRGBA16Float;
static void ghost_fatal_error_dialog(const char *msg)
{
@autoreleasepool {
@ -85,6 +87,19 @@ GHOST_ContextCGL::GHOST_ContextCGL(bool stereoVisual,
[m_metalLayer removeAllAnimations];
[m_metalLayer setDevice:metalDevice];
m_metalLayer.allowsNextDrawableTimeout = NO;
/* Enable EDR support. This is done by:
* 1. Using a floating point render target, so that values ouside 0..1 can be used
* 2. Informing the OS that we are EDR aware, and intend to use values outside 0..1
* 3. Setting the extended sRGB color space so that the OS knows how to interpret the
* values. */
m_metalLayer.wantsExtendedDynamicRangeContent = YES;
m_metalLayer.pixelFormat = METAL_FRAMEBUFFERPIXEL_FORMAT_EDR;
const CFStringRef name = kCGColorSpaceExtendedSRGB;
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(name);
m_metalLayer.colorspace = colorspace;
CGColorSpaceRelease(colorspace);
metalInit();
}
else {
@ -199,8 +214,6 @@ GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
return GHOST_kSuccess;
}
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
void GHOST_ContextCGL::metalInit()
{
@autoreleasepool {
@ -266,11 +279,12 @@ void GHOST_ContextCGL::metalInit()
desc.fragmentFunction = [library newFunctionWithName:@"fragment_shader"];
desc.vertexFunction = [library newFunctionWithName:@"vertex_shader"];
[desc.colorAttachments objectAtIndexedSubscript:0].pixelFormat =
METAL_FRAMEBUFFERPIXEL_FORMAT_EDR;
/* Ensure library is released. */
[library autorelease];
[desc.colorAttachments objectAtIndexedSubscript:0].pixelFormat = METAL_FRAMEBUFFERPIXEL_FORMAT;
m_metalRenderPipeline = (MTLRenderPipelineState *)[device
newRenderPipelineStateWithDescriptor:desc
error:&error];
@ -332,7 +346,7 @@ void GHOST_ContextCGL::metalUpdateFramebuffer()
id<MTLDevice> device = m_metalLayer.device;
MTLTextureDescriptor *overlayDesc = [MTLTextureDescriptor
texture2DDescriptorWithPixelFormat:MTLPixelFormatRGBA16Float
texture2DDescriptorWithPixelFormat:METAL_FRAMEBUFFERPIXEL_FORMAT_EDR
width:width
height:height
mipmapped:NO];
@ -347,12 +361,9 @@ void GHOST_ContextCGL::metalUpdateFramebuffer()
else {
overlayTex.label = [NSString
stringWithFormat:@"Metal Overlay for GHOST Context %p", this]; //@"";
// NSLog(@"Created new Metal Overlay (backbuffer) for context %p\n", this);
}
m_defaultFramebufferMetalTexture[current_swapchain_index].texture =
overlayTex; //[(MTLTexture *)overlayTex retain];
m_defaultFramebufferMetalTexture[current_swapchain_index].texture = overlayTex;
/* Clear texture on create */
id<MTLCommandBuffer> cmdBuffer = [s_sharedMetalCommandQueue commandBuffer];

View File

@ -24,7 +24,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
if (event->getType() == GHOST_kEventWindowUpdate) {
return false;
}
std::cout << "GHOST_EventPrinter::processEvent, time: " << (int32_t)event->getTime()
std::cout << "GHOST_EventPrinter::processEvent, time: " << int32_t(event->getTime())
<< ", type: ";
switch (event->getType()) {
case GHOST_kEventUnknown:
@ -58,15 +58,11 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
case GHOST_kEventKeyUp: {
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
char str[32] = {'\0'};
getKeyString(keyData->key, str);
std::cout << "GHOST_kEventKeyUp, key: " << str;
std::cout << "GHOST_kEventKeyUp, key: " << getKeyString(keyData->key);
} break;
case GHOST_kEventKeyDown: {
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
char str[32] = {'\0'};
getKeyString(keyData->key, str);
std::cout << "GHOST_kEventKeyDown, key: " << str;
std::cout << "GHOST_kEventKeyDown, key: " << getKeyString(keyData->key);
} break;
case GHOST_kEventDraggingEntered: {
@ -159,161 +155,152 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
return handled;
}
void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
const char *GHOST_EventPrinter::getKeyString(const GHOST_TKey key) const
{
if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
sprintf(str, "%c", char(key));
}
else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
}
else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);
}
else {
const char *tstr = nullptr;
switch (key) {
case GHOST_kKeyBackSpace:
tstr = "BackSpace";
break;
case GHOST_kKeyTab:
tstr = "Tab";
break;
case GHOST_kKeyLinefeed:
tstr = "Linefeed";
break;
case GHOST_kKeyClear:
tstr = "Clear";
break;
case GHOST_kKeyEnter:
tstr = "Enter";
break;
case GHOST_kKeyEsc:
tstr = "Esc";
break;
case GHOST_kKeySpace:
tstr = "Space";
break;
case GHOST_kKeyQuote:
tstr = "Quote";
break;
case GHOST_kKeyBackslash:
tstr = "\\";
break;
case GHOST_kKeyAccentGrave:
tstr = "`";
break;
case GHOST_kKeyLeftShift:
tstr = "LeftShift";
break;
case GHOST_kKeyRightShift:
tstr = "RightShift";
break;
case GHOST_kKeyLeftControl:
tstr = "LeftControl";
break;
case GHOST_kKeyRightControl:
tstr = "RightControl";
break;
case GHOST_kKeyLeftAlt:
tstr = "LeftAlt";
break;
case GHOST_kKeyRightAlt:
tstr = "RightAlt";
break;
case GHOST_kKeyLeftOS:
tstr = "LeftOS";
break;
case GHOST_kKeyRightOS:
tstr = "RightOS";
break;
case GHOST_kKeyApp:
tstr = "App";
break;
case GHOST_kKeyGrLess:
// PC german!
tstr = "GrLess";
break;
case GHOST_kKeyCapsLock:
tstr = "CapsLock";
break;
case GHOST_kKeyNumLock:
tstr = "NumLock";
break;
case GHOST_kKeyScrollLock:
tstr = "ScrollLock";
break;
case GHOST_kKeyLeftArrow:
tstr = "LeftArrow";
break;
case GHOST_kKeyRightArrow:
tstr = "RightArrow";
break;
case GHOST_kKeyUpArrow:
tstr = "UpArrow";
break;
case GHOST_kKeyDownArrow:
tstr = "DownArrow";
break;
case GHOST_kKeyPrintScreen:
tstr = "PrintScreen";
break;
case GHOST_kKeyPause:
tstr = "Pause";
break;
case GHOST_kKeyInsert:
tstr = "Insert";
break;
case GHOST_kKeyDelete:
tstr = "Delete";
break;
case GHOST_kKeyHome:
tstr = "Home";
break;
case GHOST_kKeyEnd:
tstr = "End";
break;
case GHOST_kKeyUpPage:
tstr = "UpPage";
break;
case GHOST_kKeyDownPage:
tstr = "DownPage";
break;
case GHOST_kKeyNumpadPeriod:
tstr = "NumpadPeriod";
break;
case GHOST_kKeyNumpadEnter:
tstr = "NumpadEnter";
break;
case GHOST_kKeyNumpadPlus:
tstr = "NumpadPlus";
break;
case GHOST_kKeyNumpadMinus:
tstr = "NumpadMinus";
break;
case GHOST_kKeyNumpadAsterisk:
tstr = "NumpadAsterisk";
break;
case GHOST_kKeyNumpadSlash:
tstr = "NumpadSlash";
break;
case GHOST_kKeyMediaPlay:
tstr = "MediaPlayPause";
break;
case GHOST_kKeyMediaStop:
tstr = "MediaStop";
break;
case GHOST_kKeyMediaFirst:
tstr = "MediaFirst";
break;
case GHOST_kKeyMediaLast:
tstr = "MediaLast";
break;
default:
tstr = "unknown";
break;
}
const char *tstr = nullptr;
sprintf(str, "%s", tstr);
#define CASE_KEY(k, v) \
case k: { \
tstr = v; \
break; \
}
switch (key) {
CASE_KEY(GHOST_kKeyBackSpace, "BackSpace");
CASE_KEY(GHOST_kKeyTab, "Tab");
CASE_KEY(GHOST_kKeyLinefeed, "Linefeed");
CASE_KEY(GHOST_kKeyClear, "Clear");
CASE_KEY(GHOST_kKeyEnter, "Enter");
CASE_KEY(GHOST_kKeyEsc, "Esc");
CASE_KEY(GHOST_kKeySpace, "Space");
CASE_KEY(GHOST_kKeyQuote, "Quote");
CASE_KEY(GHOST_kKeyBackslash, "\\");
CASE_KEY(GHOST_kKeyAccentGrave, "`");
CASE_KEY(GHOST_kKeyLeftShift, "LeftShift");
CASE_KEY(GHOST_kKeyRightShift, "RightShift");
CASE_KEY(GHOST_kKeyLeftControl, "LeftControl");
CASE_KEY(GHOST_kKeyRightControl, "RightControl");
CASE_KEY(GHOST_kKeyLeftAlt, "LeftAlt");
CASE_KEY(GHOST_kKeyRightAlt, "RightAlt");
CASE_KEY(GHOST_kKeyLeftOS, "LeftOS");
CASE_KEY(GHOST_kKeyRightOS, "RightOS");
CASE_KEY(GHOST_kKeyApp, "App");
CASE_KEY(GHOST_kKeyGrLess, "GrLess");
CASE_KEY(GHOST_kKeyCapsLock, "CapsLock");
CASE_KEY(GHOST_kKeyNumLock, "NumLock");
CASE_KEY(GHOST_kKeyScrollLock, "ScrollLock");
CASE_KEY(GHOST_kKeyLeftArrow, "LeftArrow");
CASE_KEY(GHOST_kKeyRightArrow, "RightArrow");
CASE_KEY(GHOST_kKeyUpArrow, "UpArrow");
CASE_KEY(GHOST_kKeyDownArrow, "DownArrow");
CASE_KEY(GHOST_kKeyPrintScreen, "PrintScreen");
CASE_KEY(GHOST_kKeyPause, "Pause");
CASE_KEY(GHOST_kKeyInsert, "Insert");
CASE_KEY(GHOST_kKeyDelete, "Delete");
CASE_KEY(GHOST_kKeyHome, "Home");
CASE_KEY(GHOST_kKeyEnd, "End");
CASE_KEY(GHOST_kKeyUpPage, "UpPage");
CASE_KEY(GHOST_kKeyDownPage, "DownPage");
CASE_KEY(GHOST_kKeyNumpadPeriod, "NumpadPeriod");
CASE_KEY(GHOST_kKeyNumpadEnter, "NumpadEnter");
CASE_KEY(GHOST_kKeyNumpadPlus, "NumpadPlus");
CASE_KEY(GHOST_kKeyNumpadMinus, "NumpadMinus");
CASE_KEY(GHOST_kKeyNumpadAsterisk, "NumpadAsterisk");
CASE_KEY(GHOST_kKeyNumpadSlash, "NumpadSlash");
CASE_KEY(GHOST_kKeyMediaPlay, "MediaPlayPause");
CASE_KEY(GHOST_kKeyMediaStop, "MediaStop");
CASE_KEY(GHOST_kKeyMediaFirst, "MediaFirst");
CASE_KEY(GHOST_kKeyMediaLast, "MediaLast");
CASE_KEY(GHOST_kKeyNumpad0, "Numpad 0");
CASE_KEY(GHOST_kKeyNumpad1, "Numpad 1");
CASE_KEY(GHOST_kKeyNumpad2, "Numpad 2");
CASE_KEY(GHOST_kKeyNumpad3, "Numpad 3");
CASE_KEY(GHOST_kKeyNumpad4, "Numpad 4");
CASE_KEY(GHOST_kKeyNumpad5, "Numpad 5");
CASE_KEY(GHOST_kKeyNumpad6, "Numpad 6");
CASE_KEY(GHOST_kKeyNumpad7, "Numpad 7");
CASE_KEY(GHOST_kKeyNumpad8, "Numpad 8");
CASE_KEY(GHOST_kKeyNumpad9, "Numpad 9");
CASE_KEY(GHOST_kKeyF1, "F1");
CASE_KEY(GHOST_kKeyF2, "F2");
CASE_KEY(GHOST_kKeyF3, "F3");
CASE_KEY(GHOST_kKeyF4, "F4");
CASE_KEY(GHOST_kKeyF5, "F5");
CASE_KEY(GHOST_kKeyF6, "F6");
CASE_KEY(GHOST_kKeyF7, "F7");
CASE_KEY(GHOST_kKeyF8, "F8");
CASE_KEY(GHOST_kKeyF9, "F9");
CASE_KEY(GHOST_kKeyF10, "F10");
CASE_KEY(GHOST_kKeyF11, "F11");
CASE_KEY(GHOST_kKeyF12, "F12");
CASE_KEY(GHOST_kKeyF13, "F13");
CASE_KEY(GHOST_kKeyF14, "F14");
CASE_KEY(GHOST_kKeyF15, "F15");
CASE_KEY(GHOST_kKeyF16, "F16");
CASE_KEY(GHOST_kKeyF17, "F17");
CASE_KEY(GHOST_kKeyF18, "F18");
CASE_KEY(GHOST_kKeyF19, "F19");
CASE_KEY(GHOST_kKeyF20, "F20");
CASE_KEY(GHOST_kKeyF21, "F21");
CASE_KEY(GHOST_kKeyF22, "F22");
CASE_KEY(GHOST_kKeyF23, "F23");
CASE_KEY(GHOST_kKeyF24, "F24");
CASE_KEY(GHOST_kKeyUnknown, "Unknown");
CASE_KEY(GHOST_kKeyComma, ",");
CASE_KEY(GHOST_kKeyMinus, "-");
CASE_KEY(GHOST_kKeyPlus, "=");
CASE_KEY(GHOST_kKeyPeriod, ".");
CASE_KEY(GHOST_kKeySlash, "/");
CASE_KEY(GHOST_kKey0, "0");
CASE_KEY(GHOST_kKey1, "1");
CASE_KEY(GHOST_kKey2, "2");
CASE_KEY(GHOST_kKey3, "3");
CASE_KEY(GHOST_kKey4, "4");
CASE_KEY(GHOST_kKey5, "5");
CASE_KEY(GHOST_kKey6, "6");
CASE_KEY(GHOST_kKey7, "7");
CASE_KEY(GHOST_kKey8, "8");
CASE_KEY(GHOST_kKey9, "9");
CASE_KEY(GHOST_kKeySemicolon, ";");
CASE_KEY(GHOST_kKeyEqual, "=");
CASE_KEY(GHOST_kKeyA, "A");
CASE_KEY(GHOST_kKeyB, "B");
CASE_KEY(GHOST_kKeyC, "C");
CASE_KEY(GHOST_kKeyD, "D");
CASE_KEY(GHOST_kKeyE, "E");
CASE_KEY(GHOST_kKeyF, "F");
CASE_KEY(GHOST_kKeyG, "G");
CASE_KEY(GHOST_kKeyH, "H");
CASE_KEY(GHOST_kKeyI, "I");
CASE_KEY(GHOST_kKeyJ, "J");
CASE_KEY(GHOST_kKeyK, "K");
CASE_KEY(GHOST_kKeyL, "L");
CASE_KEY(GHOST_kKeyM, "M");
CASE_KEY(GHOST_kKeyN, "N");
CASE_KEY(GHOST_kKeyO, "O");
CASE_KEY(GHOST_kKeyP, "P");
CASE_KEY(GHOST_kKeyQ, "Q");
CASE_KEY(GHOST_kKeyR, "R");
CASE_KEY(GHOST_kKeyS, "S");
CASE_KEY(GHOST_kKeyT, "T");
CASE_KEY(GHOST_kKeyU, "U");
CASE_KEY(GHOST_kKeyV, "V");
CASE_KEY(GHOST_kKeyW, "W");
CASE_KEY(GHOST_kKeyX, "X");
CASE_KEY(GHOST_kKeyY, "Y");
CASE_KEY(GHOST_kKeyZ, "Z");
CASE_KEY(GHOST_kKeyLeftBracket, "[");
CASE_KEY(GHOST_kKeyRightBracket, "]");
}
#undef CASE_KEY
/* Shouldn't happen (the value is not known to #GHOST_TKey). */
if (tstr == nullptr) {
tstr = "Invalid";
}
return tstr;
}

View File

@ -30,5 +30,5 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer {
* \param key: The GHOST key code to convert.
* \param str: The GHOST key code converted to a readable string.
*/
void getKeyString(GHOST_TKey key, char str[32]) const;
const char *getKeyString(GHOST_TKey key) const;
};

File diff suppressed because it is too large Load Diff

View File

@ -89,10 +89,19 @@ void ghost_wl_dynload_libraries_exit();
#endif
struct GWL_Output {
/** Wayland core types. */
struct {
wl_output *output = nullptr;
} wl;
/** XDG native types. */
struct {
struct zxdg_output_v1 *output = nullptr;
} xdg;
GHOST_SystemWayland *system = nullptr;
struct wl_output *wl_output = nullptr;
struct zxdg_output_v1 *xdg_output = nullptr;
/** Dimensions in pixels. */
int32_t size_native[2] = {0, 0};
/** Dimensions in millimeter. */

View File

@ -126,7 +126,7 @@ static void initRawInput()
/* Success. */
}
else {
GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError());
GHOST_PRINTF("could not register for RawInput: %d\n", int(GetLastError()));
}
#undef DEVICE_COUNT
}
@ -178,7 +178,7 @@ uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
/* Calculate the time passed since system initialization. */
__int64 delta = (perf_ticks - m_start) * 1000;
uint64_t t = (uint64_t)(delta / m_freq);
uint64_t t = uint64_t(delta / m_freq);
return t;
}

View File

@ -1244,8 +1244,9 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
const XFocusChangeEvent &xfe = xe->xfocus;
/* TODO: make sure this is the correct place for activate/deactivate */
// printf("X: focus %s for window %d\n",
// xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
#if 0
printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", int(xfe.window));
#endif
/* May have to look at the type of event and filter some out. */
@ -1339,8 +1340,10 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
window->GetTabletData());
}
// printf("X: %s window %d\n",
// xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
#if 0
printf(
"X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", int(xce.window));
#endif
if (xce.type == EnterNotify) {
m_windowManager->setActiveWindow(window);
@ -1482,7 +1485,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
window->GetTabletData().Pressure = axis_value / float(xtablet.PressureLevels);
}
/* NOTE(@broken): the (short) cast and the & 0xffff is bizarre and unexplained anywhere,
/* NOTE(@broken): the `short` cast and the & 0xffff is bizarre and unexplained anywhere,
* but I got garbage data without it. Found it in the `xidump.c` source.
*
* NOTE(@mont29): The '& 0xffff' just truncates the value to its two lowest bytes,

View File

@ -347,6 +347,20 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa,
[m_metalLayer removeAllAnimations];
[m_metalLayer setDevice:metalDevice];
if (type == GHOST_kDrawingContextTypeMetal) {
/* Enable EDR support. This is done by:
* 1. Using a floating point render target, so that values ouside 0..1 can be used
* 2. Informing the OS that we are EDR aware, and intend to use values outside 0..1
* 3. Setting the extended sRGB color space so that the OS knows how to interpret the
* values. */
m_metalLayer.wantsExtendedDynamicRangeContent = YES;
m_metalLayer.pixelFormat = MTLPixelFormatRGBA16Float;
const CFStringRef name = kCGColorSpaceExtendedSRGB;
CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(name);
m_metalLayer.colorspace = colorspace;
CGColorSpaceRelease(colorspace);
}
m_metalView = [[CocoaMetalView alloc] initWithFrame:rect];
[m_metalView setWantsLayer:YES];
[m_metalView setLayer:m_metalLayer];

View File

@ -212,9 +212,33 @@ struct GWL_WindowFrame {
};
struct GWL_Window {
/** Wayland core types. */
struct {
wl_surface *surface = nullptr;
wl_egl_window *egl_window = nullptr;
} wl;
/** Wayland native types. */
struct {
wp_viewport *viewport = nullptr;
/**
* When set, only respond to the #wp_fractional_scale_v1_listener::preferred_scale callback
* and ignore updated scale based on #wl_surface_listener::enter & exit events.
*/
wp_fractional_scale_v1 *fractional_scale_handle = nullptr;
} wp;
/** XDG native types. */
struct {
/** A temporary token used for the window to be notified of it's activation. */
xdg_activation_token_v1 *activation_token = nullptr;
} xdg;
GHOST_WindowWayland *ghost_window = nullptr;
GHOST_SystemWayland *ghost_system = nullptr;
struct wl_surface *wl_surface = nullptr;
/**
* Outputs on which the window is currently shown on.
*
@ -223,16 +247,6 @@ struct GWL_Window {
*/
std::vector<GWL_Output *> outputs;
/** A temporary token used for the window to be notified of it's activation. */
xdg_activation_token_v1 *xdg_activation_token = nullptr;
wp_viewport *viewport = nullptr;
/**
* When set, only respond to the #wp_fractional_scale_v1_listener::preferred_scale callback
* and ignore updated scale based on #wl_surface_listener::enter & exit events.
*/
wp_fractional_scale_v1 *fractional_scale_handle = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
WGL_LibDecor_Window *libdecor = nullptr;
#endif
@ -253,8 +267,6 @@ struct GWL_Window {
std::mutex frame_pending_mutex;
#endif
wl_egl_window *egl_window = nullptr;
std::string title;
bool is_dialog = false;
@ -447,15 +459,15 @@ static bool gwl_window_viewport_set(GWL_Window *win,
bool *r_surface_needs_commit,
bool *r_surface_needs_buffer_scale)
{
if (win->viewport != nullptr) {
if (win->wp.viewport != nullptr) {
return false;
}
wp_viewporter *viewporter = win->ghost_system->wp_viewporter();
if (viewporter == nullptr) {
return false;
}
win->viewport = wp_viewporter_get_viewport(viewporter, win->wl_surface);
if (win->viewport == nullptr) {
win->wp.viewport = wp_viewporter_get_viewport(viewporter, win->wl.surface);
if (win->wp.viewport == nullptr) {
return false;
}
@ -467,14 +479,14 @@ static bool gwl_window_viewport_set(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
@ -485,12 +497,12 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
bool *r_surface_needs_commit,
bool *r_surface_needs_buffer_scale)
{
if (win->viewport == nullptr) {
if (win->wp.viewport == nullptr) {
return false;
}
wp_viewport_destroy(win->viewport);
win->viewport = nullptr;
wp_viewport_destroy(win->wp.viewport);
win->wp.viewport = nullptr;
GHOST_ASSERT(win->frame.buffer_scale == 1, "Unexpected scale!");
if (win->frame_pending.buffer_scale != win->frame.buffer_scale) {
@ -500,14 +512,14 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
return true;
@ -515,16 +527,16 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
static bool gwl_window_viewport_size_update(GWL_Window *win)
{
if (win->viewport == nullptr) {
if (win->wp.viewport == nullptr) {
return false;
}
wp_viewport_set_source(win->viewport,
wp_viewport_set_source(win->wp.viewport,
wl_fixed_from_int(0),
wl_fixed_from_int(0),
wl_fixed_from_int(win->frame.size[0]),
wl_fixed_from_int(win->frame.size[1]));
wp_viewport_set_destination(
win->viewport,
win->wp.viewport,
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]),
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[1]));
return true;
@ -550,23 +562,23 @@ static void gwl_window_activate(GWL_Window *win)
return;
}
if (win->xdg_activation_token) {
if (win->xdg.activation_token) {
/* We're about to overwrite this with a new request. */
xdg_activation_token_v1_destroy(win->xdg_activation_token);
xdg_activation_token_v1_destroy(win->xdg.activation_token);
}
win->xdg_activation_token = xdg_activation_v1_get_activation_token(activation_manager);
win->xdg.activation_token = xdg_activation_v1_get_activation_token(activation_manager);
xdg_activation_token_v1_add_listener(
win->xdg_activation_token, xdg_activation_listener_get(), win);
win->xdg.activation_token, xdg_activation_listener_get(), win);
xdg_activation_token_v1_set_app_id(win->xdg_activation_token, GHOST_SystemWayland::xdg_app_id());
xdg_activation_token_v1_set_app_id(win->xdg.activation_token, GHOST_SystemWayland::xdg_app_id());
/* The serial of the input device requesting activation. */
{
uint32_t serial = 0;
wl_seat *seat = system->wl_seat_active_get_with_input_serial(serial);
if (seat) {
xdg_activation_token_v1_set_serial(win->xdg_activation_token, serial, seat);
xdg_activation_token_v1_set_serial(win->xdg.activation_token, serial, seat);
}
}
@ -577,12 +589,12 @@ static void gwl_window_activate(GWL_Window *win)
if (ghost_window_active) {
wl_surface *surface = ghost_window_active->wl_surface();
if (surface) {
xdg_activation_token_v1_set_surface(win->xdg_activation_token, surface);
xdg_activation_token_v1_set_surface(win->xdg.activation_token, surface);
}
}
}
xdg_activation_token_v1_commit(win->xdg_activation_token);
xdg_activation_token_v1_commit(win->xdg.activation_token);
}
/** \} */
@ -607,7 +619,7 @@ static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
gwl_window_viewport_size_update(win);
}
else {
if (win->viewport) {
if (win->wp.viewport) {
gwl_window_viewport_unset(win, r_surface_needs_commit, r_surface_needs_buffer_scale);
}
else {
@ -616,13 +628,13 @@ static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
}
@ -654,7 +666,7 @@ static void gwl_window_frame_pending_size_set(GWL_Window *win,
*r_surface_needs_egl_resize = true;
}
else {
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
}
win->ghost_window->notify_size();
@ -703,7 +715,7 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
win->ghost_window->outputs_changed_update_scale();
}
if (actions[PENDING_WINDOW_SURFACE_COMMIT]) {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
@ -747,11 +759,11 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
}
if (surface_needs_egl_resize) {
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
}
if (surface_needs_buffer_scale) {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (win->xdg_decor) {
@ -771,7 +783,7 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
/* Postponing the commit avoids flickering when moving between monitors of different scale. */
gwl_window_pending_actions_tag(win, PENDING_WINDOW_SURFACE_COMMIT);
#else
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
#endif
}
@ -979,15 +991,15 @@ static void xdg_activation_handle_done(void *data,
const char *token)
{
GWL_Window *win = static_cast<GWL_Window *>(data);
if (xdg_activation_token_v1 != win->xdg_activation_token) {
if (xdg_activation_token_v1 != win->xdg.activation_token) {
return;
}
GHOST_SystemWayland *system = win->ghost_system;
xdg_activation_v1 *activation_manager = system->xdg_activation_manager();
xdg_activation_v1_activate(activation_manager, token, win->wl_surface);
xdg_activation_token_v1_destroy(win->xdg_activation_token);
win->xdg_activation_token = nullptr;
xdg_activation_v1_activate(activation_manager, token, win->wl.surface);
xdg_activation_token_v1_destroy(win->xdg.activation_token);
win->xdg.activation_token = nullptr;
}
static const xdg_activation_token_v1_listener xdg_activation_listener = {
@ -1338,22 +1350,22 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
window_->is_dialog = is_dialog;
/* Window surfaces. */
window_->wl_surface = wl_compositor_create_surface(system_->wl_compositor());
ghost_wl_surface_tag(window_->wl_surface);
window_->wl.surface = wl_compositor_create_surface(system_->wl_compositor());
ghost_wl_surface_tag(window_->wl.surface);
wl_surface_set_buffer_scale(window_->wl_surface, window_->frame.buffer_scale);
wl_surface_set_buffer_scale(window_->wl.surface, window_->frame.buffer_scale);
wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_);
wl_surface_add_listener(window_->wl.surface, &wl_surface_listener, window_);
window_->egl_window = wl_egl_window_create(
window_->wl_surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
window_->wl.egl_window = wl_egl_window_create(
window_->wl.surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
wp_fractional_scale_manager_v1 *fractional_scale_manager = system->wp_fractional_scale_manager();
if (fractional_scale_manager) {
window_->fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
fractional_scale_manager, window_->wl_surface);
window_->wp.fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
fractional_scale_manager, window_->wl.surface);
wp_fractional_scale_v1_add_listener(
window_->fractional_scale_handle, &wp_fractional_scale_listener, window_);
window_->wp.fractional_scale_handle, &wp_fractional_scale_listener, window_);
}
/* NOTE: The limit is in points (not pixels) so Hi-DPI will limit to larger number of pixels.
@ -1371,7 +1383,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
/* create window decorations */
decor.frame = libdecor_decorate(
system_->libdecor_context(), window_->wl_surface, &libdecor_frame_iface, window_);
system_->libdecor_context(), window_->wl.surface, &libdecor_frame_iface, window_);
libdecor_frame_map(window_->libdecor->frame);
libdecor_frame_set_min_content_size(decor.frame, UNPACK2(size_min));
@ -1388,7 +1400,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
{
window_->xdg_decor = new WGL_XDG_Decor_Window;
WGL_XDG_Decor_Window &decor = *window_->xdg_decor;
decor.surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell(), window_->wl_surface);
decor.surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell(), window_->wl.surface);
decor.toplevel = xdg_surface_get_toplevel(decor.surface);
xdg_toplevel_set_min_size(decor.toplevel, UNPACK2(size_min));
@ -1415,10 +1427,10 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
gwl_window_title_set(window_, title);
wl_surface_set_user_data(window_->wl_surface, this);
wl_surface_set_user_data(window_->wl.surface, this);
/* Call top-level callbacks. */
wl_surface_commit(window_->wl_surface);
wl_surface_commit(window_->wl.surface);
wl_display_roundtrip(system_->wl_display());
#ifdef GHOST_OPENGL_ALPHA
@ -1480,7 +1492,7 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
m_cursorGrabInitPos,
bounds,
m_cursorGrabAxis,
window_->wl_surface,
window_->wl.surface,
this->scale_params()))
{
return GHOST_kSuccess;
@ -1599,21 +1611,21 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
releaseNativeHandles();
wl_egl_window_destroy(window_->egl_window);
wl_egl_window_destroy(window_->wl.egl_window);
if (window_->xdg_activation_token) {
xdg_activation_token_v1_destroy(window_->xdg_activation_token);
window_->xdg_activation_token = nullptr;
if (window_->xdg.activation_token) {
xdg_activation_token_v1_destroy(window_->xdg.activation_token);
window_->xdg.activation_token = nullptr;
}
if (window_->fractional_scale_handle) {
wp_fractional_scale_v1_destroy(window_->fractional_scale_handle);
window_->fractional_scale_handle = nullptr;
if (window_->wp.fractional_scale_handle) {
wp_fractional_scale_v1_destroy(window_->wp.fractional_scale_handle);
window_->wp.fractional_scale_handle = nullptr;
}
if (window_->viewport) {
wp_viewport_destroy(window_->viewport);
window_->viewport = nullptr;
if (window_->wp.viewport) {
wp_viewport_destroy(window_->wp.viewport);
window_->wp.viewport = nullptr;
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
@ -1628,9 +1640,9 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
/* Clear any pointers to this window. This is needed because there are no guarantees
* that flushing the display will the "leave" handlers before handling events. */
system_->window_surface_unref(window_->wl_surface);
system_->window_surface_unref(window_->wl.surface);
wl_surface_destroy(window_->wl_surface);
wl_surface_destroy(window_->wl.surface);
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
@ -1744,7 +1756,7 @@ void GHOST_WindowWayland::setOpaque() const
/* Make the window opaque. */
region = wl_compositor_create_region(system_->wl_compositor());
wl_region_add(region, 0, 0, UNPACK2(window_->size));
wl_surface_set_opaque_region(window_->wl_surface, region);
wl_surface_set_opaque_region(window_->wl.surface, region);
wl_region_destroy(region);
}
#endif
@ -1763,8 +1775,8 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
GHOST_kVulkanPlatformWayland,
0,
nullptr,
window_->wl_surface,
system_->wl_display(),
window_->wl.surface,
system_->wl.display(),
1,
2,
true);
@ -1781,7 +1793,7 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextEGL(system_,
m_wantStereoVisual,
EGLNativeWindowType(window_->egl_window),
EGLNativeWindowType(window_->wl.egl_window),
EGLNativeDisplayType(system_->wl_display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
@ -1847,7 +1859,7 @@ wl_fixed_t GHOST_WindowWayland::wl_fixed_to_window(wl_fixed_t value) const
wl_surface *GHOST_WindowWayland::wl_surface() const
{
return window_->wl_surface;
return window_->wl.surface;
}
const std::vector<GWL_Output *> &GHOST_WindowWayland::outputs()
@ -1980,7 +1992,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
return false;
}
if (window_->fractional_scale_handle) {
if (window_->wp.fractional_scale_handle) {
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_frame_guard{window_->frame_pending_mutex};
#endif

View File

@ -423,7 +423,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientWidth(uint32_t width)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if (cBnds.getWidth() != (int32_t)width) {
if (cBnds.getWidth() != int32_t(width)) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth() + width - cBnds.getWidth();
int cy = wBnds.getHeight();
@ -442,7 +442,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientHeight(uint32_t height)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if (cBnds.getHeight() != (int32_t)height) {
if (cBnds.getHeight() != int32_t(height)) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth();
int cy = wBnds.getHeight() + height - cBnds.getHeight();
@ -461,7 +461,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientSize(uint32_t width, uint32_t height)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if ((cBnds.getWidth() != (int32_t)width) || (cBnds.getHeight() != (int32_t)height)) {
if ((cBnds.getWidth() != int32_t(width)) || (cBnds.getHeight() != int32_t(height))) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth() + width - cBnds.getWidth();
int cy = wBnds.getHeight() + height - cBnds.getHeight();

View File

@ -348,7 +348,7 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
*
* wintab.h defines orAltitude as a `uint` but documents orAltitude as positive for upward
* angles and negative for downward angles. WACOM uses negative altitude values to show that
* the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
* the pen is inverted; therefore we cast orAltitude as an `int` and then use the absolute
* value.
*/

View File

@ -77,6 +77,12 @@ struct FallbackTransform {
applyRGB(pixel);
}
bool isNoOp()
{
/* Rely on the short-circuiting based on name-space comparison in the IMB_colormanagement. */
return false;
}
TransformType type;
/* Scale transform. */
float scale;
@ -99,6 +105,11 @@ struct FallbackProcessor {
transform.applyRGBA(pixel);
}
bool isNoOp()
{
return transform.isNoOp();
}
FallbackTransform transform;
MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
@ -337,6 +348,11 @@ void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
delete (FallbackProcessor *)(processor);
}
bool FallbackImpl::cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
{
return ((FallbackProcessor *)cpu_processor)->isNoOp();
}
void FallbackImpl::cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
OCIO_PackedImageDesc *img)
{

View File

@ -169,7 +169,16 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay)
* merge UI using alpha blending in the correct color space. */
if (parameters.use_overlay) {
col.rgb = pow(col.rgb, vec3(parameters.exponent * 2.2));
col = clamp(col, 0.0, 1.0);
if (!parameters.use_hdr) {
/* If we're not using an extended colour space, clamp the color 0..1. */
col = clamp(col, 0.0, 1.0);
}
else {
/* When using extended colorspace, interpolate towards clamped color to improve display of
* alpha-blended overlays. */
col = mix(max(col, 0.0), clamp(col, 0.0, 1.0), col_overlay.a);
}
col *= 1.0 - col_overlay.a;
col += col_overlay; /* Assumed unassociated alpha. */
col.rgb = pow(col.rgb, vec3(1.0 / 2.2));

View File

@ -189,6 +189,11 @@ OCIO_ConstCPUProcessorRcPtr *OCIO_processorGetCPUProcessor(OCIO_ConstProcessorRc
return impl->processorGetCPUProcessor(processor);
}
bool OCIO_cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
{
return impl->cpuProcessorIsNoOp(cpu_processor);
}
void OCIO_cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img)
{
impl->cpuProcessorApply(cpu_processor, img);
@ -290,7 +295,8 @@ bool OCIO_gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
const float exponent,
const float dither,
const bool use_predivide,
const bool use_overlay)
const bool use_overlay,
const bool use_hdr)
{
return impl->gpuDisplayShaderBind(config,
input,
@ -302,7 +308,8 @@ bool OCIO_gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
exponent,
dither,
use_predivide,
use_overlay);
use_overlay,
use_hdr);
}
void OCIO_gpuDisplayShaderUnbind()

View File

@ -151,6 +151,7 @@ OCIO_ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(OCIO_ConstConfigRcPtr
void OCIO_processorRelease(OCIO_ConstProcessorRcPtr *cpu_processor);
OCIO_ConstCPUProcessorRcPtr *OCIO_processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
bool OCIO_cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor);
void OCIO_cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
struct OCIO_PackedImageDesc *img);
void OCIO_cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
@ -197,7 +198,8 @@ bool OCIO_gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
const float exponent,
const float dither,
const bool use_predivide,
const bool use_overlay);
const bool use_overlay,
const bool use_hdr);
void OCIO_gpuDisplayShaderUnbind(void);
void OCIO_gpuCacheFree(void);

View File

@ -590,6 +590,11 @@ void OCIOImpl::cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_proc
}
}
bool OCIOImpl::cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor)
{
return (*(ConstCPUProcessorRcPtr *)cpu_processor)->isNoOp();
}
void OCIOImpl::cpuProcessorApplyRGB(OCIO_ConstCPUProcessorRcPtr *cpu_processor, float *pixel)
{
(*(ConstCPUProcessorRcPtr *)cpu_processor)->applyRGB(pixel);

View File

@ -63,6 +63,7 @@ class IOCIOImpl {
virtual void processorRelease(OCIO_ConstProcessorRcPtr *processor) = 0;
virtual OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *p) = 0;
virtual bool cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor) = 0;
virtual void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
OCIO_PackedImageDesc *img) = 0;
virtual void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
@ -113,7 +114,8 @@ class IOCIOImpl {
const float /*exponent*/,
const float /*dither*/,
const bool /*use_predivide*/,
const bool /*use_overlay*/)
const bool /*use_overlay*/,
const bool /*use_hdr*/)
{
return false;
}
@ -176,6 +178,7 @@ class FallbackImpl : public IOCIOImpl {
void processorRelease(OCIO_ConstProcessorRcPtr *processor);
OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
bool cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor);
void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img);
void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
OCIO_PackedImageDesc *img);
@ -266,6 +269,7 @@ class OCIOImpl : public IOCIOImpl {
void processorRelease(OCIO_ConstProcessorRcPtr *processor);
OCIO_ConstCPUProcessorRcPtr *processorGetCPUProcessor(OCIO_ConstProcessorRcPtr *processor);
bool cpuProcessorIsNoOp(OCIO_ConstCPUProcessorRcPtr *cpu_processor);
void cpuProcessorApply(OCIO_ConstCPUProcessorRcPtr *cpu_processor, OCIO_PackedImageDesc *img);
void cpuProcessorApply_predivide(OCIO_ConstCPUProcessorRcPtr *cpu_processor,
OCIO_PackedImageDesc *img);
@ -310,7 +314,8 @@ class OCIOImpl : public IOCIOImpl {
const float exponent,
const float dither,
const bool use_predivide,
const bool use_overlay);
const bool use_overlay,
const bool use_hdr);
void gpuDisplayShaderUnbind(void);
void gpuCacheFree(void);

View File

@ -515,7 +515,8 @@ static void updateGPUDisplayParameters(OCIO_GPUShader &shader,
float exponent,
float dither,
bool use_predivide,
bool use_overlay)
bool use_overlay,
bool use_hdr)
{
bool do_update = false;
if (shader.parameters_buffer == nullptr) {
@ -543,6 +544,10 @@ static void updateGPUDisplayParameters(OCIO_GPUShader &shader,
data.use_overlay = use_overlay;
do_update = true;
}
if (bool(data.use_hdr) != use_hdr) {
data.use_hdr = use_hdr;
do_update = true;
}
if (do_update) {
GPU_uniformbuf_update(shader.parameters_buffer, &data);
}
@ -684,7 +689,8 @@ bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
const float exponent,
const float dither,
const bool use_predivide,
const bool use_overlay)
const bool use_overlay,
const bool use_hdr)
{
/* Get GPU shader from cache or create new one. */
OCIO_GPUDisplayShader &display_shader = getGPUDisplayShader(
@ -719,7 +725,7 @@ bool OCIOImpl::gpuDisplayShaderBind(OCIO_ConstConfigRcPtr *config,
GPU_uniformbuf_bind(textures.uniforms_buffer, UNIFORMBUF_SLOT_LUTS);
}
updateGPUDisplayParameters(shader, scale, exponent, dither, use_predivide, use_overlay);
updateGPUDisplayParameters(shader, scale, exponent, dither, use_predivide, use_overlay, use_hdr);
GPU_uniformbuf_bind(shader.parameters_buffer, UNIFORMBUF_SLOT_DISPLAY);
/* TODO(fclem): remove remains of IMM. */

View File

@ -36,7 +36,7 @@ struct OCIO_GPUParameters {
float exponent;
bool1 use_predivide;
bool1 use_overlay;
bool1 use_hdr;
int _pad0;
int _pad1;
int _pad2;
};

View File

@ -21,14 +21,14 @@ roles:
reference: Linear CIE-XYZ E
# Internal scene linear space
scene_linear: Linear
rendering: Linear
scene_linear: Linear Rec.709
rendering: Linear Rec.709
# Default color space for byte image
default_byte: sRGB
# Default color space for float images
default_float: Linear
default_float: Linear Rec.709
# Default color space sequencer is working in
default_sequencer: sRGB
@ -40,15 +40,15 @@ roles:
data: Non-Color
# For interop between configs, and to determine XYZ for rendering
aces_interchange: Linear ACES
aces_interchange: ACES2065-1
cie_xyz_d65_interchange: Linear CIE-XYZ D65
# Specified by OCIO, not used in Blender
color_timing: Filmic Log
compositing_log: Filmic Log
default: Linear
matte_paint: Linear
texture_paint: Linear
default: Linear Rec.709
matte_paint: Linear Rec.709
texture_paint: Linear Rec.709
displays:
sRGB:
@ -60,6 +60,7 @@ displays:
active_displays: [sRGB]
active_views: [Standard, Filmic, Filmic Log, False Color, Raw]
inactive_colorspaces: [False Color]
colorspaces:
- !<ColorSpace>
@ -74,7 +75,7 @@ colorspaces:
- !<ColorSpace>
name: Linear CIE-XYZ D65
aliases: [cie_xyz_d65, CIE-XYZ-D65, XYZ, Linear CIE-XYZ D65]
aliases: [cie_xyz_d65, CIE-XYZ-D65, XYZ, Linear CIE-XYZ I-D65]
family: Chromaticity
equalitygroup:
bitdepth: 32f
@ -84,12 +85,13 @@ colorspaces:
from_scene_reference: !<FileTransform> {src: xyz_E_to_D65.spimtx, interpolation: linear}
- !<ColorSpace>
name: Linear
family: linear
name: Linear Rec.709
aliases: [Linear, Linear BT.709, Linear BT.709 I-D65, Linear Tristimulus, linrec709, Utility - Linear - sRGB, Utility - Linear - Rec.709, lin_srgb, Linear Rec.709 (sRGB), lin_rec709_srgb, lin_rec709, lin_srgb, "CGI: Linear - Rec.709"]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
Rec. 709 (Full Range), Blender native linear space
Linear BT.709 with illuminant D65 white point
isdata: false
from_scene_reference: !<GroupTransform>
children:
@ -97,12 +99,41 @@ colorspaces:
- !<MatrixTransform> {matrix: [ 3.2410032329763587, -1.5373989694887855, -0.4986158819963629, 0, -0.9692242522025164, 1.8759299836951759, 0.0415542263400847, 0, 0.0556394198519755, -0.2040112061239099, 1.0571489771875333, 0, 0, 0, 0, 1]}
- !<ColorSpace>
name: Linear ACES
family: linear
name: Linear DCI-P3 D65
aliases: [Linear DCI-P3 I-D65, Linear P3-D65, lin_p3d65, Utility - Linear - P3-D65, Apple DCI-P3 D65]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
ACES2065-1 linear space
Linear DCI-P3 with illuminant D65 white point
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear CIE-XYZ D65}
- !<MatrixTransform> {matrix: [2.4935091239346101, -0.9313881794047790, -0.4027127567416516, 0, -0.8294732139295544, 1.7626305796003032, 0.0236242371055886, 0, 0.0358512644339181, -0.0761839369220759, 0.9570295866943110, 0, 0, 0, 0, 1]}
- !<ColorSpace>
name: Linear Rec.2020
aliases: [Linear BT.2020 I-D65, Linear BT.2020, lin_rec2020, Utility - Linear - Rec.2020]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
Linear BT.2020 with illuminant D65 white point
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear CIE-XYZ D65}
- !<MatrixTransform> {matrix: [ 1.7166634277958805, -0.3556733197301399, -0.2533680878902478, 0, -0.6666738361988869, 1.6164557398246981, 0.0157682970961337, 0, 0.0176424817849772, -0.0427769763827532, 0.9422432810184308, 0, 0, 0, 0, 1]}
- !<ColorSpace>
name: ACES2065-1
aliases: [Linear ACES, aces2065_1, ACES - ACES2065-1, lin_ap0, "ACES: Linear - AP0"]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
Linear AP0 with ACES white point
isdata: false
from_reference: !<GroupTransform>
children:
@ -110,12 +141,13 @@ colorspaces:
- !<BuiltinTransform> {style: "UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD", direction: inverse}
- !<ColorSpace>
name: Linear ACEScg
family: linear
name: ACEScg
aliases: [Linear ACEScg, lin_ap1, ACES - ACEScg, "ACEScg: Linear - AP1"]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
ACEScg linear space
Linear AP1 with ACES white point
isdata: false
from_reference: !<GroupTransform>
children:
@ -123,22 +155,79 @@ colorspaces:
- !<BuiltinTransform> {style: "UTILITY - ACES-AP1_to_CIE-XYZ-D65_BFD", direction: inverse}
- !<ColorSpace>
name: sRGB
family:
name: Linear FilmLight E-Gamut
aliases: [Linear E-Gamut I-D65, "FilmLight: Linear - E-Gamut"]
family: Linear
equalitygroup:
bitdepth: 32f
description: |
sRGB display space
Linear E-Gamut with illuminant D65 white point
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ I-E, dst: Linear CIE-XYZ I-D65}
- !<MatrixTransform> {matrix: [ 0.7053968501, 0.1640413283, 0.08101774865, 0, 0.2801307241, 0.8202066415, -0.1003373656, 0, -0.1037815116, -0.07290725703, 1.265746519, 0, 0, 0, 0, 1], direction: inverse}
- !<ColorSpace>
name: sRGB
aliases: [sRGB 2.2, sRGB I-D65, srgb_display, sRGB - Display, g22_rec709, Utility - Gamma 2.2 - Rec.709 - Texture, Utility - sRGB - Texture, sRGB - Texture, srgb_tx, srgb_texture, Input - Generic - sRGB - Texture, "sRGB Display: 2.2 Gamma - Rec.709"]
family: Display
equalitygroup:
bitdepth: 32f
description: |
sRGB IEC 61966-2-1 compound (piece-wise) encoding
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709}
- !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}
- !<ColorSpace>
name: Display P3
aliases: [Display P3 2.2, Display P3 I-D65, P3-D65 - Display, p3_d65_display, p3d65_display, AppleP3 sRGB OETF]
family: Display
equalitygroup:
bitdepth: 32f
description: |
Apple's Display P3 with sRGB compound (piece-wise) encoding transfer function, common on Mac devices
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear DCI-P3 D65}
- !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}
- !<ColorSpace>
name: Rec.1886
aliases: [BT.1886, BT.1886 2.4, BT.1886 EOTF, BT.1886 I-D65, Rec.1886 / Rec.709 Video - Display, rec1886_rec709_video_display, Rec.1886 Rec.709 - Display, rec1886_rec709_display, "Rec1886: 2.4 Gamma - Rec.709"]
family: Display
equalitygroup:
bitdepth: 32f
description: |
BT.1886 2.4 Exponent EOTF Display, commonly used for TVs
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709}
- !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0, direction: inverse}
- !<ColorSpace>
name: Rec.2020
aliases: [BT.2020, BT.2020 2.4, BT.2020 I-D65, Rec.1886 / Rec.2020 Video - Display, rec1886_rec2020_video_display, Rec.1886 Rec.2020 - Display, rec1886_rec2020_display, "Rec1886: 2.4 Gamma - Rec.2020"]
family: Display
equalitygroup:
bitdepth: 32f
description: |
BT.2020 2.4 Exponent EOTF Display
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.2020}
- !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0, direction: inverse}
- !<ColorSpace>
name: Non-Color
aliases: [Generic Data, Non-Colour Data, Raw, Utility - Raw]
family: raw
family: Data
description: |
Generic data that is not color, will not apply any color transform (e.g. normal maps)
equalitygroup:
@ -147,7 +236,7 @@ colorspaces:
- !<ColorSpace>
name: Filmic Log
family: log
family: Log Encodings
equalitygroup:
bitdepth: 32f
description: |
@ -155,18 +244,18 @@ colorspaces:
isdata: false
from_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709}
- !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 12.526068812]}
- !<FileTransform> {src: filmic_desat65cube.spi3d, interpolation: best}
- !<AllocationTransform> {allocation: uniform, vars: [0, 0.66]}
to_scene_reference: !<GroupTransform>
children:
- !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 4.026068812], direction: inverse}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear, direction: inverse}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear Rec.709, direction: inverse}
- !<ColorSpace>
name: Filmic sRGB
family:
family: Filmic
equalitygroup:
bitdepth: 32f
description: |
@ -179,7 +268,7 @@ colorspaces:
- !<ColorSpace>
name: False Color
family: display
family: Filmic
equalitygroup:
bitdepth: 32f
description: |

View File

@ -23,24 +23,14 @@ addons_fake_modules = {}
# called only once at startup, avoids calling 'reset_all', correct but slower.
def _initialize():
path_list = paths()
for path in path_list:
def _initialize_once():
for path in paths():
_bpy.utils._sys_path_ensure_append(path)
# Original code:
# for addon in _preferences.addons:
# enable(addon.module)
# NOTE(@ideasman42): package support, may be implemented add-on (temporary for extension development).
addon_submodules = []
_initialize_extensions_repos_once()
for addon in _preferences.addons:
module = addon.module
if "." in module:
addon_submodules.append(module)
continue
enable(module)
for module in addon_submodules:
enable(module)
enable(addon.module)
def paths():
@ -56,6 +46,33 @@ def paths():
]
# A version of `paths` that includes extension repositories returning a list `(path, package)` pairs.
#
# Notes on the ``package`` value.
#
# - For top-level modules (the "addons" directories, the value is an empty string)
# because those add-ons can be imported directly.
# - For extension repositories the value is a module string (which can be imported for example)
# where any modules within the `path` can be imported as a sub-module.
# So for example, given a list value of: `("/tmp/repo", "bl_ext.temp_repo")`.
#
# An add-on located at `/tmp/repo/my_handy_addon.py` will have a unique module path of:
# `bl_ext.temp_repo.my_handy_addon`, which can be imported and will be the value of it's `Addon.module`.
def _paths_with_extension_repos():
import os
addon_paths = [(path, "") for path in paths()]
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
dirpath = repo.directory
if not os.path.isdir(dirpath):
continue
addon_paths.append((dirpath, "%s.%s" % (_ext_base_pkg_idname, repo.module)))
return addon_paths
def _fake_module(mod_name, mod_path, speedy=True, force_support=None):
global error_encoding
import os
@ -152,16 +169,14 @@ def modules_refresh(*, module_cache=addons_fake_modules):
error_encoding = False
error_duplicates.clear()
path_list = paths()
modules_stale = set(module_cache.keys())
for path in path_list:
for path, pkg_id in _paths_with_extension_repos():
# Force all user contributed add-ons to be 'TESTING'.
force_support = 'TESTING' if path.endswith("addons_contrib") else None
force_support = 'TESTING' if ((not pkg_id) and path.endswith("addons_contrib")) else None
for mod_name, mod_path in _bpy.path.module_names(path):
for mod_name, mod_path in _bpy.path.module_names(path, package=pkg_id):
modules_stale.discard(mod_name)
mod = module_cache.get(mod_name)
if mod:
@ -464,12 +479,11 @@ def reset_all(*, reload_scripts=False):
# initializes addons_fake_modules
modules_refresh()
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths_list = paths()
for path, pkg_id in _paths_with_extension_repos():
if not pkg_id:
_bpy.utils._sys_path_ensure_append(path)
for path in paths_list:
_bpy.utils._sys_path_ensure_append(path)
for mod_name, _mod_path in _bpy.path.module_names(path):
for mod_name, _mod_path in _bpy.path.module_names(path, package=pkg_id):
is_enabled, is_loaded = check(mod_name)
# first check if reload is needed before changing state.
@ -548,3 +562,162 @@ def module_bl_info(mod, *, info_basis=None):
addon_info["_init"] = None
return addon_info
# -----------------------------------------------------------------------------
# Extensions
# Module-like class, store singletons.
class _ext_global:
__slots__ = ()
# Store a map of `preferences.filepaths.extension_repos` -> `module_id`.
# Only needed to detect renaming between `bpy.app.handlers.extension_repos_update_{pre & post}` events.
idmap = {}
# The base package created by `JunctionModuleHandle`.
module_handle = None
# The name (in `sys.modules`) keep this short because it's stored as part of add-on modules name.
_ext_base_pkg_idname = "bl_ext"
def _extension_preferences_idmap():
repos_idmap = {}
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
repos_idmap[repo.as_pointer()] = repo.module
return repos_idmap
def _extension_dirpath_from_preferences():
repos_dict = {}
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
repos_dict[repo.module] = repo.directory
return repos_dict
def _extension_dirpath_from_handle():
repos_info = {}
for module_id, module in _ext_global.module_handle.submodule_items():
# Account for it being unset although this should never happen unless script authors
# meddle with the modules.
try:
dirpath = module.__path__[0]
except BaseException:
dirpath = ""
repos_info[module_id] = dirpath
return repos_info
# Use `bpy.app.handlers.extension_repos_update_{pre/post}` to track changes to extension repositories
# and sync the changes to the Python module.
@_bpy.app.handlers.persistent
def _initialize_extension_repos_pre(*_):
_ext_global.idmap = _extension_preferences_idmap()
@_bpy.app.handlers.persistent
def _initialize_extension_repos_post(*_):
# Map `module_id` -> `dirpath`.
repos_info_prev = _extension_dirpath_from_handle()
repos_info_next = _extension_dirpath_from_preferences()
# Map `repo.as_pointer()` -> `module_id`.
repos_idmap_prev = _ext_global.idmap
repos_idmap_next = _extension_preferences_idmap()
# Map `module_id` -> `repo.as_pointer()`.
repos_idmap_next_reverse = {value: key for key, value in repos_idmap_next.items()}
# Mainly needed when the `preferences.experimental.use_extension_repos` option is enabled at run-time.
#
# Filter `repos_idmap_prev` so only items which were also in the `repos_info_prev` are included.
# This is an awkward situation, they should be in sync, however when enabling the experimental option
# means the preferences wont have changed, but the module will not be in sync with the preferences.
# Support this by removing items in `repos_idmap_prev` which aren't also initialized in the managed package.
#
# The only situation this would be useful to keep is if we want to support renaming a package
# that manipulates all add-ons using it, when those add-ons are in the preferences but have not had
# their package loaded. It's possible we want to do this but is also reasonably obscure.
for repo_id_prev, module_id_prev in list(repos_idmap_prev.items()):
if module_id_prev not in repos_info_prev:
del repos_idmap_prev[repo_id_prev]
# NOTE(@ideasman42): supporting renaming at all is something we might limit to extensions
# which have no add-ons loaded as supporting renaming add-ons in-place seems error prone as the add-on
# may define internal variables based on the full package path.
submodules_add = [] # List of module names to add: `(module_id, dirpath)`.
submodules_del = [] # List of module names to remove: `module_id`.
submodules_rename_module = [] # List of module names: `(module_id_src, module_id_dst)`.
submodules_rename_dirpath = [] # List of module names: `(module_id, dirpath)`.
renamed_prev = set()
renamed_next = set()
# Detect rename modules & module directories.
for module_id_next, dirpath_next in repos_info_next.items():
# Lookup never fails, as the "next" values use: `preferences.filepaths.extension_repos`.
repo_id = repos_idmap_next_reverse[module_id_next]
# Lookup may fail if this is a newly added module.
# Don't attempt to setup `submodules_add` though as it's possible
# the module name persists while the underlying `repo_id` changes.
module_id_prev = repos_idmap_prev.get(repo_id)
if module_id_prev is None:
continue
# Detect rename.
if module_id_next != module_id_prev:
submodules_rename_module.append((module_id_prev, module_id_next))
renamed_prev.add(module_id_prev)
renamed_next.add(module_id_next)
# Detect `dirpath` change.
if dirpath_next != repos_info_prev[module_id_prev]:
submodules_rename_dirpath.append((module_id_next, dirpath_next))
# Detect added modules.
for module_id, dirpath in repos_info_next.items():
if (module_id not in repos_info_prev) and (module_id not in renamed_next):
submodules_add.append((module_id, dirpath))
# Detect deleted modules.
for module_id, _dirpath in repos_info_prev.items():
if (module_id not in repos_info_next) and (module_id not in renamed_prev):
submodules_del.append(module_id)
# Apply changes to the `_ext_base_pkg_idname` named module so it matches extension data from the preferences.
module_handle = _ext_global.module_handle
for module_id in submodules_del:
module_handle.unregister_submodule(module_id)
for module_id, dirpath in submodules_add:
module_handle.register_submodule(module_id, dirpath)
for module_id_prev, module_id_next in submodules_rename_module:
module_handle.rename_submodule(module_id_prev, module_id_next)
for module_id, dirpath in submodules_rename_dirpath:
module_handle.rename_directory(module_id, dirpath)
_ext_global.idmap.clear()
# Force refreshing if directory paths change.
if submodules_del or submodules_add or submodules_rename_dirpath:
modules._is_first = True
def _initialize_extensions_repos_once():
from bpy_extras.extensions.junction_module import JunctionModuleHandle
module_handle = JunctionModuleHandle(_ext_base_pkg_idname)
module_handle.register_module()
_ext_global.module_handle = module_handle
# Setup repositories for the first time.
# Intentionally don't call `_initialize_extension_repos_pre` as this is the first time,
# the previous state is not useful to read.
_initialize_extension_repos_post()
# Internal handlers intended for Blender's own handling of repositories.
_bpy.app.handlers._extension_repos_update_pre.append(_initialize_extension_repos_pre)
_bpy.app.handlers._extension_repos_update_post.append(_initialize_extension_repos_post)

View File

@ -355,7 +355,7 @@ def ensure_ext(filepath, ext, *, case_sensitive=False):
return filepath + ext
def module_names(path, *, recursive=False):
def module_names(path, *, recursive=False, package=""):
"""
Return a list of modules which can be imported from *path*.
@ -363,6 +363,8 @@ def module_names(path, *, recursive=False):
:type path: string
:arg recursive: Also return submodule names for packages.
:type recursive: bool
:arg package: Optional string, used as the prefix for module names (without the trailing ".").
:type package: string
:return: a list of string pairs (module_name, module_file).
:rtype: list of strings
"""
@ -371,22 +373,24 @@ def module_names(path, *, recursive=False):
modules = []
pacakge_prefix = (package + ".") if package else ""
for filename in sorted(_os.listdir(path)):
if filename == "modules":
if (filename == "modules") and (not pacakge_prefix):
pass # XXX, hard coded exception.
elif filename.endswith(".py") and filename != "__init__.py":
fullpath = join(path, filename)
modules.append((filename[0:-3], fullpath))
modules.append((pacakge_prefix + filename[0:-3], fullpath))
elif not filename.startswith("."):
# Skip hidden files since they are used by for version control.
directory = join(path, filename)
fullpath = join(directory, "__init__.py")
if isfile(fullpath):
modules.append((filename, fullpath))
modules.append((pacakge_prefix + filename, fullpath))
if recursive:
for mod_name, mod_path in module_names(directory, recursive=True):
modules.append((
"%s.%s" % (filename, mod_name),
"%s.%s" % (pacakge_prefix + filename, mod_name),
mod_path,
))

View File

@ -305,15 +305,15 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
bl_app_template_utils.reset(reload_scripts=reload_scripts)
del bl_app_template_utils
# deal with addons separately
_initialize = getattr(_addon_utils, "_initialize", None)
if _initialize is not None:
# first time, use fast-path
_initialize()
del _addon_utils._initialize
# Deal with add-ons separately.
_initialize_once = getattr(_addon_utils, "_initialize_once", None)
if _initialize_once is not None:
# First time, use fast-path.
_initialize_once()
del _addon_utils._initialize_once
else:
_addon_utils.reset_all(reload_scripts=reload_scripts)
del _initialize
del _initialize_once
if reload_scripts:
_bpy.context.window_manager.tag_script_reload()

View File

@ -0,0 +1,146 @@
# SPDX-FileCopyrightText: 2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
JunctionModuleHandle creates a module whose sub-modules are not located
in the same directory on the file-system as usual. Instead the sub-modules are
added into the package from different locations on the file-system.
The ``JunctionModuleHandle`` class is used to manipulate sub-modules at run-time.
This is needed to implement package management functionality, repositories can be added/removed at run-time.
"""
__all__ = (
"JunctionModuleHandle",
)
import sys
from types import ModuleType
from typing import (
Dict,
Optional,
Sequence,
Tuple,
)
def _module_file_set(module: ModuleType, name_full: str) -> None:
# File is just an identifier, as this doesn't reference an actual file,
# it just needs to be descriptive.
module.__name__ = name_full
module.__package__ = name_full
module.__file__ = "[{:s}]".format(name_full)
def _module_create(
name: str,
*,
parent: Optional[ModuleType] = None,
doc: Optional[str] = None,
) -> ModuleType:
if parent is not None:
name_full = parent.__name__ + "." + name
else:
name_full = name
module = ModuleType(name, doc)
_module_file_set(module, name_full)
if parent is not None:
setattr(parent, name, module)
return module
class JunctionModuleHandle:
__slots__ = (
"_module_name",
"_module",
"_submodules",
)
def __init__(self, module_name: str):
self._module_name: str = module_name
self._module: Optional[ModuleType] = None
self._submodules: Dict[str, ModuleType] = {}
def submodule_items(self) -> Sequence[Tuple[str, ModuleType]]:
return tuple(self._submodules.items())
def register_module(self) -> ModuleType:
"""
Register the base module in ``sys.modules``.
"""
if self._module is not None:
raise Exception("Module {!r} already registered!".format(self._module))
if self._module_name in sys.modules:
raise Exception("Module {:s} already in 'sys.modules'!".format(self._module_name))
module = _module_create(self._module_name)
sys.modules[self._module_name] = module
# Differentiate this, and allow access to the factory (may be useful).
# `module.__module_factory__ = self`
self._module = module
return module
def unregister_module(self) -> None:
"""
Unregister the base module in ``sys.modules``.
Keep everything except the modules name (allowing re-registration).
"""
# Cleanup `sys.modules`.
sys.modules.pop(self._module_name, None)
for submodule_name in self._submodules.keys():
sys.modules.pop("{:s}.{:s}".format(self._module_name, submodule_name), None)
# Remove from self.
self._submodules.clear()
self._module = None
def register_submodule(self, submodule_name: str, dirpath: str) -> ModuleType:
name_full = self._module_name + "." + submodule_name
if self._module is None:
raise Exception("Module not registered, cannot register a submodule!")
if submodule_name in self._submodules:
raise Exception("Module \"{:s}\" already registered!".format(submodule_name))
# Register.
submodule = _module_create(submodule_name, parent=self._module)
sys.modules[name_full] = submodule
submodule.__path__ = [dirpath]
setattr(self._module, submodule_name, submodule)
self._submodules[submodule_name] = submodule
return submodule
def unregister_submodule(self, submodule_name: str) -> None:
name_full = self._module_name + "." + submodule_name
if self._module is None:
raise Exception("Module not registered, cannot register a submodule!")
# Unregister.
submodule = self._submodules.pop(submodule_name, None)
if submodule is None:
raise Exception("Module \"{:s}\" not registered!".format(submodule_name))
delattr(self._module, submodule_name)
del sys.modules[name_full]
def rename_submodule(self, submodule_name_src: str, submodule_name_dst: str) -> None:
name_full_prev = self._module_name + "." + submodule_name_src
name_full_next = self._module_name + "." + submodule_name_dst
submodule = self._submodules.pop(submodule_name_src)
self._submodules[submodule_name_dst] = submodule
delattr(self._module, submodule_name_src)
setattr(self._module, submodule_name_dst, submodule)
_module_file_set(submodule, name_full_next)
del sys.modules[name_full_prev]
sys.modules[name_full_next] = submodule
def rename_directory(self, submodule_name: str, dirpath: str) -> None:
# TODO: how to deal with existing loaded modules?
# In practice this is mostly users setting up directories for the first time.
submodule = self._submodules[submodule_name]
submodule.__path__ = [dirpath]

View File

@ -58,6 +58,7 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel):
'BLENDER_WORKBENCH_NEXT'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
@ -84,6 +85,36 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel):
col.prop(scene.sequencer_colorspace_settings, "name", text="Sequencer")
class RENDER_PT_color_management_display_settings(RenderButtonsPanel, Panel):
bl_label = "Display"
bl_parent_id = "RENDER_PT_color_management"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {
'BLENDER_RENDER',
'BLENDER_EEVEE',
'BLENDER_EEVEE_NEXT',
'BLENDER_WORKBENCH',
'BLENDER_WORKBENCH_NEXT'}
def draw(self, context):
layout = self.layout
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
scene = context.scene
view = scene.view_settings
# Only enable display sub-section if HDR support is available.
import gpu
layout.enabled = gpu.capabilities.hdr_support_get()
# Only display HDR toggle for non-Filmic display transforms.
col = layout.column(align=True)
sub = col.row()
sub.active = (view.view_transform != "Filmic" and view.view_transform != "Filmic Log")
sub.prop(view, "use_hdr_view")
class RENDER_PT_color_management_curves(RenderButtonsPanel, Panel):
bl_label = "Use Curves"
bl_parent_id = "RENDER_PT_color_management"
@ -1223,6 +1254,7 @@ classes = (
RENDER_PT_opengl_film,
RENDER_PT_hydra_debug,
RENDER_PT_color_management,
RENDER_PT_color_management_display_settings,
RENDER_PT_color_management_curves,
RENDER_PT_simplify,
RENDER_PT_simplify_viewport,

View File

@ -1532,6 +1532,62 @@ class USERPREF_UL_asset_libraries(bpy.types.UIList):
layout.prop(asset_library, "name", text="", emboss=False)
class USERPREF_PT_file_paths_extension_repos(FilePathsPanel, Panel):
bl_label = "Extension Repositories"
@classmethod
def poll(cls, context):
return context.preferences.experimental.use_extension_repos
def draw(self, context):
layout = self.layout
layout.use_property_split = False
layout.use_property_decorate = False
paths = context.preferences.filepaths
active_library_index = paths.active_extension_repo
row = layout.row()
row.template_list(
"USERPREF_UL_extension_repos", "user_extension_repos",
paths, "extension_repos",
paths, "active_extension_repo"
)
col = row.column(align=True)
col.operator("preferences.extension_repo_add", text="", icon='ADD')
props = col.operator("preferences.extension_repo_remove", text="", icon='REMOVE')
props.index = active_library_index
try:
active_repo = None if active_library_index < 0 else paths.extension_repos[active_library_index]
except IndexError:
active_repo = None
if active_repo is None:
return
layout.separator()
layout.prop(active_repo, "directory")
layout.prop(active_repo, "remote_path")
row = layout.row()
row.prop(active_repo, "use_cache")
row.prop(active_repo, "module")
class USERPREF_UL_extension_repos(bpy.types.UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
repo = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(repo, "name", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(repo, "name", text="", emboss=False)
# -----------------------------------------------------------------------------
# Save/Load Panels
@ -2427,6 +2483,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
({"property": "enable_workbench_next"}, ("blender/blender/issues/101619", "#101619")),
({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/6", "Grease Pencil 3.0")),
({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")),
({"property": "use_extension_repos"}, ("/blender/blender/issues/106254", "#106254")),
),
)
@ -2540,6 +2597,7 @@ classes = (
USERPREF_PT_text_editor_presets,
USERPREF_PT_file_paths_development,
USERPREF_PT_file_paths_asset_libraries,
USERPREF_PT_file_paths_extension_repos,
USERPREF_PT_saveload_blend,
USERPREF_PT_saveload_blend_autosave,
@ -2577,6 +2635,7 @@ classes = (
# UI lists
USERPREF_UL_asset_libraries,
USERPREF_UL_extension_repos,
# Add dynamically generated editor theme panels last,
# so they show up last in the theme section.

View File

@ -53,6 +53,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_nla_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_tree_interface_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force_types.h

View File

@ -16,8 +16,8 @@ struct bAddon;
#ifdef __RNA_TYPES_H__
typedef struct bAddonPrefType {
/* type info */
char idname[64]; /* best keep the same size as #BKE_ST_MAXNAME */
/** Type info, match #bAddon::module. */
char idname[128];
/* RNA integration */
ExtensionRNA rna_ext;

View File

@ -109,6 +109,8 @@ typedef enum {
BKE_CB_EVT_COMPOSITE_CANCEL,
BKE_CB_EVT_ANIMATION_PLAYBACK_PRE,
BKE_CB_EVT_ANIMATION_PLAYBACK_POST,
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE,
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
BKE_CB_EVT_TOT,
} eCbEvent;

View File

@ -34,7 +34,6 @@ struct Library;
struct Main;
struct Object;
struct Scene;
struct SceneCollection;
struct ViewLayer;
typedef struct CollectionParent {
@ -322,14 +321,6 @@ void BKE_collection_blend_read_lib(struct BlendLibReader *reader, struct Collect
void BKE_collection_blend_read_expand(struct BlendExpander *expander,
struct Collection *collection);
void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader,
struct SceneCollection *sc);
void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader,
struct ID *self_id,
struct SceneCollection *sc);
void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
struct SceneCollection *sc);
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);

View File

@ -95,8 +95,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
uint8_t runtime_flag = 0;
/**
* Contains a number increased for each nodetree update.
* Store a state variable in the `NestedTreePreviews` structure to compare if they differ.
* Contains a number increased for each node-tree update.
* Store a state variable in the #NestedTreePreviews structure to compare if they differ.
*/
uint32_t previews_refresh_state = 0;

View File

@ -0,0 +1,221 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_tree_interface_types.h"
#include "DNA_node_types.h"
#include "BKE_node.h"
#include <queue>
#include <type_traits>
#include "BLI_parameter_pack_utils.hh"
#include "BLI_vector.hh"
namespace blender::bke {
/* Runtime topology cache for linear access to items. */
struct bNodeTreeInterfaceCache {
Vector<bNodeTreeInterfaceItem *> items;
Vector<bNodeTreeInterfaceSocket *> inputs;
Vector<bNodeTreeInterfaceSocket *> outputs;
void rebuild(bNodeTreeInterface &tree_interface);
};
namespace node_interface {
namespace detail {
template<typename T> static bool item_is_type(const bNodeTreeInterfaceItem &item)
{
bool match = false;
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
match |= std::is_same<T, bNodeTreeInterfaceSocket>::value;
break;
}
case NODE_INTERFACE_PANEL: {
match |= std::is_same<T, bNodeTreeInterfacePanel>::value;
break;
}
}
return match;
}
} // namespace detail
template<typename T> T &get_item_as(bNodeTreeInterfaceItem &item)
{
BLI_assert(detail::item_is_type<T>(item));
return reinterpret_cast<T &>(item);
}
template<typename T> const T &get_item_as(const bNodeTreeInterfaceItem &item)
{
BLI_assert(detail::item_is_type<T>(item));
return reinterpret_cast<const T &>(item);
}
template<typename T> T *get_item_as(bNodeTreeInterfaceItem *item)
{
if (item && detail::item_is_type<T>(*item)) {
return reinterpret_cast<T *>(item);
}
return nullptr;
}
template<typename T> const T *get_item_as(const bNodeTreeInterfaceItem *item)
{
if (item && detail::item_is_type<T>(*item)) {
return reinterpret_cast<const T *>(item);
}
return nullptr;
}
namespace socket_types {
constexpr const char *node_socket_data_float = "NodeSocketFloat";
constexpr const char *node_socket_data_int = "NodeSocketInt";
constexpr const char *node_socket_data_bool = "NodeSocketBool";
constexpr const char *node_socket_data_rotation = "NodeSocketRotation";
constexpr const char *node_socket_data_vector = "NodeSocketVector";
constexpr const char *node_socket_data_color = "NodeSocketColor";
constexpr const char *node_socket_data_string = "NodeSocketString";
constexpr const char *node_socket_data_object = "NodeSocketObject";
constexpr const char *node_socket_data_image = "NodeSocketImage";
constexpr const char *node_socket_data_collection = "NodeSocketCollection";
constexpr const char *node_socket_data_texture = "NodeSocketTexture";
constexpr const char *node_socket_data_material = "NodeSocketMaterial";
template<typename Fn> void socket_data_to_static_type(const char *socket_type, const Fn &fn)
{
if (STREQ(socket_type, socket_types::node_socket_data_float)) {
fn.template operator()<bNodeSocketValueFloat>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_int)) {
fn.template operator()<bNodeSocketValueInt>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_bool)) {
fn.template operator()<bNodeSocketValueBoolean>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_rotation)) {
fn.template operator()<bNodeSocketValueRotation>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_vector)) {
fn.template operator()<bNodeSocketValueVector>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_color)) {
fn.template operator()<bNodeSocketValueRGBA>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_string)) {
fn.template operator()<bNodeSocketValueString>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_object)) {
fn.template operator()<bNodeSocketValueObject>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_image)) {
fn.template operator()<bNodeSocketValueImage>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_collection)) {
fn.template operator()<bNodeSocketValueCollection>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_texture)) {
fn.template operator()<bNodeSocketValueTexture>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_material)) {
fn.template operator()<bNodeSocketValueMaterial>();
}
}
namespace detail {
template<typename Fn> struct TypeTagExecutor {
const Fn &fn;
TypeTagExecutor(const Fn &fn_) : fn(fn_) {}
template<typename T> void operator()() const
{
fn(TypeTag<T>{});
}
};
} // namespace detail
template<typename Fn> void socket_data_to_static_type_tag(const char *socket_type, const Fn &fn)
{
detail::TypeTagExecutor executor{fn};
socket_data_to_static_type(socket_type, executor);
}
} // namespace socket_types
template<typename T> bool socket_data_is_type(const char *socket_type)
{
bool match = false;
socket_types::socket_data_to_static_type_tag(socket_type, [&match](auto type_tag) {
using SocketDataType = typename decltype(type_tag)::type;
match |= std::is_same_v<T, SocketDataType>;
});
return match;
}
template<typename T> T &get_socket_data_as(bNodeTreeInterfaceSocket &item)
{
BLI_assert(socket_data_is_type<T>(item.socket_type));
return *static_cast<T *>(item.socket_data);
}
template<typename T> const T &get_socket_data_as(const bNodeTreeInterfaceSocket &item)
{
BLI_assert(socket_data_is_type<T>(item.socket_type));
return *static_cast<const T *>(item.socket_data);
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode & /*from_node*/,
const bNodeSocket &from_sock,
const StringRefNull socket_type,
const StringRefNull name)
{
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);
bNodeTreeInterfaceSocket *iosock = ntree.tree_interface.add_socket(
name.data(), from_sock.description, socket_type, flag, nullptr);
if (iosock == nullptr) {
return nullptr;
}
const bNodeSocketType *typeinfo = iosock->socket_typeinfo();
if (typeinfo->interface_from_socket) {
/* XXX Enable when bNodeSocketType callbacks have been updated. */
UNUSED_VARS(from_sock);
// typeinfo->interface_from_socket(ntree.id, iosock, &from_node, &from_sock);
}
return iosock;
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode &from_node,
const bNodeSocket &from_sock,
const StringRefNull socket_type)
{
return add_interface_socket_from_node(ntree, from_node, from_sock, socket_type, from_sock.name);
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode &from_node,
const bNodeSocket &from_sock)
{
return add_interface_socket_from_node(
ntree, from_node, from_sock, from_sock.typeinfo->idname, from_sock.name);
}
} // namespace node_interface
} // namespace blender::bke

View File

@ -15,6 +15,7 @@ extern "C" {
#include "BLI_compiler_attrs.h"
struct UserDef;
struct bUserExtensionRepo;
struct bUserAssetLibrary;
/* -------------------------------------------------------------------- */
@ -74,6 +75,31 @@ void BKE_preferences_asset_library_default_add(struct UserDef *userdef) ATTR_NON
/** \} */
/* -------------------------------------------------------------------- */
/** \name Extension Repositories
* \{ */
bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
const char *name,
const char *dirpath);
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo);
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *name);
void BKE_preferences_extension_repo_module_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *module);
void BKE_preferences_extension_repo_path_set(bUserExtensionRepo *repo, const char *path);
bUserExtensionRepo *BKE_preferences_extension_repo_find_index(const UserDef *userdef, int index);
bUserExtensionRepo *BKE_preferences_extension_repo_find_by_module(const UserDef *userdef,
const char *module);
int BKE_preferences_extension_repo_get_index(const UserDef *userdef,
const bUserExtensionRepo *repo);
/** \} */
#ifdef __cplusplus
}
#endif

View File

@ -235,6 +235,7 @@ set(SRC
intern/node_tree_anonymous_attributes.cc
intern/node_tree_dot_export.cc
intern/node_tree_field_inferencing.cc
intern/node_tree_interface.cc
intern/node_tree_update.cc
intern/node_tree_zones.cc
intern/object.cc
@ -454,6 +455,7 @@ set(SRC
BKE_node_runtime.hh
BKE_node_tree_anonymous_attributes.hh
BKE_node_tree_dot_export.hh
BKE_node_tree_interface.hh
BKE_node_tree_update.h
BKE_node_tree_zones.hh
BKE_object.h

View File

@ -730,8 +730,8 @@ static void animsys_blend_in_fcurves(PointerRNA *ptr,
case PROP_ENUM:
value_to_write = roundf(value_to_write);
break;
default: /* All other types are just handled as float, and value_to_write is already
correct. */
/* All other types are just handled as float, and value_to_write is already correct. */
default:
break;
}
}
@ -1072,8 +1072,8 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
return nullptr;
}
break;
case NLASTRIP_TYPE_TRANSITION: /* there must be strips to transition from and to (i.e. prev and
next required) */
/* There must be strips to transition from and to (i.e. `prev` and `next` required). */
case NLASTRIP_TYPE_TRANSITION:
if (ELEM(nullptr, estrip->prev, estrip->next)) {
return nullptr;
}

View File

@ -327,6 +327,7 @@ void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
BLI_freelistN(&userdef->autoexec_paths);
BLI_freelistN(&userdef->script_directories);
BLI_freelistN(&userdef->asset_libraries);
BLI_freelistN(&userdef->extension_repos);
BLI_freelistN(&userdef->uistyles);
BLI_freelistN(&userdef->uifonts);
@ -356,7 +357,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
} \
((void)0)
#define LIST_SWAP(id) \
#define LISTBASE_SWAP(id) \
{ \
SWAP(ListBase, userdef_a->id, userdef_b->id); \
} \
@ -373,12 +374,12 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
} \
((void)0)
LIST_SWAP(uistyles);
LIST_SWAP(uifonts);
LIST_SWAP(themes);
LIST_SWAP(addons);
LIST_SWAP(user_keymaps);
LIST_SWAP(user_keyconfig_prefs);
LISTBASE_SWAP(uistyles);
LISTBASE_SWAP(uifonts);
LISTBASE_SWAP(themes);
LISTBASE_SWAP(addons);
LISTBASE_SWAP(user_keymaps);
LISTBASE_SWAP(user_keyconfig_prefs);
DATA_SWAP(font_path_ui);
DATA_SWAP(font_path_ui_mono);
@ -394,7 +395,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
#undef SWAP_TYPELESS
#undef DATA_SWAP
#undef LIST_SWAP
#undef LISTBASE_SWAP
#undef FLAG_SWAP
}

View File

@ -256,18 +256,6 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a
BKE_collection_blend_write_nolib(writer, collection);
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollection *sc)
{
BLO_read_list(reader, &sc->objects);
BLO_read_list(reader, &sc->scene_collections);
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_data(reader, nsc);
}
}
#endif
void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection, ID *owner_id)
{
/* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
@ -306,19 +294,6 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
BLO_read_data_address(reader, &collection->preview);
BKE_previewimg_blend_read(reader, collection->preview);
#ifdef USE_COLLECTION_COMPAT_28
/* This runs before the very first doversion. */
BLO_read_data_address(reader, &collection->collection);
if (collection->collection != nullptr) {
BKE_collection_compat_blend_read_data(reader, collection->collection);
}
BLO_read_data_address(reader, &collection->view_layer);
if (collection->view_layer != nullptr) {
BKE_view_layer_blend_read_data(reader, collection->view_layer);
}
#endif
}
static void collection_blend_read_data(BlendDataReader *reader, ID *id)
@ -343,32 +318,8 @@ static void lib_link_collection_data(BlendLibReader *reader, ID *self_id, Collec
}
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_lib(BlendLibReader *reader, ID *self_id, SceneCollection *sc)
{
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
BLO_read_id_address(reader, self_id, &link->data);
BLI_assert(link->data);
}
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_lib(reader, self_id, nsc);
}
}
#endif
void BKE_collection_blend_read_lib(BlendLibReader *reader, Collection *collection)
{
#ifdef USE_COLLECTION_COMPAT_28
if (collection->collection) {
BKE_collection_compat_blend_read_lib(reader, &collection->id, collection->collection);
}
if (collection->view_layer) {
BKE_view_layer_blend_read_lib(reader, &collection->id, collection->view_layer);
}
#endif
lib_link_collection_data(reader, &collection->id, collection);
}
@ -378,19 +329,6 @@ static void collection_blend_read_lib(BlendLibReader *reader, ID *id)
BKE_collection_blend_read_lib(reader, collection);
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_expand(BlendExpander *expander, SceneCollection *sc)
{
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
BLO_expand(expander, link->data);
}
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_expand(expander, nsc);
}
}
#endif
void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *collection)
{
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
@ -400,12 +338,6 @@ void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *colle
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
BLO_expand(expander, child->collection);
}
#ifdef USE_COLLECTION_COMPAT_28
if (collection->collection != nullptr) {
BKE_collection_compat_blend_read_expand(expander, collection->collection);
}
#endif
}
static void collection_blend_read_expand(BlendExpander *expander, ID *id)

View File

@ -225,12 +225,14 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
/* Skip if trying to copy from old boundary cell. */
if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth) {
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth)
{
continue;
}
/* Skip if trying to copy into new boundary cell. */
if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth) {
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth)
{
continue;
}
# endif

View File

@ -1482,95 +1482,125 @@ bool GreasePencil::insert_duplicate_frame(blender::bke::greasepencil::Layer &lay
return true;
}
bool GreasePencil::remove_frame_at(blender::bke::greasepencil::Layer &layer,
const int frame_number)
bool GreasePencil::remove_frames(blender::bke::greasepencil::Layer &layer,
blender::Span<int> frame_numbers)
{
using namespace blender::bke::greasepencil;
if (!layer.frames().contains(frame_number)) {
return false;
bool removed_any_drawing_user = false;
for (const int frame_number : frame_numbers) {
if (!layer.frames().contains(frame_number)) {
continue;
}
const GreasePencilFrame frame_to_remove = layer.frames().lookup(frame_number);
const int64_t drawing_index_to_remove = frame_to_remove.drawing_index;
if (!layer.remove_frame(frame_number)) {
/* If removing the frame was not successful, continue. */
continue;
}
if (frame_to_remove.is_null()) {
/* Null frames don't reference a drawing, continue. */
continue;
}
GreasePencilDrawingBase *drawing_base = this->drawings(drawing_index_to_remove);
if (drawing_base->type != GP_DRAWING) {
/* If the drawing is referenced from another object, we don't track it's users because we
* cannot delete drawings from another object. */
continue;
}
Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base)->wrap();
drawing.remove_user();
removed_any_drawing_user = true;
}
const GreasePencilFrame &frame_to_remove = layer.frames().lookup(frame_number);
const int drawing_index_to_remove = frame_to_remove.drawing_index;
if (!layer.remove_frame(frame_number)) {
/* If removing the frame was not successful, return early. */
return false;
if (removed_any_drawing_user) {
this->remove_drawings_with_no_users();
return true;
}
GreasePencilDrawingBase *drawing_base = this->drawings(drawing_index_to_remove);
if (drawing_base->type != GP_DRAWING) {
/* If the drawing is referenced from another object, we don't track it's users because we
* cannot delete drawings from another object. Return early. */
return false;
}
Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base)->wrap();
drawing.remove_user();
if (!drawing.has_users()) {
this->remove_drawing(drawing_index_to_remove);
}
return true;
return false;
}
void GreasePencil::remove_drawing(const int index_to_remove)
static void remove_drawings_unchecked(GreasePencil &grease_pencil,
Span<int64_t> sorted_indices_to_remove)
{
using namespace blender::bke::greasepencil;
/* In order to not change the indices of the drawings, we do the following to the drawing to be
* removed:
* - If the drawing (A) is not the last one:
* 1.1) Find any frames in the layers that reference the last drawing (B) and point them to
* A's index.
* 1.2) Swap drawing A with drawing B.
* 2) Destroy A and shrink the array by one.
* 3) Remove any frames in the layers that reference the A's index.
*/
BLI_assert(this->drawing_array_num > 0);
BLI_assert(index_to_remove >= 0 && index_to_remove < this->drawing_array_num);
if (grease_pencil.drawing_array_num == 0 || sorted_indices_to_remove.size() == 0) {
return;
}
const int64_t drawings_to_remove = sorted_indices_to_remove.size();
const blender::IndexRange last_drawings_range(
grease_pencil.drawings().size() - drawings_to_remove, drawings_to_remove);
/* Move the drawing that should be removed to the last index. */
const int last_drawing_index = this->drawing_array_num - 1;
if (index_to_remove != last_drawing_index) {
for (Layer *layer : this->layers_for_write()) {
blender::Map<int, GreasePencilFrame> &frames = layer->frames_for_write();
for (auto [key, value] : frames.items()) {
if (value.drawing_index == last_drawing_index) {
/* We keep track of the next available index (for swapping) by iterating from the end and
* skipping over drawings that are already in the range to be removed. */
auto next_available_index = last_drawings_range.last();
auto greatest_index_to_remove_it = std::rbegin(sorted_indices_to_remove);
auto get_next_available_index = [&]() {
while (next_available_index == *greatest_index_to_remove_it) {
greatest_index_to_remove_it = std::prev(greatest_index_to_remove_it);
next_available_index--;
}
return next_available_index;
};
/* Move the drawings to be removed to the end of the array by swapping the pointers. Make sure to
* remap any frames pointing to the drawings being swapped. */
for (const int64_t index_to_remove : sorted_indices_to_remove) {
if (index_to_remove >= last_drawings_range.first()) {
/* This drawing and all the next drawings are already in the range to be removed. */
break;
}
const int64_t swap_index = get_next_available_index();
/* Remap the drawing_index for frames that point to the drawing to be swapped with. */
for (Layer *layer : grease_pencil.layers_for_write()) {
for (auto [key, value] : layer->frames_for_write().items()) {
if (value.drawing_index == swap_index) {
value.drawing_index = index_to_remove;
}
else if (value.drawing_index == index_to_remove) {
value.drawing_index = last_drawing_index;
}
}
}
std::swap(this->drawings()[index_to_remove], this->drawings()[last_drawing_index]);
/* Swap the pointers to the drawings in the drawing array. */
std::swap(grease_pencil.drawings()[index_to_remove], grease_pencil.drawings()[swap_index]);
next_available_index--;
}
/* Delete the last drawing. */
GreasePencilDrawingBase *drawing_base_to_remove = this->drawings(last_drawing_index);
switch (drawing_base_to_remove->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing_to_remove = reinterpret_cast<GreasePencilDrawing *>(
drawing_base_to_remove);
MEM_delete(&drawing_to_remove->wrap());
break;
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference_to_remove =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base_to_remove);
MEM_freeN(drawing_reference_to_remove);
break;
}
}
/* Remove any frame that points to the last drawing. */
for (Layer *layer : this->layers_for_write()) {
blender::Map<int, GreasePencilFrame> &frames = layer->frames_for_write();
int64_t frames_removed = frames.remove_if([last_drawing_index](auto item) {
return item.value.drawing_index == last_drawing_index;
});
if (frames_removed > 0) {
layer->tag_frames_map_keys_changed();
/* Free the last drawings. */
for (const int64_t drawing_index : last_drawings_range) {
GreasePencilDrawingBase *drawing_base_to_remove = grease_pencil.drawings(drawing_index);
switch (drawing_base_to_remove->type) {
case GP_DRAWING: {
GreasePencilDrawing *drawing_to_remove = reinterpret_cast<GreasePencilDrawing *>(
drawing_base_to_remove);
MEM_delete(&drawing_to_remove->wrap());
break;
}
case GP_DRAWING_REFERENCE: {
GreasePencilDrawingReference *drawing_reference_to_remove =
reinterpret_cast<GreasePencilDrawingReference *>(drawing_base_to_remove);
MEM_freeN(drawing_reference_to_remove);
break;
}
}
}
/* Shrink drawing array. */
shrink_array<GreasePencilDrawingBase *>(&this->drawing_array, &this->drawing_array_num, 1);
shrink_array<GreasePencilDrawingBase *>(
&grease_pencil.drawing_array, &grease_pencil.drawing_array_num, drawings_to_remove);
}
void GreasePencil::remove_drawings_with_no_users()
{
using namespace blender;
Vector<int64_t> drawings_to_be_removed;
for (const int64_t drawing_i : this->drawings().index_range()) {
GreasePencilDrawingBase *drawing_base = this->drawings(drawing_i);
if (drawing_base->type != GP_DRAWING) {
continue;
}
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
if (!drawing->wrap().has_users()) {
drawings_to_be_removed.append(drawing_i);
}
}
remove_drawings_unchecked(*this, drawings_to_be_removed.as_span());
}
blender::bke::greasepencil::Drawing *GreasePencil::get_editable_drawing_at(
@ -1895,10 +1925,15 @@ void GreasePencil::remove_layer(blender::bke::greasepencil::Layer &layer)
layer.parent_group().unlink_node(&layer.as_node());
/* Remove drawings. */
/* TODO: In the future this should only remove drawings when the user count hits zero. */
for (GreasePencilFrame frame : layer.frames_for_write().values()) {
this->remove_drawing(frame.drawing_index);
GreasePencilDrawingBase *drawing_base = this->drawings(frame.drawing_index);
if (drawing_base->type != GP_DRAWING) {
continue;
}
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(drawing_base);
drawing->wrap().remove_user();
}
this->remove_drawings_with_no_users();
/* Delete the layer. */
MEM_delete(&layer);

View File

@ -53,7 +53,7 @@ TEST(greasepencil, add_empty_drawings)
EXPECT_EQ(grease_pencil.drawings().size(), 3);
}
TEST(greasepencil, remove_drawing)
TEST(greasepencil, remove_drawings)
{
GreasePencilIDTestContext ctx;
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(BKE_id_new(ctx.bmain, ID_GP, "GP"));
@ -61,7 +61,7 @@ TEST(greasepencil, remove_drawing)
GreasePencilDrawing *drawing = reinterpret_cast<GreasePencilDrawing *>(
grease_pencil.drawings(1));
drawing->geometry.wrap().resize(0, 10);
drawing->wrap().strokes_for_write().resize(0, 10);
Layer &layer1 = grease_pencil.root_group().add_layer("Layer1");
Layer &layer2 = grease_pencil.root_group().add_layer("Layer2");
@ -71,8 +71,10 @@ TEST(greasepencil, remove_drawing)
layer1.add_frame(20, 2);
layer2.add_frame(0, 1);
drawing->wrap().add_user();
grease_pencil.remove_drawing(1);
grease_pencil.remove_frames(layer1, {10});
grease_pencil.remove_frames(layer2, {0});
EXPECT_EQ(grease_pencil.drawings().size(), 2);
static int expected_frames_size[] = {2, 0};

View File

@ -2399,10 +2399,6 @@ static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb,
{
BLO_read_list(reader, lb);
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
#ifdef USE_COLLECTION_COMPAT_28
BLO_read_data_address(reader, &lc->scene_collection);
#endif
/* Master collection is not a real data-block. */
if (master) {
BLO_read_data_address(reader, &lc->collection);

File diff suppressed because it is too large Load Diff

View File

@ -1562,51 +1562,27 @@ float BKE_ocean_jminus_to_foam(float /*jminus*/, float /*coverage*/)
return 0.0f;
}
void BKE_ocean_eval_uv(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*u*/,
float /*v*/)
{
}
void BKE_ocean_eval_uv(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*u*/, float /*v*/) {}
/* use catmullrom interpolation rather than linear */
void BKE_ocean_eval_uv_catrom(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*u*/,
float /*v*/)
{
}
void BKE_ocean_eval_uv_catrom(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*u*/, float /*v*/) {}
void BKE_ocean_eval_xz(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*x*/,
float /*z*/)
{
}
void BKE_ocean_eval_xz(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*x*/, float /*z*/) {}
void BKE_ocean_eval_xz_catrom(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*x*/,
float /*z*/)
{
}
void BKE_ocean_eval_xz_catrom(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*x*/, float /*z*/) {}
void BKE_ocean_eval_ij(struct Ocean * /*oc*/, struct OceanResult * /*ocr*/, int /*i*/, int /*j*/)
{
}
void BKE_ocean_eval_ij(Ocean * /*oc*/, OceanResult * /*ocr*/, int /*i*/, int /*j*/) {}
void BKE_ocean_simulate(struct Ocean * /*o*/, float /*t*/, float /*scale*/, float /*chop_amount*/)
{
}
void BKE_ocean_simulate(Ocean * /*o*/, float /*t*/, float /*scale*/, float /*chop_amount*/) {}
struct Ocean *BKE_ocean_add()
Ocean *BKE_ocean_add()
{
Ocean *oc = static_cast<Ocean *>(MEM_callocN(sizeof(Ocean), "ocean sim data"));
return oc;
}
bool BKE_ocean_init(struct Ocean * /*o*/,
bool BKE_ocean_init(Ocean * /*o*/,
int /*M*/,
int /*N*/,
float /*Lx*/,
@ -1632,9 +1608,9 @@ bool BKE_ocean_init(struct Ocean * /*o*/,
return false;
}
void BKE_ocean_free_data(struct Ocean * /*oc*/) {}
void BKE_ocean_free_data(Ocean * /*oc*/) {}
void BKE_ocean_free(struct Ocean *oc)
void BKE_ocean_free(Ocean *oc)
{
if (!oc) {
return;
@ -1644,7 +1620,7 @@ void BKE_ocean_free(struct Ocean *oc)
/* ********* Baking/Caching ********* */
void BKE_ocean_free_cache(struct OceanCache *och)
void BKE_ocean_free_cache(OceanCache *och)
{
if (!och) {
return;
@ -1654,12 +1630,12 @@ void BKE_ocean_free_cache(struct OceanCache *och)
}
void BKE_ocean_cache_eval_uv(
struct OceanCache * /*och*/, struct OceanResult * /*ocr*/, int /*f*/, float /*u*/, float /*v*/)
OceanCache * /*och*/, OceanResult * /*ocr*/, int /*f*/, float /*u*/, float /*v*/)
{
}
void BKE_ocean_cache_eval_ij(
struct OceanCache * /*och*/, struct OceanResult * /*ocr*/, int /*f*/, int /*i*/, int /*j*/)
OceanCache * /*och*/, OceanResult * /*ocr*/, int /*f*/, int /*i*/, int /*j*/)
{
}
@ -1678,10 +1654,10 @@ OceanCache *BKE_ocean_init_cache(const char * /*bakepath*/,
return och;
}
void BKE_ocean_simulate_cache(struct OceanCache * /*och*/, int /*frame*/) {}
void BKE_ocean_simulate_cache(OceanCache * /*och*/, int /*frame*/) {}
void BKE_ocean_bake(struct Ocean * /*o*/,
struct OceanCache * /*och*/,
void BKE_ocean_bake(Ocean * /*o*/,
OceanCache * /*och*/,
void (*update_cb)(void *, float progress, int *cancel),
void * /*update_cb_data*/)
{
@ -1689,8 +1665,8 @@ void BKE_ocean_bake(struct Ocean * /*o*/,
(void)update_cb;
}
bool BKE_ocean_init_from_modifier(struct Ocean * /*ocean*/,
struct OceanModifierData const * /*omd*/,
bool BKE_ocean_init_from_modifier(Ocean * /*ocean*/,
OceanModifierData const * /*omd*/,
int /*resolution*/)
{
return true;

View File

@ -4360,8 +4360,8 @@ static void particles_fluid_step(ParticleSimulationData *sim,
return;
}
# if 0
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
# endif
/* Type of particle must match current particle system type
@ -4379,8 +4379,8 @@ printf("system type is %d and particle type is %d\n", part->type, flagActivePart
continue;
}
# if 0
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
# endif
/* Particle system has allocated 'tottypepart' particles - so break early before exceeded.
*/
@ -4438,16 +4438,22 @@ printf("system type is %d and particle type is %d\n", part->type, flagActivePart
mul_v3_v3(tmp, ob->scale);
add_v3_v3(pa->state.co, tmp);
# if 0
/* Debugging: Print particle coordinates. */
printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n", pa->state.co[0], pa->state.co[1], pa->state.co[2]);
/* Debugging: Print particle coordinates. */
printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n",
pa->state.co[0],
pa->state.co[1],
pa->state.co[2]);
# endif
/* Set particle velocity. */
const float velParticle[3] = {velX, velY, velZ};
copy_v3_v3(pa->state.vel, velParticle);
mul_v3_fl(pa->state.vel, fds->dx);
# if 0
/* Debugging: Print particle velocity. */
printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n", pa->state.vel[0], pa->state.vel[1], pa->state.vel[2]);
/* Debugging: Print particle velocity. */
printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n",
pa->state.vel[0],
pa->state.vel[1],
pa->state.vel[2]);
# endif
/* Set default angular velocity and particle rotation. */
zero_v3(pa->state.ave);
@ -4463,8 +4469,8 @@ printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n", pa-
}
}
# if 0
/* Debugging: Print number of active particles. */
printf("active parts: %d\n", activeParts);
/* Debugging: Print number of active particles. */
printf("active parts: %d\n", activeParts);
# endif
totpart = psys->totpart = part->totpart = activeParts;

View File

@ -126,3 +126,128 @@ void BKE_preferences_asset_library_default_add(UserDef *userdef)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Extension Repositories
* \{ */
/**
* A string copy that ensures: `[A-Za-z]+[A-Za-z0-9_]*`.
*/
static size_t strncpy_py_module(char *dst, const char *src, const size_t dst_maxncpy)
{
const size_t dst_len_max = dst_maxncpy - 1;
dst[0] = '\0';
size_t i_src = 0, i_dst = 0;
while (src[i_src] && (i_dst < dst_len_max)) {
const char c = src[i_src++];
const bool is_alpha = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
/* The first character must be `[a-zA-Z]`. */
if (i_dst == 0 && !is_alpha) {
continue;
}
const bool is_num = (is_alpha == false) && ((c >= '0' && c <= '9') || c == '_');
if (!(is_alpha || is_num)) {
continue;
}
dst[i_dst++] = c;
}
dst[i_dst] = '\0';
return i_dst;
}
bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
const char *name,
const char *dirpath)
{
bUserExtensionRepo *repo = DNA_struct_default_alloc(bUserExtensionRepo);
BLI_addtail(&userdef->extension_repos, repo);
/* Set the unique ID-name. */
BKE_preferences_extension_repo_name_set(userdef, repo, name);
/* Set the unique module-name. */
BKE_preferences_extension_repo_module_set(userdef, repo, name);
/* Set the directory. */
STRNCPY(repo->dirpath, dirpath);
BLI_path_normalize(repo->dirpath);
BLI_path_slash_rstrip(repo->dirpath);
/* While not a strict rule, ignored paths that already exist, *
* pointing to the same path is going to logical problems with package-management. */
LISTBASE_FOREACH (const bUserExtensionRepo *, repo_iter, &userdef->extension_repos) {
if (repo == repo_iter) {
continue;
}
if (BLI_path_cmp(repo->dirpath, repo_iter->dirpath) == 0) {
repo->dirpath[0] = '\0';
break;
}
}
return repo;
}
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo)
{
BLI_freelinkN(&userdef->extension_repos, repo);
}
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *name)
{
if (*name == '\0') {
name = "User Repository";
}
STRNCPY_UTF8(repo->name, name);
BLI_uniquename(&userdef->extension_repos,
repo,
name,
'.',
offsetof(bUserExtensionRepo, name),
sizeof(repo->name));
}
void BKE_preferences_extension_repo_module_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *module)
{
if (strncpy_py_module(repo->module, module, sizeof(repo->module)) == 0) {
STRNCPY(repo->module, "repository");
}
BLI_uniquename(&userdef->extension_repos,
repo,
module,
'_',
offsetof(bUserExtensionRepo, module),
sizeof(repo->module));
}
void BKE_preferences_extension_repo_path_set(bUserExtensionRepo *repo, const char *path)
{
STRNCPY(repo->dirpath, path);
}
bUserExtensionRepo *BKE_preferences_extension_repo_find_index(const UserDef *userdef, int index)
{
return static_cast<bUserExtensionRepo *>(BLI_findlink(&userdef->extension_repos, index));
}
bUserExtensionRepo *BKE_preferences_extension_repo_find_by_module(const UserDef *userdef,
const char *module)
{
return static_cast<bUserExtensionRepo *>(
BLI_findstring(&userdef->extension_repos, module, offsetof(bUserExtensionRepo, module)));
}
int BKE_preferences_extension_repo_get_index(const UserDef *userdef,
const bUserExtensionRepo *repo)
{
return BLI_findindex(&userdef->extension_repos, repo);
}
/** \} */

View File

@ -2397,29 +2397,25 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
{
zero_v3(r_center);
}
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
{
return nullptr;
}
struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
{
return nullptr;
}
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw,
RigidbodyWorldIDFunc func,
void *userdata)
{
}
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
{
return nullptr;
}
struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
{
return nullptr;
}
struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
{
return nullptr;
}
@ -2432,9 +2428,7 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
return false;
}
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
}
void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bool free_us) {}
void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us) {}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
void BKE_rigidbody_aftertrans_update(

View File

@ -1486,14 +1486,6 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BKE_curvemapping_blend_read(reader, &sce->r.mblur_shutter_curve);
#ifdef USE_COLLECTION_COMPAT_28
/* this runs before the very first doversion */
if (sce->collection) {
BLO_read_data_address(reader, &sce->collection);
BKE_collection_compat_blend_read_data(reader, sce->collection);
}
#endif
/* insert into global old-new map for reading without UI (link_global accesses it again) */
BLO_read_glob_list(reader, &sce->view_layers);
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
@ -1651,12 +1643,6 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
/* Motion Tracking */
BLO_read_id_address(reader, id, &sce->clip);
#ifdef USE_COLLECTION_COMPAT_28
if (sce->collection) {
BKE_collection_compat_blend_read_lib(reader, id, sce->collection);
}
#endif
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
BKE_view_layer_blend_read_lib(reader, id, view_layer);
}
@ -1743,12 +1729,6 @@ static void scene_blend_read_expand(BlendExpander *expander, ID *id)
BLO_expand(expander, sce->clip);
#ifdef USE_COLLECTION_COMPAT_28
if (sce->collection) {
BKE_collection_compat_blend_read_expand(expander, sce->collection);
}
#endif
if (sce->r.bake.cage_object) {
BLO_expand(expander, sce->r.bake.cage_object);
}

View File

@ -2275,7 +2275,8 @@ static void softbody_calc_forces(
/* check conditions for various options */
do_deflector = query_external_colliders(depsgraph, sb->collision_group);
#if 0
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_selfcollision = ((ob->softflag & OB_SB_EDGES) && (sb->bspring) &&
(ob->softflag & OB_SB_SELF));
#endif
do_springcollision = do_deflector && (ob->softflag & OB_SB_EDGES) &&
(ob->softflag & OB_SB_EDGECOLL);

View File

@ -458,71 +458,38 @@ void BKE_sound_exit_once()
# if 0
bSound *BKE_sound_new_buffer(Main *bmain, bSound *source)
{
bSound *sound = nullptr;
bSound *sound = nullptr;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "buf_", source->id.name);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->type = SOUND_TYPE_BUFFER;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "buf_", source->id.name);
sound_load(bmain, sound);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->type = SOUND_TYPE_BUFFER;
sound_load(bmain, sound);
return sound;
return sound;
}
bSound *BKE_sound_new_limiter(Main *bmain, bSound *source, float start, float end)
{
bSound *sound = nullptr;
bSound *sound = nullptr;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "lim_", source->id.name);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->start = start;
sound->end = end;
sound->type = SOUND_TYPE_LIMITER;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "lim_", source->id.name);
sound_load(bmain, sound);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->start = start;
sound->end = end;
sound->type = SOUND_TYPE_LIMITER;
sound_load(bmain, sound);
return sound;
return sound;
}
# endif
@ -572,8 +539,8 @@ static void sound_load_audio(Main *bmain, bSound *sound, bool free_waveform)
/* XXX unused currently */
# if 0
switch (sound->type) {
case SOUND_TYPE_FILE:
switch (sound->type) {
case SOUND_TYPE_FILE:
# endif
{
char fullpath[FILE_MAX];
@ -596,16 +563,18 @@ case SOUND_TYPE_FILE:
}
/* XXX unused currently */
# if 0
break;
}
case SOUND_TYPE_BUFFER: if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_bufferSound(sound->child_sound->handle);
}
break;
case SOUND_TYPE_LIMITER: if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
}
break;
break;
}
case SOUND_TYPE_BUFFER:
if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_bufferSound(sound->child_sound->handle);
}
break;
case SOUND_TYPE_LIMITER:
if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
}
break;
}
# endif
if (sound->flags & SOUND_FLAGS_MONO) {
@ -1332,17 +1301,17 @@ bool BKE_sound_stream_info_get(Main *main,
# include "BLI_utildefines.h"
void BKE_sound_force_device(const char * /*device*/) {}
void BKE_sound_init_once(void) {}
void BKE_sound_init_once() {}
void BKE_sound_init(Main * /*bmain*/) {}
void BKE_sound_exit(void) {}
void BKE_sound_exit_once(void) {}
void BKE_sound_exit() {}
void BKE_sound_exit_once() {}
void BKE_sound_cache(bSound * /*sound*/) {}
void BKE_sound_delete_cache(bSound * /*sound*/) {}
void BKE_sound_load(Main * /*bmain*/, bSound * /*sound*/) {}
void BKE_sound_create_scene(Scene * /*scene*/) {}
void BKE_sound_destroy_scene(Scene * /*scene*/) {}
void BKE_sound_lock(void) {}
void BKE_sound_unlock(void) {}
void BKE_sound_lock() {}
void BKE_sound_unlock() {}
void BKE_sound_reset_scene_specs(Scene * /*scene*/) {}
void BKE_sound_mute_scene(Scene * /*scene*/, int /*muted*/) {}
void *BKE_sound_scene_add_scene_sound(Scene * /*scene*/,
@ -1421,7 +1390,7 @@ void BKE_sound_set_scene_sound_pitch_constant_range(void * /*handle*/,
float /*pitch*/)
{
}
float BKE_sound_get_length(struct Main * /*bmain*/, bSound * /*sound*/)
float BKE_sound_get_length(Main * /*bmain*/, bSound * /*sound*/)
{
return 0;
}
@ -1433,14 +1402,12 @@ char **BKE_sound_get_device_names()
void BKE_sound_free_waveform(bSound * /*sound*/) {}
bool BKE_sound_info_get(struct Main * /*main*/,
struct bSound * /*sound*/,
SoundInfo * /*sound_info*/)
bool BKE_sound_info_get(Main * /*main*/, bSound * /*sound*/, SoundInfo * /*sound_info*/)
{
return false;
}
bool BKE_sound_stream_info_get(struct Main * /*main*/,
bool BKE_sound_stream_info_get(Main * /*main*/,
const char * /*filepath*/,
int /*stream*/,
SoundStreamInfo * /*sound_info*/)

View File

@ -146,7 +146,7 @@ static bUnitDef buMetricLenDef[] = {
{"decimeter", "decimeters", "dm", nullptr, "10 Centimeters", "DECIMETERS", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"centimeter", "centimeters", "cm", nullptr, "Centimeters", "CENTIMETERS", UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"millimeter", "millimeters", "mm", nullptr, "Millimeters", "MILLIMETERS", UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, {"micrometer", "micrometers", "µm", "um", "Micrometers", "MICROMETERS", UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
/* These get displayed because of float precision problems in the transform header,
* could work around, but for now probably people won't use these. */
* could work around, but for now probably people won't use these. */
#if 0
{"nanometer", "Nanometers", "nm", nullptr, 0.000000001, 0.0, B_UNIT_DEF_NONE}, {"picometer", "Picometers", "pm", nullptr, 0.000000000001, 0.0, B_UNIT_DEF_NONE},
#endif
@ -201,10 +201,8 @@ static bUnitDef buImperialMassDef[] = {
{"ounce", "ounces", "oz", nullptr, "Ounces", "OUNCES", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE}, NULL_UNIT, };
static bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, UNIT_COLLECTION_LENGTH(buImperialMassDef)};
/* Even if user scales the system to a point where km^3 is used, velocity and
* acceleration aren't scaled: that's why we have so few units for them. */
* acceleration aren't scaled: that's why we have so few units for them. */
/* Velocity. */
static bUnitDef buMetricVelDef[] = {

View File

@ -12,9 +12,15 @@
#if defined(__ARM_NEON) && defined(WITH_SSE2NEON)
/* SSE/SSE2 emulation on ARM Neon. Match SSE precision. */
# define SSE2NEON_PRECISE_MINMAX 1
# define SSE2NEON_PRECISE_DIV 1
# define SSE2NEON_PRECISE_SQRT 1
# if !defined(SSE2NEON_PRECISE_MINMAX)
# define SSE2NEON_PRECISE_MINMAX 1
# endif
# if !defined(SSE2NEON_PRECISE_DIV)
# define SSE2NEON_PRECISE_DIV 1
# endif
# if !defined(SSE2NEON_PRECISE_SQRT)
# define SSE2NEON_PRECISE_SQRT 1
# endif
# include <sse2neon.h>
# define BLI_HAVE_SSE2 1
#elif defined(__SSE2__)

View File

@ -53,6 +53,15 @@ char *BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESU
*/
char *BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC;
/**
* Duplicates the C-string \a str into a newly mallocN'd
* string and returns it.
*
* \param str: The string to be duplicated, can be null
* \retval Returns the duplicated string or null if \a str is null
*/
char *BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC;
/**
* Appends the two strings, and returns new mallocN'ed string
* \param str1: first string for copy

View File

@ -795,14 +795,15 @@ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *pre
float projmat_trans[4][4];
transpose_m4_m4(projmat_trans, projmat);
if (!isect_plane_plane_plane_v3(
projmat_trans[0], projmat_trans[1], projmat_trans[3], precalc->ray_origin)) {
projmat_trans[0], projmat_trans[1], projmat_trans[3], precalc->ray_origin))
{
/* Orthographic projection. */
isect_plane_plane_v3(px, py, precalc->ray_origin, precalc->ray_direction);
}
else {
/* Perspective projection. */
cross_v3_v3v3(precalc->ray_direction, py, px);
//normalize_v3(precalc->ray_direction);
// normalize_v3(precalc->ray_direction);
}
#else
if (!isect_plane_plane_v3(px, py, precalc->ray_origin, precalc->ray_direction)) {
@ -1870,7 +1871,7 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3],
* otherwise we won't match any of the other intersect functions here...
* which would be confusing. */
#if 0
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
)
{

View File

@ -42,6 +42,11 @@ char *BLI_strdup(const char *str)
return BLI_strdupn(str, strlen(str));
}
char *BLI_strdup_null(const char *str)
{
return (str != NULL) ? BLI_strdupn(str, strlen(str)) : NULL;
}
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
/* include the NULL terminator of str2 only */

View File

@ -3377,6 +3377,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
BLO_read_list(reader, &user->autoexec_paths);
BLO_read_list(reader, &user->script_directories);
BLO_read_list(reader, &user->asset_libraries);
BLO_read_list(reader, &user->extension_repos);
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
keymap->modal_items = nullptr;

File diff suppressed because it is too large Load Diff

View File

@ -251,168 +251,6 @@ static void do_version_workspaces_after_lib_link(Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
enum {
COLLECTION_DEPRECATED_VISIBLE = (1 << 0),
COLLECTION_DEPRECATED_VIEWPORT = (1 << 0),
COLLECTION_DEPRECATED_SELECTABLE = (1 << 1),
COLLECTION_DEPRECATED_DISABLED = (1 << 2),
COLLECTION_DEPRECATED_RENDER = (1 << 3),
};
static void do_version_view_layer_visibility(ViewLayer *view_layer)
{
/* Convert from deprecated VISIBLE flag to DISABLED */
LISTBASE_FOREACH (LayerCollection *, lc, &view_layer->layer_collections) {
if (lc->flag & COLLECTION_DEPRECATED_DISABLED) {
lc->flag &= ~COLLECTION_DEPRECATED_DISABLED;
}
if ((lc->flag & COLLECTION_DEPRECATED_VISIBLE) == 0) {
lc->flag |= COLLECTION_DEPRECATED_DISABLED;
}
lc->flag |= COLLECTION_DEPRECATED_VIEWPORT | COLLECTION_DEPRECATED_RENDER;
}
}
static void do_version_layer_collection_pre(ViewLayer *view_layer,
ListBase *lb,
GSet *enabled_set,
GSet *selectable_set)
{
/* Convert from deprecated DISABLED to new layer collection and collection flags */
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
if (lc->scene_collection) {
if (!(lc->flag & COLLECTION_DEPRECATED_DISABLED)) {
BLI_gset_insert(enabled_set, lc->scene_collection);
}
if (lc->flag & COLLECTION_DEPRECATED_SELECTABLE) {
BLI_gset_insert(selectable_set, lc->scene_collection);
}
}
do_version_layer_collection_pre(
view_layer, &lc->layer_collections, enabled_set, selectable_set);
}
}
static void do_version_layer_collection_post(ViewLayer *view_layer,
ListBase *lb,
GSet *enabled_set,
GSet *selectable_set,
GHash *collection_map)
{
/* Apply layer collection exclude flags. */
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
if (!(lc->collection->flag & COLLECTION_IS_MASTER)) {
SceneCollection *sc = static_cast<SceneCollection *>(
BLI_ghash_lookup(collection_map, lc->collection));
const bool enabled = (sc && BLI_gset_haskey(enabled_set, sc));
const bool selectable = (sc && BLI_gset_haskey(selectable_set, sc));
if (!enabled) {
lc->flag |= LAYER_COLLECTION_EXCLUDE;
}
if (enabled && !selectable) {
lc->collection->flag |= COLLECTION_HIDE_SELECT;
}
}
do_version_layer_collection_post(
view_layer, &lc->layer_collections, enabled_set, selectable_set, collection_map);
}
}
static void do_version_scene_collection_convert(
Main *bmain, ID *id, SceneCollection *sc, Collection *collection, GHash *collection_map)
{
if (collection_map) {
BLI_ghash_insert(collection_map, collection, sc);
}
for (SceneCollection *nsc = static_cast<SceneCollection *>(sc->scene_collections.first);
nsc != nullptr;)
{
SceneCollection *nsc_next = nsc->next;
Collection *ncollection = BKE_collection_add(bmain, collection, nsc->name);
ncollection->id.lib = id->lib;
do_version_scene_collection_convert(bmain, id, nsc, ncollection, collection_map);
nsc = nsc_next;
}
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
Object *ob = static_cast<Object *>(link->data);
if (ob) {
BKE_collection_object_add_notest(bmain, collection, ob);
id_us_min(&ob->id);
}
}
BLI_freelistN(&sc->objects);
MEM_freeN(sc);
}
static void do_version_group_collection_to_collection(Main *bmain, Collection *group)
{
/* Convert old 2.8 group collections to new unified collections. */
if (group->collection) {
do_version_scene_collection_convert(bmain, &group->id, group->collection, group, nullptr);
}
group->collection = nullptr;
group->view_layer = nullptr;
id_fake_user_set(&group->id);
}
static void do_version_scene_collection_to_collection(Main *bmain, Scene *scene)
{
/* Convert old 2.8 scene collections to new unified collections. */
/* Temporarily clear view layers so we don't do any layer collection syncing
* and destroy old flags that we want to restore. */
ListBase view_layers = scene->view_layers;
BLI_listbase_clear(&scene->view_layers);
if (!scene->master_collection) {
scene->master_collection = BKE_collection_master_add(scene);
}
/* Convert scene collections. */
GHash *collection_map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
if (scene->collection) {
do_version_scene_collection_convert(
bmain, &scene->id, scene->collection, scene->master_collection, collection_map);
scene->collection = nullptr;
}
scene->view_layers = view_layers;
/* Convert layer collections. */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
GSet *enabled_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
GSet *selectable_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
do_version_layer_collection_pre(
view_layer, &view_layer->layer_collections, enabled_set, selectable_set);
BKE_layer_collection_doversion_2_80(scene, view_layer);
BKE_layer_collection_sync(scene, view_layer);
do_version_layer_collection_post(
view_layer, &view_layer->layer_collections, enabled_set, selectable_set, collection_map);
BLI_gset_free(enabled_set, nullptr);
BLI_gset_free(selectable_set, nullptr);
BKE_layer_collection_sync(scene, view_layer);
}
BLI_ghash_free(collection_map, nullptr, nullptr);
}
#endif
static void do_version_layers_to_collections(Main *bmain, Scene *scene)
{
/* Since we don't have access to FileData we check the (always valid) first
@ -2342,11 +2180,7 @@ static void update_wave_node_directions_and_offset(bNodeTree *ntree)
void do_versions_after_linking_280(FileData *fd, Main *bmain)
{
bool use_collection_compat_28 = true;
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
/* Convert group layer visibility flags to hidden nested collection. */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
/* Add fake user for all existing groups. */
@ -2568,18 +2402,6 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 && !MAIN_VERSION_FILE_ATLEAST(bmain, 280, 14)) {
LISTBASE_FOREACH (Collection *, group, &bmain->collections) {
do_version_group_collection_to_collection(bmain, group);
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
do_version_scene_collection_to_collection(bmain, scene);
}
}
#endif
/* Update Curve object Shape Key data layout to include the Radius property */
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 23)) {
LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
@ -3150,11 +2972,7 @@ ENUM_OPERATORS(eNTreeDoVersionErrors, ~int8_t{});
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
{
bool use_collection_compat_28 = true;
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
scene->r.gauss = 1.5f;
}
@ -3272,24 +3090,6 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
"shader nodes.\n");
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 &&
(DNA_struct_elem_find(fd->filesdna, "ViewLayer", "FreestyleConfig", "freestyle_config") ==
false) &&
DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers"))
{
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
view_layer->flag |= VIEW_LAYER_FREESTYLE;
view_layer->layflag = 0x7FFF; /* solid Z-transparency halo edge strand. */
view_layer->passflag = SCE_PASS_COMBINED | SCE_PASS_Z;
view_layer->pass_alpha_threshold = 0.5f;
BKE_freestyle_config_init(&view_layer->freestyle_config);
}
}
}
#endif
{
/* Init grease pencil edit line color */
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "float", "line_color[4]")) {
@ -3334,22 +3134,6 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 && !MAIN_VERSION_FILE_ATLEAST(bmain, 280, 3)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
do_version_view_layer_visibility(view_layer);
}
}
LISTBASE_FOREACH (Collection *, group, &bmain->collections) {
if (group->view_layer != nullptr) {
do_version_view_layer_visibility(group->view_layer);
}
}
}
#endif
/* Files from this version included do get a valid `win->screen` pointer written for backward
* compatibility, however this should never be used nor needed, so clear these pointers here. */
if (MAIN_VERSION_FILE_ATLEAST(bmain, 280, 1)) {

View File

@ -934,6 +934,10 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
BLO_write_struct(writer, bUserAssetLibrary, asset_library_ref);
}
LISTBASE_FOREACH (const bUserExtensionRepo *, repo_ref, &userdef->extension_repos) {
BLO_write_struct(writer, bUserExtensionRepo, repo_ref);
}
LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) {
BLO_write_struct(writer, uiStyle, style);
}

View File

@ -471,7 +471,7 @@ bool BM_mesh_boolean_knife(BMesh *bm,
}
#else
bool BM_mesh_boolean(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
BMLoop *(*looptris)[3],
const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
void * /*user_data*/,
@ -494,7 +494,7 @@ bool BM_mesh_boolean(BMesh * /*bm*/,
* to the intersection result faces.
*/
bool BM_mesh_boolean_knife(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
BMLoop *(*looptris)[3],
const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
void * /*user_data*/,

View File

@ -317,4 +317,3 @@ if(WITH_OPENCOLORIO)
endif()
blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -386,11 +386,13 @@ void dof_gather_accumulate_sample_pair(DofGatherData pair_data[2],
/* TODO(@fclem): Promote to parameter? dither with Noise? */
const float mirroring_min_distance = 15.0;
if (pair_data[0].coc < mirroring_threshold &&
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc) {
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc)
{
pair_data[1].coc = pair_data[0].coc;
}
else if (pair_data[1].coc < mirroring_threshold &&
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc) {
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc)
{
pair_data[0].coc = pair_data[1].coc;
}
#endif

View File

@ -350,7 +350,7 @@ void IrradianceCache::set_view(View & /*view*/)
grid_upload_ps_.bind_texture("irradiance_d_tx", &irradiance_d_tx);
grid_upload_ps_.bind_texture("validity_tx", &validity_tx);
grid_upload_ps_.bind_image("irradiance_atlas_img", &irradiance_atlas_tx_);
/* NOTE: We are read and writting the same texture that we are sampling from. If that causes an
/* NOTE: We are read and writing the same texture that we are sampling from. If that causes an
* issue, we should revert to manual trilinear interpolation. */
grid_upload_ps_.bind_texture("irradiance_atlas_tx", &irradiance_atlas_tx_);
/* If visibility is invalid, either it is still baking and visibility is stored with

View File

@ -197,7 +197,7 @@ void ShadowTileMapPool::end_sync(ShadowModule &module)
* of the setup steps to release the pages. */
ShadowTileMapData tilemap_data = {};
tilemap_data.tiles_index = index;
tilemap_data.clip_data_index = 0;
tilemap_data.clip_data_index = -1;
tilemap_data.grid_shift = int2(SHADOW_TILEMAP_RES);
tilemap_data.projection_type = SHADOW_PROJECTION_CUBEFACE;

View File

@ -216,4 +216,4 @@ vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B)
return tH * mat3(N, T, B);
}
/** \} */
/** \} */

View File

@ -148,11 +148,13 @@ void dof_gather_accumulate_sample_pair(DofGatherData pair_data[2],
/* TODO(fclem) Promote to parameter? dither with Noise? */
const float mirroring_min_distance = 15.0;
if (pair_data[0].coc < mirroring_threshold &&
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc) {
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc)
{
pair_data[1].coc = pair_data[0].coc;
}
else if (pair_data[1].coc < mirroring_threshold &&
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc) {
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc)
{
pair_data[0].coc = pair_data[1].coc;
}
#endif

View File

@ -186,4 +186,4 @@ void main()
out_radiance = from_accumulation_space(out_radiance);
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
}
}

View File

@ -230,4 +230,4 @@ void main()
imageStore(out_radiance_img, texel_fullres, vec4(radiance_accum, 0.0));
imageStore(out_variance_img, texel_fullres, vec4(hit_variance));
imageStore(out_hit_depth_img, texel_fullres, vec4(hit_depth));
}
}

View File

@ -209,4 +209,4 @@ void main()
float out_variance = mix(in_variance, history_variance.x, mix_variance_fac);
/* This is feedback next frame as variance_history_tx. */
imageStore(out_variance_img, texel_fullres, vec4(out_variance));
}
}

View File

@ -64,4 +64,4 @@ void main()
imageStore(tile_mask_img, tile_co, uvec4(tile_mask));
}
}
}

View File

@ -36,4 +36,4 @@ void main()
uint tile_index = atomicAdd(ray_dispatch_buf.num_groups_x, 1u);
ray_tiles_buf[tile_index] = packUvec2x16(uvec2(tile));
}
}
}

View File

@ -73,4 +73,4 @@ void main()
atlas_store(result[2], atlas_coord, 2);
atlas_store(result[3], atlas_coord, 3);
}
}
}

View File

@ -36,8 +36,11 @@ void main()
/* Reset shift to not tag for update more than once per sync cycle. */
tilemaps_buf[tilemap_index].grid_shift = ivec2(0);
if (tilemap.projection_type != SHADOW_PROJECTION_CUBEFACE) {
int clip_index = tilemap.clip_data_index;
int clip_index = tilemap.clip_data_index;
if (clip_index == -1) {
/* Noop. This is the case for unused tilemaps that are getting pushed to the free heap. */
}
else if (tilemap.projection_type != SHADOW_PROJECTION_CUBEFACE) {
ShadowTileMapClip clip_data = tilemaps_clip_buf[clip_index];
float clip_near_new = orderedIntBitsToFloat(clip_data.clip_near);
float clip_far_new = orderedIntBitsToFloat(clip_data.clip_far);

View File

@ -157,7 +157,8 @@ vec3 volume_shadow(LightData ld, vec3 ray_wpos, vec3 L, float l_dist)
# if 0 /* TODO use shadow maps instead. */
vec3 shadow = vec3(1.0);
for (float s = 1.0; s < VOLUMETRIC_SHADOW_MAX_STEP && s <= volumes_info_buf.shadow_steps; s += 1.0) {
for (float s = 1.0; s < VOLUMETRIC_SHADOW_MAX_STEP && s <= volumes_info_buf.shadow_steps;
s += 1.0) {
vec3 pos = ray_wpos + L * s;
vec3 s_extinction = volume_participating_media_extinction(pos, volume_extinction);
shadow *= exp(-s_extinction * dd);

View File

@ -2834,7 +2834,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_engines_cache_finish();
drw_task_graph_deinit();
#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug. (See #69377) */
#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug (see #69377). */
DRW_render_instance_buffer_finish();
#else
DST.buffer_finish_called = true;

View File

@ -353,6 +353,11 @@ bool ANIM_is_active_channel(bAnimListElem *ale)
bGPDlayer *gpl = (bGPDlayer *)ale->data;
return gpl->flag & GP_LAYER_ACTIVE;
}
case ANIMTYPE_GREASE_PENCIL_LAYER: {
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(ale->id);
return grease_pencil->is_layer_active(
static_cast<blender::bke::greasepencil::Layer *>(ale->data));
}
/* These channel types do not have active flags. */
case ANIMTYPE_MASKLAYER:
case ANIMTYPE_SHAPEKEY:
@ -3629,23 +3634,47 @@ static int click_select_channel_gplayer(bContext *C,
return (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
}
static int click_select_channel_grease_pencil_datablock(bAnimListElem *ale)
{
GreasePencil *grease_pencil = static_cast<GreasePencil *>(ale->data);
/* Toggle expand:
* - Although the triangle widget already allows this,
* the whole channel can also be used for this purpose.
*/
grease_pencil->flag ^= GREASE_PENCIL_ANIM_CHANNEL_EXPANDED;
return (ND_ANIMCHAN | NA_EDITED);
}
static int click_select_channel_grease_pencil_layer(bContext *C,
bAnimContext *ac,
bAnimListElem *ale,
const short /*selectmode*/,
const short selectmode,
const int /*filter*/)
{
/* TODO: Implement other selection modes. */
GreasePencilLayer *layer = static_cast<GreasePencilLayer *>(ale->data);
using namespace blender::bke::greasepencil;
Layer *layer = static_cast<Layer *>(ale->data);
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(ale->id);
/* Clear previous channel selection and set active flag on current selection */
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
if (selectmode == SELECT_INVERT) {
layer->base.flag ^= GP_LAYER_TREE_NODE_SELECT;
}
else if (selectmode == SELECT_EXTEND_RANGE) {
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_EXTEND_RANGE);
animchannel_select_range(ac, ale);
}
else {
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
layer->base.flag |= GP_LAYER_TREE_NODE_SELECT;
}
layer->base.flag |= GP_LAYER_TREE_NODE_SELECT;
grease_pencil->active_layer = layer;
/* Active channel is not changed during range select. */
if (layer->is_selected() && (selectmode != SELECT_EXTEND_RANGE)) {
grease_pencil->set_active_layer(layer);
}
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, nullptr);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, nullptr);
return (ND_ANIMCHAN | NA_EDITED);
}
@ -3784,11 +3813,10 @@ static int mouse_anim_channels(bContext *C,
notifierFlags |= click_select_channel_gplayer(C, ac, ale, selectmode, filter);
break;
case ANIMTYPE_GREASE_PENCIL_DATABLOCK:
/*todo*/
notifierFlags |= click_select_channel_grease_pencil_datablock(ale);
break;
case ANIMTYPE_GREASE_PENCIL_LAYER:
notifierFlags |= click_select_channel_grease_pencil_layer(
C, ac, ale, SELECT_REPLACE, filter);
notifierFlags |= click_select_channel_grease_pencil_layer(C, ac, ale, selectmode, filter);
break;
case ANIMTYPE_MASKDATABLOCK:
notifierFlags |= click_select_channel_maskdatablock(ale);

View File

@ -504,11 +504,10 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
float min_coord = FLT_MAX;
fcurve_scene_coord_range_get(scene, fcu, &min_coord, &max_coord);
/* We use an ulps-based floating point comparison here, with the
/* We use an ULPS-based floating point comparison here, with the
* rationale that if there are too few possible values between
* `min_coord` and `max_coord`, then after display normalization it
* will certainly be a weird quantized experience for the user anyway.
*/
* will certainly be a weird quantized experience for the user anyway. */
if (min_coord < max_coord && ulp_diff_ff(min_coord, max_coord) > 256) {
/* Normalize. */
const float range = max_coord - min_coord;

View File

@ -966,12 +966,21 @@ static bAnimListElem *make_new_animlistelem(void *data,
break;
}
case ANIMTYPE_GREASE_PENCIL_LAYER: {
GreasePencilLayer *layer = (GreasePencilLayer *)data;
GreasePencilLayer *layer = static_cast<GreasePencilLayer *>(data);
ale->flag = layer->base.flag;
ale->key_data = nullptr;
ale->datatype = ALE_GREASE_PENCIL_CELS;
ale->datatype = ALE_GREASE_PENCIL_CEL;
break;
}
case ANIMTYPE_GREASE_PENCIL_DATABLOCK: {
GreasePencil *grease_pencil = static_cast<GreasePencil *>(data);
ale->flag = grease_pencil->flag;
ale->key_data = nullptr;
ale->datatype = ALE_GREASE_PENCIL_DATA;
break;
}
case ANIMTYPE_MASKLAYER: {

View File

@ -324,9 +324,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
/* handle curve-property mappings based on mapping_type */
switch (mapping_type) {
case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible, * then use the first
one */
{
/* N-N - Try to match as much as possible, then use the first one. */
case CREATEDRIVER_MAPPING_N_N: {
/* Use the shorter of the two (to avoid out of bounds access) */
int dst_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
int src_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr2, prop2) : 1;
@ -350,8 +349,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
}
break;
}
case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
/* 1-N - Specified target index for all. */
case CREATEDRIVER_MAPPING_1_N:
default: {
int len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
@ -373,8 +372,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
break;
}
case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
{
/* 1-1 - Use the specified index (unless -1). */
case CREATEDRIVER_MAPPING_1_1: {
done_tot = add_driver_with_target(reports,
dst_id,
dst_path,

View File

@ -383,6 +383,7 @@ enum eAnimKeylistDrawListElemType {
ANIM_KEYLIST_ACTION,
ANIM_KEYLIST_AGROUP,
ANIM_KEYLIST_GREASE_PENCIL_CELS,
ANIM_KEYLIST_GREASE_PENCIL_DATA,
ANIM_KEYLIST_GP_LAYER,
ANIM_KEYLIST_MASK_LAYER,
};
@ -406,7 +407,8 @@ struct AnimKeylistDrawListElem {
bAction *act;
bActionGroup *agrp;
bGPDlayer *gpl;
GreasePencilLayer *grease_pencil_layer;
const GreasePencilLayer *grease_pencil_layer;
const GreasePencil *grease_pencil;
MaskLayer *masklay;
};
@ -442,6 +444,11 @@ static void ED_keylist_draw_list_elem_build_keylist(AnimKeylistDrawListElem *ele
elem->adt, elem->grease_pencil_layer, elem->keylist, elem->saction_flag);
break;
}
case ANIM_KEYLIST_GREASE_PENCIL_DATA: {
grease_pencil_data_block_to_keylist(
elem->adt, elem->grease_pencil, elem->keylist, elem->saction_flag);
break;
}
case ANIM_KEYLIST_GP_LAYER: {
gpl_to_keylist(elem->ads, elem->gpl, elem->keylist);
break;
@ -706,9 +713,21 @@ void draw_action_channel(AnimKeylistDrawList *draw_list,
draw_elem->channel_locked = locked;
}
void draw_grease_pencil_datablock_channel(AnimKeylistDrawList *draw_list,
bDopeSheet * /*ads*/,
const GreasePencil *grease_pencil,
const float ypos,
const float yscale_fac,
int saction_flag)
{
AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem(
draw_list, ANIM_KEYLIST_GREASE_PENCIL_DATA, ypos, yscale_fac, eSAction_Flag(saction_flag));
draw_elem->grease_pencil = grease_pencil;
}
void draw_grease_pencil_cels_channel(AnimKeylistDrawList *draw_list,
bDopeSheet * /*ads*/,
GreasePencilLayer *layer,
const GreasePencilLayer *layer,
const float ypos,
const float yscale_fac,
int saction_flag)

View File

@ -54,8 +54,10 @@ BLI_INLINE bool is_cfra_lt(const float a, const float b)
/* --------------- */
/* Animation data of Grease Pencil cels,
which are drawings positioned in time. */
/**
* Animation data of Grease Pencil cels,
* which are drawings positioned in time.
*/
struct GreasePencilCel {
int frame_number;
GreasePencilFrame frame;
@ -959,6 +961,10 @@ void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, const int sactio
case ALE_GPFRAME:
gpl_to_keylist(ac->ads, static_cast<bGPDlayer *>(ale->data), keylist);
break;
case ALE_GREASE_PENCIL_CEL:
grease_pencil_cels_to_keylist(
ale->adt, static_cast<const GreasePencilLayer *>(ale->data), keylist, saction_flag);
break;
default:
// printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
break;
@ -1158,8 +1164,21 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, con
}
}
void grease_pencil_data_block_to_keylist(AnimData *adt,
const GreasePencil *grease_pencil,
AnimKeylist *keylist,
const int saction_flag)
{
if ((grease_pencil == nullptr) || (keylist == nullptr)) {
return;
}
for (const blender::bke::greasepencil::Layer *layer : grease_pencil->layers()) {
grease_pencil_cels_to_keylist(adt, layer, keylist, saction_flag);
}
}
void grease_pencil_cels_to_keylist(AnimData * /*adt*/,
GreasePencilLayer *gpl,
const GreasePencilLayer *gpl,
AnimKeylist *keylist,
int /*saction_flag*/)
{

View File

@ -893,8 +893,9 @@ static int select_random_exec(bContext *C, wmOperator *op)
const eAttrDomain selection_domain = eAttrDomain(curves_id->selection_domain);
IndexMaskMemory memory;
const IndexMask random_elements = random_mask(
curves, selection_domain, seed, probability, memory);
const IndexMask inv_random_elements = random_mask(
curves, selection_domain, seed, probability, memory)
.complement(curves.points_range(), memory);
const bool was_anything_selected = has_anything_selected(curves);
bke::GSpanAttributeWriter selection = ensure_selection_attribute(
@ -903,7 +904,7 @@ static int select_random_exec(bContext *C, wmOperator *op)
curves::fill_selection_true(selection.span);
}
curves::fill_selection_false(selection.span, random_elements);
curves::fill_selection_false(selection.span, inv_random_elements);
selection.finish();
/* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic

View File

@ -166,9 +166,9 @@ static void dial_geom_draw(const float color[4],
imm_draw_circle_partial_wire_3d(
pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
# if 0
if (arc_inner_factor != 0.0f) {
BLI_assert(0);
}
if (arc_inner_factor != 0.0f) {
BLI_assert(0);
}
# endif
}
}

View File

@ -2469,9 +2469,9 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
* Problem is that the stroke is converted to 3D only after it is finished.
* This approach should work better in tools that immediately apply in 3D space. */
#if 0
if (event->type == NDOF_MOTION) {
return OPERATOR_PASS_THROUGH;
}
if (event->type == NDOF_MOTION) {
return OPERATOR_PASS_THROUGH;
}
#endif
if (p->status == GP_STATUS_IDLING) {

View File

@ -28,15 +28,14 @@ namespace blender::ed::greasepencil {
bool remove_all_selected_frames(GreasePencil &grease_pencil, bke::greasepencil::Layer &layer)
{
bool changed = false;
Vector<int> frames_to_remove;
for (auto [frame_number, frame] : layer.frames().items()) {
if (!frame.is_selected()) {
continue;
}
changed |= grease_pencil.remove_frame_at(layer, frame_number);
frames_to_remove.append(frame_number);
}
return changed;
return grease_pencil.remove_frames(layer, frames_to_remove.as_span());
}
static void select_frame(GreasePencilFrame &frame, const short select_mode)

View File

@ -248,18 +248,20 @@ enum eAnim_ChannelType {
/* types of keyframe data in bAnimListElem */
enum eAnim_KeyType {
ALE_NONE = 0, /* no keyframe data */
ALE_FCURVE, /* F-Curve */
ALE_GPFRAME, /* Grease Pencil Frames (Legacy) */
ALE_GREASE_PENCIL_CELS, /* Grease Pencil Cels */
ALE_MASKLAY, /* Mask */
ALE_NLASTRIP, /* NLA Strips */
ALE_NONE = 0, /* no keyframe data */
ALE_FCURVE, /* F-Curve */
ALE_GPFRAME, /* Grease Pencil Frames (Legacy) */
ALE_MASKLAY, /* Mask */
ALE_NLASTRIP, /* NLA Strips */
ALE_ALL, /* All channels summary */
ALE_SCE, /* Scene summary */
ALE_OB, /* Object summary */
ALE_ACT, /* Action summary */
ALE_GROUP, /* Action Group summary */
ALE_GREASE_PENCIL_CEL, /* Grease Pencil Cels. */
ALE_GREASE_PENCIL_DATA, /* Grease Pencil Cels summary. */
};
/**

View File

@ -22,6 +22,7 @@ struct bActionGroup;
struct bAnimContext;
struct bDopeSheet;
struct bGPDlayer;
struct GreasePencil;
struct GreasePencilLayer;
/* draw simple diamond-shape keyframe */
@ -94,11 +95,19 @@ void draw_summary_channel(AnimKeylistDrawList *draw_list,
/* Grease Pencil cels channels */
void draw_grease_pencil_cels_channel(AnimKeylistDrawList *draw_list,
bDopeSheet *ads,
GreasePencilLayer *layer,
const GreasePencilLayer *layer,
float ypos,
float yscale_fac,
int saction_flag);
/* Grease Pencil data channels */
void draw_grease_pencil_datablock_channel(AnimKeylistDrawList *draw_list,
bDopeSheet *ads,
const GreasePencil *grease_pencil,
const float ypos,
const float yscale_fac,
int saction_flag);
/* Grease Pencil Layer */
void draw_gpl_channel(AnimKeylistDrawList *draw_list,
bDopeSheet *ads,

View File

@ -13,6 +13,7 @@
struct AnimData;
struct CacheFile;
struct FCurve;
struct GreasePencil;
struct GreasePencilLayer;
struct ListBase;
struct MaskLayer;
@ -158,17 +159,24 @@ void cachefile_to_keylist(bDopeSheet *ads,
void scene_to_keylist(bDopeSheet *ads, Scene *sce, AnimKeylist *keylist, int saction_flag);
/* DopeSheet Summary */
void summary_to_keylist(bAnimContext *ac, AnimKeylist *keylist, int saction_flag);
/* Grease Pencil datablock summary */
/* Grease Pencil datablock summary (Legacy) */
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, bool active);
/* Grease Pencil Cels */
/* Grease Pencil Cels. */
void grease_pencil_cels_to_keylist(AnimData *adt,
GreasePencilLayer *layer,
const GreasePencilLayer *layer,
AnimKeylist *keylist,
int saction_flag);
/* Grease Pencil Layer */
/* Grease Pencil Data-Block. */
void grease_pencil_data_block_to_keylist(AnimData *adt,
const GreasePencil *grease_pencil,
AnimKeylist *keylist,
const int saction_flag);
/* Grease Pencil Layer (Legacy) */
void gpl_to_keylist(bDopeSheet *ads, bGPDlayer *gpl, AnimKeylist *keylist);
/* Mask */
void mask_to_keylist(bDopeSheet *ads, MaskLayer *masklay, AnimKeylist *keylist);

View File

@ -172,5 +172,5 @@ void free_gpcopybuf();
void copy_gpdata();
void paste_gpdata();
void mirror_masklayer_frames( MaskLayer *mask_layer, short mode);
void mirror_masklayer_frames(MaskLayer *mask_layer, short mode);
#endif

View File

@ -17,7 +17,7 @@ namespace blender::ed::space_node {
struct NestedTreePreviews {
Render *previews_render = nullptr;
/* Use this map to keep track of the latest ImBuf used (after freeing the renderresult). */
/** Use this map to keep track of the latest #ImBuf used (after freeing the render-result). */
blender::Map<int32_t, ImBuf *> previews_map;
int preview_size;
bool rendering = false;

View File

@ -166,7 +166,7 @@ void uvedit_edge_select_shared_vert(const Scene *scene,
/**
* Selects shared UVs based on #sticky_flag.
*
* \param sticky_flag: Type of sticky selection :
* \param sticky_flag: Type of sticky selection:
* - #SI_STICKY_LOC: selects all UVs sharing same mesh vertex and UV coordinates.
* - #SI_STICKY_VERTEX: selects all UVs sharing same mesh vertex.
*/

View File

@ -756,9 +756,9 @@ void UI_popup_block_ex(bContext *C,
void *arg,
wmOperator *op);
#if 0 /* UNUSED */
void uiPupBlockOperator( bContext *C,
void uiPupBlockOperator(bContext *C,
uiBlockCreateFunc func,
wmOperator *op,
wmOperator *op,
wmOperatorCallContext opcontext);
#endif

View File

@ -1871,9 +1871,9 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
}
/* ignored for now */
# if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
# endif
}
else {
@ -1885,12 +1885,12 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
}
/* ignored for now */
# if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
# endif
}
}

View File

@ -21,6 +21,7 @@
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_vector_types.hh"
#include "BLI_memarena.h"
#include "BLI_smallhash.h"
#include "BLI_stack.h"
@ -64,6 +65,8 @@
#include "mesh_intern.h" /* Own include. */
using namespace blender;
/* Detect isolated holes and fill them. */
#define USE_NET_ISLAND_CONNECT
@ -147,8 +150,8 @@ struct KnifeLineHit {
};
struct KnifePosData {
float co[3];
float cage[3];
float3 co;
float3 cage;
/* At most one of vert, edge, or bmface should be non-null,
* saying whether the point is snapped to a vertex, edge, or in a face.
@ -1493,13 +1496,13 @@ static void knife_project_v2(const KnifeTool_OpData *kcd, const float co[3], flo
/* Ray is returned in world space. */
static void knife_input_ray_segment(KnifeTool_OpData *kcd,
const float mval[2],
const float ofs,
float r_origin[3],
float r_origin_ofs[3])
float r_end[3])
{
/* Unproject to find view ray. */
ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin);
ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs);
ED_view3d_win_to_segment_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, mval, r_origin, r_end, false);
add_v3_v3(r_end, r_origin);
}
/* No longer used, but may be useful in the future. */
@ -1512,7 +1515,7 @@ static void UNUSED_FUNCTION(knifetool_recast_cageco)(KnifeTool_OpData *kcd,
float ray[3], ray_normal[3];
float co[3]; /* Unused. */
knife_input_ray_segment(kcd, mval, 1.0f, origin, origin_ofs);
knife_input_ray_segment(kcd, mval, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
normalize_v3_v3(ray_normal, ray);
@ -2850,7 +2853,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
void *val;
void **val_p;
float s[2], se1[2], se2[2], sint[2];
float r1[3], r2[3];
float d1, d2, lambda;
float vert_tol, vert_tol_sq;
float line_tol, line_tol_sq;
@ -3089,12 +3091,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
d1 = len_v2v2(sint, se1);
d2 = len_v2v2(se2, se1);
if (!(d1 <= line_tol || d2 <= line_tol || fabsf(d1 - d2) <= line_tol)) {
float3 r1, r2;
float p_cage[3], p_cage_tmp[3];
lambda = d1 / d2;
/* Can't just interpolate between ends of kfe because
* that doesn't work with perspective transformation.
* Need to find 3d intersection of ray through sint. */
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
knife_input_ray_segment(kcd, sint, r1, r2);
isect_kind = isect_line_line_v3(
kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, bm_elem_from_knife_edge(kfe))) {
@ -3210,19 +3214,16 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
Object **r_ob,
uint *r_ob_index,
bool *is_space,
float r_co[3],
float r_cageco[3])
float3 &r_co,
float3 &r_cageco)
{
BMFace *f;
float dist = KMAXDIST;
float origin[3];
float origin_ofs[3];
float ray[3], ray_normal[3];
float3 origin;
float3 ray_normal;
/* Unproject to find view ray. */
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
normalize_v3_v3(ray_normal, ray);
ED_view3d_win_to_ray_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, kcd->curr.mval, origin, ray_normal, false);
f = knife_bvh_raycast(kcd, origin, ray_normal, 0.0f, nullptr, r_co, r_cageco, r_ob_index);
@ -3252,9 +3253,9 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
/* Cheat for now; just put in the origin instead
* of a true coordinate on the face.
* This just puts a point 1.0f in front of the view. */
add_v3_v3v3(r_co, origin, ray);
r_co = origin + ray_normal;
/* Use this value for the cage location too as it's used to find near edges/vertices. */
copy_v3_v3(r_cageco, r_co);
r_cageco = r_co;
}
}
@ -3639,7 +3640,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
float ray_hit[3];
float lambda;
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, curr_origin, curr_origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, curr_origin, curr_origin_ofs);
sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
normalize_v3_v3(curr_ray_normal, curr_ray);
@ -3709,7 +3710,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
float prev_ray[3], prev_ray_normal[3];
float prev_co[3], prev_cage[3]; /* Unused. */
knife_input_ray_segment(kcd, kcd->prev.mval, 1.0f, prev_origin, prev_origin_ofs);
knife_input_ray_segment(kcd, kcd->prev.mval, prev_origin, prev_origin_ofs);
sub_v3_v3v3(prev_ray, prev_origin_ofs, prev_origin);
normalize_v3_v3(prev_ray_normal, prev_ray);
@ -3771,7 +3772,7 @@ static int knife_calculate_snap_ref_edges(KnifeTool_OpData *kcd)
float curr_ray[3], curr_ray_normal[3];
float curr_co[3], curr_cage[3]; /* Unused. */
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, curr_origin, curr_origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, curr_origin, curr_origin_ofs);
sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
normalize_v3_v3(curr_ray_normal, curr_ray);
@ -4274,7 +4275,7 @@ static int knife_update_active(KnifeTool_OpData *kcd)
float origin[3];
float origin_ofs[3];
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, origin, origin_ofs);
if (!isect_line_plane_v3(
kcd->curr.cage, origin, origin_ofs, kcd->prev.cage, kcd->vc.rv3d->viewinv[2]))

View File

@ -4001,49 +4001,19 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
/* NOLINTNEXTLINE: readability-redundant-preprocessor */
# if 0 /* Kind of works but looks worse than what's below. */
/* Move the unselected point on a vector based on the
* hair direction and the offset */
float c1[3], c2[3];
sub_v3_v3v3(dco, lastco, co);
mul_mat3_m4_v3(imat, dco); /* into particle space */
/* Move the unselected point on a vector based on the
* hair direction and the offset */
float c1[3], c2[3];
sub_v3_v3v3(dco, lastco, co);
mul_mat3_m4_v3(imat, dco); /* into particle space */
/* move the point along a vector perpendicular to the
* hairs direction, reduces odd kinks, */
cross_v3_v3v3(c1, ofs, dco);
cross_v3_v3v3(c2, c1, dco);
normalize_v3(c2);
mul_v3_fl(c2, len_v3(ofs));
add_v3_v3(key->co, c2);
/* move the point along a vector perpendicular to the
* hairs direction, reduces odd kinks, */
cross_v3_v3v3(c1, ofs, dco);
cross_v3_v3v3(c2, c1, dco);
normalize_v3(c2);
mul_v3_fl(c2, len_v3(ofs));
add_v3_v3(key->co, c2);
# else
/* Move the unselected point on a vector based on the
* the normal of the closest geometry */

View File

@ -64,17 +64,16 @@ struct EraseOperationExecutor {
/**
* Computes the intersections between a 2D line segment and a circle with integer values.
*
* \param s0, s1 : endpoints of the segment.
* \param center : center of the circle,
* \param s0, s1: endpoints of the segment.
* \param center: center of the circle,
* \param radius_2: squared radius of the circle.
*
* \param r_mu0 : (output) signed distance from \a s0 to the first intersection, if it exists.
* \param r_mu1 : (output) signed distance from \a s0 to the second intersection, if it exists.
* \param r_mu0: (output) signed distance from \a s0 to the first intersection, if it exists.
* \param r_mu1: (output) signed distance from \a s0 to the second intersection, if it exists.
*
* All intersections with the infinite line of the segment are considered.
*
* \returns the number of intersection found.
*
*/
static int8_t intersections_segment_circle_integers(const int2 &s0,
const int2 &s1,
@ -238,14 +237,13 @@ struct EraseOperationExecutor {
* \param r_intersections_factors: (output) factors of the potential intersections with each
* segment. Should be the size of the source point range (cyclic curves get an extra segment).
*
* \param r_is_point_inside : (output) true if the point lies inside the eraser, and thus should
* \param r_is_point_inside: (output) true if the point lies inside the eraser, and thus should
* be removed. Note that if the point lies exactly on the boundary of the eraser, it will not be
* marked as inside. Should be the size of the source point range.
* \param r_is_point_cut : (output) true if the point falls exactly on the boundary of th
* \param r_is_point_cut: (output) true if the point falls exactly on the boundary of the
* eraser. Should be the size of the source point range.
*
* \returns total number of intersections found.
*
*/
int64_t intersections_with_curves(const bke::CurvesGeometry &src,
const Span<float2> screen_space_positions,
@ -320,7 +318,7 @@ struct EraseOperationExecutor {
}
/* The hard eraser cuts out the curves at their intersection with the eraser, and removes
* everything that lies in-between two consecutives intersections. Note that intersections are
* everything that lies in-between two consecutive intersections. Note that intersections are
* computed using integers (pixel-space) to avoid floating-point approximation errors. */
bool hard_eraser(const bke::CurvesGeometry &src,

View File

@ -3007,14 +3007,6 @@ static void calc_brush_local_mat(const float rotation,
/* Scale by brush radius. */
float radius = cache->radius;
/* Square tips should scale by square root of 2. */
if (BKE_brush_has_cube_tip(cache->brush, PAINT_MODE_SCULPT)) {
radius += (radius / M_SQRT2 - radius) * cache->brush->tip_roundness;
}
else {
radius /= M_SQRT2;
}
normalize_m4(mat);
scale_m4_fl(scale, radius);
mul_m4_m4m4(tmat, mat, scale);

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