forked from blender/blender
me-main #1
@ -236,6 +236,8 @@ ForEachMacros:
|
|||||||
- LOOP_UNSELECTED_POINTS
|
- LOOP_UNSELECTED_POINTS
|
||||||
- LOOP_VISIBLE_KEYS
|
- LOOP_VISIBLE_KEYS
|
||||||
- LOOP_VISIBLE_POINTS
|
- LOOP_VISIBLE_POINTS
|
||||||
|
- LIGHT_FOREACH_BEGIN_DIRECTIONAL
|
||||||
|
- LIGHT_FOREACH_BEGIN_LOCAL
|
||||||
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
|
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
|
||||||
- LISTBASE_CIRCULAR_FORWARD_BEGIN
|
- LISTBASE_CIRCULAR_FORWARD_BEGIN
|
||||||
- LISTBASE_FOREACH
|
- LISTBASE_FOREACH
|
||||||
|
8
.gitmodules
vendored
8
.gitmodules
vendored
@ -1,20 +1,20 @@
|
|||||||
[submodule "release/scripts/addons"]
|
[submodule "release/scripts/addons"]
|
||||||
path = release/scripts/addons
|
path = release/scripts/addons
|
||||||
url = ../blender-addons.git
|
url = ../blender-addons.git
|
||||||
branch = master
|
branch = main
|
||||||
ignore = all
|
ignore = all
|
||||||
[submodule "release/scripts/addons_contrib"]
|
[submodule "release/scripts/addons_contrib"]
|
||||||
path = release/scripts/addons_contrib
|
path = release/scripts/addons_contrib
|
||||||
url = ../blender-addons-contrib.git
|
url = ../blender-addons-contrib.git
|
||||||
branch = master
|
branch = main
|
||||||
ignore = all
|
ignore = all
|
||||||
[submodule "release/datafiles/locale"]
|
[submodule "release/datafiles/locale"]
|
||||||
path = release/datafiles/locale
|
path = release/datafiles/locale
|
||||||
url = ../blender-translations.git
|
url = ../blender-translations.git
|
||||||
branch = master
|
branch = main
|
||||||
ignore = all
|
ignore = all
|
||||||
[submodule "source/tools"]
|
[submodule "source/tools"]
|
||||||
path = source/tools
|
path = source/tools
|
||||||
url = ../blender-dev-tools.git
|
url = ../blender-dev-tools.git
|
||||||
branch = master
|
branch = main
|
||||||
ignore = all
|
ignore = all
|
||||||
|
@ -625,8 +625,10 @@ mark_as_advanced(
|
|||||||
|
|
||||||
# Vulkan
|
# Vulkan
|
||||||
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
|
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)
|
||||||
mark_as_advanced(
|
mark_as_advanced(
|
||||||
WITH_VULKAN_BACKEND
|
WITH_VULKAN_BACKEND
|
||||||
|
WITH_VULKAN_GUARDEDALLOC
|
||||||
)
|
)
|
||||||
|
|
||||||
# Metal
|
# Metal
|
||||||
|
@ -22,7 +22,7 @@ elseif(UNIX AND NOT APPLE)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Boolean crashes with Arm assembly, see T103423.
|
# Boolean crashes with Arm assembly, see #103423.
|
||||||
if(BLENDER_PLATFORM_ARM)
|
if(BLENDER_PLATFORM_ARM)
|
||||||
set(GMP_OPTIONS
|
set(GMP_OPTIONS
|
||||||
${GMP_OPTIONS}
|
${GMP_OPTIONS}
|
||||||
|
@ -40,7 +40,8 @@ ExternalProject_Add(external_igc_llvm
|
|||||||
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0004-OpenCL-support-cl_ext_float_atomics.patch &&
|
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0004-OpenCL-support-cl_ext_float_atomics.patch &&
|
||||||
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0005-OpenCL-Add-cl_khr_integer_dot_product.patch &&
|
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/clang/0005-OpenCL-Add-cl_khr_integer_dot_product.patch &&
|
||||||
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0001-Memory-leak-fix-for-Managed-Static-Mutex.patch &&
|
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0001-Memory-leak-fix-for-Managed-Static-Mutex.patch &&
|
||||||
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch
|
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0002-Remove-repo-name-in-LLVM-IR.patch &&
|
||||||
|
${PATCH_CMD} -p 1 -d ${IGC_LLVM_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/llvm/0003-Add-missing-include-limit-in-benchmark.patch
|
||||||
)
|
)
|
||||||
add_dependencies(
|
add_dependencies(
|
||||||
external_igc_llvm
|
external_igc_llvm
|
||||||
@ -55,9 +56,6 @@ ExternalProject_Add(external_igc_spirv_translator
|
|||||||
CONFIGURE_COMMAND echo .
|
CONFIGURE_COMMAND echo .
|
||||||
BUILD_COMMAND echo .
|
BUILD_COMMAND echo .
|
||||||
INSTALL_COMMAND echo .
|
INSTALL_COMMAND echo .
|
||||||
PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0001-update-SPIR-V-headers-for-SPV_INTEL_split_barrier.patch &&
|
|
||||||
${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0002-Add-support-for-split-barriers-extension-SPV_INTEL_s.patch &&
|
|
||||||
${PATCH_CMD} -p 1 -d ${IGC_SPIRV_TRANSLATOR_SOURCE_DIR} < ${IGC_OPENCL_CLANG_PATCH_DIR}/spirv/0003-Support-cl_bf16_conversions.patch
|
|
||||||
)
|
)
|
||||||
add_dependencies(
|
add_dependencies(
|
||||||
external_igc_spirv_translator
|
external_igc_spirv_translator
|
||||||
|
@ -88,6 +88,19 @@ else()
|
|||||||
export LDFLAGS=${PYTHON_LDFLAGS} &&
|
export LDFLAGS=${PYTHON_LDFLAGS} &&
|
||||||
export PKG_CONFIG_PATH=${LIBDIR}/ffi/lib/pkgconfig)
|
export PKG_CONFIG_PATH=${LIBDIR}/ffi/lib/pkgconfig)
|
||||||
|
|
||||||
|
# NOTE: untested on APPLE so far.
|
||||||
|
if(NOT APPLE)
|
||||||
|
set(PYTHON_CONFIGURE_EXTRA_ARGS
|
||||||
|
${PYTHON_CONFIGURE_EXTRA_ARGS}
|
||||||
|
# Used on most release Linux builds (Fedora for e.g.),
|
||||||
|
# increases build times noticeably with the benefit of a modest speedup at runtime.
|
||||||
|
--enable-optimizations
|
||||||
|
# While LTO is OK when building on the same system, it's incompatible across GCC versions,
|
||||||
|
# making it impractical for developers to build against, so keep it disabled.
|
||||||
|
# `--with-lto`
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
ExternalProject_Add(external_python
|
ExternalProject_Add(external_python
|
||||||
URL file://${PACKAGE_DIR}/${PYTHON_FILE}
|
URL file://${PACKAGE_DIR}/${PYTHON_FILE}
|
||||||
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
DOWNLOAD_DIR ${DOWNLOAD_DIR}
|
||||||
|
@ -668,9 +668,9 @@ set(SPIRV_HEADERS_FILE SPIR-V-Headers-${SPIRV_HEADERS_VERSION}.tar.gz)
|
|||||||
# compiler, the versions used are taken from the following location
|
# compiler, the versions used are taken from the following location
|
||||||
# https://github.com/intel/intel-graphics-compiler/releases
|
# https://github.com/intel/intel-graphics-compiler/releases
|
||||||
|
|
||||||
set(IGC_VERSION 1.0.12149.1)
|
set(IGC_VERSION 1.0.13064.7)
|
||||||
set(IGC_URI https://github.com/intel/intel-graphics-compiler/archive/refs/tags/igc-${IGC_VERSION}.tar.gz)
|
set(IGC_URI https://github.com/intel/intel-graphics-compiler/archive/refs/tags/igc-${IGC_VERSION}.tar.gz)
|
||||||
set(IGC_HASH 44f67f24e3bc5130f9f062533abf8154782a9d0a992bc19b498639a8521ae836)
|
set(IGC_HASH a929abd4cca2b293961ec0437ee4b3b2147bd3b2c8a3c423af78c0c359b2e5ae)
|
||||||
set(IGC_HASH_TYPE SHA256)
|
set(IGC_HASH_TYPE SHA256)
|
||||||
set(IGC_FILE igc-${IGC_VERSION}.tar.gz)
|
set(IGC_FILE igc-${IGC_VERSION}.tar.gz)
|
||||||
|
|
||||||
@ -690,15 +690,15 @@ set(IGC_LLVM_FILE ${IGC_LLVM_VERSION}.tar.gz)
|
|||||||
#
|
#
|
||||||
# WARNING WARNING WARNING
|
# WARNING WARNING WARNING
|
||||||
|
|
||||||
set(IGC_OPENCL_CLANG_VERSION 363a5262d8c7cff3fb28f3bdb5d85c8d7e91c1bb)
|
set(IGC_OPENCL_CLANG_VERSION ee31812ea8b89d08c2918f045d11a19bd33525c5)
|
||||||
set(IGC_OPENCL_CLANG_URI https://github.com/intel/opencl-clang/archive/${IGC_OPENCL_CLANG_VERSION}.tar.gz)
|
set(IGC_OPENCL_CLANG_URI https://github.com/intel/opencl-clang/archive/${IGC_OPENCL_CLANG_VERSION}.tar.gz)
|
||||||
set(IGC_OPENCL_CLANG_HASH aa8cf72bb239722ce8ce44f79413c6887ecc8ca18477dd520aa5c4809756da9a)
|
set(IGC_OPENCL_CLANG_HASH 1db6735bbcfaa31e8a9ba39f121d6bafa806ea8919e9f56782d6aaa67771ddda)
|
||||||
set(IGC_OPENCL_CLANG_HASH_TYPE SHA256)
|
set(IGC_OPENCL_CLANG_HASH_TYPE SHA256)
|
||||||
set(IGC_OPENCL_CLANG_FILE opencl-clang-${IGC_OPENCL_CLANG_VERSION}.tar.gz)
|
set(IGC_OPENCL_CLANG_FILE opencl-clang-${IGC_OPENCL_CLANG_VERSION}.tar.gz)
|
||||||
|
|
||||||
set(IGC_VCINTRINSICS_VERSION v0.5.0)
|
set(IGC_VCINTRINSICS_VERSION v0.11.0)
|
||||||
set(IGC_VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/refs/tags/${IGC_VCINTRINSICS_VERSION}.tar.gz)
|
set(IGC_VCINTRINSICS_URI https://github.com/intel/vc-intrinsics/archive/refs/tags/${IGC_VCINTRINSICS_VERSION}.tar.gz)
|
||||||
set(IGC_VCINTRINSICS_HASH 70bb47c5e32173cf61514941e83ae7c7eb4485e6d2fca60cfa1f50d4f42c41f2)
|
set(IGC_VCINTRINSICS_HASH e5acd5626ce7fa6d41ce154c50ac805eda734ee66af94ef28e680ac2ad81bb9f)
|
||||||
set(IGC_VCINTRINSICS_HASH_TYPE SHA256)
|
set(IGC_VCINTRINSICS_HASH_TYPE SHA256)
|
||||||
set(IGC_VCINTRINSICS_FILE vc-intrinsics-${IGC_VCINTRINSICS_VERSION}.tar.gz)
|
set(IGC_VCINTRINSICS_FILE vc-intrinsics-${IGC_VCINTRINSICS_VERSION}.tar.gz)
|
||||||
|
|
||||||
@ -714,9 +714,9 @@ set(IGC_SPIRV_TOOLS_HASH 6e19900e948944243024aedd0a201baf3854b377b9cc7a386553bc1
|
|||||||
set(IGC_SPIRV_TOOLS_HASH_TYPE SHA256)
|
set(IGC_SPIRV_TOOLS_HASH_TYPE SHA256)
|
||||||
set(IGC_SPIRV_TOOLS_FILE SPIR-V-Tools-${IGC_SPIRV_TOOLS_VERSION}.tar.gz)
|
set(IGC_SPIRV_TOOLS_FILE SPIR-V-Tools-${IGC_SPIRV_TOOLS_VERSION}.tar.gz)
|
||||||
|
|
||||||
set(IGC_SPIRV_TRANSLATOR_VERSION a31ffaeef77e23d500b3ea3d35e0c42ff5648ad9)
|
set(IGC_SPIRV_TRANSLATOR_VERSION d739c01d65ec00dee64dedd40deed805216a7193)
|
||||||
set(IGC_SPIRV_TRANSLATOR_URI https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
|
set(IGC_SPIRV_TRANSLATOR_URI https://github.com/KhronosGroup/SPIRV-LLVM-Translator/archive/${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
|
||||||
set(IGC_SPIRV_TRANSLATOR_HASH 9e26c96a45341b8f8af521bacea20e752623346340addd02af95d669f6e89252)
|
set(IGC_SPIRV_TRANSLATOR_HASH ddc0cc9ccbe59dadeaf291012d59de142b2e9f2b124dbb634644d39daddaa13e)
|
||||||
set(IGC_SPIRV_TRANSLATOR_HASH_TYPE SHA256)
|
set(IGC_SPIRV_TRANSLATOR_HASH_TYPE SHA256)
|
||||||
set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
|
set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.tar.gz)
|
||||||
|
|
||||||
@ -724,15 +724,15 @@ set(IGC_SPIRV_TRANSLATOR_FILE SPIR-V-Translator-${IGC_SPIRV_TRANSLATOR_VERSION}.
|
|||||||
### Intel Graphics Compiler DEPS END ###
|
### Intel Graphics Compiler DEPS END ###
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
set(GMMLIB_VERSION intel-gmmlib-22.1.8)
|
set(GMMLIB_VERSION intel-gmmlib-22.3.0)
|
||||||
set(GMMLIB_URI https://github.com/intel/gmmlib/archive/refs/tags/${GMMLIB_VERSION}.tar.gz)
|
set(GMMLIB_URI https://github.com/intel/gmmlib/archive/refs/tags/${GMMLIB_VERSION}.tar.gz)
|
||||||
set(GMMLIB_HASH bf23e9a3742b4fb98c7666c9e9b29f3219e4b2fb4d831aaf4eed71f5e2d17368)
|
set(GMMLIB_HASH c1f33e1519edfc527127baeb0436b783430dfd256c643130169a3a71dc86aff9)
|
||||||
set(GMMLIB_HASH_TYPE SHA256)
|
set(GMMLIB_HASH_TYPE SHA256)
|
||||||
set(GMMLIB_FILE ${GMMLIB_VERSION}.tar.gz)
|
set(GMMLIB_FILE ${GMMLIB_VERSION}.tar.gz)
|
||||||
|
|
||||||
set(OCLOC_VERSION 22.38.24278)
|
set(OCLOC_VERSION 22.49.25018.21)
|
||||||
set(OCLOC_URI https://github.com/intel/compute-runtime/archive/refs/tags/${OCLOC_VERSION}.tar.gz)
|
set(OCLOC_URI https://github.com/intel/compute-runtime/archive/refs/tags/${OCLOC_VERSION}.tar.gz)
|
||||||
set(OCLOC_HASH db0c542fccd651e6404b15a74d46027f1ce0eda8dc9e25a40cbb6c0faef257ee)
|
set(OCLOC_HASH 92362dae08b503a34e5d3820ed284198c452bcd5e7504d90eb69887b20492c06)
|
||||||
set(OCLOC_HASH_TYPE SHA256)
|
set(OCLOC_HASH_TYPE SHA256)
|
||||||
set(OCLOC_FILE ocloc-${OCLOC_VERSION}.tar.gz)
|
set(OCLOC_FILE ocloc-${OCLOC_VERSION}.tar.gz)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
diff -Naur external_igc_opencl_clang.orig/CMakeLists.txt external_igc_opencl_clang/CMakeLists.txt
|
diff -Naur external_igc_opencl_clang.orig/CMakeLists.txt external_igc_opencl_clang/CMakeLists.txt
|
||||||
--- external_igc_opencl_clang.orig/CMakeLists.txt 2022-03-16 05:51:10 -0600
|
--- external_igc_opencl_clang.orig/CMakeLists.txt 2022-03-16 05:51:10 -0600
|
||||||
+++ external_igc_opencl_clang/CMakeLists.txt 2022-05-23 10:40:09 -0600
|
+++ external_igc_opencl_clang/CMakeLists.txt 2022-05-23 10:40:09 -0600
|
||||||
@@ -126,22 +126,24 @@
|
@@ -147,22 +147,24 @@
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -544,7 +544,7 @@ endfunction()
|
|||||||
function(setup_platform_linker_libs
|
function(setup_platform_linker_libs
|
||||||
target
|
target
|
||||||
)
|
)
|
||||||
# jemalloc must be early in the list, to be before pthread (see T57998)
|
# jemalloc must be early in the list, to be before pthread (see #57998).
|
||||||
if(WITH_MEM_JEMALLOC)
|
if(WITH_MEM_JEMALLOC)
|
||||||
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
||||||
endif()
|
endif()
|
||||||
|
@ -440,7 +440,7 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
|
|||||||
# Make stack size more similar to Embree, required for Embree.
|
# Make stack size more similar to Embree, required for Embree.
|
||||||
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
||||||
|
|
||||||
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
# Suppress ranlib "has no symbols" warnings (workaround for #48250).
|
||||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||||
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
||||||
|
@ -121,7 +121,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
|
|||||||
include(InstallRequiredSystemLibraries)
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
||||||
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
||||||
# redirects for this dll, for details see T88813.
|
# redirects for this dll, for details see #88813.
|
||||||
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
||||||
string(FIND ${lib} "ucrtbase" pos)
|
string(FIND ${lib} "ucrtbase" pos)
|
||||||
if(NOT pos EQUAL -1)
|
if(NOT pos EQUAL -1)
|
||||||
|
@ -170,7 +170,7 @@ def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True)
|
|||||||
return "rebase or merge in progress, complete it first"
|
return "rebase or merge in progress, complete it first"
|
||||||
|
|
||||||
# Abort if uncommitted changes.
|
# Abort if uncommitted changes.
|
||||||
changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no'])
|
changes = check_output([args.git_command, 'status', '--porcelain', '--untracked-files=no', '--ignore-submodules'])
|
||||||
if len(changes) != 0:
|
if len(changes) != 0:
|
||||||
return "you have unstaged changes"
|
return "you have unstaged changes"
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ MODULE_GROUPING = {
|
|||||||
|
|
||||||
# -------------------------------BLENDER----------------------------------------
|
# -------------------------------BLENDER----------------------------------------
|
||||||
|
|
||||||
# converting bytes to strings, due to T30154
|
# Converting bytes to strings, due to #30154.
|
||||||
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
||||||
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
||||||
|
|
||||||
@ -2200,7 +2200,7 @@ def write_rst_enum_items(basepath, key, key_no_prefix, enum_items):
|
|||||||
Write a single page for a static enum in RST.
|
Write a single page for a static enum in RST.
|
||||||
|
|
||||||
This helps avoiding very large lists being in-lined in many places which is an issue
|
This helps avoiding very large lists being in-lined in many places which is an issue
|
||||||
especially with icons in ``bpy.types.UILayout``. See T87008.
|
especially with icons in ``bpy.types.UILayout``. See #87008.
|
||||||
"""
|
"""
|
||||||
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
|
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
|
||||||
with open(filepath, "w", encoding="utf-8") as fh:
|
with open(filepath, "w", encoding="utf-8") as fh:
|
||||||
|
@ -12,6 +12,7 @@ from bpy.props import (
|
|||||||
PointerProperty,
|
PointerProperty,
|
||||||
StringProperty,
|
StringProperty,
|
||||||
)
|
)
|
||||||
|
from bpy.app.translations import pgettext_iface as iface_
|
||||||
|
|
||||||
from math import pi
|
from math import pi
|
||||||
|
|
||||||
@ -1664,30 +1665,48 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||||||
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
|
col.label(text="No compatible GPUs found for Cycles", icon='INFO')
|
||||||
|
|
||||||
if device_type == 'CUDA':
|
if device_type == 'CUDA':
|
||||||
col.label(text="Requires NVIDIA GPU with compute capability 3.0", icon='BLANK1')
|
compute_capability = "3.0"
|
||||||
|
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
elif device_type == 'OPTIX':
|
elif device_type == 'OPTIX':
|
||||||
col.label(text="Requires NVIDIA GPU with compute capability 5.0", icon='BLANK1')
|
compute_capability = "5.0"
|
||||||
col.label(text="and NVIDIA driver version 470 or newer", icon='BLANK1')
|
driver_version = "470"
|
||||||
|
col.label(text=iface_("Requires NVIDIA GPU with compute capability %s") % compute_capability,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
|
col.label(text="and NVIDIA driver version %s or newer" % driver_version,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
elif device_type == 'HIP':
|
elif device_type == 'HIP':
|
||||||
import sys
|
import sys
|
||||||
if sys.platform[:3] == "win":
|
if sys.platform[:3] == "win":
|
||||||
|
driver_version = "21.Q4"
|
||||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
||||||
col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1')
|
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
elif sys.platform.startswith("linux"):
|
elif sys.platform.startswith("linux"):
|
||||||
|
driver_version = "22.10"
|
||||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
||||||
col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1')
|
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
|
||||||
|
translate=False)
|
||||||
elif device_type == 'ONEAPI':
|
elif device_type == 'ONEAPI':
|
||||||
import sys
|
import sys
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
|
driver_version = "101.4032"
|
||||||
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
|
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
|
||||||
col.label(text="and Windows driver version 101.4032 or newer", icon='BLANK1')
|
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
elif sys.platform.startswith("linux"):
|
elif sys.platform.startswith("linux"):
|
||||||
|
driver_version = "1.3.24931"
|
||||||
col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
|
col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1')
|
||||||
col.label(text=" - intel-level-zero-gpu version 1.3.24931 or newer", icon='BLANK1')
|
col.label(text=iface_(" - intel-level-zero-gpu version %s or newer") % driver_version,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
|
col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1')
|
||||||
elif device_type == 'METAL':
|
elif device_type == 'METAL':
|
||||||
col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1')
|
silicon_mac_version = "12.2"
|
||||||
col.label(text="or AMD with macOS 12.3 or newer", icon='BLANK1')
|
amd_mac_version = "12.3"
|
||||||
|
col.label(text=iface_("Requires Apple Silicon with macOS %s or newer") % silicon_mac_version,
|
||||||
|
icon='BLANK1', translate=False)
|
||||||
|
col.label(text=iface_("or AMD with macOS %s or newer") % amd_mac_version, icon='BLANK1',
|
||||||
|
translate=False)
|
||||||
return
|
return
|
||||||
|
|
||||||
for device in devices:
|
for device in devices:
|
||||||
|
@ -20,7 +20,7 @@ class CyclesPresetPanel(PresetPanel, Panel):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def post_cb(context):
|
def post_cb(context):
|
||||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||||
# update, because add-on properties don't. (see T62325)
|
# update, because add-on properties don't. (see #62325)
|
||||||
render = context.scene.render
|
render = context.scene.render
|
||||||
render.filter_size = render.filter_size
|
render.filter_size = render.filter_size
|
||||||
|
|
||||||
|
@ -105,11 +105,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
|
|||||||
|
|
||||||
/* Bind shader now to enable uniform assignment. */
|
/* Bind shader now to enable uniform assignment. */
|
||||||
GPU_shader_bind(shader_program_);
|
GPU_shader_bind(shader_program_);
|
||||||
GPU_shader_uniform_int(shader_program_, image_texture_location_, 0);
|
int slot = 0;
|
||||||
|
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
|
||||||
float size[2];
|
float size[2];
|
||||||
size[0] = width;
|
size[0] = width;
|
||||||
size[1] = height;
|
size[1] = height;
|
||||||
GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size);
|
GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size);
|
||||||
return shader_program_;
|
return shader_program_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
|
|||||||
: b_image(b_image),
|
: b_image(b_image),
|
||||||
frame(frame),
|
frame(frame),
|
||||||
tile_number(tile_number),
|
tile_number(tile_number),
|
||||||
/* Don't free cache for preview render to avoid race condition from T93560, to be fixed
|
/* Don't free cache for preview render to avoid race condition from #93560, to be fixed
|
||||||
* properly later as we are close to release. */
|
* properly later as we are close to release. */
|
||||||
free_cache(!is_preview_render && !b_image.has_data())
|
free_cache(!is_preview_render && !b_image.has_data())
|
||||||
{
|
{
|
||||||
@ -72,7 +72,7 @@ bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaDat
|
|||||||
metadata.colorspace = u_colorspace_raw;
|
metadata.colorspace = u_colorspace_raw;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* In some cases (e.g. T94135), the colorspace setting in Blender gets updated as part of the
|
/* In some cases (e.g. #94135), the colorspace setting in Blender gets updated as part of the
|
||||||
* metadata queries in this function, so update the colorspace setting here. */
|
* metadata queries in this function, so update the colorspace setting here. */
|
||||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||||
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");
|
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||||
|
@ -24,7 +24,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||||||
Light *light = light_map.find(key);
|
Light *light = light_map.find(key);
|
||||||
|
|
||||||
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
||||||
* specific depsgraph update (T88515). This also mimics the behavior for Objects. */
|
* specific depsgraph update (#88515). This also mimics the behavior for Objects. */
|
||||||
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
||||||
|
|
||||||
/* Update if either object or light data changed. */
|
/* Update if either object or light data changed. */
|
||||||
|
@ -404,7 +404,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||||||
* point we know that we've got everything to render current view layer.
|
* point we know that we've got everything to render current view layer.
|
||||||
*/
|
*/
|
||||||
/* At the moment we only free if we are not doing multi-view
|
/* At the moment we only free if we are not doing multi-view
|
||||||
* (or if we are rendering the last view). See T58142/D4239 for discussion.
|
* (or if we are rendering the last view). See #58142/D4239 for discussion.
|
||||||
*/
|
*/
|
||||||
if (view_index == num_views - 1) {
|
if (view_index == num_views - 1) {
|
||||||
free_blender_memory_if_possible();
|
free_blender_memory_if_possible();
|
||||||
|
@ -766,7 +766,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
|||||||
(BlenderSession::headless || is_interface_locked) &&
|
(BlenderSession::headless || is_interface_locked) &&
|
||||||
/* Baking re-uses the depsgraph multiple times, clearing crashes
|
/* Baking re-uses the depsgraph multiple times, clearing crashes
|
||||||
* reading un-evaluated mesh data which isn't aligned with the
|
* reading un-evaluated mesh data which isn't aligned with the
|
||||||
* geometry we're baking, see T71012. */
|
* geometry we're baking, see #71012. */
|
||||||
!scene->bake_manager->get_baking() &&
|
!scene->bake_manager->get_baking() &&
|
||||||
/* Persistent data must main caches for performance and correctness. */
|
/* Persistent data must main caches for performance and correctness. */
|
||||||
!is_persistent_data;
|
!is_persistent_data;
|
||||||
|
@ -648,7 +648,7 @@ GPUDevice::Mem *GPUDevice::generic_alloc(device_memory &mem, size_t pitch_paddin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mem_alloc_result) {
|
if (mem_alloc_result) {
|
||||||
assert(transform_host_pointer(&device_pointer, shared_pointer));
|
assert(transform_host_pointer(device_pointer, shared_pointer));
|
||||||
map_host_used += size;
|
map_host_used += size;
|
||||||
status = " in host memory";
|
status = " in host memory";
|
||||||
}
|
}
|
||||||
|
@ -906,7 +906,7 @@ bool HIPDevice::should_use_graphics_interop()
|
|||||||
* possible, but from the empiric measurements it can be considerably slower than using naive
|
* possible, but from the empiric measurements it can be considerably slower than using naive
|
||||||
* pixels copy. */
|
* pixels copy. */
|
||||||
|
|
||||||
/* Disable graphics interop for now, because of driver bug in 21.40. See T92972 */
|
/* Disable graphics interop for now, because of driver bug in 21.40. See #92972 */
|
||||||
# if 0
|
# if 0
|
||||||
HIPContextScope scope(this);
|
HIPContextScope scope(this);
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
|
|||||||
}
|
}
|
||||||
case METAL_GPU_AMD: {
|
case METAL_GPU_AMD: {
|
||||||
max_threads_per_threadgroup = 128;
|
max_threads_per_threadgroup = 128;
|
||||||
|
use_metalrt = info.use_metalrt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case METAL_GPU_APPLE: {
|
case METAL_GPU_APPLE: {
|
||||||
@ -585,7 +586,7 @@ void MetalDevice::erase_allocation(device_memory &mem)
|
|||||||
if (it != metal_mem_map.end()) {
|
if (it != metal_mem_map.end()) {
|
||||||
MetalMem *mmem = it->second.get();
|
MetalMem *mmem = it->second.get();
|
||||||
|
|
||||||
/* blank out reference to MetalMem* in the launch params (fixes crash T94736) */
|
/* blank out reference to MetalMem* in the launch params (fixes crash #94736) */
|
||||||
if (mmem->pointer_index >= 0) {
|
if (mmem->pointer_index >= 0) {
|
||||||
device_ptr *pointers = (device_ptr *)&launch_params;
|
device_ptr *pointers = (device_ptr *)&launch_params;
|
||||||
pointers[mmem->pointer_index] = 0;
|
pointers[mmem->pointer_index] = 0;
|
||||||
|
@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
{
|
{
|
||||||
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
||||||
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
||||||
* usable visual feedback for artists. There are a couple of tricks though. */
|
* usable visual feedback for artists. */
|
||||||
|
|
||||||
if (is_denoise_active_during_update()) {
|
if (is_denoise_active_during_update()) {
|
||||||
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
||||||
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution_divider <= pixel_size_) {
|
/* Schedule samples equal to the resolution divider up to a maximum of 4.
|
||||||
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
|
* The idea is to have enough information on the screen by increasing the sample count as the
|
||||||
* the sample count at this resolution division, but instead assists in the calculation of
|
* resolution is decreased. */
|
||||||
* the resolution divider. */
|
/* NOTE: Changeing this formula will change the formula in
|
||||||
return 1;
|
* "RenderScheduler::calculate_resolution_divider_for_time()"*/
|
||||||
}
|
return min(max(1, resolution_divider / pixel_size_), 4);
|
||||||
|
|
||||||
if (resolution_divider == pixel_size_ * 2) {
|
|
||||||
/* When resolution divider is the previous step to the final resolution, schedule two samples.
|
|
||||||
* This is so that rendering on lower resolution does not exceed time that it takes to render
|
|
||||||
* first sample at the full resolution. */
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Always render 4 samples, even if scene is configured for less.
|
|
||||||
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
|
|
||||||
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
|
|
||||||
* at one sample. */
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderScheduler::work_need_adaptive_filter() const
|
bool RenderScheduler::work_need_adaptive_filter() const
|
||||||
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
|
|||||||
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
||||||
* render time is somewhere on a boundary between two resolutions. */
|
* render time is somewhere on a boundary between two resolutions. */
|
||||||
|
|
||||||
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
|
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
|
||||||
* simple and compute device is fast). */
|
* unreadable viewport render. */
|
||||||
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
|
start_resolution_divider_ = min(resolution_divider_for_update,
|
||||||
|
default_start_resolution_divider_);
|
||||||
|
|
||||||
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
||||||
}
|
}
|
||||||
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
|
|||||||
|
|
||||||
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
||||||
{
|
{
|
||||||
/* TODO(sergey): There should a non-iterative analytical formula here. */
|
const double ratio_between_times = actual_time / desired_time;
|
||||||
|
|
||||||
int resolution_divider = 1;
|
/* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our
|
||||||
|
* navigation samples because the equation for calculating the resolution divider is as follows:
|
||||||
|
* "actual_time / desired_time = sqr(resolution_divider) / sample_count".
|
||||||
|
* While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count"
|
||||||
|
* (This relationship is determined in "get_num_samples_during_navigation()"). With some
|
||||||
|
* substitution we end up with "actual_time / desired_time = resolution_divider" while the
|
||||||
|
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
|
||||||
|
* the relationsip of "actual_time / desired_time = resolution_divider" is no longer true,
|
||||||
|
* however the sample count retrieved from "get_num_samples_during_navigation()" is still
|
||||||
|
* accurate if we continue using this assumption. It should be noted that the interaction between
|
||||||
|
* pixel_size, sample count, and resolution divider are automatically accounted for and that's
|
||||||
|
* why pixel_size isn't included in any of the equations. */
|
||||||
|
const int navigation_samples = get_num_samples_during_navigation(
|
||||||
|
ceil_to_int(ratio_between_times));
|
||||||
|
|
||||||
/* This algorithm iterates through resolution dividers until a divider is found that achieves
|
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
|
||||||
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
|
|
||||||
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
|
|
||||||
* pre_resolution_division_samples and post_resolution_division_samples are used in this
|
|
||||||
* calculation to better predict the performance impact of changing resolution divisions as
|
|
||||||
* the sample count can also change between resolution divisions. */
|
|
||||||
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
|
|
||||||
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
resolution_divider = resolution_divider * 2;
|
|
||||||
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolution_divider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE__
|
# define __KERNEL_SSE__
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
# endif
|
# endif
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
|
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
|
||||||
# define KERNEL_STUB
|
# define KERNEL_STUB
|
||||||
#else
|
#else
|
||||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||||
# define __KERNEL_SSE2__
|
# define __KERNEL_SSE2__
|
||||||
# define __KERNEL_SSE3__
|
# define __KERNEL_SSE3__
|
||||||
|
@ -645,7 +645,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
|
|||||||
const int y,
|
const int y,
|
||||||
const half4 half_pixel)
|
const half4 half_pixel)
|
||||||
{
|
{
|
||||||
/* Work around HIP issue with half float display, see T92972. */
|
/* Work around HIP issue with half float display, see #92972. */
|
||||||
#ifdef __KERNEL_HIP__
|
#ifdef __KERNEL_HIP__
|
||||||
ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4;
|
ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4;
|
||||||
out[0] = half_pixel.x;
|
out[0] = half_pixel.x;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "scene/light.h"
|
#include "scene/light.h"
|
||||||
#include "scene/mesh.h"
|
#include "scene/mesh.h"
|
||||||
#include "scene/object.h"
|
#include "scene/object.h"
|
||||||
|
#include "scene/osl.h"
|
||||||
#include "scene/pointcloud.h"
|
#include "scene/pointcloud.h"
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "scene/shader.h"
|
#include "scene/shader.h"
|
||||||
@ -25,7 +26,6 @@
|
|||||||
|
|
||||||
#ifdef WITH_OSL
|
#ifdef WITH_OSL
|
||||||
# include "kernel/osl/globals.h"
|
# include "kernel/osl/globals.h"
|
||||||
# include "kernel/osl/services.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "util/foreach.h"
|
#include "util/foreach.h"
|
||||||
@ -1717,20 +1717,7 @@ void GeometryManager::device_update_displacement_images(Device *device,
|
|||||||
/* If any OSL node is used for displacement, it may reference a texture. But it's
|
/* If any OSL node is used for displacement, it may reference a texture. But it's
|
||||||
* unknown which ones, so have to load them all. */
|
* unknown which ones, so have to load them all. */
|
||||||
if (has_osl_node) {
|
if (has_osl_node) {
|
||||||
set<OSLRenderServices *> services_shared;
|
OSLShaderManager::osl_image_slots(device, image_manager, bump_images);
|
||||||
device->foreach_device([&services_shared](Device *sub_device) {
|
|
||||||
OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
|
|
||||||
services_shared.insert(og->services);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (OSLRenderServices *services : services_shared) {
|
|
||||||
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
|
|
||||||
if (it->second->handle.get_manager() == image_manager) {
|
|
||||||
const int slot = it->second->handle.svm_slot();
|
|
||||||
bump_images.insert(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -394,7 +394,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
|
|||||||
|
|
||||||
/* Compile.
|
/* Compile.
|
||||||
*
|
*
|
||||||
* Mutex protected because the OSL compiler does not appear to be thread safe, see T92503. */
|
* Mutex protected because the OSL compiler does not appear to be thread safe, see #92503. */
|
||||||
static thread_mutex osl_compiler_mutex;
|
static thread_mutex osl_compiler_mutex;
|
||||||
thread_scoped_lock lock(osl_compiler_mutex);
|
thread_scoped_lock lock(osl_compiler_mutex);
|
||||||
|
|
||||||
@ -665,6 +665,27 @@ OSLNode *OSLShaderManager::osl_node(ShaderGraph *graph,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Static function, so only this file needs to be compile with RTTT. */
|
||||||
|
void OSLShaderManager::osl_image_slots(Device *device,
|
||||||
|
ImageManager *image_manager,
|
||||||
|
set<int> &image_slots)
|
||||||
|
{
|
||||||
|
set<OSLRenderServices *> services_shared;
|
||||||
|
device->foreach_device([&services_shared](Device *sub_device) {
|
||||||
|
OSLGlobals *og = (OSLGlobals *)sub_device->get_cpu_osl_memory();
|
||||||
|
services_shared.insert(og->services);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (OSLRenderServices *services : services_shared) {
|
||||||
|
for (auto it = services->textures.begin(); it != services->textures.end(); ++it) {
|
||||||
|
if (it->second->handle.get_manager() == image_manager) {
|
||||||
|
const int slot = it->second->handle.svm_slot();
|
||||||
|
image_slots.insert(slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Graph Compiler */
|
/* Graph Compiler */
|
||||||
|
|
||||||
OSLCompiler::OSLCompiler(OSLShaderManager *manager, OSL::ShadingSystem *ss, Scene *scene)
|
OSLCompiler::OSLCompiler(OSLShaderManager *manager, OSL::ShadingSystem *ss, Scene *scene)
|
||||||
|
@ -92,6 +92,9 @@ class OSLShaderManager : public ShaderManager {
|
|||||||
const std::string &bytecode_hash = "",
|
const std::string &bytecode_hash = "",
|
||||||
const std::string &bytecode = "");
|
const std::string &bytecode = "");
|
||||||
|
|
||||||
|
/* Get image slots used by OSL services on device. */
|
||||||
|
static void osl_image_slots(Device *device, ImageManager *image_manager, set<int> &image_slots);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void texture_system_init();
|
void texture_system_init();
|
||||||
void texture_system_free();
|
void texture_system_free();
|
||||||
|
@ -573,7 +573,7 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||||||
kfilm->is_rec709 = is_rec709;
|
kfilm->is_rec709 = is_rec709;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
|
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/)
|
||||||
{
|
{
|
||||||
dscene->shaders.free();
|
dscene->shaders.free();
|
||||||
}
|
}
|
||||||
|
@ -520,7 +520,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers)
|
|||||||
/* If there is an overscan used for the tile copy pixels into single continuous block of memory
|
/* If there is an overscan used for the tile copy pixels into single continuous block of memory
|
||||||
* without any "gaps".
|
* without any "gaps".
|
||||||
* This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176).
|
* This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176).
|
||||||
* Our task reference: T93008. */
|
* Our task reference: #93008. */
|
||||||
if (tile_params.window_x || tile_params.window_y ||
|
if (tile_params.window_x || tile_params.window_y ||
|
||||||
tile_params.window_width != tile_params.width ||
|
tile_params.window_width != tile_params.width ||
|
||||||
tile_params.window_height != tile_params.height) {
|
tile_params.window_height != tile_params.height) {
|
||||||
|
@ -421,7 +421,7 @@ ccl_device_inline float fast_expf(float x)
|
|||||||
|
|
||||||
#if !defined(__KERNEL_GPU__) && !defined(_MSC_VER)
|
#if !defined(__KERNEL_GPU__) && !defined(_MSC_VER)
|
||||||
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
||||||
* T78047 and T78869 for details. Just disable for now, it only makes
|
* #78047 and #78869 for details. Just disable for now, it only makes
|
||||||
* a small difference in denoising performance. */
|
* a small difference in denoising performance. */
|
||||||
ccl_device float4 fast_exp2f4(float4 x)
|
ccl_device float4 fast_exp2f4(float4 x)
|
||||||
{
|
{
|
||||||
|
@ -516,7 +516,7 @@ GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
|
|||||||
|
|
||||||
/* OpenGL on Metal
|
/* OpenGL on Metal
|
||||||
*
|
*
|
||||||
* Use Metal layer to avoid Viewport lagging on macOS, see T60043. */
|
* Use Metal layer to avoid Viewport lagging on macOS, see #60043. */
|
||||||
|
|
||||||
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
|
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
|
||||||
static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA;
|
static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA;
|
||||||
|
@ -141,7 +141,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
|||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
#else
|
#else
|
||||||
/* Important to initialize only GLXEW (_not_ GLEW),
|
/* Important to initialize only GLXEW (_not_ GLEW),
|
||||||
* since this breaks w/ Mesa's `swrast`, see: T46431. */
|
* since this breaks w/ Mesa's `swrast`, see: #46431. */
|
||||||
glxewInit();
|
glxewInit();
|
||||||
#endif /* USE_GLXEW_INIT_WORKAROUND */
|
#endif /* USE_GLXEW_INIT_WORKAROUND */
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||||||
switch (product_id) {
|
switch (product_id) {
|
||||||
case 0xC62E: /* Plugged in. */
|
case 0xC62E: /* Plugged in. */
|
||||||
case 0xC62F: /* Wireless. */
|
case 0xC62F: /* Wireless. */
|
||||||
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see T82412. */
|
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see #82412. */
|
||||||
{
|
{
|
||||||
device_type_ = NDOF_SpaceMouseWireless;
|
device_type_ = NDOF_SpaceMouseWireless;
|
||||||
hid_map_button_num_ = 2;
|
hid_map_button_num_ = 2;
|
||||||
@ -341,7 +341,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||||||
hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_));
|
hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_));
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, (uint)hid_map_button_mask_);
|
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, uint(hid_map_button_mask_));
|
||||||
|
|
||||||
return device_type_ != NDOF_UnknownDevice;
|
return device_type_ != NDOF_UnknownDevice;
|
||||||
}
|
}
|
||||||
@ -445,14 +445,14 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
|
|||||||
2,
|
2,
|
||||||
"button=%d, press=%d (out of range %d, ignoring!)",
|
"button=%d, press=%d (out of range %d, ignoring!)",
|
||||||
button_number,
|
button_number,
|
||||||
(int)press,
|
int(press),
|
||||||
hid_map_button_num_);
|
hid_map_button_num_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const NDOF_ButtonT button = hid_map_[button_number];
|
const NDOF_ButtonT button = hid_map_[button_number];
|
||||||
if (button == NDOF_BUTTON_NONE) {
|
if (button == NDOF_BUTTON_NONE) {
|
||||||
CLOG_INFO(
|
CLOG_INFO(
|
||||||
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, (int)press);
|
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, int(press));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +460,7 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
|
|||||||
2,
|
2,
|
||||||
"button=%d, press=%d, name=%s",
|
"button=%d, press=%d, name=%s",
|
||||||
button_number,
|
button_number,
|
||||||
(int)press,
|
int(press),
|
||||||
ndof_button_names[button]);
|
ndof_button_names[button]);
|
||||||
|
|
||||||
GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();
|
GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();
|
||||||
|
@ -602,7 +602,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
|||||||
/* NOTE: the `sdl_sub_evt.keysym.sym` is truncated,
|
/* NOTE: the `sdl_sub_evt.keysym.sym` is truncated,
|
||||||
* for unicode support ghost has to be modified. */
|
* for unicode support ghost has to be modified. */
|
||||||
|
|
||||||
/* TODO(@campbellbarton): support full unicode, SDL supports this but it needs to be
|
/* TODO(@ideasman42): support full unicode, SDL supports this but it needs to be
|
||||||
* explicitly enabled via #SDL_StartTextInput which GHOST would have to wrap. */
|
* explicitly enabled via #SDL_StartTextInput which GHOST would have to wrap. */
|
||||||
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
|
char utf8_buf[sizeof(GHOST_TEventKeyData::utf8_buf)] = {'\0'};
|
||||||
if (type == GHOST_kEventKeyDown) {
|
if (type == GHOST_kEventKeyDown) {
|
||||||
|
@ -141,7 +141,7 @@ constexpr size_t events_pending_default_size = 4096 / sizeof(void *);
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
|
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: #98793.
|
||||||
* Even though this has been fixed, at time of writing it's not yet in a release.
|
* Even though this has been fixed, at time of writing it's not yet in a release.
|
||||||
* Workaround the problem by implementing confine with a software cursor.
|
* Workaround the problem by implementing confine with a software cursor.
|
||||||
* While this isn't ideal, it's not adding a lot of overhead as software
|
* While this isn't ideal, it's not adding a lot of overhead as software
|
||||||
@ -176,7 +176,7 @@ static bool use_gnome_confine_hack = false;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
|
* KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
|
||||||
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: T102048.
|
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: #102048.
|
||||||
* See: https://bugs.kde.org/show_bug.cgi?id=461001
|
* See: https://bugs.kde.org/show_bug.cgi?id=461001
|
||||||
*/
|
*/
|
||||||
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
||||||
@ -197,8 +197,8 @@ static bool use_gnome_confine_hack = false;
|
|||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194.
|
* Fix short-cut part of keyboard reading code not properly handling some keys, see: #102194.
|
||||||
* \note This is similar to X11 workaround by the same name, see: T47228.
|
* \note This is similar to X11 workaround by the same name, see: #47228.
|
||||||
*/
|
*/
|
||||||
#define USE_NON_LATIN_KB_WORKAROUND
|
#define USE_NON_LATIN_KB_WORKAROUND
|
||||||
|
|
||||||
@ -241,7 +241,7 @@ enum {
|
|||||||
BTN_STYLUS = 0x14b,
|
BTN_STYLUS = 0x14b,
|
||||||
/** Use as right-mouse. */
|
/** Use as right-mouse. */
|
||||||
BTN_STYLUS2 = 0x14c,
|
BTN_STYLUS2 = 0x14c,
|
||||||
/** NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */
|
/** NOTE(@ideasman42): Map to an additional button (not sure which hardware uses this). */
|
||||||
BTN_STYLUS3 = 0x149,
|
BTN_STYLUS3 = 0x149,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -916,7 +916,7 @@ struct GWL_Display {
|
|||||||
* The main purpose of having an active seat is an alternative from always using the first
|
* The main purpose of having an active seat is an alternative from always using the first
|
||||||
* seat which prevents events from any other seat.
|
* seat which prevents events from any other seat.
|
||||||
*
|
*
|
||||||
* NOTE(@campbellbarton): This could be extended and developed further extended to support
|
* NOTE(@ideasman42): This could be extended and developed further extended to support
|
||||||
* an active seat per window (for e.g.), basic support is sufficient for now as currently isn't
|
* an active seat per window (for e.g.), basic support is sufficient for now as currently isn't
|
||||||
* a widely used feature.
|
* a widely used feature.
|
||||||
*/
|
*/
|
||||||
@ -957,7 +957,7 @@ struct GWL_Display {
|
|||||||
* Needed because #GHOST_System::dispatchEvents fires timers
|
* Needed because #GHOST_System::dispatchEvents fires timers
|
||||||
* outside of WAYLAND (without locking the `timer_mutex`).
|
* outside of WAYLAND (without locking the `timer_mutex`).
|
||||||
*/
|
*/
|
||||||
GHOST_TimerManager *ghost_timer_manager;
|
GHOST_TimerManager *ghost_timer_manager = nullptr;
|
||||||
|
|
||||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||||
};
|
};
|
||||||
@ -1014,8 +1014,10 @@ static void gwl_display_destroy(GWL_Display *display)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Important to remove after the seats which may have key repeat timers active. */
|
/* Important to remove after the seats which may have key repeat timers active. */
|
||||||
|
if (display->ghost_timer_manager) {
|
||||||
delete display->ghost_timer_manager;
|
delete display->ghost_timer_manager;
|
||||||
display->ghost_timer_manager = nullptr;
|
display->ghost_timer_manager = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||||
|
|
||||||
@ -1237,7 +1239,7 @@ static void gwl_registry_entry_remove_all(GWL_Display *display)
|
|||||||
{
|
{
|
||||||
const bool on_exit = true;
|
const bool on_exit = true;
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): Free by slot instead of simply looping over
|
/* NOTE(@ideasman42): Free by slot instead of simply looping over
|
||||||
* `display->registry_entry` so the order of freeing is always predictable.
|
* `display->registry_entry` so the order of freeing is always predictable.
|
||||||
* Otherwise global objects would be feed in the order they are registered.
|
* Otherwise global objects would be feed in the order they are registered.
|
||||||
* While this works in my tests, it could cause difficult to reproduce bugs
|
* While this works in my tests, it could cause difficult to reproduce bugs
|
||||||
@ -1267,7 +1269,7 @@ static void gwl_registry_entry_remove_all(GWL_Display *display)
|
|||||||
* so there is no reason to update all other outputs that an output was removed (for e.g.).
|
* so there is no reason to update all other outputs that an output was removed (for e.g.).
|
||||||
* Pass as -1 to update all slots.
|
* Pass as -1 to update all slots.
|
||||||
*
|
*
|
||||||
* NOTE(@campbellbarton): Updating all other items on a single change is typically worth avoiding.
|
* NOTE(@ideasman42): Updating all other items on a single change is typically worth avoiding.
|
||||||
* In practice this isn't a problem as so there are so few elements in `display->registry_entry`,
|
* In practice this isn't a problem as so there are so few elements in `display->registry_entry`,
|
||||||
* so few use update functions and adding/removal at runtime is rarely called (plugging/unplugging)
|
* so few use update functions and adding/removal at runtime is rarely called (plugging/unplugging)
|
||||||
* hardware for e.g. So while it's possible to store dependency links to avoid unnecessary
|
* hardware for e.g. So while it's possible to store dependency links to avoid unnecessary
|
||||||
@ -1316,7 +1318,7 @@ static void ghost_wl_display_report_error(struct wl_display *display)
|
|||||||
fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode));
|
fprintf(stderr, "The Wayland connection experienced a fatal error: %s\n", strerror(ecode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): The application is running,
|
/* NOTE(@ideasman42): The application is running,
|
||||||
* however an error closes all windows and most importantly:
|
* however an error closes all windows and most importantly:
|
||||||
* shuts down the GPU context (loosing all GPU state - shaders, bind codes etc),
|
* shuts down the GPU context (loosing all GPU state - shaders, bind codes etc),
|
||||||
* so recovering from this effectively involves restarting.
|
* so recovering from this effectively involves restarting.
|
||||||
@ -1326,7 +1328,7 @@ static void ghost_wl_display_report_error(struct wl_display *display)
|
|||||||
* So in practice re-connecting to the display server isn't an option.
|
* So in practice re-connecting to the display server isn't an option.
|
||||||
*
|
*
|
||||||
* Exit since leaving the process open will simply flood the output and do nothing.
|
* Exit since leaving the process open will simply flood the output and do nothing.
|
||||||
* Although as the process is in a valid state, auto-save for e.g. is possible, see: T100855. */
|
* Although as the process is in a valid state, auto-save for e.g. is possible, see: #100855. */
|
||||||
::exit(-1);
|
::exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,7 +1442,7 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
|||||||
|
|
||||||
/* Additional keys for non US layouts. */
|
/* Additional keys for non US layouts. */
|
||||||
|
|
||||||
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */
|
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: #102287. */
|
||||||
GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
|
GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2968,7 +2970,7 @@ static void gesture_pinch_handle_begin(void *data,
|
|||||||
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
if (wl_surface *wl_surface_focus = seat->pointer.wl_surface_window) {
|
||||||
win = ghost_wl_surface_user_data(wl_surface_focus);
|
win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||||
}
|
}
|
||||||
/* NOTE(@campbellbarton): Blender's use of track-pad coordinates is inconsistent and needs work.
|
/* NOTE(@ideasman42): Blender's use of track-pad coordinates is inconsistent and needs work.
|
||||||
* This isn't specific to WAYLAND, in practice they tend to work well enough in most cases.
|
* This isn't specific to WAYLAND, in practice they tend to work well enough in most cases.
|
||||||
* Some operators scale by the UI scale, some don't.
|
* Some operators scale by the UI scale, some don't.
|
||||||
* Even this window scale is not correct because it doesn't account for:
|
* Even this window scale is not correct because it doesn't account for:
|
||||||
@ -2982,7 +2984,7 @@ static void gesture_pinch_handle_begin(void *data,
|
|||||||
*/
|
*/
|
||||||
const wl_fixed_t win_scale = win ? win->scale() : 1;
|
const wl_fixed_t win_scale = win ? win->scale() : 1;
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): Scale factors match Blender's operators & default preferences.
|
/* NOTE(@ideasman42): Scale factors match Blender's operators & default preferences.
|
||||||
* For these values to work correctly, operator logic will need to be changed not to scale input
|
* For these values to work correctly, operator logic will need to be changed not to scale input
|
||||||
* by the region size (as with 3D view zoom) or preference for 3D view orbit sensitivity.
|
* by the region size (as with 3D view zoom) or preference for 3D view orbit sensitivity.
|
||||||
*
|
*
|
||||||
@ -3145,7 +3147,7 @@ static const struct zwp_pointer_gesture_swipe_v1_listener gesture_swipe_listener
|
|||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Listener (Touch Seat), #wl_touch_listener
|
/** \name Listener (Touch Seat), #wl_touch_listener
|
||||||
*
|
*
|
||||||
* NOTE(@campbellbarton): It's not clear if this interface is used by popular compositors.
|
* NOTE(@ideasman42): It's not clear if this interface is used by popular compositors.
|
||||||
* It looks like GNOME/KDE only support `zwp_pointer_gestures_v1_interface`.
|
* It looks like GNOME/KDE only support `zwp_pointer_gestures_v1_interface`.
|
||||||
* If this isn't used anywhere, it could be removed.
|
* If this isn't used anywhere, it could be removed.
|
||||||
* \{ */
|
* \{ */
|
||||||
@ -3806,9 +3808,9 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
|
|||||||
/* Use an empty keyboard state to access key symbol without modifiers. */
|
/* Use an empty keyboard state to access key symbol without modifiers. */
|
||||||
xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state_empty, key);
|
xkb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state_empty, key);
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): Only perform the number-locked lookup as a fallback
|
/* NOTE(@ideasman42): Only perform the number-locked lookup as a fallback
|
||||||
* when a number-pad key has been pressed. This is important as some key-maps use number lock
|
* when a number-pad key has been pressed. This is important as some key-maps use number lock
|
||||||
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: T96170.
|
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: #96170.
|
||||||
* Alternative solutions could be to inspect the layout however this could get involved
|
* Alternative solutions could be to inspect the layout however this could get involved
|
||||||
* and turning on the number-lock is only needed for a limited set of keys. */
|
* and turning on the number-lock is only needed for a limited set of keys. */
|
||||||
|
|
||||||
@ -3936,7 +3938,7 @@ static void keyboard_handle_key(void *data,
|
|||||||
else {
|
else {
|
||||||
/* Key-up from keys that were not repeating cause the repeat timer to pause.
|
/* Key-up from keys that were not repeating cause the repeat timer to pause.
|
||||||
*
|
*
|
||||||
* NOTE(@campbellbarton): This behavior isn't universal, some text input systems will
|
* NOTE(@ideasman42): This behavior isn't universal, some text input systems will
|
||||||
* stop the repeat entirely. Choose to pause repeat instead as this is what GTK/WIN32 do,
|
* stop the repeat entirely. Choose to pause repeat instead as this is what GTK/WIN32 do,
|
||||||
* and it fits better for keyboard input that isn't related to text entry. */
|
* and it fits better for keyboard input that isn't related to text entry. */
|
||||||
timer_action = RESET;
|
timer_action = RESET;
|
||||||
@ -4465,7 +4467,7 @@ static void xdg_output_handle_logical_size(void *data,
|
|||||||
|
|
||||||
#ifdef USE_GNOME_CONFINE_HACK
|
#ifdef USE_GNOME_CONFINE_HACK
|
||||||
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
|
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
|
||||||
* as T98793 has been fixed up-stream too, but not in a release at time of writing. */
|
* as #98793 has been fixed up-stream too, but not in a release at time of writing. */
|
||||||
use_gnome_confine_hack = true;
|
use_gnome_confine_hack = true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -7035,7 +7037,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||||||
UNPACK2(xy_next));
|
UNPACK2(xy_next));
|
||||||
wl_surface_commit(wl_surface);
|
wl_surface_commit(wl_surface);
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): The new cursor position is a hint,
|
/* NOTE(@ideasman42): The new cursor position is a hint,
|
||||||
* it's possible the hint is ignored. It doesn't seem like there is a good way to
|
* it's possible the hint is ignored. It doesn't seem like there is a good way to
|
||||||
* know if the hint will be used or not, at least not immediately. */
|
* know if the hint will be used or not, at least not immediately. */
|
||||||
xy_motion[0] = xy_next[0];
|
xy_motion[0] = xy_next[0];
|
||||||
@ -7078,7 +7080,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
|||||||
if (mode != GHOST_kGrabDisable) {
|
if (mode != GHOST_kGrabDisable) {
|
||||||
if (grab_state_next.use_lock) {
|
if (grab_state_next.use_lock) {
|
||||||
if (!grab_state_prev.use_lock) {
|
if (!grab_state_prev.use_lock) {
|
||||||
/* TODO(@campbellbarton): As WAYLAND does not support warping the pointer it may not be
|
/* TODO(@ideasman42): As WAYLAND does not support warping the pointer it may not be
|
||||||
* possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates.
|
* possible to support #GHOST_kGrabWrap by pragmatically settings it's coordinates.
|
||||||
* An alternative could be to draw the cursor in software (and hide the real cursor),
|
* An alternative could be to draw the cursor in software (and hide the real cursor),
|
||||||
* or just accept a locked cursor on WAYLAND. */
|
* or just accept a locked cursor on WAYLAND. */
|
||||||
|
@ -208,7 +208,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||||||
* Clear all references to this output.
|
* Clear all references to this output.
|
||||||
*
|
*
|
||||||
* \note The compositor should have already called the `wl_surface_listener.leave` callback,
|
* \note The compositor should have already called the `wl_surface_listener.leave` callback,
|
||||||
* however some compositors may not (see T103586).
|
* however some compositors may not (see #103586).
|
||||||
* So remove references to the output before it's destroyed to avoid crashing.
|
* So remove references to the output before it's destroyed to avoid crashing.
|
||||||
*
|
*
|
||||||
* \return true when any references were removed.
|
* \return true when any references were removed.
|
||||||
|
@ -424,10 +424,9 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
|
|||||||
|
|
||||||
processTrackpad();
|
processTrackpad();
|
||||||
|
|
||||||
/* PeekMessage above is allowed to dispatch messages to the wndproc without us
|
/* `PeekMessage` above is allowed to dispatch messages to the `wndproc` without us
|
||||||
* noticing, so we need to check the event manager here to see if there are
|
* noticing, so we need to check the event manager here to see if there are
|
||||||
* events waiting in the queue.
|
* events waiting in the queue. */
|
||||||
*/
|
|
||||||
hasEventHandled |= this->m_eventManager->getNumEvents() > 0;
|
hasEventHandled |= this->m_eventManager->getNumEvents() > 0;
|
||||||
|
|
||||||
} while (waitForEvent && !hasEventHandled);
|
} while (waitForEvent && !hasEventHandled);
|
||||||
@ -566,8 +565,8 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down)
|
|||||||
/**
|
/**
|
||||||
* \note this function can be extended to include other exotic cases as they arise.
|
* \note this function can be extended to include other exotic cases as they arise.
|
||||||
*
|
*
|
||||||
* This function was added in response to bug T25715.
|
* This function was added in response to bug #25715.
|
||||||
* This is going to be a long list T42426.
|
* This is going to be a long list #42426.
|
||||||
*/
|
*/
|
||||||
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
|
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
|
||||||
{
|
{
|
||||||
@ -1080,11 +1079,11 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
|||||||
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
||||||
window->getClientBounds(bounds);
|
window->getClientBounds(bounds);
|
||||||
|
|
||||||
/* WARNING(@campbellbarton): The current warping logic fails to warp on every event,
|
/* WARNING(@ideasman42): The current warping logic fails to warp on every event,
|
||||||
* so the box needs to small enough not to let the cursor escape the window but large
|
* so the box needs to small enough not to let the cursor escape the window but large
|
||||||
* enough that the cursor isn't being warped every time.
|
* enough that the cursor isn't being warped every time.
|
||||||
* If this was not the case it would be less trouble to simply warp the cursor to the
|
* If this was not the case it would be less trouble to simply warp the cursor to the
|
||||||
* center of the screen on every motion, see: D16558 (alternative fix for T102346). */
|
* center of the screen on every motion, see: D16558 (alternative fix for #102346). */
|
||||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||||
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
||||||
@ -1179,7 +1178,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||||||
GHOST_TKey key = system->hardKey(raw, &key_down);
|
GHOST_TKey key = system->hardKey(raw, &key_down);
|
||||||
GHOST_EventKey *event;
|
GHOST_EventKey *event;
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys.
|
/* NOTE(@ideasman42): key repeat in WIN32 also applies to modifier-keys.
|
||||||
* Check for this case and filter out modifier-repeat.
|
* Check for this case and filter out modifier-repeat.
|
||||||
* Typically keyboard events are *not* filtered as part of GHOST's event handling.
|
* Typically keyboard events are *not* filtered as part of GHOST's event handling.
|
||||||
* As other GHOST back-ends don't have the behavior, it's simplest not to send them through.
|
* As other GHOST back-ends don't have the behavior, it's simplest not to send them through.
|
||||||
@ -1210,7 +1209,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||||||
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
||||||
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
||||||
|
|
||||||
/* We can be here with !key_down if processing dead keys (diacritics). See T103119. */
|
/* We can be here with !key_down if processing dead keys (diacritics). See #103119. */
|
||||||
|
|
||||||
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
||||||
if (ctrl_pressed && !alt_pressed) {
|
if (ctrl_pressed && !alt_pressed) {
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
#ifdef WITH_X11_XFIXES
|
#ifdef WITH_X11_XFIXES
|
||||||
# include <X11/extensions/Xfixes.h>
|
# include <X11/extensions/Xfixes.h>
|
||||||
/* Workaround for XWayland grab glitch: T53004. */
|
/* Workaround for XWayland grab glitch: #53004. */
|
||||||
# define WITH_XWAYLAND_HACK
|
# define WITH_XWAYLAND_HACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -71,11 +71,11 @@
|
|||||||
# define USE_XINPUT_HOTPLUG
|
# define USE_XINPUT_HOTPLUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* see T34039 Fix Alt key glitch on Unity desktop */
|
/* see #34039 Fix Alt key glitch on Unity desktop */
|
||||||
#define USE_UNITY_WORKAROUND
|
#define USE_UNITY_WORKAROUND
|
||||||
|
|
||||||
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map
|
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map
|
||||||
* instead of active one. See T47228 and D1746 */
|
* instead of active one. See #47228 and D1746 */
|
||||||
#define USE_NON_LATIN_KB_WORKAROUND
|
#define USE_NON_LATIN_KB_WORKAROUND
|
||||||
|
|
||||||
static uchar bit_is_on(const uchar *ptr, int bit)
|
static uchar bit_is_on(const uchar *ptr, int bit)
|
||||||
@ -278,7 +278,7 @@ uint8_t GHOST_SystemX11::getNumDisplays() const
|
|||||||
void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const
|
void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const
|
||||||
{
|
{
|
||||||
if (m_display) {
|
if (m_display) {
|
||||||
/* NOTE(@campbellbarton): for this to work as documented,
|
/* NOTE(@ideasman42): for this to work as documented,
|
||||||
* we would need to use Xinerama check r54370 for code that did this,
|
* we would need to use Xinerama check r54370 for code that did this,
|
||||||
* we've since removed since its not worth the extra dependency. */
|
* we've since removed since its not worth the extra dependency. */
|
||||||
getAllDisplayDimensions(width, height);
|
getAllDisplayDimensions(width, height);
|
||||||
@ -927,8 +927,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
if (window->getCursorGrabMode() == GHOST_kGrabHide) {
|
||||||
window->getClientBounds(bounds);
|
window->getClientBounds(bounds);
|
||||||
|
|
||||||
/* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`,
|
/* TODO(@ideasman42): warp the cursor to `window->getCursorGrabInitPos`,
|
||||||
* on every motion event, see: D16557 (alternative fix for T102346). */
|
* on every motion event, see: D16557 (alternative fix for #102346). */
|
||||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||||
const int32_t center[2] = {
|
const int32_t center[2] = {
|
||||||
@ -964,7 +964,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
if (x_new != xme.x_root || y_new != xme.y_root) {
|
if (x_new != xme.x_root || y_new != xme.y_root) {
|
||||||
/* Use time of last event to avoid wrapping several times on the 'same' actual wrap.
|
/* Use time of last event to avoid wrapping several times on the 'same' actual wrap.
|
||||||
* Note that we need to deal with X and Y separately as those might wrap at the same time
|
* Note that we need to deal with X and Y separately as those might wrap at the same time
|
||||||
* but still in two different events (corner case, see T74918).
|
* but still in two different events (corner case, see #74918).
|
||||||
* We also have to add a few extra milliseconds of 'padding', as sometimes we get two
|
* We also have to add a few extra milliseconds of 'padding', as sometimes we get two
|
||||||
* close events that will generate extra wrap on the same axis within those few
|
* close events that will generate extra wrap on the same axis within those few
|
||||||
* milliseconds. */
|
* milliseconds. */
|
||||||
@ -1028,7 +1028,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||||||
/* XXX: Code below is kinda awfully convoluted... Issues are:
|
/* XXX: Code below is kinda awfully convoluted... Issues are:
|
||||||
* - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym
|
* - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym
|
||||||
* is unmodified (or anyone swapping the keys with `xmodmap`).
|
* is unmodified (or anyone swapping the keys with `xmodmap`).
|
||||||
* - #XLookupKeysym seems to always use first defined key-map (see T47228), which generates
|
* - #XLookupKeysym seems to always use first defined key-map (see #47228), which generates
|
||||||
* key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps.
|
* key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps.
|
||||||
*
|
*
|
||||||
* To address this, we:
|
* To address this, we:
|
||||||
@ -1715,7 +1715,7 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||||||
|
|
||||||
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
|
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
|
||||||
if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
|
if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
|
||||||
/* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */
|
/* Needed to account for XInput "Coordinate Transformation Matrix", see #48901 */
|
||||||
int device_id;
|
int device_id;
|
||||||
if (XIGetClientPointer(m_display, None, &device_id) != False) {
|
if (XIGetClientPointer(m_display, None, &device_id) != False) {
|
||||||
XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
|
XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
|
||||||
|
@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
||||||
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
||||||
* If this is supported we can add back XINPUT for warping (fixing T48901).
|
* If this is supported we can add back XINPUT for warping (fixing #48901).
|
||||||
* For now disable (see T50383). */
|
* For now disable (see #50383). */
|
||||||
// # define USE_X11_XINPUT_WARP
|
// # define USE_X11_XINPUT_WARP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -669,7 +669,7 @@ static void xdg_surface_handle_configure(void *data,
|
|||||||
GHOST_SystemWayland *system = win->ghost_system;
|
GHOST_SystemWayland *system = win->ghost_system;
|
||||||
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
|
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
|
||||||
if (!is_main_thread) {
|
if (!is_main_thread) {
|
||||||
/* NOTE(@campbellbarton): this only gets one redraw,
|
/* NOTE(@ideasman42): this only gets one redraw,
|
||||||
* I could not find a case where this causes problems. */
|
* I could not find a case where this causes problems. */
|
||||||
gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE);
|
gwl_window_pending_actions_tag(win, PENDING_FRAME_CONFIGURE);
|
||||||
}
|
}
|
||||||
@ -774,7 +774,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||||||
window_->ghost_window = this;
|
window_->ghost_window = this;
|
||||||
window_->ghost_system = system;
|
window_->ghost_system = system;
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): The scale set here to avoid flickering on startup.
|
/* NOTE(@ideasman42): The scale set here to avoid flickering on startup.
|
||||||
* When all monitors use the same scale (which is quite common) there aren't any problems.
|
* When all monitors use the same scale (which is quite common) there aren't any problems.
|
||||||
*
|
*
|
||||||
* When monitors have different scales there may still be a visible window resize on startup.
|
* When monitors have different scales there may still be a visible window resize on startup.
|
||||||
@ -812,12 +812,12 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||||||
* when the `window_->scale` changed. */
|
* when the `window_->scale` changed. */
|
||||||
const int32_t size_min[2] = {320, 240};
|
const int32_t size_min[2] = {320, 240};
|
||||||
|
|
||||||
/* This value is expected to match the base name of the `.desktop` file. see T101805.
|
/* This value is expected to match the base name of the `.desktop` file. see #101805.
|
||||||
*
|
*
|
||||||
* NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
|
* NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
|
||||||
* For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
|
* For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
|
||||||
* simply called `blender.desktop`, so the it's important to follow that name.
|
* simply called `blender.desktop`, so the it's important to follow that name.
|
||||||
* Other distributions such as SNAP & FLATPAK may need to change this value T101779.
|
* Other distributions such as SNAP & FLATPAK may need to change this value #101779.
|
||||||
* Currently there isn't a way to configure this, we may want to support that. */
|
* Currently there isn't a way to configure this, we may want to support that. */
|
||||||
const char *xdg_app_id = (
|
const char *xdg_app_id = (
|
||||||
#ifdef WITH_GHOST_WAYLAND_APP_ID
|
#ifdef WITH_GHOST_WAYLAND_APP_ID
|
||||||
@ -1078,9 +1078,9 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
|
|||||||
|
|
||||||
wl_surface_destroy(window_->wl_surface);
|
wl_surface_destroy(window_->wl_surface);
|
||||||
|
|
||||||
/* NOTE(@campbellbarton): Flushing will often run the appropriate handlers event
|
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
|
||||||
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
|
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
|
||||||
* This is not fool-proof though, hence the call to #window_surface_unref, see: T99078. */
|
* This is not fool-proof though, hence the call to #window_surface_unref, see: #99078. */
|
||||||
wl_display_flush(system_->wl_display());
|
wl_display_flush(system_->wl_display());
|
||||||
|
|
||||||
delete window_;
|
delete window_;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <wayland-util.h> /* For #wl_fixed_t */
|
#include <wayland-util.h> /* For #wl_fixed_t */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define to workaround for a bug/limitation in WAYLAND, see: T100855 & upstream report:
|
* Define to workaround for a bug/limitation in WAYLAND, see: #100855 & upstream report:
|
||||||
* https://gitlab.freedesktop.org/wayland/wayland/-/issues/159
|
* https://gitlab.freedesktop.org/wayland/wayland/-/issues/159
|
||||||
*
|
*
|
||||||
* Consume events from WAYLAND in a thread, this is needed because overflowing the event queue
|
* Consume events from WAYLAND in a thread, this is needed because overflowing the event queue
|
||||||
|
@ -154,7 +154,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parentwindow) {
|
if (parentwindow) {
|
||||||
/* Release any parent capture to allow immediate interaction (T90110). */
|
/* Release any parent capture to allow immediate interaction (#90110). */
|
||||||
::ReleaseCapture();
|
::ReleaseCapture();
|
||||||
parentwindow->lostMouseCapture();
|
parentwindow->lostMouseCapture();
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ void GHOST_WindowX11::refreshXInputDevices()
|
|||||||
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
||||||
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
||||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
* otherwise we do not get any tablet motion event once pen is pressed... See #43367.
|
||||||
*/
|
*/
|
||||||
XEventClass ev;
|
XEventClass ev;
|
||||||
|
|
||||||
@ -1467,7 +1467,7 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Perform this last so to workaround XWayland bug, see: T53004. */
|
/* Perform this last so to workaround XWayland bug, see: #53004. */
|
||||||
if (m_cursorGrab == GHOST_kGrabHide) {
|
if (m_cursorGrab == GHOST_kGrabHide) {
|
||||||
setWindowCursorVisibility(true);
|
setWindowCursorVisibility(true);
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ void bl_locale_set(const char *locale)
|
|||||||
}
|
}
|
||||||
/* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
|
/* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
|
||||||
* like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
|
* like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
|
||||||
* not caught by their ancestor `std::exception`. See T88877#1177108 */
|
* not caught by their ancestor `std::exception`. See #88877#1177108 */
|
||||||
catch (std::runtime_error const &e) {
|
catch (std::runtime_error const &e) {
|
||||||
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
|
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ const char *osx_user_locale()
|
|||||||
[myNSLocale autorelease];
|
[myNSLocale autorelease];
|
||||||
|
|
||||||
// This produces gettext-invalid locale in recent macOS versions (11.4),
|
// This produces gettext-invalid locale in recent macOS versions (11.4),
|
||||||
// like `ko-Kore_KR` instead of `ko_KR`. See T88877.
|
// like `ko-Kore_KR` instead of `ko_KR`. See #88877.
|
||||||
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
||||||
|
|
||||||
const NSString *nsIdentifier = [myNSLocale languageCode];
|
const NSString *nsIdentifier = [myNSLocale languageCode];
|
||||||
|
@ -193,7 +193,7 @@ static bool createGPUShader(OCIO_GPUShader &shader,
|
|||||||
info.fragment_source("gpu_shader_display_transform_frag.glsl");
|
info.fragment_source("gpu_shader_display_transform_frag.glsl");
|
||||||
info.fragment_source_generated = source;
|
info.fragment_source_generated = source;
|
||||||
|
|
||||||
/* T96502: Work around for incorrect OCIO GLSL code generation when using
|
/* #96502: Work around for incorrect OCIO GLSL code generation when using
|
||||||
* GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO.
|
* GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO.
|
||||||
* (currently v2.1.1). */
|
* (currently v2.1.1). */
|
||||||
info.define("inf 1e32");
|
info.define("inf 1e32");
|
||||||
|
@ -145,7 +145,7 @@ const UserDef U_default = {
|
|||||||
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
|
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
|
||||||
NDOF_SHOULD_ROTATE |
|
NDOF_SHOULD_ROTATE |
|
||||||
/* Software from the driver authors follows this convention
|
/* Software from the driver authors follows this convention
|
||||||
* so invert this by default, see: T67579. */
|
* so invert this by default, see: #67579. */
|
||||||
NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
|
NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
|
||||||
NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
|
NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
|
||||||
NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM),
|
NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM),
|
||||||
|
@ -370,6 +370,7 @@ const bTheme U_theme_default = {
|
|||||||
.clipping_border_3d = RGBA(0x3f3f3fff),
|
.clipping_border_3d = RGBA(0x3f3f3fff),
|
||||||
.bundle_solid = RGBA(0xc8c8c8ff),
|
.bundle_solid = RGBA(0xc8c8c8ff),
|
||||||
.camera_path = RGBA(0x000000ff),
|
.camera_path = RGBA(0x000000ff),
|
||||||
|
.camera_passepartout = RGBA(0x000000),
|
||||||
.gp_vertex_size = 3,
|
.gp_vertex_size = 3,
|
||||||
.gp_vertex = RGBA(0x000000ff),
|
.gp_vertex = RGBA(0x000000ff),
|
||||||
.gp_vertex_select = RGBA(0xff8500ff),
|
.gp_vertex_select = RGBA(0xff8500ff),
|
||||||
|
@ -1,41 +1,18 @@
|
|||||||
This folder contains several scripts to smoothen the Blender LTS releases.
|
This folder contains a script to generate release notes and download URLs
|
||||||
|
for Blender LTS releases.
|
||||||
|
|
||||||
create_download_urls.py
|
Ensure required Python modules are installed before running:
|
||||||
=======================
|
|
||||||
|
|
||||||
This python script is used to generate the download urls which we can
|
|
||||||
copy-paste directly into the CMS of www.blender.org.
|
|
||||||
|
|
||||||
Usage: create_download_urls.py --version 2.83.7
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
--version VERSION Version string in the form of {major}.{minor}.{build}
|
|
||||||
(eg 2.83.7)
|
|
||||||
|
|
||||||
The resulting html will be printed to the console.
|
|
||||||
|
|
||||||
create_release_notes.py
|
|
||||||
=======================
|
|
||||||
|
|
||||||
This python script is used to generate the release notes which we can
|
|
||||||
copy-paste directly into the CMS of www.blender.org and stores.
|
|
||||||
|
|
||||||
Usage: ./create_release_notes.py --task=T77348 --version=2.83.7
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
--version VERSION Version string in the form of {major}.{minor}.{build}
|
|
||||||
(e.g. 2.83.7)
|
|
||||||
--task TASK Phabricator ticket that is contains the release notes
|
|
||||||
information (e.g. T77348)
|
|
||||||
--format FORMAT Format the result in `text`, `steam`, `wiki` or `html`
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
============
|
|
||||||
|
|
||||||
* Python 3.8 or later
|
|
||||||
* Python phabricator client version 0.7.0
|
|
||||||
https://pypi.org/project/phabricator/
|
|
||||||
|
|
||||||
For convenience the python modules can be installed using pip
|
|
||||||
|
|
||||||
pip3 install -r ./requirements.txt
|
pip3 install -r ./requirements.txt
|
||||||
|
|
||||||
|
Then run for example:
|
||||||
|
|
||||||
|
./create_release_notes.py --version 3.3.2 --format=html
|
||||||
|
|
||||||
|
Available arguments:
|
||||||
|
|
||||||
|
--version VERSION Version string in the form of {major}.{minor}.{build}
|
||||||
|
(e.g. 3.3.2)
|
||||||
|
--issue ISSUE Gitea issue that is contains the release notes
|
||||||
|
information (e.g. #77348)
|
||||||
|
--format FORMAT Format the result in `text`, `steam`, `wiki` or `html`
|
||||||
|
@ -1,169 +1,46 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import phabricator
|
|
||||||
|
|
||||||
|
import lts_issue
|
||||||
|
import lts_download
|
||||||
|
|
||||||
DESCRIPTION = ("This python script is used to generate the release notes "
|
DESCRIPTION = ("This python script is used to generate the release notes and "
|
||||||
"which we can copy-paste directly into the CMS of "
|
"download URLs which we can copy-paste directly into the CMS of "
|
||||||
"www.blender.org and stores.")
|
"www.blender.org and stores.")
|
||||||
USAGE = "./create_release_notes.py --task=T77348 --version=2.83.7"
|
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
class ReleaseLogLine:
|
parser = argparse.ArgumentParser(description=DESCRIPTION)
|
||||||
"""
|
|
||||||
Class containing the information of a single line of the release log
|
|
||||||
|
|
||||||
Instance attributes:
|
|
||||||
|
|
||||||
* line: (str) the original line used to create this log line
|
|
||||||
* task_id: (int or None) the extracted task id associated with this log
|
|
||||||
line. Can be None if the log line isn't associated with a task.
|
|
||||||
* commit_id: (str or None) the extracted commit id associated with this log
|
|
||||||
line. Only filled when no `task_id` could be found.
|
|
||||||
* ref: (str) `task_id` or `commit_id` of this line, including `T` for tasks
|
|
||||||
or `D` for diffs.
|
|
||||||
* title: (str) title of this log line. When constructed this attribute is
|
|
||||||
an empty string. The called needs to retrieve the title from the
|
|
||||||
backend.
|
|
||||||
* url: (str) url of the ticket task or commit.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, line: str):
|
|
||||||
self.line = line
|
|
||||||
items = line.split("|")
|
|
||||||
self.task_id = None
|
|
||||||
self.commit_id = None
|
|
||||||
try:
|
|
||||||
task_id = int(items[1].strip()[1:])
|
|
||||||
self.task_id = task_id
|
|
||||||
self.ref = f"T{self.task_id}"
|
|
||||||
except ValueError:
|
|
||||||
# no task
|
|
||||||
commit_string = items[3].strip()
|
|
||||||
commits = commit_string.split(",")
|
|
||||||
commit_id = commits[0]
|
|
||||||
commit_id = commit_id.replace("{", "").replace("}", "")
|
|
||||||
if not commit_id.startswith("rB"):
|
|
||||||
commit_id = f"rB{commit_id}"
|
|
||||||
self.commit_id = commit_id
|
|
||||||
|
|
||||||
self.ref = f"{self.commit_id}"
|
|
||||||
|
|
||||||
self.title = ""
|
|
||||||
self.url = f"https://developer.blender.org/{self.ref}"
|
|
||||||
|
|
||||||
def __format_as_html(self) -> str:
|
|
||||||
return f" <li>{self.title} [<a href=\"{self.url}\">{self.ref}</a>]</li>"
|
|
||||||
|
|
||||||
def __format_as_text(self) -> str:
|
|
||||||
return f"* {self.title} [{self.ref}]"
|
|
||||||
|
|
||||||
def __format_as_steam(self) -> str:
|
|
||||||
return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
|
|
||||||
|
|
||||||
def __format_as_wiki(self) -> str:
|
|
||||||
if self.task_id:
|
|
||||||
return f"* {self.title} [{{{{BugReport|{self.task_id}}}}}]"
|
|
||||||
else:
|
|
||||||
return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
|
|
||||||
|
|
||||||
def format(self, format: str) -> str:
|
|
||||||
"""
|
|
||||||
Format this line
|
|
||||||
|
|
||||||
:attr format: the desired format. Possible values are 'text', 'steam' or 'html'
|
|
||||||
:type string:
|
|
||||||
"""
|
|
||||||
if format == 'html':
|
|
||||||
return self.__format_as_html()
|
|
||||||
elif format == 'steam':
|
|
||||||
return self.__format_as_steam()
|
|
||||||
elif format == 'wiki':
|
|
||||||
return self.__format_as_wiki()
|
|
||||||
else:
|
|
||||||
return self.__format_as_text()
|
|
||||||
|
|
||||||
|
|
||||||
def format_title(title: str) -> str:
|
|
||||||
title = title.strip()
|
|
||||||
if not title.endswith("."):
|
|
||||||
title = title + "."
|
|
||||||
return title
|
|
||||||
|
|
||||||
|
|
||||||
def extract_release_notes(version: str, task_id: int):
|
|
||||||
"""
|
|
||||||
Extract all release notes logs
|
|
||||||
|
|
||||||
# Process
|
|
||||||
|
|
||||||
1. Retrieval of description of the given `task_id`.
|
|
||||||
2. Find rows for the given `version` and convert to `ReleaseLogLine`.
|
|
||||||
3. based on the associated task or commit retrieves the title of the log
|
|
||||||
line.
|
|
||||||
"""
|
|
||||||
phab = phabricator.Phabricator()
|
|
||||||
phab.update_interfaces()
|
|
||||||
task = phab.maniphest.info(task_id=task_id)
|
|
||||||
description = task["description"]
|
|
||||||
lines = description.split("\n")
|
|
||||||
start_index = lines.index(f"## Blender {version} ##")
|
|
||||||
lines = lines[start_index + 1:]
|
|
||||||
for line in lines:
|
|
||||||
if not line.strip():
|
|
||||||
continue
|
|
||||||
if line.startswith("| **Report**"):
|
|
||||||
continue
|
|
||||||
if line.startswith("## Blender"):
|
|
||||||
break
|
|
||||||
|
|
||||||
log_line = ReleaseLogLine(line)
|
|
||||||
if log_line.task_id:
|
|
||||||
issue_task = phab.maniphest.info(task_id=log_line.task_id)
|
|
||||||
log_line.title = format_title(issue_task.title)
|
|
||||||
yield log_line
|
|
||||||
elif log_line.commit_id:
|
|
||||||
commits = phab.diffusion.commit.search(constraints={"identifiers": [log_line.commit_id]})
|
|
||||||
commit = commits.data[0]
|
|
||||||
commit_message = commit['fields']['message']
|
|
||||||
commit_title = commit_message.split("\n")[0]
|
|
||||||
log_line.title = format_title(commit_title)
|
|
||||||
yield log_line
|
|
||||||
|
|
||||||
|
|
||||||
def print_release_notes(version: str, format: str, task_id: int):
|
|
||||||
"""
|
|
||||||
Generate and print the release notes to the console.
|
|
||||||
"""
|
|
||||||
if format == 'html':
|
|
||||||
print("<ul>")
|
|
||||||
if format == 'steam':
|
|
||||||
print("[ul]")
|
|
||||||
for log_item in extract_release_notes(version=version, task_id=task_id):
|
|
||||||
print(log_item.format(format=format))
|
|
||||||
if format == 'html':
|
|
||||||
print("</ul>")
|
|
||||||
if format == 'steam':
|
|
||||||
print("[/ul]")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--version",
|
"--version",
|
||||||
required=True,
|
required=True,
|
||||||
help="Version string in the form of {major}.{minor}.{build} (e.g. 2.83.7)")
|
help="Version string in the form of {major}.{minor}.{patch} (e.g. 3.3.2)")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--task",
|
"--issue",
|
||||||
required=True,
|
help="Task that is contains the release notes information (e.g. #77348)")
|
||||||
help="Phabricator ticket that is contains the release notes information (e.g. T77348)")
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--format",
|
"--format",
|
||||||
help="Format the result in `text`, `steam`, `wiki` or `html`",
|
help="Format the result in `text`, `steam`, `wiki` or `html`",
|
||||||
default="text")
|
default="text")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
print_release_notes(version=args.version, format=args.format, task_id=int(args.task[1:]))
|
# Determine issue number
|
||||||
|
version = args.version
|
||||||
|
issue = args.issue
|
||||||
|
if not issue:
|
||||||
|
if version.startswith("2.83."):
|
||||||
|
issue = "#77348"
|
||||||
|
elif version.startswith("2.93."):
|
||||||
|
issue = "#88449"
|
||||||
|
elif version.startswith("3.3."):
|
||||||
|
issue = "#100749"
|
||||||
|
else:
|
||||||
|
raise ValueError("Specify --issue or update script to include issue number for this version")
|
||||||
|
|
||||||
|
# Print
|
||||||
|
if args.format == "html":
|
||||||
|
lts_download.print_urls(version=version)
|
||||||
|
print("")
|
||||||
|
|
||||||
|
lts_issue.print_notes(version=version, format=args.format, issue=issue)
|
||||||
|
20
release/lts/create_download_urls.py → release/lts/lts_download.py
Executable file → Normal file
20
release/lts/create_download_urls.py → release/lts/lts_download.py
Executable file → Normal file
@ -1,14 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
import argparse
|
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
DESCRIPTION = ("This python script is used to generate the download urls "
|
|
||||||
"which we can copy-paste directly into the CMS of "
|
|
||||||
"www.blender.org")
|
|
||||||
USAGE = "create_download_urls --version=2.83.7"
|
|
||||||
# Used date format: "September 30, 2020"
|
# Used date format: "September 30, 2020"
|
||||||
DATE_FORMAT = "%B %d, %Y"
|
DATE_FORMAT = "%B %d, %Y"
|
||||||
|
|
||||||
@ -62,19 +57,8 @@ def generate_html(version: Version) -> str:
|
|||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
def print_download_urls(version: Version):
|
def print_urls(version: str):
|
||||||
"""
|
"""
|
||||||
Generate the download urls and print them to the console.
|
Generate the download urls and print them to the console.
|
||||||
"""
|
"""
|
||||||
print(generate_html(version))
|
print(generate_html(Version(version)))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
parser = argparse.ArgumentParser(description=DESCRIPTION, usage=USAGE)
|
|
||||||
parser.add_argument("--version",
|
|
||||||
required=True,
|
|
||||||
help=("Version string in the form of {major}.{minor}."
|
|
||||||
"{build} (eg 2.83.7)"))
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
print_download_urls(version=Version(args.version))
|
|
169
release/lts/lts_issue.py
Normal file
169
release/lts/lts_issue.py
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
|
||||||
|
class ReleaseLogLine:
|
||||||
|
"""
|
||||||
|
Class containing the information of a single line of the release log
|
||||||
|
|
||||||
|
Instance attributes:
|
||||||
|
|
||||||
|
* line: (str) the original line used to create this log line
|
||||||
|
* issue_id: (int or None) the extracted issue id associated with this log
|
||||||
|
line. Can be None if the log line isn't associated with a issue.
|
||||||
|
* commit_id: (str or None) the extracted commit id associated with this log
|
||||||
|
line. Only filled when no `issue_id` could be found.
|
||||||
|
* ref: (str) `issue_id` or `commit_id` of this line, including `T` for issues
|
||||||
|
or `D` for diffs.
|
||||||
|
* title: (str) title of this log line. When constructed this attribute is
|
||||||
|
an empty string. The called needs to retrieve the title from the
|
||||||
|
backend.
|
||||||
|
* url: (str) url of the ticket issue or commit.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, line: str):
|
||||||
|
self.line = line
|
||||||
|
items = line.split("|")
|
||||||
|
self.issue_id = None
|
||||||
|
self.issue_repo = None
|
||||||
|
self.commit_id = None
|
||||||
|
self.commit_repo = None
|
||||||
|
base_url = "https://projects.blender.org"
|
||||||
|
try:
|
||||||
|
issue_tokens = items[1].strip().split("#")
|
||||||
|
if len(issue_tokens[0]) > 0:
|
||||||
|
self.issue_repo = issue_tokens[0]
|
||||||
|
self.issue_id = issue_tokens[1]
|
||||||
|
else:
|
||||||
|
self.issue_repo = "blender/blender"
|
||||||
|
self.issue_id = issue_tokens[1]
|
||||||
|
|
||||||
|
self.ref = f"#{self.issue_id}"
|
||||||
|
self.url = f"{base_url}/{self.issue_repo}/issues/{self.issue_id}"
|
||||||
|
except IndexError:
|
||||||
|
# no issue
|
||||||
|
commit_string = items[3].strip()
|
||||||
|
commit_string = commit_string.split(",")[0]
|
||||||
|
commit_string = commit_string.split("]")[0]
|
||||||
|
commit_string = commit_string.replace("[", "")
|
||||||
|
|
||||||
|
commit_tokens = commit_string.split("@")
|
||||||
|
if len(commit_tokens) > 1:
|
||||||
|
self.commit_repo = commit_tokens[0]
|
||||||
|
self.commit_id = commit_tokens[1]
|
||||||
|
else:
|
||||||
|
self.commit_repo = "blender/blender"
|
||||||
|
self.commit_id = commit_tokens[0]
|
||||||
|
|
||||||
|
self.ref = f"{self.commit_id}"
|
||||||
|
self.url = f"{base_url}/{self.commit_repo}/commit/{self.commit_id}"
|
||||||
|
|
||||||
|
self.title = ""
|
||||||
|
|
||||||
|
def __format_as_html(self) -> str:
|
||||||
|
return f" <li>{self.title} [<a href=\"{self.url}\">{self.ref}</a>]</li>"
|
||||||
|
|
||||||
|
def __format_as_text(self) -> str:
|
||||||
|
return f"* {self.title} [{self.ref}]"
|
||||||
|
|
||||||
|
def __format_as_steam(self) -> str:
|
||||||
|
return f"* {self.title} ([url={self.url}]{self.ref}[/url])"
|
||||||
|
|
||||||
|
def __format_as_wiki(self) -> str:
|
||||||
|
if self.issue_id:
|
||||||
|
return f"* {self.title} [{{{{BugReport|{self.issue_id}}}}}]"
|
||||||
|
else:
|
||||||
|
return f"* {self.title} [{{{{GitCommit|{self.commit_id[2:]}}}}}]"
|
||||||
|
|
||||||
|
def format(self, format: str) -> str:
|
||||||
|
"""
|
||||||
|
Format this line
|
||||||
|
|
||||||
|
:attr format: the desired format. Possible values are 'text', 'steam' or 'html'
|
||||||
|
:type string:
|
||||||
|
"""
|
||||||
|
if format == 'html':
|
||||||
|
return self.__format_as_html()
|
||||||
|
elif format == 'steam':
|
||||||
|
return self.__format_as_steam()
|
||||||
|
elif format == 'wiki':
|
||||||
|
return self.__format_as_wiki()
|
||||||
|
else:
|
||||||
|
return self.__format_as_text()
|
||||||
|
|
||||||
|
|
||||||
|
def format_title(title: str) -> str:
|
||||||
|
title = title.strip()
|
||||||
|
if not title.endswith("."):
|
||||||
|
title = title + "."
|
||||||
|
return title
|
||||||
|
|
||||||
|
|
||||||
|
def extract_release_notes(version: str, issue: str):
|
||||||
|
"""
|
||||||
|
Extract all release notes logs
|
||||||
|
|
||||||
|
# Process
|
||||||
|
|
||||||
|
1. Retrieval of description of the given `issue_id`.
|
||||||
|
2. Find rows for the given `version` and convert to `ReleaseLogLine`.
|
||||||
|
3. based on the associated issue or commit retrieves the title of the log
|
||||||
|
line.
|
||||||
|
"""
|
||||||
|
base_url = "https://projects.blender.org/api/v1/repos"
|
||||||
|
issues_url = base_url + "/blender/blender/issues/"
|
||||||
|
headers = {'accept': 'application/json'}
|
||||||
|
|
||||||
|
response = requests.get(issues_url + issue[1:], headers=headers)
|
||||||
|
description = response.json()["body"]
|
||||||
|
|
||||||
|
lines = description.split("\n")
|
||||||
|
start_index = lines.index(f"## Blender {version}")
|
||||||
|
lines = lines[start_index + 1:]
|
||||||
|
for line in lines:
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
if line.startswith("| **Report**"):
|
||||||
|
continue
|
||||||
|
if line.startswith("## Blender"):
|
||||||
|
break
|
||||||
|
if line.find("| -- |") != -1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
log_line = ReleaseLogLine(line)
|
||||||
|
if log_line.issue_id:
|
||||||
|
issue_url = f"{base_url}/{log_line.issue_repo}/issues/{log_line.issue_id}"
|
||||||
|
response = requests.get(issue_url, headers=headers)
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise ValueError("Issue not found: " + str(log_line.issue_id))
|
||||||
|
|
||||||
|
log_line.title = format_title(response.json()["title"])
|
||||||
|
yield log_line
|
||||||
|
elif log_line.commit_id:
|
||||||
|
commit_url = f"{base_url}/{log_line.commit_repo}/git/commits/{log_line.commit_id}"
|
||||||
|
response = requests.get(commit_url, headers=headers)
|
||||||
|
if response.status_code != 200:
|
||||||
|
raise ValueError("Commit not found: " + log_line.commit_id)
|
||||||
|
|
||||||
|
commit_message = response.json()['commit']['message']
|
||||||
|
commit_title = commit_message.split("\n")[0]
|
||||||
|
log_line.title = format_title(commit_title)
|
||||||
|
yield log_line
|
||||||
|
|
||||||
|
|
||||||
|
def print_notes(version: str, format: str, issue: str):
|
||||||
|
"""
|
||||||
|
Generate and print the release notes to the console.
|
||||||
|
"""
|
||||||
|
if format == 'html':
|
||||||
|
print("<ul>")
|
||||||
|
if format == 'steam':
|
||||||
|
print("[ul]")
|
||||||
|
for log_item in extract_release_notes(version=version, issue=issue):
|
||||||
|
print(log_item.format(format=format))
|
||||||
|
if format == 'html':
|
||||||
|
print("</ul>")
|
||||||
|
if format == 'steam':
|
||||||
|
print("[/ul]")
|
@ -1 +1 @@
|
|||||||
phabricator==0.7.0
|
requests
|
||||||
|
@ -286,7 +286,7 @@ class pySketchyChainingIterator(ChainingIterator):
|
|||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
# This is a fatal error condition: self.current_edge must be found
|
# This is a fatal error condition: self.current_edge must be found
|
||||||
# among the edges seen by the AdjacencyIterator [bug T35695].
|
# among the edges seen by the AdjacencyIterator [bug #35695].
|
||||||
if bpy.app.debug_freestyle:
|
if bpy.app.debug_freestyle:
|
||||||
print('pySketchyChainingIterator: current edge not found')
|
print('pySketchyChainingIterator: current edge not found')
|
||||||
return None
|
return None
|
||||||
|
@ -487,7 +487,7 @@ def disable_all():
|
|||||||
|
|
||||||
|
|
||||||
def _blender_manual_url_prefix():
|
def _blender_manual_url_prefix():
|
||||||
return "https://docs.blender.org/manual/en/%d.%d" % _bpy.app.version[:2]
|
return "https://docs.blender.org/manual/%s/%d.%d" % (_bpy.utils.manual_language_code(), *_bpy.app.version[:2])
|
||||||
|
|
||||||
|
|
||||||
def module_bl_info(mod, *, info_basis=None):
|
def module_bl_info(mod, *, info_basis=None):
|
||||||
|
@ -113,7 +113,7 @@ def expand(line, cursor, namespace, *, private=True):
|
|||||||
if len(matches) == 1:
|
if len(matches) == 1:
|
||||||
scrollback = ''
|
scrollback = ''
|
||||||
else:
|
else:
|
||||||
# causes blender bug T27495 since string keys may contain '.'
|
# causes blender bug #27495 since string keys may contain '.'
|
||||||
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||||
|
|
||||||
# add white space to align with the cursor
|
# add white space to align with the cursor
|
||||||
|
@ -32,7 +32,7 @@ class _BPyOpsSubModOp:
|
|||||||
# XXX You never quite know what you get from bpy.types,
|
# XXX You never quite know what you get from bpy.types,
|
||||||
# with operators... Operator and OperatorProperties
|
# with operators... Operator and OperatorProperties
|
||||||
# are shadowing each other, and not in the same way for
|
# are shadowing each other, and not in the same way for
|
||||||
# native ops and py ones! See T39158.
|
# native ops and py ones! See #39158.
|
||||||
# op_class = getattr(bpy.types, idname)
|
# op_class = getattr(bpy.types, idname)
|
||||||
op_class = _op_get_rna_type(idname)
|
op_class = _op_get_rna_type(idname)
|
||||||
descr = op_class.description
|
descr = op_class.description
|
||||||
|
@ -26,6 +26,7 @@ __all__ = (
|
|||||||
"register_tool",
|
"register_tool",
|
||||||
"make_rna_paths",
|
"make_rna_paths",
|
||||||
"manual_map",
|
"manual_map",
|
||||||
|
"manual_language_code",
|
||||||
"previews",
|
"previews",
|
||||||
"resource_path",
|
"resource_path",
|
||||||
"script_path_user",
|
"script_path_user",
|
||||||
@ -1002,11 +1003,11 @@ def unregister_tool(tool_cls):
|
|||||||
|
|
||||||
# we start with the built-in default mapping
|
# we start with the built-in default mapping
|
||||||
def _blender_default_map():
|
def _blender_default_map():
|
||||||
import rna_manual_reference as ref_mod
|
# NOTE(@ideasman42): Avoid importing this as there is no need to keep the lookup table in memory.
|
||||||
ret = (ref_mod.url_manual_prefix, ref_mod.url_manual_mapping)
|
# As this runs when the user accesses the "Online Manual", the overhead loading the file is acceptable.
|
||||||
# avoid storing in memory
|
# In my tests it's under 1/100th of a second loading from a `pyc`.
|
||||||
del _sys.modules["rna_manual_reference"]
|
ref_mod = execfile(_os.path.join(_script_base_dir, "modules", "rna_manual_reference.py"))
|
||||||
return ret
|
return (ref_mod.url_manual_prefix, ref_mod.url_manual_mapping)
|
||||||
|
|
||||||
|
|
||||||
# hooks for doc lookups
|
# hooks for doc lookups
|
||||||
@ -1035,6 +1036,53 @@ def manual_map():
|
|||||||
yield prefix, url_manual_mapping
|
yield prefix, url_manual_mapping
|
||||||
|
|
||||||
|
|
||||||
|
# Languages which are supported by the user manual (commented when there is no translation).
|
||||||
|
_manual_language_codes = {
|
||||||
|
"ar_EG": "ar", # Arabic
|
||||||
|
# "bg_BG": "bg", # Bulgarian
|
||||||
|
# "ca_AD": "ca", # Catalan
|
||||||
|
# "cs_CZ": "cz", # Czech
|
||||||
|
"de_DE": "de", # German
|
||||||
|
# "el_GR": "el", # Greek
|
||||||
|
"es": "es", # Spanish
|
||||||
|
"fi_FI": "fi", # Finnish
|
||||||
|
"fr_FR": "fr", # French
|
||||||
|
"id_ID": "id", # Indonesian
|
||||||
|
"it_IT": "it", # Italian
|
||||||
|
"ja_JP": "ja", # Japanese
|
||||||
|
"ko_KR": "ko", # Korean
|
||||||
|
# "nb": "nb", # Norwegian
|
||||||
|
# "nl_NL": "nl", # Dutch
|
||||||
|
# "pl_PL": "pl", # Polish
|
||||||
|
"pt_PT": "pt", # Portuguese
|
||||||
|
# Portuguese - Brazil, for until we have a pt_BR version.
|
||||||
|
"pt_BR": "pt",
|
||||||
|
"ru_RU": "ru", # Russian
|
||||||
|
"sk_SK": "sk", # Slovak
|
||||||
|
# "sl": "sl", # Slovenian
|
||||||
|
"sr_RS": "sr", # Serbian
|
||||||
|
# "sv_SE": "sv", # Swedish
|
||||||
|
# "tr_TR": "th", # Thai
|
||||||
|
"uk_UA": "uk", # Ukrainian
|
||||||
|
"vi_VN": "vi", # Vietnamese
|
||||||
|
"zh_CN": "zh-hans", # Simplified Chinese
|
||||||
|
"zh_TW": "zh-hant", # Traditional Chinese
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def manual_language_code(default="en"):
|
||||||
|
"""
|
||||||
|
:return:
|
||||||
|
The language code used for user manual URL component based on the current language user-preference,
|
||||||
|
falling back to the ``default`` when unavailable.
|
||||||
|
:rtype: str
|
||||||
|
"""
|
||||||
|
language = _bpy.context.preferences.view.language
|
||||||
|
if language == 'DEFAULT':
|
||||||
|
language = _os.getenv("LANG", "").split(".")[0]
|
||||||
|
return _manual_language_codes.get(language, default)
|
||||||
|
|
||||||
|
|
||||||
# Build an RNA path from struct/property/enum names.
|
# Build an RNA path from struct/property/enum names.
|
||||||
def make_rna_paths(struct_name, prop_name, enum_name):
|
def make_rna_paths(struct_name, prop_name, enum_name):
|
||||||
"""
|
"""
|
||||||
|
@ -259,15 +259,15 @@ def bake_action_iter(
|
|||||||
if is_new_action:
|
if is_new_action:
|
||||||
action = bpy.data.actions.new("Action")
|
action = bpy.data.actions.new("Action")
|
||||||
|
|
||||||
# Only leave tweak mode if we actually need to modify the action (T57159)
|
# Only leave tweak mode if we actually need to modify the action (#57159)
|
||||||
if action != atd.action:
|
if action != atd.action:
|
||||||
# Leave tweak mode before trying to modify the action (T48397)
|
# Leave tweak mode before trying to modify the action (#48397)
|
||||||
if atd.use_tweak_mode:
|
if atd.use_tweak_mode:
|
||||||
atd.use_tweak_mode = False
|
atd.use_tweak_mode = False
|
||||||
|
|
||||||
atd.action = action
|
atd.action = action
|
||||||
|
|
||||||
# Baking the action only makes sense in Replace mode, so force it (T69105)
|
# Baking the action only makes sense in Replace mode, so force it (#69105)
|
||||||
if not atd.use_tweak_mode:
|
if not atd.use_tweak_mode:
|
||||||
atd.action_blend_type = 'REPLACE'
|
atd.action_blend_type = 'REPLACE'
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'):
|
|||||||
"""
|
"""
|
||||||
def wrapper(cls):
|
def wrapper(cls):
|
||||||
# Without that, we may end up adding those fields to some **parent** class' __annotations__ property
|
# Without that, we may end up adding those fields to some **parent** class' __annotations__ property
|
||||||
# (like the ImportHelper or ExportHelper ones)! See T58772.
|
# (like the ImportHelper or ExportHelper ones)! See #58772.
|
||||||
if "__annotations__" not in cls.__dict__:
|
if "__annotations__" not in cls.__dict__:
|
||||||
setattr(cls, "__annotations__", {})
|
setattr(cls, "__annotations__", {})
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ class Mesh(bpy_types.ID):
|
|||||||
|
|
||||||
face_lengths = tuple(map(len, faces))
|
face_lengths = tuple(map(len, faces))
|
||||||
|
|
||||||
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: T90268.
|
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: #90268.
|
||||||
vertices_len = len(vertices)
|
vertices_len = len(vertices)
|
||||||
edges_len = len(edges)
|
edges_len = len(edges)
|
||||||
faces_len = len(faces)
|
faces_len = len(faces)
|
||||||
|
@ -4,38 +4,10 @@
|
|||||||
# autopep8: off
|
# autopep8: off
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
manual_version = '%d.%d' % bpy.app.version[:2]
|
url_manual_prefix = "https://docs.blender.org/manual/%s/%d.%d/" % (
|
||||||
|
bpy.utils.manual_language_code(),
|
||||||
url_manual_prefix = "https://docs.blender.org/manual/en/" + manual_version + "/"
|
*bpy.app.version[:2],
|
||||||
|
)
|
||||||
language = bpy.context.preferences.view.language
|
|
||||||
if language == 'DEFAULT':
|
|
||||||
import os
|
|
||||||
language = os.getenv('LANG', '').split('.')[0]
|
|
||||||
|
|
||||||
LANG = {
|
|
||||||
"ar_EG": "ar",
|
|
||||||
"de_DE": "de",
|
|
||||||
"es": "es",
|
|
||||||
"fi_FI": "fi",
|
|
||||||
"fr_FR": "fr",
|
|
||||||
"id_ID": "id",
|
|
||||||
"it_IT": "it",
|
|
||||||
"ja_JP": "ja",
|
|
||||||
"ko_KR": "ko",
|
|
||||||
"pt_PT": "pt",
|
|
||||||
"pt_BR": "pt",
|
|
||||||
"ru_RU": "ru",
|
|
||||||
"sk_SK": "sk",
|
|
||||||
"sr_RS": "sr",
|
|
||||||
"uk_UA": "uk",
|
|
||||||
"vi_VN": "vi",
|
|
||||||
"zh_CN": "zh-hans",
|
|
||||||
"zh_TW": "zh-hant",
|
|
||||||
}.get(language)
|
|
||||||
|
|
||||||
if LANG is not None:
|
|
||||||
url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG)
|
|
||||||
|
|
||||||
url_manual_mapping = (
|
url_manual_mapping = (
|
||||||
("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"),
|
("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"),
|
||||||
@ -641,7 +613,6 @@ url_manual_mapping = (
|
|||||||
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
|
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
|
||||||
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
|
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
|
||||||
("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
|
("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
|
||||||
("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"),
|
|
||||||
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
|
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
|
||||||
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
|
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
|
||||||
("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"),
|
("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"),
|
||||||
@ -672,7 +643,7 @@ url_manual_mapping = (
|
|||||||
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
|
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
|
||||||
("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
|
("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
|
||||||
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
|
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
|
||||||
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
|
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_group_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
|
||||||
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
|
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
|
||||||
("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"),
|
("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"),
|
||||||
("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"),
|
("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"),
|
||||||
@ -1417,6 +1388,7 @@ url_manual_mapping = (
|
|||||||
("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"),
|
("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"),
|
||||||
("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"),
|
("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"),
|
||||||
("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"),
|
("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"),
|
||||||
|
("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"),
|
||||||
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
||||||
("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"),
|
("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"),
|
||||||
("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"),
|
("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"),
|
||||||
@ -2055,7 +2027,6 @@ url_manual_mapping = (
|
|||||||
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
||||||
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
||||||
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
||||||
("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
|
|
||||||
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
|
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
|
||||||
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
|
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
|
||||||
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
|
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
|
||||||
@ -2111,7 +2082,6 @@ url_manual_mapping = (
|
|||||||
("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"),
|
("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"),
|
||||||
("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"),
|
("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"),
|
||||||
("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"),
|
("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"),
|
||||||
("bpy.types.geometrynodematerial*", "-1"),
|
|
||||||
("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"),
|
("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"),
|
||||||
("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"),
|
("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"),
|
||||||
("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"),
|
("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"),
|
||||||
|
@ -86,7 +86,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||||||
update=update_fn,
|
update=update_fn,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Experimental: only show with developer extras, see: T96544.
|
# Experimental: only show with developer extras, see: #96544.
|
||||||
use_tweak_select_passthrough: BoolProperty(
|
use_tweak_select_passthrough: BoolProperty(
|
||||||
name="Tweak Select: Mouse Select & Move",
|
name="Tweak Select: Mouse Select & Move",
|
||||||
description=(
|
description=(
|
||||||
@ -96,7 +96,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||||||
default=False,
|
default=False,
|
||||||
update=update_fn,
|
update=update_fn,
|
||||||
)
|
)
|
||||||
# Experimental: only show with developer extras, see: T96544.
|
# Experimental: only show with developer extras, see: #96544.
|
||||||
use_tweak_tool_lmb_interaction: BoolProperty(
|
use_tweak_tool_lmb_interaction: BoolProperty(
|
||||||
name="Tweak Tool: Left Mouse Select & Move",
|
name="Tweak Tool: Left Mouse Select & Move",
|
||||||
description=(
|
description=(
|
||||||
|
@ -37,7 +37,7 @@ class Params:
|
|||||||
# instead be bound to a binding that doesn't de-select all, this way:
|
# instead be bound to a binding that doesn't de-select all, this way:
|
||||||
# - Click-drag moves the current selection.
|
# - Click-drag moves the current selection.
|
||||||
# - Click selects only the item at the cursor position.
|
# - Click selects only the item at the cursor position.
|
||||||
# See: T97032.
|
# See: #97032.
|
||||||
"use_tweak_select_passthrough",
|
"use_tweak_select_passthrough",
|
||||||
"use_tweak_tool_lmb_interaction",
|
"use_tweak_tool_lmb_interaction",
|
||||||
"use_mouse_emulate_3_button",
|
"use_mouse_emulate_3_button",
|
||||||
@ -465,7 +465,7 @@ def _template_items_tool_select(
|
|||||||
fallback=False,
|
fallback=False,
|
||||||
):
|
):
|
||||||
if not params.legacy and not fallback:
|
if not params.legacy and not fallback:
|
||||||
# Experimental support for LMB interaction for the tweak tool. see: T96544.
|
# Experimental support for LMB interaction for the tweak tool. see: #96544.
|
||||||
# NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB.
|
# NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB.
|
||||||
# For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor).
|
# For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor).
|
||||||
select_passthrough = False
|
select_passthrough = False
|
||||||
@ -498,7 +498,7 @@ def _template_items_tool_select(
|
|||||||
{"properties": [("toggle", True), *operator_props]}),
|
{"properties": [("toggle", True), *operator_props]}),
|
||||||
|
|
||||||
# Fallback key-map must transform as the primary tool is expected
|
# Fallback key-map must transform as the primary tool is expected
|
||||||
# to be accessed via gizmos in this case. See: T96885.
|
# to be accessed via gizmos in this case. See: #96885.
|
||||||
*(() if not fallback else (
|
*(() if not fallback else (
|
||||||
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
||||||
{"properties": [("release_confirm", True)]}),
|
{"properties": [("release_confirm", True)]}),
|
||||||
@ -3478,7 +3478,8 @@ def km_animation_channels(params):
|
|||||||
# Selection.
|
# Selection.
|
||||||
*_template_items_select_actions(params, "anim.channels_select_all"),
|
*_template_items_select_actions(params, "anim.channels_select_all"),
|
||||||
("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None),
|
("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None),
|
||||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, None),
|
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
||||||
|
{"properties": [("extend", False)]}),
|
||||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True},
|
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True},
|
||||||
{"properties": [("extend", True)]}),
|
{"properties": [("extend", True)]}),
|
||||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True},
|
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True},
|
||||||
@ -4729,7 +4730,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal
|
|||||||
|
|
||||||
def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
|
def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
|
||||||
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
|
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
|
||||||
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See T92467.
|
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467.
|
||||||
|
|
||||||
props_vert_without_handles = ()
|
props_vert_without_handles = ()
|
||||||
if select_passthrough:
|
if select_passthrough:
|
||||||
@ -5627,6 +5628,7 @@ def km_curves(params):
|
|||||||
("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
|
("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
|
||||||
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
|
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
|
||||||
*_template_items_select_actions(params, "curves.select_all"),
|
*_template_items_select_actions(params, "curves.select_all"),
|
||||||
|
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||||
])
|
])
|
||||||
|
|
||||||
return keymap
|
return keymap
|
||||||
@ -5681,7 +5683,7 @@ def km_object_non_modal(params):
|
|||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
items.extend([
|
items.extend([
|
||||||
# NOTE: this shortcut (while not temporary) is not ideal, see: T89757.
|
# NOTE: this shortcut (while not temporary) is not ideal, see: #89757.
|
||||||
("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None),
|
("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None),
|
||||||
])
|
])
|
||||||
|
|
||||||
@ -6344,6 +6346,8 @@ def km_node_link_modal_map(_params):
|
|||||||
return keymap
|
return keymap
|
||||||
|
|
||||||
# Fallback for gizmos that don't have custom a custom key-map.
|
# Fallback for gizmos that don't have custom a custom key-map.
|
||||||
|
|
||||||
|
|
||||||
def km_generic_gizmo(_params):
|
def km_generic_gizmo(_params):
|
||||||
keymap = (
|
keymap = (
|
||||||
"Generic Gizmo",
|
"Generic Gizmo",
|
||||||
|
@ -790,7 +790,7 @@ class TransformsToDeltasAnim(Operator):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# first pass over F-Curves: ensure that we don't have conflicting
|
# first pass over F-Curves: ensure that we don't have conflicting
|
||||||
# transforms already (e.g. if this was applied already) T29110.
|
# transforms already (e.g. if this was applied already) #29110.
|
||||||
existingFCurves = {}
|
existingFCurves = {}
|
||||||
for fcu in adt.action.fcurves:
|
for fcu in adt.action.fcurves:
|
||||||
# get "delta" path - i.e. the final paths which may clash
|
# get "delta" path - i.e. the final paths which may clash
|
||||||
|
@ -700,7 +700,7 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||||||
addons_new.discard("modules")
|
addons_new.discard("modules")
|
||||||
|
|
||||||
# disable any addons we may have enabled previously and removed.
|
# disable any addons we may have enabled previously and removed.
|
||||||
# this is unlikely but do just in case. bug T23978.
|
# this is unlikely but do just in case. bug #23978.
|
||||||
for new_addon in addons_new:
|
for new_addon in addons_new:
|
||||||
addon_utils.disable(new_addon, default_set=True)
|
addon_utils.disable(new_addon, default_set=True)
|
||||||
|
|
||||||
|
@ -581,7 +581,7 @@ class LightMapPack(Operator):
|
|||||||
# Proper solution would be to make undo stack aware of such things,
|
# Proper solution would be to make undo stack aware of such things,
|
||||||
# but for now just disable redo. Keep undo here so unwanted changes to uv
|
# but for now just disable redo. Keep undo here so unwanted changes to uv
|
||||||
# coords might be undone.
|
# coords might be undone.
|
||||||
# This fixes infinite image creation reported there T30968 (sergey)
|
# This fixes infinite image creation reported there #30968 (sergey)
|
||||||
bl_options = {'UNDO'}
|
bl_options = {'UNDO'}
|
||||||
|
|
||||||
PREF_CONTEXT: bpy.props.EnumProperty(
|
PREF_CONTEXT: bpy.props.EnumProperty(
|
||||||
|
@ -90,7 +90,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
|||||||
tone_range = max_tone - min_tone
|
tone_range = max_tone - min_tone
|
||||||
|
|
||||||
if tone_range < 0.0001:
|
if tone_range < 0.0001:
|
||||||
# weak, don't cancel, see T43345
|
# weak, don't cancel, see #43345
|
||||||
tone_range = 0.0
|
tone_range = 0.0
|
||||||
else:
|
else:
|
||||||
tone_range = 1.0 / tone_range
|
tone_range = 1.0 / tone_range
|
||||||
|
@ -42,7 +42,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||||||
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
||||||
|
|
||||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||||
# and cause this one not to be freed. T24671.
|
# and cause this one not to be freed. #24671.
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def invoke(self, context, _event):
|
def invoke(self, context, _event):
|
||||||
@ -104,7 +104,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||||||
'INVOKE_REGION_WIN',
|
'INVOKE_REGION_WIN',
|
||||||
TRANSFORM_OT_translate={
|
TRANSFORM_OT_translate={
|
||||||
# Don't set the constraint axis since users will expect MMB
|
# Don't set the constraint axis since users will expect MMB
|
||||||
# to use the user setting, see: T61637
|
# to use the user setting, see: #61637
|
||||||
# "orient_type": 'NORMAL',
|
# "orient_type": 'NORMAL',
|
||||||
# Not a popular choice, too restrictive for retopo.
|
# Not a popular choice, too restrictive for retopo.
|
||||||
# "constraint_axis": (True, True, False)})
|
# "constraint_axis": (True, True, False)})
|
||||||
@ -114,7 +114,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||||||
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
||||||
|
|
||||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||||
# and cause this one not to be freed. T24671.
|
# and cause this one not to be freed. #24671.
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
@ -1056,7 +1056,7 @@ class WM_OT_url_open_preset(Operator):
|
|||||||
return "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2]
|
return "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2]
|
||||||
|
|
||||||
def _url_from_manual(self, _context):
|
def _url_from_manual(self, _context):
|
||||||
return "https://docs.blender.org/manual/en/%d.%d/" % bpy.app.version[:2]
|
return "https://docs.blender.org/manual/%s/%d.%d/" % (bpy.utils.manual_language_code(), *bpy.app.version[:2])
|
||||||
|
|
||||||
def _url_from_api(self, _context):
|
def _url_from_api(self, _context):
|
||||||
return "https://docs.blender.org/api/%d.%d/" % bpy.app.version[:2]
|
return "https://docs.blender.org/api/%d.%d/" % bpy.app.version[:2]
|
||||||
@ -1725,7 +1725,7 @@ class WM_OT_properties_edit(Operator):
|
|||||||
for nt in adt.nla_tracks:
|
for nt in adt.nla_tracks:
|
||||||
_update_strips(nt.strips)
|
_update_strips(nt.strips)
|
||||||
|
|
||||||
# Otherwise existing buttons which reference freed memory may crash Blender (T26510).
|
# Otherwise existing buttons which reference freed memory may crash Blender (#26510).
|
||||||
for win in context.window_manager.windows:
|
for win in context.window_manager.windows:
|
||||||
for area in win.screen.areas:
|
for area in win.screen.areas:
|
||||||
area.tag_redraw()
|
area.tag_redraw()
|
||||||
|
@ -35,19 +35,10 @@ def draw_node_group_add_menu(context, layout):
|
|||||||
if node_tree:
|
if node_tree:
|
||||||
from nodeitems_builtins import node_tree_group_type
|
from nodeitems_builtins import node_tree_group_type
|
||||||
|
|
||||||
def contains_group(nodetree, group):
|
|
||||||
if nodetree == group:
|
|
||||||
return True
|
|
||||||
for node in nodetree.nodes:
|
|
||||||
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
|
|
||||||
if contains_group(node.node_tree, group):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
groups = [
|
groups = [
|
||||||
group for group in context.blend_data.node_groups
|
group for group in context.blend_data.node_groups
|
||||||
if (group.bl_idname == node_tree.bl_idname and
|
if (group.bl_idname == node_tree.bl_idname and
|
||||||
not contains_group(group, node_tree) and
|
not group.contains_tree(node_tree) and
|
||||||
not group.name.startswith('.'))
|
not group.name.startswith('.'))
|
||||||
]
|
]
|
||||||
if groups:
|
if groups:
|
||||||
|
@ -338,6 +338,7 @@ class NODE_MT_geometry_node_GEO_MESH_READ(Menu):
|
|||||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
|
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
|
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
|
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices")
|
||||||
|
node_add_menu.add_node_type(layout, "GeometryNodeEdgesToFaceGroups")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
|
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
|
node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors")
|
||||||
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
|
node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries")
|
||||||
|
@ -140,7 +140,7 @@ class DATA_PT_EEVEE_light_distance(DataButtonsPanel, Panel):
|
|||||||
class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
|
class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
|
||||||
bl_label = "Shadow"
|
bl_label = "Shadow"
|
||||||
bl_options = {'DEFAULT_CLOSED'}
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@ -168,6 +168,7 @@ class DATA_PT_EEVEE_shadow(DataButtonsPanel, Panel):
|
|||||||
if light.type != 'SUN':
|
if light.type != 'SUN':
|
||||||
sub.prop(light, "shadow_buffer_clip_start", text="Clip Start")
|
sub.prop(light, "shadow_buffer_clip_start", text="Clip Start")
|
||||||
|
|
||||||
|
if context.engine != 'BLENDER_EEVEE_NEXT':
|
||||||
col.prop(light, "shadow_buffer_bias", text="Bias")
|
col.prop(light, "shadow_buffer_bias", text="Bias")
|
||||||
|
|
||||||
|
|
||||||
|
@ -485,7 +485,6 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
|||||||
layout.use_property_split = True
|
layout.use_property_split = True
|
||||||
layout.use_property_decorate = False
|
layout.use_property_decorate = False
|
||||||
|
|
||||||
obj = context.object
|
|
||||||
me = context.mesh
|
me = context.mesh
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
|
|
||||||
|
@ -62,7 +62,6 @@ class PARTICLE_MT_context_menu(Menu):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
psys = context.particle_system
|
psys = context.particle_system
|
||||||
experimental = context.preferences.experimental
|
|
||||||
|
|
||||||
props = layout.operator(
|
props = layout.operator(
|
||||||
"particle.copy_particle_systems",
|
"particle.copy_particle_systems",
|
||||||
|
@ -460,6 +460,32 @@ class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel):
|
|||||||
col.prop(props, "light_threshold")
|
col.prop(props, "light_threshold")
|
||||||
|
|
||||||
|
|
||||||
|
class RENDER_PT_eevee_next_shadows(RenderButtonsPanel, Panel):
|
||||||
|
bl_label = "Shadows"
|
||||||
|
bl_options = {'DEFAULT_CLOSED'}
|
||||||
|
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
return (context.engine in cls.COMPAT_ENGINES)
|
||||||
|
|
||||||
|
def draw_header(self, context):
|
||||||
|
scene = context.scene
|
||||||
|
props = scene.eevee
|
||||||
|
self.layout.prop(props, "use_shadows", text="")
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
props = scene.eevee
|
||||||
|
|
||||||
|
col = layout.column()
|
||||||
|
col.prop(props, "shadow_pool_size", text="Pool Size")
|
||||||
|
col.prop(props, "light_threshold")
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel):
|
class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel):
|
||||||
bl_label = "Sampling"
|
bl_label = "Sampling"
|
||||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||||
@ -615,7 +641,6 @@ class RENDER_PT_eevee_next_film(RenderButtonsPanel, Panel):
|
|||||||
|
|
||||||
scene = context.scene
|
scene = context.scene
|
||||||
rd = scene.render
|
rd = scene.render
|
||||||
props = scene.eevee
|
|
||||||
|
|
||||||
col = layout.column()
|
col = layout.column()
|
||||||
col.prop(rd, "filter_size")
|
col.prop(rd, "filter_size")
|
||||||
@ -808,6 +833,10 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel):
|
|||||||
col = flow.column()
|
col = flow.column()
|
||||||
col.prop(rd, "simplify_volumes", text="Volume Resolution")
|
col.prop(rd, "simplify_volumes", text="Volume Resolution")
|
||||||
|
|
||||||
|
if context.engine in 'BLENDER_EEVEE_NEXT':
|
||||||
|
col = flow.column()
|
||||||
|
col.prop(rd, "simplify_shadows", text="Shadow Resolution")
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_simplify_render(RenderButtonsPanel, Panel):
|
class RENDER_PT_simplify_render(RenderButtonsPanel, Panel):
|
||||||
bl_label = "Render"
|
bl_label = "Render"
|
||||||
@ -835,6 +864,10 @@ class RENDER_PT_simplify_render(RenderButtonsPanel, Panel):
|
|||||||
col = flow.column()
|
col = flow.column()
|
||||||
col.prop(rd, "simplify_child_particles_render", text="Max Child Particles")
|
col.prop(rd, "simplify_child_particles_render", text="Max Child Particles")
|
||||||
|
|
||||||
|
if context.engine in 'BLENDER_EEVEE_NEXT':
|
||||||
|
col = flow.column()
|
||||||
|
col.prop(rd, "simplify_shadows_render", text="Shadow Resolution")
|
||||||
|
|
||||||
|
|
||||||
class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSimplifyPanel):
|
class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSimplifyPanel):
|
||||||
bl_label = "Grease Pencil"
|
bl_label = "Grease Pencil"
|
||||||
@ -869,6 +902,7 @@ classes = (
|
|||||||
RENDER_PT_eevee_performance,
|
RENDER_PT_eevee_performance,
|
||||||
RENDER_PT_eevee_hair,
|
RENDER_PT_eevee_hair,
|
||||||
RENDER_PT_eevee_shadows,
|
RENDER_PT_eevee_shadows,
|
||||||
|
RENDER_PT_eevee_next_shadows,
|
||||||
RENDER_PT_eevee_indirect_lighting,
|
RENDER_PT_eevee_indirect_lighting,
|
||||||
RENDER_PT_eevee_indirect_lighting_display,
|
RENDER_PT_eevee_indirect_lighting_display,
|
||||||
RENDER_PT_eevee_film,
|
RENDER_PT_eevee_film,
|
||||||
|
@ -91,7 +91,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
|
|||||||
else:
|
else:
|
||||||
layout.template_preview(tex, slot=slot)
|
layout.template_preview(tex, slot=slot)
|
||||||
|
|
||||||
# Show Alpha Button for Brush Textures, see T29502.
|
# Show Alpha Button for Brush Textures, see #29502.
|
||||||
idblock = context_tex_datablock(context)
|
idblock = context_tex_datablock(context)
|
||||||
if isinstance(idblock, Brush):
|
if isinstance(idblock, Brush):
|
||||||
layout.prop(tex, "use_preview_alpha")
|
layout.prop(tex, "use_preview_alpha")
|
||||||
|
@ -62,7 +62,7 @@ class NODE_HT_header(Header):
|
|||||||
|
|
||||||
types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META',
|
types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META',
|
||||||
'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'}
|
'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'}
|
||||||
# disable material slot buttons when pinned, cannot find correct slot within id_from (T36589)
|
# disable material slot buttons when pinned, cannot find correct slot within id_from (#36589)
|
||||||
# disable also when the selected object does not support materials
|
# disable also when the selected object does not support materials
|
||||||
has_material_slots = not snode.pin and ob_type in types_that_support_material
|
has_material_slots = not snode.pin and ob_type in types_that_support_material
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ class SEQUENCER_MT_view(Menu):
|
|||||||
if st.view_type == 'PREVIEW':
|
if st.view_type == 'PREVIEW':
|
||||||
# Specifying the REGION_PREVIEW context is needed in preview-only
|
# Specifying the REGION_PREVIEW context is needed in preview-only
|
||||||
# mode, else the lookup for the shortcut will fail in
|
# mode, else the lookup for the shortcut will fail in
|
||||||
# wm_keymap_item_find_props() (see T32595).
|
# wm_keymap_item_find_props() (see #32595).
|
||||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||||
layout.prop(st, "show_region_ui")
|
layout.prop(st, "show_region_ui")
|
||||||
layout.prop(st, "show_region_tool_header")
|
layout.prop(st, "show_region_tool_header")
|
||||||
@ -429,7 +429,7 @@ class SEQUENCER_MT_view(Menu):
|
|||||||
|
|
||||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||||
if st.view_type == 'PREVIEW':
|
if st.view_type == 'PREVIEW':
|
||||||
# See above (T32595)
|
# See above (#32595)
|
||||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||||
layout.operator("sequencer.view_selected", text="Frame Selected")
|
layout.operator("sequencer.view_selected", text="Frame Selected")
|
||||||
|
|
||||||
@ -1996,7 +1996,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
|
|||||||
|
|
||||||
split = col.split(factor=0.4)
|
split = col.split(factor=0.4)
|
||||||
split.alignment = 'RIGHT'
|
split.alignment = 'RIGHT'
|
||||||
split.label(text="Pan", heading_ctxt=i18n_contexts.id_sound)
|
split.label(text="Pan", text_ctxt=i18n_contexts.id_sound)
|
||||||
split.prop(strip, "pan", text="")
|
split.prop(strip, "pan", text="")
|
||||||
split.enabled = pan_enabled
|
split.enabled = pan_enabled
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -326,7 +326,7 @@ class TOPBAR_MT_file_new(Menu):
|
|||||||
# Expand template paths.
|
# Expand template paths.
|
||||||
|
|
||||||
# Use a set to avoid duplicate user/system templates.
|
# Use a set to avoid duplicate user/system templates.
|
||||||
# This is a corner case, but users managed to do it! T76849.
|
# This is a corner case, but users managed to do it! #76849.
|
||||||
app_templates = set()
|
app_templates = set()
|
||||||
for path in template_paths:
|
for path in template_paths:
|
||||||
for d in os.listdir(path):
|
for d in os.listdir(path):
|
||||||
|
@ -2319,11 +2319,19 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
|||||||
bl_label = "New Features"
|
bl_label = "New Features"
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self._draw_items(
|
self._draw_items(context,
|
||||||
context, (
|
(({"property": "use_sculpt_tools_tilt"},
|
||||||
({"property": "use_sculpt_tools_tilt"}, ("blender/blender/issues/82877", "#82877")),
|
("blender/blender/issues/82877",
|
||||||
({"property": "use_extended_asset_browser"}, ("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")),
|
"#82877")),
|
||||||
({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")),
|
({"property": "use_extended_asset_browser"},
|
||||||
|
("blender/blender/projects/10",
|
||||||
|
"Pipeline, Assets & IO Project Page")),
|
||||||
|
({"property": "use_override_templates"},
|
||||||
|
("blender/blender/issues/73318",
|
||||||
|
"Milestone 4")),
|
||||||
|
({"property": "use_new_volume_nodes"},
|
||||||
|
("blender/blender/issues/103248",
|
||||||
|
"#103248")),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -161,6 +161,8 @@ class VIEW3D_HT_tool_header(Header):
|
|||||||
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
||||||
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
||||||
|
|
||||||
|
layout.prop(context.object.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True)
|
||||||
|
|
||||||
# Expand panels from the side-bar as popovers.
|
# Expand panels from the side-bar as popovers.
|
||||||
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
|
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
|
||||||
|
|
||||||
@ -890,7 +892,7 @@ class VIEW3D_HT_header(Header):
|
|||||||
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
||||||
|
|
||||||
# While exposing `shading.show_xray(_wireframe)` is correct.
|
# While exposing `shading.show_xray(_wireframe)` is correct.
|
||||||
# this hides the key shortcut from users: T70433.
|
# this hides the key shortcut from users: #70433.
|
||||||
if has_pose_mode:
|
if has_pose_mode:
|
||||||
draw_depressed = overlay.show_xray_bone
|
draw_depressed = overlay.show_xray_bone
|
||||||
elif shading.type == 'WIREFRAME':
|
elif shading.type == 'WIREFRAME':
|
||||||
@ -2052,6 +2054,7 @@ class VIEW3D_MT_select_edit_curves(Menu):
|
|||||||
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
||||||
layout.operator("curves.select_random", text="Random")
|
layout.operator("curves.select_random", text="Random")
|
||||||
layout.operator("curves.select_end", text="Endpoints")
|
layout.operator("curves.select_end", text="Endpoints")
|
||||||
|
layout.operator("curves.select_linked", text="Linked")
|
||||||
|
|
||||||
|
|
||||||
class VIEW3D_MT_select_sculpt_curves(Menu):
|
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||||
@ -2267,7 +2270,7 @@ class VIEW3D_MT_add(Menu):
|
|||||||
# NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context.
|
# NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context.
|
||||||
|
|
||||||
# NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents
|
# NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents
|
||||||
# "align_view" to work on first call (see T32719).
|
# "align_view" to work on first call (see #32719).
|
||||||
layout.operator_context = 'EXEC_REGION_WIN'
|
layout.operator_context = 'EXEC_REGION_WIN'
|
||||||
|
|
||||||
# layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
|
# layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
|
||||||
@ -5375,7 +5378,7 @@ class VIEW3D_MT_shading_ex_pie(Menu):
|
|||||||
pie.prop_enum(view.shading, "type", value='WIREFRAME')
|
pie.prop_enum(view.shading, "type", value='WIREFRAME')
|
||||||
pie.prop_enum(view.shading, "type", value='SOLID')
|
pie.prop_enum(view.shading, "type", value='SOLID')
|
||||||
|
|
||||||
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: T58661.
|
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: #58661.
|
||||||
if context.pose_object:
|
if context.pose_object:
|
||||||
pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
|
pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
|
||||||
else:
|
else:
|
||||||
@ -6706,13 +6709,12 @@ class VIEW3D_PT_overlay_sculpt(Panel):
|
|||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return (
|
return (
|
||||||
context.mode == 'SCULPT' and
|
context.mode == 'SCULPT' and
|
||||||
(context.sculpt_object and context.tool_settings.sculpt)
|
context.sculpt_object
|
||||||
)
|
)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
layout = self.layout
|
layout = self.layout
|
||||||
tool_settings = context.tool_settings
|
tool_settings = context.tool_settings
|
||||||
sculpt = tool_settings.sculpt
|
|
||||||
|
|
||||||
view = context.space_data
|
view = context.space_data
|
||||||
overlay = view.overlay
|
overlay = view.overlay
|
||||||
|
@ -639,7 +639,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
|
|||||||
|
|
||||||
# Note that this controls order of options in `insert keyframe` menu.
|
# Note that this controls order of options in `insert keyframe` menu.
|
||||||
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
||||||
# See also T51867.
|
# See also #51867.
|
||||||
classes = (
|
classes = (
|
||||||
BUILTIN_KSI_Available,
|
BUILTIN_KSI_Available,
|
||||||
BUILTIN_KSI_Location,
|
BUILTIN_KSI_Location,
|
||||||
|
@ -76,21 +76,11 @@ def node_group_items(context):
|
|||||||
|
|
||||||
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
|
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
|
||||||
|
|
||||||
def contains_group(nodetree, group):
|
|
||||||
if nodetree == group:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
for node in nodetree.nodes:
|
|
||||||
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
|
|
||||||
if contains_group(node.node_tree, group):
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
for group in context.blend_data.node_groups:
|
for group in context.blend_data.node_groups:
|
||||||
if group.bl_idname != ntree.bl_idname:
|
if group.bl_idname != ntree.bl_idname:
|
||||||
continue
|
continue
|
||||||
# filter out recursive groups
|
# filter out recursive groups
|
||||||
if contains_group(group, ntree):
|
if group.contains_tree(ntree):
|
||||||
continue
|
continue
|
||||||
# filter out hidden nodetrees
|
# filter out hidden nodetrees
|
||||||
if group.name.startswith('.'):
|
if group.name.startswith('.'):
|
||||||
|
@ -23,11 +23,15 @@ struct ID;
|
|||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
|
class AssetLibrary;
|
||||||
|
|
||||||
class AssetRepresentation {
|
class AssetRepresentation {
|
||||||
AssetIdentifier identifier_;
|
AssetIdentifier identifier_;
|
||||||
/** Indicate if this is a local or external asset, and as such, which of the union members below
|
/** Indicate if this is a local or external asset, and as such, which of the union members below
|
||||||
* should be used. */
|
* should be used. */
|
||||||
const bool is_local_id_ = false;
|
const bool is_local_id_ = false;
|
||||||
|
/** Asset library that owns this asset representation. */
|
||||||
|
const AssetLibrary *owner_asset_library_;
|
||||||
|
|
||||||
struct ExternalAsset {
|
struct ExternalAsset {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -44,10 +48,13 @@ class AssetRepresentation {
|
|||||||
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
||||||
AssetRepresentation(AssetIdentifier &&identifier,
|
AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata);
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
|
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
|
||||||
* local and fully editable. */
|
* local and fully editable. */
|
||||||
AssetRepresentation(AssetIdentifier &&identifier, ID &id);
|
AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
AssetRepresentation(AssetRepresentation &&other);
|
AssetRepresentation(AssetRepresentation &&other);
|
||||||
/* Non-copyable type. */
|
/* Non-copyable type. */
|
||||||
AssetRepresentation(const AssetRepresentation &other) = delete;
|
AssetRepresentation(const AssetRepresentation &other) = delete;
|
||||||
@ -65,6 +72,7 @@ class AssetRepresentation {
|
|||||||
AssetMetaData &get_metadata() const;
|
AssetMetaData &get_metadata() const;
|
||||||
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
||||||
bool is_local_id() const;
|
bool is_local_id() const;
|
||||||
|
const AssetLibrary &owner_asset_library() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::asset_system
|
} // namespace blender::asset_system
|
||||||
|
@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p
|
|||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata)
|
||||||
{
|
{
|
||||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||||
return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata));
|
return asset_storage_->add_external_asset(
|
||||||
|
std::move(identifier), name, std::move(metadata), *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
||||||
{
|
{
|
||||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||||
return asset_storage_->add_local_id_asset(std::move(identifier), id);
|
return asset_storage_->add_local_id_asset(std::move(identifier), id, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
||||||
|
@ -17,15 +17,24 @@ namespace blender::asset_system {
|
|||||||
|
|
||||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
: identifier_(identifier), is_local_id_(false), external_asset_()
|
const AssetLibrary &owner_asset_library)
|
||||||
|
: identifier_(identifier),
|
||||||
|
is_local_id_(false),
|
||||||
|
owner_asset_library_(&owner_asset_library),
|
||||||
|
external_asset_()
|
||||||
{
|
{
|
||||||
external_asset_.name = name;
|
external_asset_.name = name;
|
||||||
external_asset_.metadata_ = std::move(metadata);
|
external_asset_.metadata_ = std::move(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id)
|
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||||
: identifier_(identifier), is_local_id_(true), local_asset_id_(&id)
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
|
: identifier_(identifier),
|
||||||
|
is_local_id_(true),
|
||||||
|
owner_asset_library_(&owner_asset_library),
|
||||||
|
local_asset_id_(&id)
|
||||||
{
|
{
|
||||||
if (!id.asset_data) {
|
if (!id.asset_data) {
|
||||||
throw std::invalid_argument("Passed ID is not an asset");
|
throw std::invalid_argument("Passed ID is not an asset");
|
||||||
@ -75,6 +84,11 @@ bool AssetRepresentation::is_local_id() const
|
|||||||
return is_local_id_;
|
return is_local_id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AssetLibrary &AssetRepresentation::owner_asset_library() const
|
||||||
|
{
|
||||||
|
return *owner_asset_library_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::asset_system
|
} // namespace blender::asset_system
|
||||||
|
|
||||||
using namespace blender;
|
using namespace blender;
|
||||||
|
@ -15,18 +15,21 @@
|
|||||||
|
|
||||||
namespace blender::asset_system {
|
namespace blender::asset_system {
|
||||||
|
|
||||||
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id)
|
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
{
|
{
|
||||||
return *local_id_assets_.lookup_key_or_add(
|
return *local_id_assets_.lookup_key_or_add(
|
||||||
std::make_unique<AssetRepresentation>(std::move(identifier), id));
|
std::make_unique<AssetRepresentation>(std::move(identifier), id, owner_asset_library));
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata)
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library)
|
||||||
{
|
{
|
||||||
return *external_assets_.lookup_key_or_add(
|
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
|
||||||
std::make_unique<AssetRepresentation>(std::move(identifier), name, std::move(metadata)));
|
std::move(identifier), name, std::move(metadata), owner_asset_library));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
||||||
|
@ -35,9 +35,12 @@ class AssetStorage {
|
|||||||
/** See #AssetLibrary::add_external_asset(). */
|
/** See #AssetLibrary::add_external_asset(). */
|
||||||
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
||||||
StringRef name,
|
StringRef name,
|
||||||
std::unique_ptr<AssetMetaData> metadata);
|
std::unique_ptr<AssetMetaData> metadata,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
/** See #AssetLibrary::add_external_asset(). */
|
/** See #AssetLibrary::add_external_asset(). */
|
||||||
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id);
|
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier,
|
||||||
|
ID &id,
|
||||||
|
const AssetLibrary &owner_asset_library);
|
||||||
|
|
||||||
/** See #AssetLibrary::remove_asset(). */
|
/** See #AssetLibrary::remove_asset(). */
|
||||||
bool remove_asset(AssetRepresentation &asset);
|
bool remove_asset(AssetRepresentation &asset);
|
||||||
|
@ -165,7 +165,7 @@ int BLF_load_unique(const char *name)
|
|||||||
|
|
||||||
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
|
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
|
||||||
* our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
|
* our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
|
||||||
* (T101506). Enable again later with change of font, placement, or rendering - Harley. */
|
* (#101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||||
if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
||||||
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ typedef int32_t ft_pix;
|
|||||||
/* Macros copied from `include/freetype/internal/ftobjs.h`. */
|
/* Macros copied from `include/freetype/internal/ftobjs.h`. */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXME(@campbellbarton): Follow rounding from Blender 3.1x and older.
|
* FIXME(@ideasman42): Follow rounding from Blender 3.1x and older.
|
||||||
* This is what users will expect and changing this creates wider spaced text.
|
* This is what users will expect and changing this creates wider spaced text.
|
||||||
* Use this macro to communicate that rounding should be used, using floor is to avoid
|
* Use this macro to communicate that rounding should be used, using floor is to avoid
|
||||||
* user visible changes, which can be reviewed and handled separately.
|
* user visible changes, which can be reviewed and handled separately.
|
||||||
|
@ -271,7 +271,7 @@ struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob)
|
|||||||
* In this case the active-selected is an obvious choice when finding the target for a
|
* In this case the active-selected is an obvious choice when finding the target for a
|
||||||
* constraint for eg. however from the users perspective the active pose bone of the
|
* constraint for eg. however from the users perspective the active pose bone of the
|
||||||
* active object is the _real_ active bone, so any other non-active selected bone
|
* active object is the _real_ active bone, so any other non-active selected bone
|
||||||
* is a candidate for being the other selected bone, see: T58447.
|
* is a candidate for being the other selected bone, see: #58447.
|
||||||
*/
|
*/
|
||||||
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,7 @@ struct bActionGroup;
|
|||||||
/* Container for data required to do FCurve and Driver evaluation. */
|
/* Container for data required to do FCurve and Driver evaluation. */
|
||||||
typedef struct AnimationEvalContext {
|
typedef struct AnimationEvalContext {
|
||||||
/* For drivers, so that they have access to the dependency graph and the current view layer. See
|
/* For drivers, so that they have access to the dependency graph and the current view layer. See
|
||||||
* T77086. */
|
* #77086. */
|
||||||
struct Depsgraph *depsgraph;
|
struct Depsgraph *depsgraph;
|
||||||
|
|
||||||
/* FCurves and Drivers can be evaluated at a different time than the current scene time, for
|
/* FCurves and Drivers can be evaluated at a different time than the current scene time, for
|
||||||
|
@ -25,7 +25,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Blender file format version. */
|
/* Blender file format version. */
|
||||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||||
#define BLENDER_FILE_SUBVERSION 8
|
#define BLENDER_FILE_SUBVERSION 9
|
||||||
|
|
||||||
/* Minimum Blender version that supports reading file written with the current
|
/* Minimum Blender version that supports reading file written with the current
|
||||||
* version. Older Blender versions will test this and show a warning if the file
|
* version. Older Blender versions will test this and show a warning if the file
|
||||||
|
@ -2,17 +2,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BKE_curves.h"
|
|
||||||
|
|
||||||
/** \file
|
/** \file
|
||||||
* \ingroup bke
|
* \ingroup bke
|
||||||
* \brief Low-level operations for curves.
|
* \brief Low-level operations for curves.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
#include "BLI_bounds_types.hh"
|
#include "BLI_bounds_types.hh"
|
||||||
#include "BLI_cache_mutex.hh"
|
|
||||||
#include "BLI_generic_virtual_array.hh"
|
#include "BLI_generic_virtual_array.hh"
|
||||||
#include "BLI_index_mask.hh"
|
#include "BLI_index_mask.hh"
|
||||||
#include "BLI_math_matrix_types.hh"
|
#include "BLI_math_matrix_types.hh"
|
||||||
@ -20,12 +15,12 @@
|
|||||||
#include "BLI_offset_indices.hh"
|
#include "BLI_offset_indices.hh"
|
||||||
#include "BLI_shared_cache.hh"
|
#include "BLI_shared_cache.hh"
|
||||||
#include "BLI_span.hh"
|
#include "BLI_span.hh"
|
||||||
#include "BLI_task.hh"
|
|
||||||
#include "BLI_vector.hh"
|
#include "BLI_vector.hh"
|
||||||
#include "BLI_virtual_array.hh"
|
#include "BLI_virtual_array.hh"
|
||||||
|
|
||||||
#include "BKE_attribute.hh"
|
#include "BKE_attribute.hh"
|
||||||
#include "BKE_attribute_math.hh"
|
#include "BKE_attribute_math.hh"
|
||||||
|
#include "BKE_curves.h"
|
||||||
|
|
||||||
namespace blender::bke {
|
namespace blender::bke {
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user