Revert changes from main commits that were merged into blender-v4.0-release
The last good commit was 8474716abb0db3b06838a57f7217bc945638d8df. After this commits from main were pushed to blender-v4.0-release. These are being reverted. Commits a4880576dc from to b26f176d1a that happend afterwards were meant for 4.0, and their contents is preserved.
This commit is contained in:
parent
b26f176d1a
commit
39107b3133
116
CMakeLists.txt
116
CMakeLists.txt
@ -335,6 +335,13 @@ if(UNIX AND NOT (APPLE OR HAIKU))
|
||||
option(WITH_GHOST_WAYLAND_LIBDECOR "Optionally build with LibDecor window decorations" ON)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
|
||||
option(WITH_GHOST_WAYLAND_DBUS "\
|
||||
Optionally build with DBUS support (used for Cursor themes). \
|
||||
May hang on startup systems where DBUS is not used."
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_DBUS)
|
||||
|
||||
option(WITH_GHOST_WAYLAND_DYNLOAD "Enable runtime dynamic WAYLAND libraries loading" ON)
|
||||
mark_as_advanced(WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
|
||||
@ -511,10 +518,8 @@ Boost uses ICU library (required for linking with static Boost built with libicu
|
||||
endif()
|
||||
|
||||
# Misc
|
||||
if(WIN32 OR APPLE OR ((UNIX AND (NOT HAIKU)) AND WITH_GHOST_WAYLAND))
|
||||
if(WIN32 OR APPLE)
|
||||
option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON)
|
||||
else()
|
||||
set(WITH_INPUT_IME OFF)
|
||||
endif()
|
||||
option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON)
|
||||
if(UNIX AND NOT APPLE)
|
||||
@ -647,7 +652,7 @@ if(NOT APPLE)
|
||||
gfx900 gfx90c gfx902
|
||||
gfx1010 gfx1011 gfx1012
|
||||
gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1036
|
||||
gfx1100 gfx1101 gfx1102 gfx1103
|
||||
gfx1100 gfx1101 gfx1102
|
||||
CACHE STRING "AMD HIP architectures to build binaries for"
|
||||
)
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
|
||||
@ -679,10 +684,8 @@ This option is only for debugging purposes."
|
||||
)
|
||||
|
||||
# https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compilation/ahead-of-time-compilation.html
|
||||
# The target architectures levels can be retrieved from `ocloc` output when running
|
||||
# `ocloc compile -device {device_id} test.c` for given GPUs PCI device IDs.
|
||||
# 12.55.8 is for Arc Alchemist GPUs. 12.70.0 for Meteor Lake iGPUs.
|
||||
set(CYCLES_ONEAPI_INTEL_BINARIES_ARCH 12.55.8 12.70.0 CACHE STRING "\
|
||||
# acm-g10 is the target for the first Intel Arc Alchemist GPUs.
|
||||
set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "acm-g10" CACHE STRING "\
|
||||
oneAPI Intel GPU architectures to build binaries for"
|
||||
)
|
||||
set(CYCLES_ONEAPI_SYCL_TARGETS spir64 spir64_gen CACHE STRING "\
|
||||
@ -690,7 +693,7 @@ oneAPI targets to build AOT binaries for"
|
||||
)
|
||||
|
||||
mark_as_advanced(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION)
|
||||
mark_as_advanced(CYCLES_ONEAPI_INTEL_BINARIES_ARCH)
|
||||
mark_as_advanced(CYCLES_ONEAPI_SPIR64_GEN_DEVICES)
|
||||
mark_as_advanced(CYCLES_ONEAPI_SYCL_TARGETS)
|
||||
endif()
|
||||
|
||||
@ -790,20 +793,15 @@ else()
|
||||
endif()
|
||||
|
||||
# Vulkan
|
||||
if(NOT APPLE)
|
||||
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (experimental)" ON)
|
||||
option(WITH_VULKAN_GUARDEDALLOC "\
|
||||
Use guardedalloc for host allocations done inside Vulkan (development option)"
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced(
|
||||
WITH_VULKAN_BACKEND
|
||||
WITH_VULKAN_GUARDEDALLOC
|
||||
)
|
||||
if(NOT WITH_EXPERIMENTAL_FEATURES)
|
||||
set(WITH_VULKAN_BACKEND OFF)
|
||||
endif()
|
||||
endif()
|
||||
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(
|
||||
WITH_VULKAN_BACKEND
|
||||
WITH_VULKAN_GUARDEDALLOC
|
||||
)
|
||||
|
||||
# Metal
|
||||
if(APPLE)
|
||||
@ -846,12 +844,6 @@ Build and link against address sanitizer (only for Debug & RelWithDebInfo target
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced(WITH_COMPILER_ASAN)
|
||||
option(WITH_COMPILER_ASAN_EXTERN "\
|
||||
Build `extern` dependencies with address sanitizer when WITH_COMPILER_ASAN is on. \
|
||||
Can cause linking issues due to too large binary size."
|
||||
OFF
|
||||
)
|
||||
mark_as_advanced(WITH_EXTERN_ASAN)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if(WITH_COMPILER_ASAN)
|
||||
@ -953,10 +945,7 @@ Include the files needed for debugging python scripts with visual studio 2017+."
|
||||
option(WITH_WINDOWS_SCCACHE "Use sccache to speed up builds (Ninja builder only)" OFF)
|
||||
mark_as_advanced(WITH_WINDOWS_SCCACHE)
|
||||
|
||||
option(WITH_WINDOWS_RELEASE_PDB "\
|
||||
Generate a pdb file for client side stacktraces for release builds"
|
||||
ON
|
||||
)
|
||||
option(WITH_WINDOWS_RELEASE_PDB "Generate a pdb file for client side stacktraces for release builds" ON)
|
||||
mark_as_advanced(WITH_WINDOWS_RELEASE_PDB)
|
||||
|
||||
option(WITH_WINDOWS_RELEASE_STRIPPED_PDB "Use a stripped PDB file for release builds" ON)
|
||||
@ -1140,19 +1129,17 @@ if(WITH_INSTALL_PORTABLE)
|
||||
set(CMAKE_SKIP_BUILD_RPATH TRUE)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT (APPLE OR HAIKU))
|
||||
set_and_warn_incompatible(WITH_HEADLESS WITH_GHOST_WAYLAND OFF)
|
||||
set_and_warn_incompatible(WITH_HEADLESS WITH_GHOST_X11 OFF)
|
||||
if(WITH_GHOST_SDL OR WITH_HEADLESS)
|
||||
message(STATUS "Disabling Ghost Wayland, X11, Input IME, and OpenXR")
|
||||
set(WITH_GHOST_WAYLAND OFF)
|
||||
set(WITH_GHOST_X11 OFF)
|
||||
set(WITH_X11_XINPUT OFF)
|
||||
set(WITH_X11_XF86VMODE OFF)
|
||||
set(WITH_X11_XFIXES OFF)
|
||||
set(WITH_GHOST_XDND OFF)
|
||||
set(WITH_INPUT_IME OFF)
|
||||
set(WITH_XR_OPENXR OFF)
|
||||
endif()
|
||||
set_and_warn_incompatible(WITH_HEADLESS WITH_GHOST_SDL OFF)
|
||||
|
||||
if(WITH_INPUT_IME)
|
||||
set_and_warn_incompatible(WITH_HEADLESS WITH_INPUT_IME OFF)
|
||||
set_and_warn_incompatible(WITH_GHOST_SDL WITH_INPUT_IME OFF)
|
||||
endif()
|
||||
|
||||
set_and_warn_incompatible(WITH_HEADLESS WITH_XR_OPENXR OFF)
|
||||
set_and_warn_incompatible(WITH_GHOST_SDL WITH_XR_OPENXR OFF)
|
||||
|
||||
if(WITH_BUILDINFO)
|
||||
find_package(Git)
|
||||
@ -1374,27 +1361,23 @@ if(WITH_CPU_SIMD)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Print instructions used on first run.
|
||||
if(FIRST_RUN)
|
||||
if(WITH_CPU_SIMD)
|
||||
if(SUPPORT_NEON_BUILD)
|
||||
if(SSE2NEON_FOUND)
|
||||
message(STATUS "Neon SIMD instructions enabled")
|
||||
else()
|
||||
message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon")
|
||||
endif()
|
||||
elseif(SUPPORT_SSE2_BUILD)
|
||||
message(STATUS "SSE2 SIMD instructions enabled")
|
||||
elseif(SUPPORT_SSE_BUILD)
|
||||
message(STATUS "SSE SIMD instructions enabled")
|
||||
# Print instructions used
|
||||
if(SUPPORT_NEON_BUILD)
|
||||
if(SSE2NEON_FOUND)
|
||||
message(STATUS "Neon SIMD instructions enabled")
|
||||
else()
|
||||
message(STATUS "No SIMD instructions detected")
|
||||
message(STATUS "Neon SIMD instructions detected but unused, requires sse2neon")
|
||||
endif()
|
||||
elseif(SUPPORT_SSE2_BUILD)
|
||||
message(STATUS "SSE2 SIMD instructions enabled")
|
||||
elseif(SUPPORT_SSE_BUILD)
|
||||
message(STATUS "SSE SIMD instructions enabled")
|
||||
else()
|
||||
message(STATUS "SIMD instructions disabled")
|
||||
message(STATUS "No SIMD instructions detected")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "SIMD instructions disabled")
|
||||
endif()
|
||||
|
||||
# set the endian define
|
||||
@ -1533,8 +1516,13 @@ endif()
|
||||
# -----------------------------------------------------------------------------
|
||||
# Configure Python
|
||||
|
||||
# Not currently supported due to different required Python link flags.
|
||||
set_and_warn_incompatible(WITH_PYTHON_MODULE WITH_GTESTS OFF)
|
||||
if(WITH_PYTHON_MODULE)
|
||||
# Not currently supported due to different required Python link flags.
|
||||
if(WITH_GTESTS)
|
||||
message(STATUS "GTests not compatible with Python module, disabling WITH_GTESTS")
|
||||
set(WITH_GTESTS OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -1903,7 +1891,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
C_WARN_NO_STRICT_PROTOTYPES -Wno-strict-prototypes
|
||||
C_WARN_NO_BITWISE_INSTEAD_OF_LOGICAL -Wno-bitwise-instead-of-logical
|
||||
C_WARN_NO_IMPLICIT_CONST_INT_FLOAT_CONVERSION -Wno-implicit-const-int-float-conversion
|
||||
C_WARN_NO_SINGLE_BIT_BITFIELD_CONSTANT_CONVERSION -Wno-single-bit-bitfield-constant-conversion
|
||||
)
|
||||
|
||||
add_check_cxx_compiler_flags(
|
||||
@ -2286,6 +2273,7 @@ if(FIRST_RUN)
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
info_cfg_option(WITH_GHOST_WAYLAND_DBUS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
## Update and uncomment this in the release branch
|
||||
# set(BLENDER_VERSION 3.1)
|
||||
set(BLENDER_VERSION 4.0)
|
||||
|
||||
function(download_source dep)
|
||||
set(TARGET_FILE ${${dep}_FILE})
|
||||
|
@ -57,7 +57,7 @@ foreach(COMPONENT ${_webp_FIND_COMPONENTS})
|
||||
PATH_SUFFIXES
|
||||
lib64 lib lib/static
|
||||
)
|
||||
if(WEBP_${UPPERCOMPONENT}_LIBRARY)
|
||||
if (WEBP_${UPPERCOMPONENT}_LIBRARY)
|
||||
list(APPEND _webp_LIBRARIES "${WEBP_${UPPERCOMPONENT}_LIBRARY}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -1131,7 +1131,7 @@ function(data_to_c
|
||||
|
||||
set(optional_args "")
|
||||
foreach(f ${ARGN})
|
||||
if(f STREQUAL "STRIP_LEADING_C_COMMENTS")
|
||||
if (f STREQUAL "STRIP_LEADING_C_COMMENTS")
|
||||
set(optional_args "--options=strip_leading_c_comments")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown optional argument ${f} to \"data_to_c\"")
|
||||
@ -1168,7 +1168,7 @@ function(data_to_c_simple
|
||||
|
||||
set(optional_args "")
|
||||
foreach(f ${ARGN})
|
||||
if(f STREQUAL "STRIP_LEADING_C_COMMENTS")
|
||||
if (f STREQUAL "STRIP_LEADING_C_COMMENTS")
|
||||
set(optional_args "--options=strip_leading_c_comments")
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown optional argument ${f} to \"data_to_c_simple\"")
|
||||
@ -1526,24 +1526,6 @@ macro(set_and_warn_dependency
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(set_and_warn_incompatible
|
||||
_dependency _setting _val)
|
||||
# when $_dependency is enabled, forces $_setting = $_val
|
||||
# Both should be defined, warn if they're not.
|
||||
if(NOT DEFINED ${_dependency})
|
||||
message(STATUS "${_dependency} not defined!")
|
||||
elseif(NOT DEFINED ${_setting})
|
||||
message(STATUS "${_setting} not defined!")
|
||||
elseif(${${_dependency}} AND ${${_setting}})
|
||||
if(WITH_STRICT_BUILD_OPTIONS)
|
||||
message(SEND_ERROR "${_dependency} enabled but incompatible with ${_setting}")
|
||||
else()
|
||||
message(STATUS "${_dependency} is enabled but incompatible, setting ${_setting}=${_val}")
|
||||
endif()
|
||||
set(${_setting} ${_val})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(set_and_warn_library_found
|
||||
_library_name _library_found _setting)
|
||||
if(((NOT ${_library_found}) OR (NOT ${${_library_found}})) AND ${${_setting}})
|
||||
|
@ -54,9 +54,7 @@ if(NOT DEFINED LIBDIR)
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/darwin_${CMAKE_OSX_ARCHITECTURES})
|
||||
endif()
|
||||
else()
|
||||
if(FIRST_RUN)
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
if(NOT EXISTS "${LIBDIR}/")
|
||||
message(FATAL_ERROR "Mac OSX requires pre-compiled libs at: '${LIBDIR}'")
|
||||
@ -104,6 +102,12 @@ if(WITH_MATERIALX)
|
||||
endif()
|
||||
add_bundled_libraries(materialx/lib)
|
||||
|
||||
if(WITH_VULKAN_BACKEND)
|
||||
find_package(MoltenVK REQUIRED)
|
||||
find_package(ShaderC REQUIRED)
|
||||
find_package(Vulkan REQUIRED)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENSUBDIV)
|
||||
find_package(OpenSubdiv)
|
||||
endif()
|
||||
|
@ -46,13 +46,12 @@ else()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Support restoring this value once pre-compiled libraries have been handled.
|
||||
set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS})
|
||||
|
||||
if(DEFINED LIBDIR)
|
||||
if(FIRST_RUN)
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
|
||||
file(GLOB LIB_SUBDIRS ${LIBDIR}/*)
|
||||
|
||||
@ -119,24 +118,17 @@ if(WITH_VULKAN_BACKEND)
|
||||
find_package_wrapper(Vulkan REQUIRED)
|
||||
find_package_wrapper(ShaderC REQUIRED)
|
||||
endif()
|
||||
add_bundled_libraries(vulkan/lib)
|
||||
|
||||
function(check_freetype_for_brotli)
|
||||
if((DEFINED HAVE_BROTLI AND HAVE_BROTLI) AND
|
||||
(DEFINED HAVE_BROTLI_INC AND ("${HAVE_BROTLI_INC}" STREQUAL "${FREETYPE_INCLUDE_DIRS}")))
|
||||
# Pass, the includes didn't change, use the cached value.
|
||||
else()
|
||||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${FREETYPE_INCLUDE_DIRS})
|
||||
check_symbol_exists(FT_CONFIG_OPTION_USE_BROTLI "freetype/config/ftconfig.h" HAVE_BROTLI)
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
if(NOT HAVE_BROTLI)
|
||||
unset(HAVE_BROTLI CACHE)
|
||||
include(CheckSymbolExists)
|
||||
set(CMAKE_REQUIRED_INCLUDES ${FREETYPE_INCLUDE_DIRS})
|
||||
check_symbol_exists(FT_CONFIG_OPTION_USE_BROTLI "freetype/config/ftconfig.h" HAVE_BROTLI)
|
||||
unset(CMAKE_REQUIRED_INCLUDES)
|
||||
if(NOT HAVE_BROTLI)
|
||||
unset(HAVE_BROTLI CACHE)
|
||||
message(FATAL_ERROR "Freetype needs to be compiled with brotli support!")
|
||||
endif()
|
||||
set(HAVE_BROTLI_INC "${FREETYPE_INCLUDE_DIRS}" CACHE INTERNAL "")
|
||||
message(FATAL_ERROR "Freetype needs to be compiled with brotli support!")
|
||||
endif()
|
||||
unset(HAVE_BROTLI CACHE)
|
||||
endfunction()
|
||||
|
||||
if(NOT WITH_SYSTEM_FREETYPE)
|
||||
@ -551,9 +543,7 @@ if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING)
|
||||
if(openpgl_FOUND)
|
||||
get_target_property(OPENPGL_LIBRARIES openpgl::openpgl LOCATION)
|
||||
get_target_property(OPENPGL_INCLUDE_DIR openpgl::openpgl INTERFACE_INCLUDE_DIRECTORIES)
|
||||
if(FIRST_RUN)
|
||||
message(STATUS "Found OpenPGL: ${OPENPGL_LIBRARIES}")
|
||||
endif()
|
||||
message(STATUS "Found OpenPGL: ${OPENPGL_LIBRARIES}")
|
||||
else()
|
||||
set(WITH_CYCLES_PATH_GUIDING OFF)
|
||||
message(STATUS "OpenPGL not found, disabling WITH_CYCLES_PATH_GUIDING")
|
||||
@ -720,6 +710,10 @@ if(WITH_GHOST_WAYLAND)
|
||||
set_and_warn_library_found("xkbcommon" xkbcommon_FOUND WITH_GHOST_WAYLAND)
|
||||
|
||||
if(WITH_GHOST_WAYLAND)
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
pkg_check_modules(dbus REQUIRED dbus-1)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
if(_use_system_wayland)
|
||||
pkg_check_modules(libdecor libdecor-0>=0.1)
|
||||
@ -730,6 +724,10 @@ if(WITH_GHOST_WAYLAND)
|
||||
set_and_warn_library_found("libdecor" libdecor_FOUND WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_DBUS)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR)
|
||||
endif()
|
||||
|
@ -278,9 +278,7 @@ if(NOT DEFINED LIBDIR)
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
|
||||
endif()
|
||||
else()
|
||||
if(FIRST_RUN)
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}")
|
||||
endif()
|
||||
if(NOT EXISTS "${LIBDIR}/")
|
||||
message(FATAL_ERROR "\n\nWindows requires pre-compiled libs at: '${LIBDIR}'. Please run `make update` in the blender source folder to obtain them.")
|
||||
|
@ -19,7 +19,7 @@ buildbot:
|
||||
optix:
|
||||
version: '7.3.0'
|
||||
ocloc:
|
||||
version: '101.4723'
|
||||
version: '101.4369'
|
||||
cmake:
|
||||
default:
|
||||
version: any
|
||||
|
@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = V4.1
|
||||
PROJECT_NUMBER = V4.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
8
extern/CMakeLists.txt
vendored
8
extern/CMakeLists.txt
vendored
@ -20,14 +20,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_COMPILER_ASAN AND NOT WITH_COMPILER_ASAN_EXTERN)
|
||||
# Disable ASAN for extern dependencies, as it can lead to linking issues due to too large binaries.
|
||||
string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-sanitize=all")
|
||||
string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -fno-sanitize=all")
|
||||
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-sanitize=all")
|
||||
string(APPEND CMAKE_C_FLAGS_DEBUG " -fno-sanitize=all")
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(rangetree)
|
||||
add_subdirectory(nanosvg)
|
||||
|
10
extern/vulkan_memory_allocator/CMakeLists.txt
vendored
10
extern/vulkan_memory_allocator/CMakeLists.txt
vendored
@ -8,23 +8,15 @@ set(INC
|
||||
|
||||
set(INC_SYS
|
||||
${VULKAN_INCLUDE_DIRS}
|
||||
${MOLTENVK_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND INC_SYS
|
||||
${MOLTENVK_INCLUDE_DIRS}
|
||||
)
|
||||
endif()
|
||||
|
||||
set(SRC
|
||||
vk_mem_alloc_impl.cc
|
||||
|
||||
vk_mem_alloc.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
)
|
||||
|
||||
blender_add_lib(extern_vulkan_memory_allocator "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
8
extern/wcwidth/wcwidth.h
vendored
8
extern/wcwidth/wcwidth.h
vendored
@ -30,17 +30,9 @@ typedef unsigned int char32_t;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int mk_wcwidth(char32_t ucs);
|
||||
int mk_wcswidth(const char32_t *pwcs, size_t n);
|
||||
int mk_wcwidth_cjk(char32_t ucs);
|
||||
int mk_wcswidth_cjk(const char32_t *pwcs, size_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1019,11 +1019,6 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
|
||||
"disabling will render faster but not give accurate shadows",
|
||||
default=True,
|
||||
)
|
||||
use_bump_map_correction: BoolProperty(
|
||||
name="Bump Map Correction",
|
||||
description="Apply corrections to solve shadow terminator artifacts caused by bump mapping",
|
||||
default=True,
|
||||
)
|
||||
homogeneous_volume: BoolProperty(
|
||||
name="Homogeneous Volume",
|
||||
description="When using volume rendering, assume volume has the same density everywhere "
|
||||
@ -1648,7 +1643,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
||||
elif device_type == 'ONEAPI':
|
||||
import sys
|
||||
if sys.platform.startswith("win"):
|
||||
driver_version = "XX.X.101.4824"
|
||||
driver_version = "XX.X.101.4644"
|
||||
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
|
||||
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
|
||||
icon='BLANK1', translate=False)
|
||||
|
@ -1967,7 +1967,6 @@ class CYCLES_MATERIAL_PT_settings_surface(CyclesButtonsPanel, Panel):
|
||||
col.prop(cmat, "displacement_method", text="Displacement")
|
||||
col.prop(cmat, "emission_sampling")
|
||||
col.prop(cmat, "use_transparent_shadow")
|
||||
col.prop(cmat, "use_bump_map_correction")
|
||||
|
||||
def draw(self, context):
|
||||
self.draw_shared(self, context.material)
|
||||
|
@ -816,10 +816,9 @@ static void create_mesh(Scene *scene,
|
||||
const blender::OffsetIndices faces = b_mesh.faces();
|
||||
const blender::Span<int> corner_verts = b_mesh.corner_verts();
|
||||
const blender::bke::AttributeAccessor b_attributes = b_mesh.attributes();
|
||||
const blender::bke::MeshNormalDomain normals_domain = b_mesh.normals_domain();
|
||||
int numfaces = (!subdivision) ? b_mesh.looptris().size() : faces.size();
|
||||
|
||||
bool use_loop_normals = normals_domain == blender::bke::MeshNormalDomain::Corner &&
|
||||
bool use_loop_normals = (b_mesh.flag & ME_AUTOSMOOTH) &&
|
||||
(mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK);
|
||||
|
||||
/* If no faces, create empty mesh. */
|
||||
@ -833,7 +832,9 @@ static void create_mesh(Scene *scene,
|
||||
ATTR_DOMAIN_FACE);
|
||||
blender::Span<blender::float3> corner_normals;
|
||||
if (use_loop_normals) {
|
||||
corner_normals = b_mesh.corner_normals();
|
||||
corner_normals = {
|
||||
static_cast<const blender::float3 *>(CustomData_get_layer(&b_mesh.loop_data, CD_NORMAL)),
|
||||
corner_verts.size()};
|
||||
}
|
||||
|
||||
int numngons = 0;
|
||||
@ -938,8 +939,7 @@ static void create_mesh(Scene *scene,
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* If only face normals are needed, all faces are sharp. */
|
||||
std::fill(smooth, smooth + numtris, normals_domain != blender::bke::MeshNormalDomain::Face);
|
||||
std::fill(smooth, smooth + numtris, true);
|
||||
}
|
||||
|
||||
if (use_loop_normals && !corner_normals.is_empty()) {
|
||||
|
@ -1551,7 +1551,6 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all)
|
||||
PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles");
|
||||
shader->set_emission_sampling_method(get_emission_sampling(cmat));
|
||||
shader->set_use_transparent_shadow(get_boolean(cmat, "use_transparent_shadow"));
|
||||
shader->set_use_bump_map_correction(get_boolean(cmat, "use_bump_map_correction"));
|
||||
shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume"));
|
||||
shader->set_volume_sampling_method(get_volume_sampling(cmat));
|
||||
shader->set_volume_interpolation_method(get_volume_interpolation(cmat));
|
||||
|
@ -94,9 +94,8 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
|
||||
/* Make a copy to split faces if we use auto-smooth, otherwise not needed.
|
||||
* Also in edit mode do we need to make a copy, to ensure data layers like
|
||||
* UV are not empty. */
|
||||
if (mesh.is_editmode() || (mesh.normals_domain() == BL::Mesh::normals_domain_CORNER &&
|
||||
subdivision_type == Mesh::SUBDIVISION_NONE))
|
||||
{
|
||||
if (mesh.is_editmode() ||
|
||||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
|
||||
BL::Depsgraph depsgraph(PointerRNA_NULL);
|
||||
mesh = b_ob_info.real_object.to_mesh(false, depsgraph);
|
||||
}
|
||||
@ -120,7 +119,8 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/,
|
||||
#endif
|
||||
|
||||
if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) {
|
||||
if (mesh.normals_domain() == BL::Mesh::normals_domain_CORNER) {
|
||||
if (mesh.use_auto_smooth()) {
|
||||
mesh.calc_normals_split();
|
||||
mesh.split_faces();
|
||||
}
|
||||
|
||||
|
@ -128,7 +128,7 @@ macro(cycles_external_libraries_append libraries)
|
||||
if(WITH_PATH_GUIDING)
|
||||
list(APPEND ${libraries} ${OPENPGL_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_WEBP)
|
||||
if (WITH_WEBP)
|
||||
list(APPEND ${libraries} ${WEBP_LIBRARIES})
|
||||
endif()
|
||||
if(UNIX AND NOT APPLE)
|
||||
|
@ -853,11 +853,11 @@ void OneapiDevice::get_adjusted_global_and_local_sizes(SyclQueue *queue,
|
||||
|
||||
/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
|
||||
* since Windows driver 101.3268. */
|
||||
static const int lowest_supported_driver_version_win = 1014824;
|
||||
static const int lowest_supported_driver_version_win = 1014644;
|
||||
# ifdef _WIN32
|
||||
/* For Windows driver 101.4824, compute-runtime version is 26957.
|
||||
/* For Windows driver 101.4644, compute-runtime version is 26771.
|
||||
* This information is returned by `ocloc query OCL_DRIVER_VERSION`.*/
|
||||
static const int lowest_supported_driver_version_neo = 26957;
|
||||
static const int lowest_supported_driver_version_neo = 26771;
|
||||
# else
|
||||
static const int lowest_supported_driver_version_neo = 25812;
|
||||
# endif
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include "util/log.h"
|
||||
#include "util/math.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, const TileSize &tile_size)
|
||||
|
@ -43,7 +43,7 @@ set(SRC_KERNEL_DEVICE_OPTIX
|
||||
if(WITH_CYCLES_OSL)
|
||||
math(EXPR OSL_LIBRARY_VERSION_CODE "${OSL_LIBRARY_VERSION_MAJOR} * 10000 + ${OSL_LIBRARY_VERSION_MINOR} * 100 + ${OSL_LIBRARY_VERSION_PATCH}")
|
||||
|
||||
if(OSL_LIBRARY_VERSION_CODE GREATER_EQUAL 11300)
|
||||
if (OSL_LIBRARY_VERSION_CODE GREATER_EQUAL 11300)
|
||||
set(SRC_KERNEL_DEVICE_OPTIX
|
||||
${SRC_KERNEL_DEVICE_OPTIX}
|
||||
osl/services_optix.cu
|
||||
@ -884,32 +884,7 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
||||
endif()
|
||||
# Enable zebin, a graphics binary format with improved compatibility.
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ")
|
||||
|
||||
# Add the list of Intel devices to build binaries for.
|
||||
foreach(device ${CYCLES_ONEAPI_INTEL_BINARIES_ARCH})
|
||||
# Run ocloc ids to test if the device is supported.
|
||||
if(WIN32)
|
||||
execute_process(COMMAND ${OCLOC_INSTALL_DIR}/ocloc.exe ids ${device}
|
||||
RESULT_VARIABLE oclocids_ret
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET)
|
||||
else()
|
||||
execute_process(COMMAND ${CMAKE_COMMAND}
|
||||
-E env "LD_LIBRARY_PATH=${OCLOC_INSTALL_DIR}/lib:${IGC_INSTALL_DIR}/lib"
|
||||
${OCLOC_INSTALL_DIR}/bin/ocloc ids ${device}
|
||||
RESULT_VARIABLE oclocids_ret
|
||||
OUTPUT_QUIET
|
||||
ERROR_QUIET)
|
||||
endif()
|
||||
if(NOT oclocids_ret EQUAL 0)
|
||||
list(REMOVE_ITEM CYCLES_ONEAPI_INTEL_BINARIES_ARCH ${device})
|
||||
message(STATUS "binaries for ${device} not supported by Intel Graphics Compiler/ocloc, skipped.")
|
||||
endif()
|
||||
endforeach()
|
||||
list(JOIN CYCLES_ONEAPI_INTEL_BINARIES_ARCH "," gen_devices_string)
|
||||
if(NOT "${gen_devices_string}" STREQUAL "")
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${gen_devices_string} ")
|
||||
endif()
|
||||
string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ")
|
||||
|
||||
# Host execution won't use GPU binaries, no need to compile them.
|
||||
if(WITH_CYCLES_ONEAPI_BINARIES AND NOT WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION)
|
||||
|
@ -235,7 +235,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
||||
*eval *= shift_cos_in(cosNO, frequency_multiplier);
|
||||
}
|
||||
if (label & LABEL_DIFFUSE) {
|
||||
if ((sd->flag & SD_USE_BUMP_MAP_CORRECTION) && !isequal(sc->N, sd->N)) {
|
||||
if (!isequal(sc->N, sd->N)) {
|
||||
*eval *= bump_shadowing_term(sd->N, sc->N, *wo);
|
||||
}
|
||||
}
|
||||
@ -529,7 +529,7 @@ ccl_device_inline
|
||||
}
|
||||
|
||||
if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) {
|
||||
if ((sd->flag & SD_USE_BUMP_MAP_CORRECTION) && !isequal(sc->N, sd->N)) {
|
||||
if (!isequal(sc->N, sd->N)) {
|
||||
eval *= bump_shadowing_term(sd->N, sc->N, wo);
|
||||
}
|
||||
}
|
||||
|
@ -191,9 +191,6 @@ ccl_device float3 ensure_valid_specular_reflection(float3 Ng, float3 I, float3 N
|
||||
* normal and the shading normal is the same. */
|
||||
ccl_device float3 maybe_ensure_valid_specular_reflection(ccl_private ShaderData *sd, float3 N)
|
||||
{
|
||||
if ((sd->flag & SD_USE_BUMP_MAP_CORRECTION) == 0) {
|
||||
return N;
|
||||
}
|
||||
if ((sd->type & PRIMITIVE_CURVE) || isequal(sd->Ng, N)) {
|
||||
return N;
|
||||
}
|
||||
|
@ -223,7 +223,9 @@ ccl_device_forceinline int __float_as_int(float x)
|
||||
#define fmodf(x, y) sycl::fmod((x), (y))
|
||||
#define lgammaf(x) sycl::lgamma((x))
|
||||
|
||||
#define cosf(x) sycl::native::cos(((float)(x)))
|
||||
/* sycl::native::cos precision is not sufficient when using Nishita Sky node
|
||||
* with a small sun size. */
|
||||
#define cosf(x) sycl::cos(((float)(x)))
|
||||
#define sinf(x) sycl::native::sin(((float)(x)))
|
||||
#define powf(x, y) sycl::native::powr(((float)(x)), ((float)(y)))
|
||||
#define tanf(x) sycl::native::tan(((float)(x)))
|
||||
|
@ -492,7 +492,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce(
|
||||
/* Update path state */
|
||||
if (!(label & LABEL_TRANSPARENT)) {
|
||||
INTEGRATOR_STATE_WRITE(state, path, mis_ray_pdf) = mis_pdf;
|
||||
INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sc->N;
|
||||
INTEGRATOR_STATE_WRITE(state, path, mis_origin_n) = sd->N;
|
||||
INTEGRATOR_STATE_WRITE(state, path, min_ray_pdf) = fminf(
|
||||
unguided_bsdf_pdf, INTEGRATOR_STATE(state, path, min_ray_pdf));
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ ccl_device_inline float area_light_rect_sample(float3 P,
|
||||
float4 diff = make_float4(x0, y1, x1, y0) - make_float4(x1, y0, x0, y1);
|
||||
float4 nz = make_float4(y0, x1, y1, x0) * diff;
|
||||
nz = nz / sqrt(z0 * z0 * diff * diff + nz * nz);
|
||||
/* The original paper uses `acos()` to compute the internal angles here, and then computes the
|
||||
/* The original paper uses acos() to compute the internal angles here, and then computes the
|
||||
* solid angle as their sum minus 2*pi. However, for very small rectangles, this results in
|
||||
* excessive cancellation error since the sum will be almost 2*pi as well.
|
||||
* This can be avoided by using that `asin(x) = pi/2 - acos(x)`. */
|
||||
@ -62,8 +62,8 @@ ccl_device_inline float area_light_rect_sample(float3 P,
|
||||
float b0sq = b0 * b0;
|
||||
/* Compute cu.
|
||||
* In the original paper, an additional constant k is involved here. However, just like above,
|
||||
* it causes cancellation issues. The same `asin()` terms from above can be used instead, and
|
||||
* the extra +pi that would remain in the expression for au can be removed by flipping the sign
|
||||
* it causes cancellation issues. The same asin() terms from above can be used instead, and the
|
||||
* extra +pi that would remain in the expression for au can be removed by flipping the sign
|
||||
* of cos(au) and sin(au), which also cancels if we flip the sign of b1 in the fu term. */
|
||||
float au = rand.x * S + g2 + g3;
|
||||
float fu = (cosf(au) * b0 + b1) / sinf(au);
|
||||
|
@ -836,8 +836,6 @@ enum ShaderDataFlag {
|
||||
|
||||
/* Shader flags. */
|
||||
|
||||
/* Apply a correction term to smooth illumination on grazing angles when using bump mapping.. */
|
||||
SD_USE_BUMP_MAP_CORRECTION = (1 << 15),
|
||||
/* Use front side for direct light sampling. */
|
||||
SD_MIS_FRONT = (1 << 16),
|
||||
/* Has transparent shadow. */
|
||||
|
@ -54,7 +54,6 @@ NODE_DEFINE(Shader)
|
||||
EMISSION_SAMPLING_AUTO);
|
||||
|
||||
SOCKET_BOOLEAN(use_transparent_shadow, "Use Transparent Shadow", true);
|
||||
SOCKET_BOOLEAN(use_bump_map_correction, "Bump Map Correction", true);
|
||||
SOCKET_BOOLEAN(heterogeneous_volume, "Heterogeneous Volume", true);
|
||||
|
||||
static NodeEnum volume_sampling_method_enum;
|
||||
@ -591,9 +590,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
||||
if (shader->get_displacement_method() != DISPLACE_BUMP) {
|
||||
flag |= SD_HAS_DISPLACEMENT;
|
||||
}
|
||||
if (shader->get_use_bump_map_correction()) {
|
||||
flag |= SD_USE_BUMP_MAP_CORRECTION;
|
||||
}
|
||||
|
||||
/* constant emission check */
|
||||
if (shader->emission_is_constant) {
|
||||
|
@ -77,7 +77,6 @@ class Shader : public Node {
|
||||
/* sampling */
|
||||
NODE_SOCKET_API(EmissionSampling, emission_sampling_method)
|
||||
NODE_SOCKET_API(bool, use_transparent_shadow)
|
||||
NODE_SOCKET_API(bool, use_bump_map_correction)
|
||||
NODE_SOCKET_API(bool, heterogeneous_volume)
|
||||
NODE_SOCKET_API(VolumeSampling, volume_sampling_method)
|
||||
NODE_SOCKET_API(int, volume_interpolation_method)
|
||||
|
@ -9,6 +9,7 @@ set(INC
|
||||
)
|
||||
|
||||
set(INC_SYS
|
||||
${Epoxy_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
@ -71,36 +72,16 @@ set(SRC
|
||||
)
|
||||
|
||||
set(LIB
|
||||
${Epoxy_LIBRARIES}
|
||||
PRIVATE bf::blenlib
|
||||
PRIVATE bf::dna
|
||||
)
|
||||
|
||||
if(WITH_INPUT_IME)
|
||||
add_definitions(-DWITH_INPUT_IME)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENGL_BACKEND)
|
||||
list(APPEND INC_SYS
|
||||
${Epoxy_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
${Epoxy_LIBRARIES}
|
||||
)
|
||||
add_definitions(-DWITH_OPENGL_BACKEND)
|
||||
endif()
|
||||
|
||||
if(WITH_VULKAN_BACKEND)
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND INC_SYS
|
||||
PUBLIC ${MOLTENVK_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(APPEND LIB
|
||||
${MOLTENVK_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextVK.cc
|
||||
|
||||
@ -109,10 +90,12 @@ if(WITH_VULKAN_BACKEND)
|
||||
|
||||
list(APPEND INC_SYS
|
||||
PUBLIC ${VULKAN_INCLUDE_DIRS}
|
||||
PUBLIC ${MOLTENVK_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
list(APPEND LIB
|
||||
${VULKAN_LIBRARIES}
|
||||
${MOLTENVK_LIBRARIES}
|
||||
)
|
||||
|
||||
add_definitions(-DWITH_VULKAN_BACKEND)
|
||||
@ -181,6 +164,9 @@ elseif(WITH_GHOST_SDL)
|
||||
endif()
|
||||
|
||||
elseif(APPLE AND NOT WITH_GHOST_X11)
|
||||
if(WITH_INPUT_IME)
|
||||
add_definitions(-DWITH_INPUT_IME)
|
||||
endif()
|
||||
list(APPEND SRC
|
||||
intern/GHOST_DisplayManagerCocoa.mm
|
||||
intern/GHOST_SystemCocoa.mm
|
||||
@ -230,13 +216,11 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
||||
intern/GHOST_WindowX11.hh
|
||||
)
|
||||
|
||||
if(WITH_OPENGL_BACKEND)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextGLX.cc
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextGLX.cc
|
||||
|
||||
intern/GHOST_ContextGLX.hh
|
||||
)
|
||||
endif()
|
||||
intern/GHOST_ContextGLX.hh
|
||||
)
|
||||
|
||||
if(WITH_GHOST_XDND)
|
||||
add_definitions(-DWITH_XDND)
|
||||
@ -323,6 +307,15 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_DBUS)
|
||||
list(APPEND INC_SYS
|
||||
${dbus_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND LIB
|
||||
${dbus_LINK_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
list(APPEND INC_SYS
|
||||
${libdecor_INCLUDE_DIRS}
|
||||
@ -352,6 +345,7 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
||||
intern/GHOST_WindowWayland.cc
|
||||
|
||||
intern/GHOST_SystemWayland.hh
|
||||
intern/GHOST_WaylandCursorSettings.hh
|
||||
intern/GHOST_WaylandUtils.hh
|
||||
intern/GHOST_WindowWayland.hh
|
||||
)
|
||||
@ -440,11 +434,6 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND)
|
||||
generate_protocol_bindings(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/unstable/primary-selection/primary-selection-unstable-v1.xml"
|
||||
)
|
||||
if(WITH_INPUT_IME)
|
||||
generate_protocol_bindings(
|
||||
"${WAYLAND_PROTOCOLS_DIR}/unstable/text-input/text-input-unstable-v3.xml"
|
||||
)
|
||||
endif()
|
||||
|
||||
unset(INC_DST)
|
||||
|
||||
@ -504,6 +493,8 @@ elseif(WIN32)
|
||||
)
|
||||
|
||||
if(WITH_INPUT_IME)
|
||||
add_definitions(-DWITH_INPUT_IME)
|
||||
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ImeWin32.cc
|
||||
|
||||
@ -521,13 +512,11 @@ elseif(WIN32)
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
if(WITH_OPENGL_BACKEND)
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextEGL.cc
|
||||
list(APPEND SRC
|
||||
intern/GHOST_ContextEGL.cc
|
||||
|
||||
intern/GHOST_ContextEGL.hh
|
||||
)
|
||||
endif()
|
||||
intern/GHOST_ContextEGL.hh
|
||||
)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
|
@ -35,26 +35,26 @@ class GHOST_IEvent {
|
||||
* Returns the event type.
|
||||
* \return The event type.
|
||||
*/
|
||||
virtual GHOST_TEventType getType() const = 0;
|
||||
virtual GHOST_TEventType getType() = 0;
|
||||
|
||||
/**
|
||||
* Returns the time this event was generated.
|
||||
* \return The event generation time.
|
||||
*/
|
||||
virtual uint64_t getTime() const = 0;
|
||||
virtual uint64_t getTime() = 0;
|
||||
|
||||
/**
|
||||
* Returns the window this event was generated on,
|
||||
* or nullptr if it is a 'system' event.
|
||||
* \return The generating window.
|
||||
*/
|
||||
virtual GHOST_IWindow *getWindow() const = 0;
|
||||
virtual GHOST_IWindow *getWindow() = 0;
|
||||
|
||||
/**
|
||||
* Returns the event data.
|
||||
* \return The event data.
|
||||
*/
|
||||
virtual GHOST_TEventDataPtr getData() const = 0;
|
||||
virtual GHOST_TEventDataPtr getData() = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEvent")
|
||||
|
@ -32,7 +32,7 @@ class GHOST_IEventConsumer {
|
||||
* \param event: The event that can be handled or ignored.
|
||||
* \return Indication as to whether the event was handled.
|
||||
*/
|
||||
virtual bool processEvent(const GHOST_IEvent *event) = 0;
|
||||
virtual bool processEvent(GHOST_IEvent *event) = 0;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IEventConsumer")
|
||||
|
@ -119,10 +119,6 @@ typedef enum {
|
||||
* Support for sampling a color outside of the Blender windows.
|
||||
*/
|
||||
GHOST_kCapabilityDesktopSample = (1 << 5),
|
||||
/**
|
||||
* Supports IME text input methods (when `WITH_INPUT_IME` is defined).
|
||||
*/
|
||||
GHOST_kCapabilityInputIME = (1 << 6),
|
||||
} GHOST_TCapabilityFlag;
|
||||
|
||||
/**
|
||||
@ -132,7 +128,7 @@ typedef enum {
|
||||
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||
GHOST_kCapabilityPrimaryClipboard | GHOST_kCapabilityGPUReadFrontBuffer | \
|
||||
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityDesktopSample | GHOST_kCapabilityInputIME)
|
||||
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityDesktopSample)
|
||||
|
||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||
* vertically upright in either the X or Y direction, with X and Y the
|
||||
@ -308,6 +304,8 @@ typedef enum {
|
||||
GHOST_kEventOpenMainFile, /* Needed for Cocoa to open double-clicked .blend file at startup. */
|
||||
GHOST_kEventNativeResolutionChange, /* Needed for Cocoa when window moves to other display. */
|
||||
|
||||
GHOST_kEventTimer,
|
||||
|
||||
GHOST_kEventImeCompositionStart,
|
||||
GHOST_kEventImeComposition,
|
||||
GHOST_kEventImeCompositionEnd,
|
||||
@ -539,7 +537,7 @@ typedef enum {
|
||||
GHOST_kAxisY = (1 << 1),
|
||||
} GHOST_TAxisFlag;
|
||||
|
||||
typedef const void *GHOST_TEventDataPtr;
|
||||
typedef void *GHOST_TEventDataPtr;
|
||||
|
||||
typedef struct {
|
||||
/** The x-coordinate of the cursor position. */
|
||||
@ -593,8 +591,6 @@ typedef enum {
|
||||
GHOST_kDragnDropTypeBitmap /* Bitmap image data. */
|
||||
} GHOST_TDragnDropTypes;
|
||||
|
||||
typedef void *GHOST_TDragnDropDataPtr;
|
||||
|
||||
typedef struct {
|
||||
/** The x-coordinate of the cursor position. */
|
||||
int32_t x;
|
||||
@ -603,13 +599,10 @@ typedef struct {
|
||||
/** The dropped item type */
|
||||
GHOST_TDragnDropTypes dataType;
|
||||
/** The "dropped content" */
|
||||
GHOST_TDragnDropDataPtr data;
|
||||
GHOST_TEventDataPtr data;
|
||||
} GHOST_TEventDragnDropData;
|
||||
|
||||
/**
|
||||
* \warning this is a duplicate of #wmImeData.
|
||||
* All members must remain aligned and the struct size match!
|
||||
*/
|
||||
/** similar to wmImeData */
|
||||
typedef struct {
|
||||
/** size_t */
|
||||
GHOST_TUserDataPtr result_len, composite_len;
|
||||
|
@ -21,7 +21,7 @@ GHOST_CallbackEventConsumer::GHOST_CallbackEventConsumer(GHOST_EventCallbackProc
|
||||
m_userData = userData;
|
||||
}
|
||||
|
||||
bool GHOST_CallbackEventConsumer::processEvent(const GHOST_IEvent *event)
|
||||
bool GHOST_CallbackEventConsumer::processEvent(GHOST_IEvent *event)
|
||||
{
|
||||
return m_eventCallback((GHOST_EventHandle)event, m_userData);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer {
|
||||
* \param event: The event that can be handled or ignored.
|
||||
* \return Indication as to whether the event was handled.
|
||||
*/
|
||||
bool processEvent(const GHOST_IEvent *event);
|
||||
bool processEvent(GHOST_IEvent *event);
|
||||
|
||||
protected:
|
||||
/** The call-back routine invoked. */
|
||||
|
@ -22,9 +22,7 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
# include <epoxy/gl.h>
|
||||
#endif
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
@ -129,11 +127,9 @@ bool win32_chk(bool result, const char *file, int line, const char *text)
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
void GHOST_Context::initClearGL()
|
||||
{
|
||||
glClearColor(0.294, 0.294, 0.294, 0.000);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.000, 0.000, 0.000, 0.000);
|
||||
}
|
||||
#endif
|
||||
|
@ -187,9 +187,7 @@ class GHOST_Context : public GHOST_IContext {
|
||||
/** Caller specified, not for internal use. */
|
||||
void *m_user_data = nullptr;
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
static void initClearGL();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_Context")
|
||||
|
@ -162,6 +162,8 @@ class GHOST_ContextCGL : public GHOST_Context {
|
||||
int mtl_SwapInterval;
|
||||
const bool m_debug;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
static NSOpenGLContext *s_sharedOpenGLContext;
|
||||
static int s_sharedCount;
|
||||
|
||||
/* Single device queue for multiple contexts. */
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
@ -41,6 +43,7 @@ static void ghost_fatal_error_dialog(const char *msg)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
NSOpenGLContext *GHOST_ContextCGL::s_sharedOpenGLContext = nil;
|
||||
MTLCommandQueue *GHOST_ContextCGL::s_sharedMetalCommandQueue = nil;
|
||||
int GHOST_ContextCGL::s_sharedCount = 0;
|
||||
|
||||
|
@ -256,7 +256,7 @@ class GHOST_SharedOpenGLResource {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
/* Build the render-buffer. */
|
||||
/* Build the renderbuffer. */
|
||||
glGenRenderbuffers(1, &m_gl_render_target);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_gl_render_target);
|
||||
|
||||
@ -273,7 +273,7 @@ class GHOST_SharedOpenGLResource {
|
||||
reregisterSharedObject(TARGET_TEX2D);
|
||||
}
|
||||
|
||||
/* Build the frame-buffer. */
|
||||
/* Build the framebuffer */
|
||||
glGenFramebuffers(1, &m_shared.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_shared.fbo);
|
||||
if (m_use_gl_texture2d) {
|
||||
|
@ -8,10 +8,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef WITH_OPENGL_BACKEND
|
||||
# error "ContextEGL requires WITH_OPENGL_BACKEND"
|
||||
#endif
|
||||
|
||||
#include "GHOST_Context.hh"
|
||||
#include "GHOST_System.hh"
|
||||
|
||||
|
@ -179,7 +179,7 @@ class GHOST_DeviceVK {
|
||||
}
|
||||
}
|
||||
|
||||
bool has_extensions(const vector<const char *> &required_extensions)
|
||||
bool extensions_support(const vector<const char *> &required_extensions)
|
||||
{
|
||||
uint32_t ext_count;
|
||||
vkEnumerateDeviceExtensionProperties(physical_device, nullptr, &ext_count, nullptr);
|
||||
@ -231,20 +231,22 @@ class GHOST_DeviceVK {
|
||||
device_features.drawIndirectFirstInstance = VK_TRUE;
|
||||
device_features.fragmentStoresAndAtomics = VK_TRUE;
|
||||
|
||||
VkPhysicalDeviceVulkan12Features device_12_features = {};
|
||||
device_12_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
|
||||
device_12_features.shaderOutputLayer = VK_TRUE;
|
||||
device_12_features.shaderOutputViewportIndex = VK_TRUE;
|
||||
|
||||
VkPhysicalDeviceMaintenance4FeaturesKHR maintenance_4 = {};
|
||||
maintenance_4.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR;
|
||||
maintenance_4.pNext = &device_12_features;
|
||||
maintenance_4.maintenance4 = VK_TRUE;
|
||||
|
||||
/* Enable shader draw parameters on logical device when supported on physical device. */
|
||||
VkPhysicalDeviceShaderDrawParametersFeatures shader_draw_parameters = {};
|
||||
shader_draw_parameters.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES;
|
||||
shader_draw_parameters.shaderDrawParameters = features_11.shaderDrawParameters;
|
||||
|
||||
VkPhysicalDeviceMaintenance4FeaturesKHR maintenance_4 = {};
|
||||
maintenance_4.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_FEATURES_KHR;
|
||||
maintenance_4.maintenance4 = VK_TRUE;
|
||||
/* Mainenance4 is core in Vulkan 1.3 so we need to query for availability. */
|
||||
if (has_extensions({VK_KHR_MAINTENANCE_4_EXTENSION_NAME})) {
|
||||
maintenance_4.pNext = shader_draw_parameters.pNext;
|
||||
shader_draw_parameters.pNext = &maintenance_4;
|
||||
}
|
||||
shader_draw_parameters.pNext = &maintenance_4;
|
||||
|
||||
VkDeviceCreateInfo device_create_info = {};
|
||||
device_create_info.pNext = &shader_draw_parameters;
|
||||
@ -318,7 +320,7 @@ static GHOST_TSuccess ensure_vulkan_device(VkInstance vk_instance,
|
||||
for (const auto &physical_device : physical_devices) {
|
||||
GHOST_DeviceVK device_vk(vk_instance, physical_device);
|
||||
|
||||
if (!device_vk.has_extensions(required_extensions)) {
|
||||
if (!device_vk.extensions_support(required_extensions)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -393,7 +395,6 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual,
|
||||
/* Wayland */
|
||||
wl_surface *wayland_surface,
|
||||
wl_display *wayland_display,
|
||||
const GHOST_ContextVK_WindowInfo *wayland_window_info,
|
||||
#endif
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
@ -411,7 +412,6 @@ GHOST_ContextVK::GHOST_ContextVK(bool stereoVisual,
|
||||
/* Wayland */
|
||||
m_wayland_surface(wayland_surface),
|
||||
m_wayland_display(wayland_display),
|
||||
m_wayland_window_info(wayland_window_info),
|
||||
#endif
|
||||
m_context_major_version(contextMajorVersion),
|
||||
m_context_minor_version(contextMinorVersion),
|
||||
@ -471,25 +471,6 @@ GHOST_TSuccess GHOST_ContextVK::swapBuffers()
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND
|
||||
/* Wayland doesn't provide a WSI with windowing capabilities, therefore cannot detect whether the
|
||||
* swap-chain needs to be recreated. But as a side effect we can recreate the swap chain before
|
||||
* presenting. */
|
||||
if (m_wayland_window_info) {
|
||||
const bool recreate_swapchain =
|
||||
((m_wayland_window_info->size[0] !=
|
||||
std::max(m_render_extent.width, m_render_extent_min.width)) ||
|
||||
(m_wayland_window_info->size[1] !=
|
||||
std::max(m_render_extent.height, m_render_extent_min.height)));
|
||||
|
||||
if (recreate_swapchain) {
|
||||
/* Swap-chain is out of date. Recreate swap-chain. */
|
||||
destroySwapchain();
|
||||
createSwapchain();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(vulkan_device.has_value() && vulkan_device->device != VK_NULL_HANDLE);
|
||||
VkDevice device = vulkan_device->device;
|
||||
vkAcquireNextImageKHR(device, m_swapchain, UINT64_MAX, VK_NULL_HANDLE, m_fence, &m_currentImage);
|
||||
@ -809,29 +790,11 @@ GHOST_TSuccess GHOST_ContextVK::createSwapchain()
|
||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, m_surface, &capabilities);
|
||||
|
||||
m_render_extent = capabilities.currentExtent;
|
||||
m_render_extent_min = capabilities.minImageExtent;
|
||||
if (m_render_extent.width == UINT32_MAX) {
|
||||
/* Window Manager is going to set the surface size based on the given size.
|
||||
* Choose something between minImageExtent and maxImageExtent. */
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND
|
||||
/* Wayland doesn't provide a windowing API via WSI. */
|
||||
if (m_wayland_window_info) {
|
||||
width = m_wayland_window_info->size[0];
|
||||
height = m_wayland_window_info->size[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
width = 1280;
|
||||
height = 720;
|
||||
}
|
||||
|
||||
m_render_extent.width = width;
|
||||
m_render_extent.height = height;
|
||||
|
||||
m_render_extent.width = 1280;
|
||||
m_render_extent.height = 720;
|
||||
if (capabilities.minImageExtent.width > m_render_extent.width) {
|
||||
m_render_extent.width = capabilities.minImageExtent.width;
|
||||
}
|
||||
@ -973,6 +936,8 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
|
||||
if (m_debug) {
|
||||
enableLayer(layers_available, layers_enabled, VkLayer::KHRONOS_validation, m_debug);
|
||||
requireExtension(extensions_available, extensions_enabled, VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
|
||||
requireExtension(
|
||||
extensions_available, extensions_enabled, VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME);
|
||||
}
|
||||
|
||||
if (use_window_surface) {
|
||||
@ -985,6 +950,8 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
|
||||
}
|
||||
extensions_device.push_back("VK_KHR_dedicated_allocation");
|
||||
extensions_device.push_back("VK_KHR_get_memory_requirements2");
|
||||
/* Allow relaxed interface matching between shader stages. */
|
||||
extensions_device.push_back("VK_KHR_maintenance4");
|
||||
/* Enable MoltenVK required instance extensions. */
|
||||
#ifdef VK_MVK_MOLTENVK_EXTENSION_NAME
|
||||
requireExtension(
|
||||
@ -1075,7 +1042,7 @@ GHOST_TSuccess GHOST_ContextVK::initializeDrawingContext()
|
||||
/* According to the Vulkan specs, when `VK_KHR_portability_subset` is available it should be
|
||||
* enabled. See
|
||||
* https://vulkan.lunarg.com/doc/view/1.2.198.1/mac/1.2-extensions/vkspec.html#VUID-VkDeviceCreateInfo-pProperties-04451*/
|
||||
if (vulkan_device->has_extensions({VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) {
|
||||
if (vulkan_device->extensions_support({VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME})) {
|
||||
extensions_device.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
|
||||
}
|
||||
#endif
|
||||
|
@ -8,10 +8,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef WITH_VULKAN_BACKEND
|
||||
# error "ContextVK requires WITH_VULKAN_BACKEND"
|
||||
#endif
|
||||
|
||||
#include "GHOST_Context.hh"
|
||||
|
||||
#ifdef _WIN32
|
||||
@ -46,10 +42,6 @@ typedef enum {
|
||||
#endif
|
||||
} GHOST_TVulkanPlatformType;
|
||||
|
||||
struct GHOST_ContextVK_WindowInfo {
|
||||
int size[2];
|
||||
};
|
||||
|
||||
class GHOST_ContextVK : public GHOST_Context {
|
||||
public:
|
||||
/**
|
||||
@ -69,7 +61,6 @@ class GHOST_ContextVK : public GHOST_Context {
|
||||
/* Wayland */
|
||||
wl_surface *wayland_surface,
|
||||
wl_display *wayland_display,
|
||||
const GHOST_ContextVK_WindowInfo *wayland_window_info,
|
||||
#endif
|
||||
int contextMajorVersion,
|
||||
int contextMinorVersion,
|
||||
@ -160,7 +151,6 @@ class GHOST_ContextVK : public GHOST_Context {
|
||||
/* Wayland */
|
||||
wl_surface *m_wayland_surface;
|
||||
wl_display *m_wayland_display;
|
||||
const GHOST_ContextVK_WindowInfo *m_wayland_window_info;
|
||||
#endif
|
||||
|
||||
const int m_context_major_version;
|
||||
@ -179,7 +169,6 @@ class GHOST_ContextVK : public GHOST_Context {
|
||||
std::vector<VkImage> m_swapchain_images;
|
||||
|
||||
VkExtent2D m_render_extent;
|
||||
VkExtent2D m_render_extent_min;
|
||||
VkSurfaceFormatKHR m_surface_format;
|
||||
VkFence m_fence;
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
#include "GHOST_Debug.hh"
|
||||
#include <shellapi.h>
|
||||
|
||||
#include "utf_winfunc.hh"
|
||||
#include "utfconv.hh"
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
|
||||
#ifdef WITH_GHOST_DEBUG
|
||||
/* utility */
|
||||
|
@ -31,7 +31,7 @@ class GHOST_Event : public GHOST_IEvent {
|
||||
* Returns the event type.
|
||||
* \return The event type.
|
||||
*/
|
||||
GHOST_TEventType getType() const
|
||||
GHOST_TEventType getType()
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
@ -40,7 +40,7 @@ class GHOST_Event : public GHOST_IEvent {
|
||||
* Returns the time this event was generated.
|
||||
* \return The event generation time.
|
||||
*/
|
||||
uint64_t getTime() const
|
||||
uint64_t getTime()
|
||||
{
|
||||
return m_time;
|
||||
}
|
||||
@ -50,7 +50,7 @@ class GHOST_Event : public GHOST_IEvent {
|
||||
* or nullptr if it is a 'system' event.
|
||||
* \return The generating window.
|
||||
*/
|
||||
GHOST_IWindow *getWindow() const
|
||||
GHOST_IWindow *getWindow()
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
@ -59,7 +59,7 @@ class GHOST_Event : public GHOST_IEvent {
|
||||
* Returns the event data.
|
||||
* \return The event data.
|
||||
*/
|
||||
GHOST_TEventDataPtr getData() const
|
||||
GHOST_TEventDataPtr getData()
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ class GHOST_EventDragnDrop : public GHOST_Event {
|
||||
GHOST_IWindow *window,
|
||||
int x,
|
||||
int y,
|
||||
GHOST_TDragnDropDataPtr data)
|
||||
GHOST_TEventDataPtr data)
|
||||
: GHOST_Event(time, type, window)
|
||||
{
|
||||
m_dragnDropEventData.x = x;
|
||||
|
@ -45,7 +45,7 @@ uint32_t GHOST_EventManager::getNumEvents(GHOST_TEventType type)
|
||||
return numEvents;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_EventManager::pushEvent(const GHOST_IEvent *event)
|
||||
GHOST_TSuccess GHOST_EventManager::pushEvent(GHOST_IEvent *event)
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
GHOST_ASSERT(event, "invalid event");
|
||||
@ -59,7 +59,7 @@ GHOST_TSuccess GHOST_EventManager::pushEvent(const GHOST_IEvent *event)
|
||||
return success;
|
||||
}
|
||||
|
||||
void GHOST_EventManager::dispatchEvent(const GHOST_IEvent *event)
|
||||
void GHOST_EventManager::dispatchEvent(GHOST_IEvent *event)
|
||||
{
|
||||
TConsumerVector::iterator iter;
|
||||
|
||||
@ -70,7 +70,7 @@ void GHOST_EventManager::dispatchEvent(const GHOST_IEvent *event)
|
||||
|
||||
void GHOST_EventManager::dispatchEvent()
|
||||
{
|
||||
const GHOST_IEvent *event = m_events.back();
|
||||
GHOST_IEvent *event = m_events.back();
|
||||
m_events.pop_back();
|
||||
m_handled_events.push_back(event);
|
||||
|
||||
@ -130,7 +130,7 @@ void GHOST_EventManager::removeWindowEvents(const GHOST_IWindow *window)
|
||||
TEventStack::iterator iter;
|
||||
iter = m_events.begin();
|
||||
while (iter != m_events.end()) {
|
||||
const GHOST_IEvent *event = *iter;
|
||||
GHOST_IEvent *event = *iter;
|
||||
if (event->getWindow() == window) {
|
||||
GHOST_PRINT("GHOST_EventManager::removeWindowEvents(): removing event\n");
|
||||
/*
|
||||
@ -152,7 +152,7 @@ void GHOST_EventManager::removeTypeEvents(GHOST_TEventType type, const GHOST_IWi
|
||||
TEventStack::iterator iter;
|
||||
iter = m_events.begin();
|
||||
while (iter != m_events.end()) {
|
||||
const GHOST_IEvent *event = *iter;
|
||||
GHOST_IEvent *event = *iter;
|
||||
if ((event->getType() == type) && (!window || (event->getWindow() == window))) {
|
||||
GHOST_PRINT("GHOST_EventManager::removeTypeEvents(): removing event\n");
|
||||
/*
|
||||
|
@ -53,12 +53,12 @@ class GHOST_EventManager {
|
||||
* Do not delete the event!
|
||||
* \param event: The event to push on the stack.
|
||||
*/
|
||||
GHOST_TSuccess pushEvent(const GHOST_IEvent *event);
|
||||
GHOST_TSuccess pushEvent(GHOST_IEvent *event);
|
||||
|
||||
/**
|
||||
* Dispatches the given event directly, bypassing the event stack.
|
||||
*/
|
||||
void dispatchEvent(const GHOST_IEvent *event);
|
||||
void dispatchEvent(GHOST_IEvent *event);
|
||||
|
||||
/**
|
||||
* Dispatches the event at the back of the stack.
|
||||
@ -108,11 +108,11 @@ class GHOST_EventManager {
|
||||
void disposeEvents();
|
||||
|
||||
/** A stack with events. */
|
||||
typedef std::deque<const GHOST_IEvent *> TEventStack;
|
||||
typedef std::deque<GHOST_IEvent *> TEventStack;
|
||||
|
||||
/** The event stack. */
|
||||
std::deque<const GHOST_IEvent *> m_events;
|
||||
std::deque<const GHOST_IEvent *> m_handled_events;
|
||||
std::deque<GHOST_IEvent *> m_events;
|
||||
std::deque<GHOST_IEvent *> m_handled_events;
|
||||
|
||||
/** A vector with event consumers. */
|
||||
typedef std::vector<GHOST_IEventConsumer *> TConsumerVector;
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
/* For now only used with NDOF. */
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
static const char *getButtonActionString(const GHOST_TButtonAction action)
|
||||
{
|
||||
switch (action) {
|
||||
@ -29,9 +27,8 @@ static const char *getButtonActionString(const GHOST_TButtonAction action)
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
|
||||
bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
|
||||
{
|
||||
bool handled = false;
|
||||
|
||||
@ -40,9 +37,6 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
if (event->getType() == GHOST_kEventWindowUpdate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GHOST_TEventDataPtr data = event->getData();
|
||||
|
||||
std::cout << "GHOST_EventPrinter::processEvent, time: " << int32_t(event->getTime())
|
||||
<< ", type: ";
|
||||
|
||||
@ -62,26 +56,30 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventCursorMove: {
|
||||
const GHOST_TEventCursorData *cursorData = static_cast<const GHOST_TEventCursorData *>(data);
|
||||
GHOST_TEventCursorData *cursorData =
|
||||
(GHOST_TEventCursorData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventCursorMove, (x,y): (" << cursorData->x << "," << cursorData->y
|
||||
<< ")";
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown: {
|
||||
const GHOST_TEventButtonData *buttonData = static_cast<const GHOST_TEventButtonData *>(data);
|
||||
GHOST_TEventButtonData *buttonData =
|
||||
(GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventButtonDown, button: " << buttonData->button;
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonUp: {
|
||||
const GHOST_TEventButtonData *buttonData = static_cast<const GHOST_TEventButtonData *>(data);
|
||||
GHOST_TEventButtonData *buttonData =
|
||||
(GHOST_TEventButtonData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventCursorButtonUp, button: " << buttonData->button;
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventWheel: {
|
||||
const GHOST_TEventWheelData *wheelData = static_cast<const GHOST_TEventWheelData *>(data);
|
||||
GHOST_TEventWheelData *wheelData =
|
||||
(GHOST_TEventWheelData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventWheel, z: " << wheelData->z;
|
||||
handled = true;
|
||||
break;
|
||||
@ -92,7 +90,7 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
case GHOST_kEventNDOFMotion: {
|
||||
const GHOST_TEventNDOFMotionData *ndof_motion =
|
||||
static_cast<const GHOST_TEventNDOFMotionData *>(data);
|
||||
(GHOST_TEventNDOFMotionData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventNDOFMotion: ";
|
||||
std::cout << std::fixed << std::setprecision(2) <<
|
||||
/* Translation. */
|
||||
@ -105,7 +103,7 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
}
|
||||
case GHOST_kEventNDOFButton: {
|
||||
const GHOST_TEventNDOFButtonData *ndof_button =
|
||||
static_cast<const GHOST_TEventNDOFButtonData *>(data);
|
||||
(GHOST_TEventNDOFButtonData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventNDOFButton: " << getButtonActionString(ndof_button->action)
|
||||
<< " button=" << ndof_button->button;
|
||||
handled = true;
|
||||
@ -114,13 +112,13 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
#endif /* WITH_INPUT_NDOF */
|
||||
|
||||
case GHOST_kEventKeyDown: {
|
||||
const GHOST_TEventKeyData *keyData = static_cast<const GHOST_TEventKeyData *>(data);
|
||||
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventKeyDown, key: " << getKeyString(keyData->key);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventKeyUp: {
|
||||
const GHOST_TEventKeyData *keyData = static_cast<const GHOST_TEventKeyData *>(data);
|
||||
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventKeyUp, key: " << getKeyString(keyData->key);
|
||||
handled = true;
|
||||
break;
|
||||
@ -137,8 +135,8 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
CASE_TYPE(GHOST_kEventWindowDPIHintChanged);
|
||||
|
||||
case GHOST_kEventDraggingEntered: {
|
||||
const GHOST_TEventDragnDropData *dragnDropData =
|
||||
static_cast<const GHOST_TEventDragnDropData *>(data);
|
||||
GHOST_TEventDragnDropData *dragnDropData =
|
||||
(GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventDraggingEntered, dragged object type : "
|
||||
<< dragnDropData->dataType;
|
||||
std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
|
||||
@ -146,8 +144,8 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventDraggingUpdated: {
|
||||
const GHOST_TEventDragnDropData *dragnDropData =
|
||||
static_cast<const GHOST_TEventDragnDropData *>(data);
|
||||
GHOST_TEventDragnDropData *dragnDropData =
|
||||
(GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventDraggingUpdated, dragged object type : "
|
||||
<< dragnDropData->dataType;
|
||||
std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
|
||||
@ -155,15 +153,15 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventDraggingExited: {
|
||||
const GHOST_TEventDragnDropData *dragnDropData =
|
||||
static_cast<const GHOST_TEventDragnDropData *>(data);
|
||||
GHOST_TEventDragnDropData *dragnDropData =
|
||||
(GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventDraggingExited, dragged object type : " << dragnDropData->dataType;
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventDraggingDropDone: {
|
||||
const GHOST_TEventDragnDropData *dragnDropData =
|
||||
static_cast<const GHOST_TEventDragnDropData *>(data);
|
||||
GHOST_TEventDragnDropData *dragnDropData =
|
||||
(GHOST_TEventDragnDropData *)((GHOST_IEvent *)event)->getData();
|
||||
std::cout << "GHOST_kEventDraggingDropDone,";
|
||||
std::cout << " mouse at x=" << dragnDropData->x << " y=" << dragnDropData->y;
|
||||
switch (dragnDropData->dataType) {
|
||||
@ -191,8 +189,10 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventOpenMainFile: {
|
||||
if (data) {
|
||||
std::cout << "GHOST_kEventOpenMainFile for path: " << static_cast<const char *>(data);
|
||||
GHOST_TEventDataPtr eventData = ((GHOST_IEvent *)event)->getData();
|
||||
|
||||
if (eventData) {
|
||||
std::cout << "GHOST_kEventOpenMainFile for path : " << (char *)eventData;
|
||||
}
|
||||
else {
|
||||
std::cout << "GHOST_kEventOpenMainFile with no path specified!!";
|
||||
@ -203,6 +203,8 @@ bool GHOST_EventPrinter::processEvent(const GHOST_IEvent *event)
|
||||
|
||||
CASE_TYPE(GHOST_kEventNativeResolutionChange);
|
||||
|
||||
CASE_TYPE(GHOST_kEventTimer);
|
||||
|
||||
CASE_TYPE(GHOST_kEventImeCompositionStart);
|
||||
CASE_TYPE(GHOST_kEventImeComposition);
|
||||
CASE_TYPE(GHOST_kEventImeCompositionEnd);
|
||||
|
@ -22,7 +22,7 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer {
|
||||
* \param event: The event that can be handled or not.
|
||||
* \return Indication as to whether the event was handled.
|
||||
*/
|
||||
bool processEvent(const GHOST_IEvent *event);
|
||||
bool processEvent(GHOST_IEvent *event);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -35,7 +35,7 @@ class GHOST_EventString : public GHOST_Event {
|
||||
~GHOST_EventString()
|
||||
{
|
||||
if (m_data) {
|
||||
free((void *)m_data);
|
||||
free(m_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -11,7 +11,7 @@
|
||||
# include "GHOST_ImeWin32.hh"
|
||||
# include "GHOST_C-api.h"
|
||||
# include "GHOST_WindowWin32.hh"
|
||||
# include "utfconv.hh"
|
||||
# include "utfconv.h"
|
||||
|
||||
/* ISO_639-1 2-Letter Abbreviations. */
|
||||
# define IMELANG_ENGLISH "en"
|
||||
|
@ -267,7 +267,7 @@ GHOST_TSuccess GHOST_System::removeEventConsumer(GHOST_IEventConsumer *consumer)
|
||||
return success;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_System::pushEvent(const GHOST_IEvent *event)
|
||||
GHOST_TSuccess GHOST_System::pushEvent(GHOST_IEvent *event)
|
||||
{
|
||||
GHOST_TSuccess success;
|
||||
if (m_eventManager) {
|
||||
|
@ -285,7 +285,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
* Do not delete the event!
|
||||
* \param event: The event to push on the stack.
|
||||
*/
|
||||
GHOST_TSuccess pushEvent(const GHOST_IEvent *event);
|
||||
GHOST_TSuccess pushEvent(GHOST_IEvent *event);
|
||||
|
||||
/**
|
||||
* \return The timer manager.
|
||||
|
@ -338,14 +338,14 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar)
|
||||
|
||||
#define FIRSTFILEBUFLG 512
|
||||
static bool g_hasFirstFile = false;
|
||||
static char g_firstFileBuf[FIRSTFILEBUFLG];
|
||||
static char g_firstFileBuf[512];
|
||||
|
||||
/* TODO: Need to investigate this.
|
||||
* Function called too early in creator.c to have g_hasFirstFile == true */
|
||||
// TODO: Need to investigate this.
|
||||
// Function called too early in creator.c to have g_hasFirstFile == true
|
||||
extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG])
|
||||
{
|
||||
if (g_hasFirstFile) {
|
||||
memcpy(buf, g_firstFileBuf, FIRSTFILEBUFLG);
|
||||
strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
|
||||
buf[FIRSTFILEBUFLG - 1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
@ -1219,7 +1219,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
NSArray *droppedArray;
|
||||
size_t pastedTextSize;
|
||||
NSString *droppedStr;
|
||||
GHOST_TDragnDropDataPtr eventData;
|
||||
GHOST_TEventDataPtr eventData;
|
||||
int i;
|
||||
|
||||
if (!data) {
|
||||
@ -1254,14 +1254,15 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(
|
||||
temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
|
||||
strncpy((char *)temp_buff,
|
||||
[droppedStr cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
pastedTextSize);
|
||||
temp_buff[pastedTextSize] = '\0';
|
||||
|
||||
strArray->strings[i] = temp_buff;
|
||||
}
|
||||
|
||||
eventData = (GHOST_TDragnDropDataPtr)strArray;
|
||||
eventData = (GHOST_TEventDataPtr)strArray;
|
||||
break;
|
||||
|
||||
case GHOST_kDragnDropTypeString:
|
||||
@ -1274,11 +1275,13 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
memcpy(
|
||||
temp_buff, [droppedStr cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
|
||||
strncpy((char *)temp_buff,
|
||||
[droppedStr cStringUsingEncoding:NSUTF8StringEncoding],
|
||||
pastedTextSize);
|
||||
|
||||
temp_buff[pastedTextSize] = '\0';
|
||||
|
||||
eventData = (GHOST_TDragnDropDataPtr)temp_buff;
|
||||
eventData = (GHOST_TEventDataPtr)temp_buff;
|
||||
break;
|
||||
|
||||
case GHOST_kDragnDropTypeBitmap: {
|
||||
@ -1410,7 +1413,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
|
||||
[droppedImg release];
|
||||
}
|
||||
|
||||
eventData = (GHOST_TDragnDropDataPtr)ibuf;
|
||||
eventData = (GHOST_TEventDataPtr)ibuf;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1481,7 +1484,7 @@ bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr)
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
memcpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize);
|
||||
strncpy(temp_buff, [filepath cStringUsingEncoding:NSUTF8StringEncoding], filenameTextSize);
|
||||
temp_buff[filenameTextSize] = '\0';
|
||||
|
||||
pushEvent(new GHOST_EventString(
|
||||
@ -2036,7 +2039,8 @@ char *GHOST_SystemCocoa::getClipboard(bool /*selection*/) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
memcpy(temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
|
||||
strncpy(temp_buff, [textPasted cStringUsingEncoding:NSUTF8StringEncoding], pastedTextSize);
|
||||
|
||||
temp_buff[pastedTextSize] = '\0';
|
||||
|
||||
if (temp_buff) {
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "GHOST_System.hh"
|
||||
#include "GHOST_WindowNULL.hh"
|
||||
|
||||
#if defined(WITH_OPENGL_BACKEND) && defined(__linux__)
|
||||
#ifdef __linux__
|
||||
# include "GHOST_ContextEGL.hh"
|
||||
#endif
|
||||
#include "GHOST_ContextNone.hh"
|
||||
@ -51,7 +51,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
||||
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||
GHOST_kCapabilityPrimaryClipboard |
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityInputIME));
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
char *getClipboard(bool /*selection*/) const override
|
||||
{
|
||||
@ -84,7 +84,7 @@ class GHOST_SystemHeadless : public GHOST_System {
|
||||
}
|
||||
GHOST_IContext *createOffscreenContext(GHOST_GPUSettings /*gpuSettings*/) override
|
||||
{
|
||||
#if defined(WITH_OPENGL_BACKEND) && defined(__linux__)
|
||||
#ifdef __linux__
|
||||
GHOST_Context *context;
|
||||
for (int minor = 6; minor >= 3; --minor) {
|
||||
context = new GHOST_ContextEGL((GHOST_System *)this,
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef _WIN32_IE
|
||||
# define _WIN32_IE 0x0501
|
||||
#endif
|
||||
#include "utfconv.hh"
|
||||
#include "utfconv.h"
|
||||
#include <shlobj.h>
|
||||
|
||||
GHOST_SystemPathsWin32::GHOST_SystemPathsWin32() {}
|
||||
|
@ -781,9 +781,7 @@ GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const
|
||||
/* This SDL back-end has not yet implemented color sampling the desktop. */
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
/* This SDL back-end has not yet implemented image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages |
|
||||
/* No support yet for IME input methods. */
|
||||
GHOST_kCapabilityInputIME));
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const
|
||||
|
@ -37,12 +37,10 @@
|
||||
# include <wayland_dynload_API.h> /* For `ghost_wl_dynload_libraries`. */
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
|
||||
# include <wayland_dynload_egl.h>
|
||||
# endif
|
||||
# include <wayland-egl.h>
|
||||
#endif /* WITH_OPENGL_BACKEND */
|
||||
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
|
||||
# include <wayland_dynload_egl.h>
|
||||
#endif
|
||||
#include <wayland-egl.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
@ -56,6 +54,8 @@
|
||||
#endif
|
||||
#include <wayland-cursor.h>
|
||||
|
||||
#include "GHOST_WaylandCursorSettings.hh"
|
||||
|
||||
#include <xkbcommon/xkbcommon-compose.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
@ -69,9 +69,6 @@
|
||||
#include <viewporter-client-protocol.h>
|
||||
#include <xdg-activation-v1-client-protocol.h>
|
||||
#include <xdg-output-unstable-v1-client-protocol.h>
|
||||
#ifdef WITH_INPUT_IME
|
||||
# include <text-input-unstable-v3-client-protocol.h>
|
||||
#endif
|
||||
|
||||
/* Decorations `xdg_decor`. */
|
||||
#include <xdg-decoration-unstable-v1-client-protocol.h>
|
||||
@ -396,7 +393,7 @@ struct GWL_Cursor {
|
||||
/** The size of `custom_data` in bytes. */
|
||||
size_t custom_data_size = 0;
|
||||
/**
|
||||
* The name of the theme (set by an environment variable).
|
||||
* The name of the theme (loaded by DBUS, depends on #WITH_GHOST_WAYLAND_DBUS).
|
||||
* When disabled, leave as an empty string and the default theme will be used.
|
||||
*/
|
||||
std::string theme_name;
|
||||
@ -724,51 +721,6 @@ static void gwl_primary_selection_discard_source(GWL_PrimarySelection *primary)
|
||||
primary->data_source = nullptr;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
struct GWL_SeatIME {
|
||||
struct wl_surface *surface_window = nullptr;
|
||||
GHOST_TEventImeData event_ime_data = {
|
||||
/*result_len*/ nullptr,
|
||||
/*composite_len*/ nullptr,
|
||||
/*result*/ nullptr,
|
||||
/*composite*/ nullptr,
|
||||
/*cursor_position*/ -1,
|
||||
/*target_start*/ -1,
|
||||
/*target_end*/ -1,
|
||||
};
|
||||
/** When true, the client has indicated that IME input should be activated on text entry. */
|
||||
bool is_enabled = false;
|
||||
/**
|
||||
* When true, some pre-edit text has been entered
|
||||
* (an IME popup may be showing however this isn't known).
|
||||
*/
|
||||
bool has_preedit = false;
|
||||
|
||||
/** Storage for #GHOST_TEventImeData::result (the result of the `commit_string` callback). */
|
||||
std::string result;
|
||||
/** Storage for #GHOST_TEventImeData::composite (the result of the `preedit_string` callback). */
|
||||
std::string composite;
|
||||
|
||||
/** #zwp_text_input_v3_listener::commit_string was called with a null text argument. */
|
||||
bool result_is_null = false;
|
||||
/** #zwp_text_input_v3_listener::preedit_string was called with a null text argument. */
|
||||
bool composite_is_null = false;
|
||||
|
||||
/** #zwp_text_input_v3_listener::preedit_string was called. */
|
||||
bool has_preedit_string_callback = false;
|
||||
/** #zwp_text_input_v3_listener::commit_string was called. */
|
||||
bool has_commit_string_callback = false;
|
||||
|
||||
/** Bounds (use for comparison). */
|
||||
struct {
|
||||
int x = -1;
|
||||
int y = -1;
|
||||
int w = -1;
|
||||
int h = -1;
|
||||
} rect;
|
||||
};
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
struct GWL_Seat {
|
||||
|
||||
/** Wayland core types. */
|
||||
@ -804,10 +756,6 @@ struct GWL_Seat {
|
||||
|
||||
/** All currently active tablet tools (needed for changing the cursor). */
|
||||
std::unordered_set<zwp_tablet_tool_v2 *> tablet_tools;
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
struct zwp_text_input_v3 *text_input = nullptr;
|
||||
#endif
|
||||
} wp;
|
||||
|
||||
/** XKB native types. */
|
||||
@ -839,10 +787,6 @@ struct GWL_Seat {
|
||||
|
||||
} xkb;
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
GWL_SeatIME ime;
|
||||
#endif
|
||||
|
||||
GHOST_SystemWayland *system = nullptr;
|
||||
|
||||
std::string name;
|
||||
@ -977,60 +921,6 @@ static void gwl_seat_key_repeat_timer_remove(GWL_Seat *seat)
|
||||
seat->key_repeat.timer = nullptr;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
||||
static void gwl_seat_ime_full_reset(GWL_Seat *seat)
|
||||
{
|
||||
const GWL_SeatIME ime_default{};
|
||||
/* Preserve the following members since they represent the state of the connection to Wayland.
|
||||
* or which callbacks have run (which shouldn't be reset). */
|
||||
wl_surface *surface_window = seat->ime.surface_window;
|
||||
const bool is_enabled = seat->ime.is_enabled;
|
||||
const bool has_preedit_string_callback = seat->ime.has_preedit_string_callback;
|
||||
const bool has_commit_string_callback = seat->ime.has_commit_string_callback;
|
||||
|
||||
seat->ime = ime_default;
|
||||
|
||||
seat->ime.surface_window = surface_window;
|
||||
seat->ime.is_enabled = is_enabled;
|
||||
seat->ime.has_preedit_string_callback = has_preedit_string_callback;
|
||||
seat->ime.has_commit_string_callback = has_commit_string_callback;
|
||||
}
|
||||
|
||||
static void gwl_seat_ime_result_reset(GWL_Seat *seat)
|
||||
{
|
||||
seat->ime.result.clear();
|
||||
seat->ime.result_is_null = false;
|
||||
|
||||
GHOST_TEventImeData &event_ime_data = seat->ime.event_ime_data;
|
||||
event_ime_data.result_len = nullptr;
|
||||
event_ime_data.result = nullptr;
|
||||
}
|
||||
|
||||
static void gwl_seat_ime_preedit_reset(GWL_Seat *seat)
|
||||
{
|
||||
seat->ime.composite.clear();
|
||||
seat->ime.composite_is_null = false;
|
||||
|
||||
GHOST_TEventImeData &event_ime_data = seat->ime.event_ime_data;
|
||||
event_ime_data.composite_len = nullptr;
|
||||
event_ime_data.composite = nullptr;
|
||||
|
||||
event_ime_data.cursor_position = -1;
|
||||
event_ime_data.target_start = -1;
|
||||
event_ime_data.target_end = -1;
|
||||
}
|
||||
|
||||
static void gwl_seat_ime_rect_reset(GWL_Seat *seat)
|
||||
{
|
||||
seat->ime.rect.x = -1;
|
||||
seat->ime.rect.y = -1;
|
||||
seat->ime.rect.w = -1;
|
||||
seat->ime.rect.h = -1;
|
||||
}
|
||||
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
@ -1062,9 +952,6 @@ struct GWL_Display {
|
||||
wp_viewporter *viewporter = nullptr;
|
||||
zwp_pointer_constraints_v1 *pointer_constraints = nullptr;
|
||||
zwp_pointer_gestures_v1 *pointer_gestures = nullptr;
|
||||
#ifdef WITH_INPUT_IME
|
||||
struct zwp_text_input_manager_v3 *text_input_manager = nullptr;
|
||||
#endif
|
||||
} wp;
|
||||
|
||||
/** Wayland XDG types. */
|
||||
@ -1125,7 +1012,7 @@ struct GWL_Display {
|
||||
* Events added from the event reading thread.
|
||||
* Added into the main event queue when on #GHOST_SystemWayland::processEvents.
|
||||
*/
|
||||
std::vector<const GHOST_IEvent *> events_pending;
|
||||
std::vector<GHOST_IEvent *> events_pending;
|
||||
/** Guard against multiple threads accessing `events_pending` at once. */
|
||||
std::mutex events_pending_mutex;
|
||||
|
||||
@ -1201,7 +1088,7 @@ static void gwl_display_destroy(GWL_Display *display)
|
||||
display->ghost_timer_manager = nullptr;
|
||||
}
|
||||
/* Pending events may be left unhandled. */
|
||||
for (const GHOST_IEvent *event : display->events_pending) {
|
||||
for (GHOST_IEvent *event : display->events_pending) {
|
||||
delete event;
|
||||
}
|
||||
|
||||
@ -4540,228 +4427,6 @@ static const zwp_primary_selection_source_v1_listener primary_selection_source_l
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Listener (Text Input), #zwp_text_input_manager_v3
|
||||
* \{ */
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
||||
class GHOST_EventIME : public GHOST_Event {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
* \param msec: The time this event was generated.
|
||||
* \param type: The type of key event.
|
||||
* \param key: The key code of the key.
|
||||
*/
|
||||
GHOST_EventIME(uint64_t msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata)
|
||||
: GHOST_Event(msec, type, window)
|
||||
{
|
||||
this->m_data = customdata;
|
||||
}
|
||||
};
|
||||
|
||||
static CLG_LogRef LOG_WL_TEXT_INPUT = {"ghost.wl.handle.text_input"};
|
||||
# define LOG (&LOG_WL_TEXT_INPUT)
|
||||
|
||||
static void text_input_handle_enter(void *data,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
if (!ghost_wl_surface_own(surface)) {
|
||||
return;
|
||||
}
|
||||
CLOG_INFO(LOG, 2, "enter");
|
||||
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
|
||||
seat->ime.surface_window = surface;
|
||||
}
|
||||
|
||||
static void text_input_handle_leave(void *data,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
struct wl_surface *surface)
|
||||
{
|
||||
/* Can be null when closing a window. */
|
||||
if (!ghost_wl_surface_own_with_null_check(surface)) {
|
||||
return;
|
||||
}
|
||||
CLOG_INFO(LOG, 2, "leave");
|
||||
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
|
||||
if (seat->ime.surface_window == surface) {
|
||||
seat->ime.surface_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void text_input_handle_preedit_string(void *data,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
const char *text,
|
||||
int32_t cursor_begin,
|
||||
int32_t cursor_end)
|
||||
{
|
||||
CLOG_INFO(LOG,
|
||||
2,
|
||||
"preedit_string (text=\"%s\", cursor_begin=%d, cursor_end=%d)",
|
||||
text ? text : "<null>",
|
||||
cursor_begin,
|
||||
cursor_end);
|
||||
|
||||
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
|
||||
if (UNLIKELY(seat->ime.surface_window == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (seat->ime.has_preedit == false) {
|
||||
/* Starting IME input. */
|
||||
gwl_seat_ime_full_reset(seat);
|
||||
}
|
||||
|
||||
seat->ime.composite_is_null = (text == nullptr);
|
||||
if (!seat->ime.composite_is_null) {
|
||||
seat->ime.composite = text;
|
||||
seat->ime.event_ime_data.composite = (void *)seat->ime.composite.c_str();
|
||||
seat->ime.event_ime_data.composite_len = (void *)seat->ime.composite.size();
|
||||
|
||||
seat->ime.event_ime_data.cursor_position = cursor_begin;
|
||||
seat->ime.event_ime_data.target_start = cursor_begin;
|
||||
seat->ime.event_ime_data.target_end = cursor_end;
|
||||
}
|
||||
|
||||
seat->ime.has_preedit_string_callback = true;
|
||||
}
|
||||
|
||||
static void text_input_handle_commit_string(void *data,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
const char *text)
|
||||
{
|
||||
CLOG_INFO(LOG, 2, "commit_string (text=\"%s\")", text ? text : "<null>");
|
||||
|
||||
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
|
||||
if (UNLIKELY(seat->ime.surface_window == nullptr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
seat->ime.result_is_null = (text == nullptr);
|
||||
if (seat->ime.result_is_null) {
|
||||
seat->ime.result = "";
|
||||
}
|
||||
else {
|
||||
seat->ime.result = text;
|
||||
}
|
||||
|
||||
seat->ime.result_is_null = (text == nullptr);
|
||||
seat->ime.event_ime_data.result = (void *)seat->ime.result.c_str();
|
||||
seat->ime.event_ime_data.result_len = (void *)seat->ime.result.size();
|
||||
seat->ime.event_ime_data.cursor_position = seat->ime.result.size();
|
||||
|
||||
seat->ime.has_commit_string_callback = true;
|
||||
}
|
||||
|
||||
static void text_input_handle_delete_surrounding_text(void * /*data*/,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
uint32_t before_length,
|
||||
uint32_t after_length)
|
||||
{
|
||||
CLOG_INFO(LOG,
|
||||
2,
|
||||
"delete_surrounding_text (before_length=%u, after_length=%u)",
|
||||
before_length,
|
||||
after_length);
|
||||
|
||||
/* NOTE: Currently unused, do we care about this event?
|
||||
* SDL ignores this event. */
|
||||
}
|
||||
|
||||
static void text_input_handle_done(void *data,
|
||||
zwp_text_input_v3 * /*zwp_text_input_v3*/,
|
||||
uint32_t /*serial*/)
|
||||
{
|
||||
CLOG_INFO(LOG, 2, "done");
|
||||
|
||||
GWL_Seat *seat = static_cast<GWL_Seat *>(data);
|
||||
GHOST_SystemWayland *system = seat->system;
|
||||
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(seat->ime.surface_window);
|
||||
if (seat->ime.has_commit_string_callback) {
|
||||
if (seat->ime.has_preedit) {
|
||||
const bool is_end = seat->ime.composite_is_null;
|
||||
if (is_end) {
|
||||
seat->ime.has_preedit = false;
|
||||
/* `commit_string` (end). */
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(system->getMilliSeconds(),
|
||||
GHOST_kEventImeComposition,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(system->getMilliSeconds(),
|
||||
GHOST_kEventImeCompositionEnd,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
}
|
||||
else {
|
||||
/* `commit_string` (continues). */
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(system->getMilliSeconds(),
|
||||
GHOST_kEventImeComposition,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* `commit_string` ran with no active IME popup, start & end to insert text. */
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(system->getMilliSeconds(),
|
||||
GHOST_kEventImeCompositionStart,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(
|
||||
system->getMilliSeconds(), GHOST_kEventImeComposition, win, &seat->ime.event_ime_data));
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(system->getMilliSeconds(),
|
||||
GHOST_kEventImeCompositionEnd,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
}
|
||||
|
||||
if (seat->ime.has_preedit == false) {
|
||||
gwl_seat_ime_preedit_reset(seat);
|
||||
}
|
||||
}
|
||||
else if (seat->ime.has_preedit_string_callback) {
|
||||
const bool is_end = seat->ime.composite_is_null;
|
||||
if (is_end) {
|
||||
/* `preedit_string` (end). */
|
||||
seat->ime.has_preedit = false;
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(seat->system->getMilliSeconds(),
|
||||
GHOST_kEventImeCompositionEnd,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
}
|
||||
else {
|
||||
const bool is_start = seat->ime.has_preedit == false;
|
||||
/* `preedit_string` (start or continue). */
|
||||
seat->ime.has_preedit = true;
|
||||
system->pushEvent_maybe_pending(new GHOST_EventIME(
|
||||
seat->system->getMilliSeconds(),
|
||||
is_start ? GHOST_kEventImeCompositionStart : GHOST_kEventImeComposition,
|
||||
win,
|
||||
&seat->ime.event_ime_data));
|
||||
}
|
||||
}
|
||||
|
||||
seat->ime.has_preedit_string_callback = false;
|
||||
seat->ime.has_commit_string_callback = false;
|
||||
}
|
||||
|
||||
static struct zwp_text_input_v3_listener text_input_listener = {
|
||||
/*enter*/ text_input_handle_enter,
|
||||
/*leave*/ text_input_handle_leave,
|
||||
/*preedit_string*/ text_input_handle_preedit_string,
|
||||
/*commit_string*/ text_input_handle_commit_string,
|
||||
/*delete_surrounding_text*/ text_input_handle_delete_surrounding_text,
|
||||
/*done*/ text_input_handle_done,
|
||||
};
|
||||
|
||||
# undef LOG
|
||||
|
||||
#endif /* WITH_INPUT_IME. */
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Listener (Seat), #wl_seat_listener
|
||||
* \{ */
|
||||
@ -4778,7 +4443,7 @@ static void gwl_seat_capability_pointer_enable(GWL_Seat *seat)
|
||||
seat->cursor.wl.surface_cursor = wl_compositor_create_surface(seat->system->wl_compositor_get());
|
||||
seat->cursor.visible = true;
|
||||
seat->cursor.wl.buffer = nullptr;
|
||||
{
|
||||
if (!get_cursor_settings(seat->cursor.theme_name, seat->cursor.theme_size)) {
|
||||
/* Use environment variables, falling back to defaults.
|
||||
* These environment variables are used by enough WAYLAND applications
|
||||
* that it makes sense to check them (see `Xcursor` man page). */
|
||||
@ -5459,20 +5124,6 @@ static void gwl_registry_wl_seat_update(GWL_Display *display,
|
||||
else {
|
||||
seat->wp.primary_selection_device = nullptr;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
if (display->wp.text_input_manager) {
|
||||
if (seat->wp.text_input == nullptr) {
|
||||
seat->wp.text_input = zwp_text_input_manager_v3_get_text_input(
|
||||
display->wp.text_input_manager, seat->wl.seat);
|
||||
zwp_text_input_v3_set_user_data(seat->wp.text_input, seat);
|
||||
zwp_text_input_v3_add_listener(seat->wp.text_input, &text_input_listener, seat);
|
||||
}
|
||||
}
|
||||
else {
|
||||
seat->wp.text_input = nullptr;
|
||||
}
|
||||
#endif /* WITH_INPUT_IME */
|
||||
}
|
||||
static void gwl_registry_wl_seat_remove(GWL_Display *display, void *user_data, const bool on_exit)
|
||||
{
|
||||
@ -5758,28 +5409,6 @@ static void gwl_registry_wp_primary_selection_device_manager_remove(GWL_Display
|
||||
*value_p = nullptr;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
||||
/* #GWL_Display.wp_text_input_manager */
|
||||
|
||||
static void gwl_registry_wp_text_input_manager_add(GWL_Display *display,
|
||||
const GWL_RegisteryAdd_Params *params)
|
||||
{
|
||||
display->wp.text_input_manager = static_cast<zwp_text_input_manager_v3 *>(wl_registry_bind(
|
||||
display->wl.registry, params->name, &zwp_text_input_manager_v3_interface, 1));
|
||||
gwl_registry_entry_add(display, params, nullptr);
|
||||
}
|
||||
static void gwl_registry_wp_text_input_manager_remove(GWL_Display *display,
|
||||
void * /*user_data*/,
|
||||
const bool /*on_exit*/)
|
||||
{
|
||||
struct zwp_text_input_manager_v3 **value_p = &display->wp.text_input_manager;
|
||||
zwp_text_input_manager_v3_destroy(*value_p);
|
||||
*value_p = nullptr;
|
||||
}
|
||||
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
/**
|
||||
* Map interfaces to initialization functions.
|
||||
*
|
||||
@ -5847,14 +5476,6 @@ static const GWL_RegistryHandler gwl_registry_handlers[] = {
|
||||
/*update_fn*/ nullptr,
|
||||
/*remove_fn*/ gwl_registry_wp_relative_pointer_manager_remove,
|
||||
},
|
||||
#ifdef WITH_INPUT_IME
|
||||
{
|
||||
/*interface_p*/ &zwp_text_input_manager_v3_interface.name,
|
||||
/*add_fn*/ gwl_registry_wp_text_input_manager_add,
|
||||
/*update_fn*/ nullptr,
|
||||
/*remove_fn*/ gwl_registry_wp_text_input_manager_remove,
|
||||
},
|
||||
#endif
|
||||
/* Higher level interfaces. */
|
||||
{
|
||||
/*interface_p*/ &zwp_pointer_constraints_v1_interface.name,
|
||||
@ -6242,7 +5863,7 @@ bool GHOST_SystemWayland::processEvents(bool waitForEvent)
|
||||
|
||||
{
|
||||
std::lock_guard lock{display_->events_pending_mutex};
|
||||
for (const GHOST_IEvent *event : display_->events_pending) {
|
||||
for (GHOST_IEvent *event : display_->events_pending) {
|
||||
|
||||
/* Perform actions that aren't handled in a thread. */
|
||||
switch (event->getType()) {
|
||||
@ -6853,7 +6474,9 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
|
||||
std::lock_guard lock_server_guard{*server_mutex};
|
||||
#endif
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
const bool debug_context = (gpuSettings.flags & GHOST_gpuDebugContext) != 0;
|
||||
#endif
|
||||
|
||||
switch (gpuSettings.context_type) {
|
||||
|
||||
@ -6868,7 +6491,6 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
|
||||
nullptr,
|
||||
wl_surface,
|
||||
display_->wl.display,
|
||||
nullptr,
|
||||
1,
|
||||
2,
|
||||
debug_context);
|
||||
@ -6894,18 +6516,16 @@ GHOST_IContext *GHOST_SystemWayland::createOffscreenContext(GHOST_GPUSettings gp
|
||||
|
||||
for (int minor = 6; minor >= 3; --minor) {
|
||||
/* Caller must lock `system->server_mutex`. */
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
this,
|
||||
false,
|
||||
EGLNativeWindowType(egl_window),
|
||||
EGLNativeDisplayType(display_->wl.display),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
|
||||
(debug_context ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
GHOST_Context *context = new GHOST_ContextEGL(this,
|
||||
false,
|
||||
EGLNativeWindowType(egl_window),
|
||||
EGLNativeDisplayType(display_->wl.display),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
|
||||
if (context->initializeDrawingContext()) {
|
||||
wl_surface_set_user_data(wl_surface, egl_window);
|
||||
@ -6937,39 +6557,18 @@ GHOST_TSuccess GHOST_SystemWayland::disposeContext(GHOST_IContext *context)
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
std::lock_guard lock_server_guard{*server_mutex};
|
||||
#endif
|
||||
|
||||
GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone;
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
if (dynamic_cast<GHOST_ContextEGL *>(context)) {
|
||||
type = GHOST_kDrawingContextTypeOpenGL;
|
||||
}
|
||||
#endif /* WITH_OPENGL_BACKEND */
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (dynamic_cast<GHOST_ContextVK *>(context)) {
|
||||
type = GHOST_kDrawingContextTypeVulkan;
|
||||
}
|
||||
#endif /* WITH_VULKAN_BACKEND */
|
||||
|
||||
wl_surface *wl_surface = static_cast<struct wl_surface *>(
|
||||
(static_cast<GHOST_Context *>(context))->getUserData());
|
||||
|
||||
/* Delete the context before the window so the context is able to release
|
||||
* native resources (such as the #EGLSurface) before WAYLAND frees them. */
|
||||
delete context;
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
wl_egl_window *egl_window = static_cast<wl_egl_window *>(wl_surface_get_user_data(wl_surface));
|
||||
if (egl_window != nullptr) {
|
||||
wl_egl_window_destroy(egl_window);
|
||||
}
|
||||
wl_egl_window *egl_window = static_cast<wl_egl_window *>(wl_surface_get_user_data(wl_surface));
|
||||
if (egl_window != nullptr) {
|
||||
wl_egl_window_destroy(egl_window);
|
||||
}
|
||||
#endif /* WITH_OPENGL_BACKEND */
|
||||
|
||||
wl_surface_destroy(wl_surface);
|
||||
|
||||
(void)type; /* Maybe unused. */
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@ -6997,8 +6596,7 @@ GHOST_IWindow *GHOST_SystemWayland::createWindow(const char *title,
|
||||
gpuSettings.context_type,
|
||||
is_dialog,
|
||||
((gpuSettings.flags & GHOST_gpuStereoVisual) != 0),
|
||||
exclusive,
|
||||
(gpuSettings.flags & GHOST_gpuDebugContext) != 0);
|
||||
exclusive);
|
||||
|
||||
if (window) {
|
||||
if (window->getValid()) {
|
||||
@ -7621,104 +7219,6 @@ GHOST_TimerManager *GHOST_SystemWayland::ghost_timer_manager()
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public WAYLAND Text Input (IME) Functions
|
||||
*
|
||||
* Functionality only used for the WAYLAND implementation.
|
||||
* \{ */
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
||||
void GHOST_SystemWayland::ime_begin(
|
||||
GHOST_WindowWayland *win, int32_t x, int32_t y, int32_t w, int32_t h, bool completed) const
|
||||
{
|
||||
GWL_Seat *seat = gwl_display_seat_active_get(display_);
|
||||
if (UNLIKELY(!seat)) {
|
||||
return;
|
||||
}
|
||||
if (seat->wp.text_input == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Prevent a feedback loop because the commits from this function cause
|
||||
* #zwp_text_input_v3_listener::preedit_string to run again which sends an event,
|
||||
* refreshing the position, running this function again. */
|
||||
gwl_seat_ime_result_reset(seat);
|
||||
|
||||
/* Don't re-enable if we're already enabled. */
|
||||
if (seat->ime.is_enabled && completed) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool force_rect_update = false;
|
||||
if (seat->ime.is_enabled == false) {
|
||||
seat->ime.has_preedit = false;
|
||||
seat->ime.is_enabled = true;
|
||||
|
||||
/* NOTE(@flibit): For some reason this has to be done twice,
|
||||
* it appears to be a bug in mutter? Maybe? */
|
||||
zwp_text_input_v3_enable(seat->wp.text_input);
|
||||
zwp_text_input_v3_commit(seat->wp.text_input);
|
||||
zwp_text_input_v3_enable(seat->wp.text_input);
|
||||
zwp_text_input_v3_commit(seat->wp.text_input);
|
||||
|
||||
/* Now that it's enabled, set the input properties. */
|
||||
zwp_text_input_v3_set_content_type(seat->wp.text_input,
|
||||
ZWP_TEXT_INPUT_V3_CONTENT_HINT_NONE,
|
||||
ZWP_TEXT_INPUT_V3_CONTENT_PURPOSE_NORMAL);
|
||||
|
||||
gwl_seat_ime_rect_reset(seat);
|
||||
force_rect_update = true;
|
||||
}
|
||||
|
||||
if ((force_rect_update == false) && /* Was just created, always update. */
|
||||
(seat->ime.rect.x == x) && /* X. */
|
||||
(seat->ime.rect.y == y) && /* Y. */
|
||||
(seat->ime.rect.w == w) && /* W. */
|
||||
(seat->ime.rect.h == h)) /* H. */
|
||||
{
|
||||
/* Only re-update the rectangle as needed. */
|
||||
}
|
||||
else {
|
||||
const int rect_x = wl_fixed_to_int(win->wl_fixed_from_window(wl_fixed_from_int(x)));
|
||||
const int rect_y = wl_fixed_to_int(win->wl_fixed_from_window(wl_fixed_from_int(y)));
|
||||
const int rect_w = wl_fixed_to_int(win->wl_fixed_from_window(wl_fixed_from_int(w))) + 1;
|
||||
const int rect_h = wl_fixed_to_int(win->wl_fixed_from_window(wl_fixed_from_int(h))) + 1;
|
||||
|
||||
zwp_text_input_v3_set_cursor_rectangle(seat->wp.text_input, rect_x, rect_y, rect_w, rect_h);
|
||||
|
||||
zwp_text_input_v3_commit(seat->wp.text_input);
|
||||
|
||||
seat->ime.rect.x = x;
|
||||
seat->ime.rect.y = y;
|
||||
seat->ime.rect.w = w;
|
||||
seat->ime.rect.h = h;
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_SystemWayland::ime_end(GHOST_WindowWayland * /*window*/) const
|
||||
{
|
||||
GWL_Seat *seat = gwl_display_seat_active_get(display_);
|
||||
if (UNLIKELY(!seat)) {
|
||||
return;
|
||||
}
|
||||
|
||||
seat->ime.is_enabled = false;
|
||||
|
||||
gwl_seat_ime_rect_reset(seat);
|
||||
|
||||
if (seat->wp.text_input == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
zwp_text_input_v3_disable(seat->wp.text_input);
|
||||
zwp_text_input_v3_commit(seat->wp.text_input);
|
||||
}
|
||||
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Public WAYLAND Query Access
|
||||
* \{ */
|
||||
@ -7791,9 +7291,6 @@ bool GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface)
|
||||
SURFACE_CLEAR_PTR(seat->tablet.wl.surface_window);
|
||||
SURFACE_CLEAR_PTR(seat->keyboard.wl.surface_window);
|
||||
SURFACE_CLEAR_PTR(seat->wl.surface_window_focus_dnd);
|
||||
#ifdef WITH_INPUT_IME
|
||||
SURFACE_CLEAR_PTR(seat->ime.surface_window);
|
||||
#endif
|
||||
}
|
||||
#undef SURFACE_CLEAR_PTR
|
||||
|
||||
@ -7881,16 +7378,16 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
||||
|
||||
/* Ignore, if the required protocols are not supported. */
|
||||
if (UNLIKELY(!display_->wp.relative_pointer_manager || !display_->wp.pointer_constraints)) {
|
||||
return false;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GWL_Seat *seat = gwl_display_seat_active_get(display_);
|
||||
if (UNLIKELY(!seat)) {
|
||||
return false;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
/* No change, success. */
|
||||
if (mode == mode_current) {
|
||||
return true;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#ifdef USE_GNOME_CONFINE_HACK
|
||||
@ -8057,7 +7554,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
||||
seat->use_pointer_software_confine = use_software_confine;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
@ -8081,11 +7578,7 @@ bool ghost_wl_dynload_libraries_init()
|
||||
|
||||
if (wayland_dynload_client_init(verbose) && /* `libwayland-client`. */
|
||||
wayland_dynload_cursor_init(verbose) && /* `libwayland-cursor`. */
|
||||
# ifdef WITH_OPENGL_BACKEND
|
||||
wayland_dynload_egl_init(verbose) /* `libwayland-egl`. */
|
||||
# else
|
||||
true
|
||||
# endif
|
||||
wayland_dynload_egl_init(verbose) /* `libwayland-egl`. */
|
||||
)
|
||||
{
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
@ -8096,9 +7589,7 @@ bool ghost_wl_dynload_libraries_init()
|
||||
|
||||
wayland_dynload_client_exit();
|
||||
wayland_dynload_cursor_exit();
|
||||
# ifdef WITH_OPENGL_BACKEND
|
||||
wayland_dynload_egl_exit();
|
||||
# endif
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -8107,9 +7598,7 @@ void ghost_wl_dynload_libraries_exit()
|
||||
{
|
||||
wayland_dynload_client_exit();
|
||||
wayland_dynload_cursor_exit();
|
||||
# ifdef WITH_OPENGL_BACKEND
|
||||
wayland_dynload_egl_exit();
|
||||
# endif
|
||||
# ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
wayland_dynload_libdecor_exit();
|
||||
# endif
|
||||
|
@ -236,10 +236,6 @@ class GHOST_SystemWayland : public GHOST_System {
|
||||
|
||||
struct wl_shm *wl_shm_get() const;
|
||||
|
||||
void ime_begin(
|
||||
GHOST_WindowWayland *win, int32_t x, int32_t y, int32_t w, int32_t h, bool completed) const;
|
||||
void ime_end(GHOST_WindowWayland *win) const;
|
||||
|
||||
static const char *xdg_app_id_get();
|
||||
|
||||
/* WAYLAND utility functions. */
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include <tlhelp32.h>
|
||||
#include <windowsx.h>
|
||||
|
||||
#include "utf_winfunc.hh"
|
||||
#include "utfconv.hh"
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
@ -358,16 +358,8 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GPUSettings gpuSet
|
||||
switch (gpuSettings.context_type) {
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
case GHOST_kDrawingContextTypeVulkan: {
|
||||
GHOST_Context *context = new GHOST_ContextVK(false,
|
||||
GHOST_kVulkanPlatformX11,
|
||||
0,
|
||||
m_display,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
1,
|
||||
2,
|
||||
debug_context);
|
||||
GHOST_Context *context = new GHOST_ContextVK(
|
||||
false, GHOST_kVulkanPlatformX11, 0, m_display, nullptr, nullptr, 1, 2, debug_context);
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
@ -1742,9 +1734,7 @@ GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
||||
/* No support yet for desktop sampling. */
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
/* No support yet for image copy/paste. */
|
||||
GHOST_kCapabilityClipboardImages |
|
||||
/* No support yet for IME input methods. */
|
||||
GHOST_kCapabilityInputIME));
|
||||
GHOST_kCapabilityClipboardImages));
|
||||
}
|
||||
|
||||
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
||||
|
131
intern/ghost/intern/GHOST_WaylandCursorSettings.hh
Normal file
131
intern/ghost/intern/GHOST_WaylandCursorSettings.hh
Normal file
@ -0,0 +1,131 @@
|
||||
/* SPDX-FileCopyrightText: 2021-2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_DBUS
|
||||
# include <dbus/dbus.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_DBUS
|
||||
static DBusMessage *get_setting_sync(DBusConnection *const connection,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
DBusError error;
|
||||
dbus_bool_t success;
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
message = dbus_message_new_method_call("org.freedesktop.portal.Desktop",
|
||||
"/org/freedesktop/portal/desktop",
|
||||
"org.freedesktop.portal.Settings",
|
||||
"Read");
|
||||
|
||||
success = dbus_message_append_args(
|
||||
message, DBUS_TYPE_STRING, &key, DBUS_TYPE_STRING, &value, DBUS_TYPE_INVALID);
|
||||
|
||||
if (!success) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
reply = dbus_connection_send_with_reply_and_block(
|
||||
connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error);
|
||||
|
||||
dbus_message_unref(message);
|
||||
|
||||
if (dbus_error_is_set(&error)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
static bool parse_type(DBusMessage *const reply, const int type, void *value)
|
||||
{
|
||||
DBusMessageIter iter[3];
|
||||
|
||||
dbus_message_iter_init(reply, &iter[0]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[0]) != DBUS_TYPE_VARIANT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_recurse(&iter[0], &iter[1]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[1]) != DBUS_TYPE_VARIANT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_recurse(&iter[1], &iter[2]);
|
||||
if (dbus_message_iter_get_arg_type(&iter[2]) != type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_iter_get_basic(&iter[2], value);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif /* WITH_GHOST_WAYLAND_DBUS */
|
||||
|
||||
static bool get_cursor_settings(std::string &theme, int &size)
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_DBUS
|
||||
static const char name[] = "org.gnome.desktop.interface";
|
||||
static const char key_theme[] = "cursor-theme";
|
||||
static const char key_size[] = "cursor-size";
|
||||
|
||||
DBusError error;
|
||||
DBusConnection *connection;
|
||||
DBusMessage *reply;
|
||||
const char *value_theme = nullptr;
|
||||
|
||||
dbus_error_init(&error);
|
||||
|
||||
connection = dbus_bus_get(DBUS_BUS_SESSION, &error);
|
||||
|
||||
if (dbus_error_is_set(&error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
reply = get_setting_sync(connection, name, key_theme);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_STRING, &value_theme)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
theme = std::string(value_theme);
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
reply = get_setting_sync(connection, name, key_size);
|
||||
if (!reply) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parse_type(reply, DBUS_TYPE_INT32, &size)) {
|
||||
dbus_message_unref(reply);
|
||||
return false;
|
||||
}
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
return true;
|
||||
#else
|
||||
/* NOTE: eventually we could have alternative ways to access the theme,
|
||||
* this uses the "default" theme which is functional (instead of a user-defined theme). */
|
||||
(void)theme;
|
||||
(void)size;
|
||||
return false;
|
||||
#endif /* !WITH_GHOST_WAYLAND_DBUS */
|
||||
}
|
@ -24,12 +24,10 @@
|
||||
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
# ifdef WITH_GHOST_WAYLAND_DYNLOAD
|
||||
# include <wayland_dynload_egl.h>
|
||||
# endif
|
||||
# include <wayland-egl.h>
|
||||
#ifdef WITH_GHOST_WAYLAND_DYNLOAD
|
||||
# include <wayland_dynload_egl.h>
|
||||
#endif
|
||||
#include <wayland-egl.h>
|
||||
|
||||
#include <algorithm> /* For `std::find`. */
|
||||
|
||||
@ -258,6 +256,8 @@ struct GWL_Window {
|
||||
/** Wayland core types. */
|
||||
struct {
|
||||
wl_surface *surface = nullptr;
|
||||
|
||||
wl_egl_window *egl_window = nullptr;
|
||||
} wl;
|
||||
|
||||
/** Wayland native types. */
|
||||
@ -277,19 +277,8 @@ struct GWL_Window {
|
||||
xdg_activation_token_v1 *activation_token = nullptr;
|
||||
} xdg;
|
||||
|
||||
struct {
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
wl_egl_window *egl_window = nullptr;
|
||||
#endif
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
GHOST_ContextVK_WindowInfo *vulkan_window_info = nullptr;
|
||||
#endif
|
||||
} backend;
|
||||
|
||||
GHOST_WindowWayland *ghost_window = nullptr;
|
||||
GHOST_SystemWayland *ghost_system = nullptr;
|
||||
GHOST_TDrawingContextType ghost_context_type = GHOST_kDrawingContextTypeNone;
|
||||
|
||||
/**
|
||||
* Outputs on which the window is currently shown on.
|
||||
*
|
||||
@ -334,21 +323,6 @@ struct GWL_Window {
|
||||
#endif /* USE_EVENT_BACKGROUND_THREAD */
|
||||
};
|
||||
|
||||
static void gwl_window_resize_for_backend(GWL_Window *win, const int32_t size[2])
|
||||
{
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
if (win->ghost_context_type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
wl_egl_window_resize(win->backend.egl_window, UNPACK2(size), 0, 0);
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (win->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
win->backend.vulkan_window_info->size[0] = size[0];
|
||||
win->backend.vulkan_window_info->size[1] = size[1];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gwl_window_title_set(GWL_Window *win, const char *title)
|
||||
{
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
@ -709,7 +683,7 @@ static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
|
||||
|
||||
static void gwl_window_frame_pending_size_set(GWL_Window *win,
|
||||
bool *r_surface_needs_commit,
|
||||
bool *r_surface_needs_resize_for_backend,
|
||||
bool *r_surface_needs_egl_resize,
|
||||
bool *r_surface_needs_buffer_scale)
|
||||
{
|
||||
if (win->frame_pending.size[0] == 0 || win->frame_pending.size[1] == 0) {
|
||||
@ -729,11 +703,11 @@ static void gwl_window_frame_pending_size_set(GWL_Window *win,
|
||||
gwl_window_viewport_size_update(win);
|
||||
}
|
||||
|
||||
if (r_surface_needs_resize_for_backend) {
|
||||
*r_surface_needs_resize_for_backend = true;
|
||||
if (r_surface_needs_egl_resize) {
|
||||
*r_surface_needs_egl_resize = true;
|
||||
}
|
||||
else {
|
||||
gwl_window_resize_for_backend(win, win->frame.size);
|
||||
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
|
||||
}
|
||||
|
||||
win->ghost_window->notify_size();
|
||||
@ -802,17 +776,15 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
|
||||
|
||||
const bool dpi_changed = win->frame_pending.fractional_scale != win->frame.fractional_scale;
|
||||
bool surface_needs_commit = false;
|
||||
bool surface_needs_resize_for_backend = false;
|
||||
bool surface_needs_egl_resize = false;
|
||||
bool surface_needs_buffer_scale = false;
|
||||
|
||||
if (win->frame_pending.size[0] != 0 && win->frame_pending.size[1] != 0) {
|
||||
if ((win->frame.size[0] != win->frame_pending.size[0]) ||
|
||||
(win->frame.size[1] != win->frame_pending.size[1]))
|
||||
{
|
||||
gwl_window_frame_pending_size_set(win,
|
||||
&surface_needs_commit,
|
||||
&surface_needs_resize_for_backend,
|
||||
&surface_needs_buffer_scale);
|
||||
gwl_window_frame_pending_size_set(
|
||||
win, &surface_needs_commit, &surface_needs_egl_resize, &surface_needs_buffer_scale);
|
||||
}
|
||||
}
|
||||
|
||||
@ -827,8 +799,8 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
|
||||
}
|
||||
}
|
||||
|
||||
if (surface_needs_resize_for_backend) {
|
||||
gwl_window_resize_for_backend(win, win->frame.size);
|
||||
if (surface_needs_egl_resize) {
|
||||
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
|
||||
}
|
||||
|
||||
if (surface_needs_buffer_scale) {
|
||||
@ -1462,12 +1434,10 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
||||
const GHOST_TDrawingContextType type,
|
||||
const bool is_dialog,
|
||||
const bool stereoVisual,
|
||||
const bool exclusive,
|
||||
const bool is_debug)
|
||||
const bool exclusive)
|
||||
: GHOST_Window(width, height, state, stereoVisual, exclusive),
|
||||
system_(system),
|
||||
window_(new GWL_Window),
|
||||
is_debug_context_(is_debug)
|
||||
window_(new GWL_Window)
|
||||
{
|
||||
#ifdef USE_EVENT_BACKGROUND_THREAD
|
||||
std::lock_guard lock_server_guard{*system->server_mutex};
|
||||
@ -1475,7 +1445,6 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
||||
|
||||
window_->ghost_window = this;
|
||||
window_->ghost_system = system;
|
||||
window_->ghost_context_type = type;
|
||||
|
||||
/* 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.
|
||||
@ -1516,19 +1485,8 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
||||
|
||||
wl_surface_add_listener(window_->wl.surface, &wl_surface_listener, window_);
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
if (type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
window_->backend.egl_window = wl_egl_window_create(
|
||||
window_->wl.surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (type == GHOST_kDrawingContextTypeVulkan) {
|
||||
window_->backend.vulkan_window_info = new GHOST_ContextVK_WindowInfo;
|
||||
window_->backend.vulkan_window_info->size[0] = window_->frame.size[0];
|
||||
window_->backend.vulkan_window_info->size[1] = window_->frame.size[1];
|
||||
}
|
||||
#endif
|
||||
window_->wl.egl_window = wl_egl_window_create(
|
||||
window_->wl.surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
|
||||
|
||||
wp_fractional_scale_manager_v1 *fractional_scale_manager =
|
||||
system->wp_fractional_scale_manager_get();
|
||||
@ -1661,9 +1619,9 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
||||
gwl_window_state_set(window_, state);
|
||||
}
|
||||
|
||||
/* Drawing context. */
|
||||
/* EGL context. */
|
||||
if (setDrawingContextType(type) == GHOST_kFailure) {
|
||||
GHOST_PRINT("Failed to create drawing context" << std::endl);
|
||||
GHOST_PRINT("Failed to create EGL context" << std::endl);
|
||||
}
|
||||
|
||||
/* Set swap interval to 0 to prevent blocking. */
|
||||
@ -1832,16 +1790,7 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
|
||||
|
||||
releaseNativeHandles();
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
if (window_->ghost_context_type == GHOST_kDrawingContextTypeOpenGL) {
|
||||
wl_egl_window_destroy(window_->backend.egl_window);
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
if (window_->ghost_context_type == GHOST_kDrawingContextTypeVulkan) {
|
||||
delete window_->backend.vulkan_window_info;
|
||||
}
|
||||
#endif
|
||||
wl_egl_window_destroy(window_->wl.egl_window);
|
||||
|
||||
if (window_->xdg.activation_token) {
|
||||
xdg_activation_token_v1_destroy(window_->xdg.activation_token);
|
||||
@ -2006,16 +1955,15 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
|
||||
|
||||
#ifdef WITH_VULKAN_BACKEND
|
||||
case GHOST_kDrawingContextTypeVulkan: {
|
||||
GHOST_ContextVK *context = new GHOST_ContextVK(m_wantStereoVisual,
|
||||
GHOST_kVulkanPlatformWayland,
|
||||
0,
|
||||
nullptr,
|
||||
window_->wl.surface,
|
||||
system_->wl_display_get(),
|
||||
window_->backend.vulkan_window_info,
|
||||
1,
|
||||
2,
|
||||
is_debug_context_);
|
||||
GHOST_Context *context = new GHOST_ContextVK(m_wantStereoVisual,
|
||||
GHOST_kVulkanPlatformWayland,
|
||||
0,
|
||||
nullptr,
|
||||
window_->wl.surface,
|
||||
system_->wl_display_get(),
|
||||
1,
|
||||
2,
|
||||
true);
|
||||
if (context->initializeDrawingContext()) {
|
||||
return context;
|
||||
}
|
||||
@ -2030,13 +1978,12 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
|
||||
GHOST_Context *context = new GHOST_ContextEGL(
|
||||
system_,
|
||||
m_wantStereoVisual,
|
||||
EGLNativeWindowType(window_->backend.egl_window),
|
||||
EGLNativeWindowType(window_->wl.egl_window),
|
||||
EGLNativeDisplayType(system_->wl_display_get()),
|
||||
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
4,
|
||||
minor,
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS |
|
||||
(is_debug_context_ ? EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR : 0),
|
||||
GHOST_OPENGL_EGL_CONTEXT_FLAGS,
|
||||
GHOST_OPENGL_EGL_RESET_NOTIFICATION_STRATEGY,
|
||||
EGL_OPENGL_API);
|
||||
|
||||
@ -2055,20 +2002,6 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
|
||||
void GHOST_WindowWayland::beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed)
|
||||
{
|
||||
system_->ime_begin(this, x, y, w, h, completed);
|
||||
}
|
||||
|
||||
void GHOST_WindowWayland::endIME()
|
||||
{
|
||||
system_->ime_end(this);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -74,8 +74,7 @@ class GHOST_WindowWayland : public GHOST_Window {
|
||||
GHOST_TDrawingContextType type,
|
||||
const bool is_dialog,
|
||||
const bool stereoVisual,
|
||||
const bool exclusive,
|
||||
const bool is_debug);
|
||||
const bool exclusive);
|
||||
|
||||
~GHOST_WindowWayland() override;
|
||||
|
||||
@ -140,11 +139,6 @@ class GHOST_WindowWayland : public GHOST_Window {
|
||||
void setOpaque() const;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) override;
|
||||
void endIME() override;
|
||||
#endif /* WITH_INPUT_IME */
|
||||
|
||||
/* WAYLAND direct-data access. */
|
||||
|
||||
int scale_get() const;
|
||||
@ -195,7 +189,6 @@ class GHOST_WindowWayland : public GHOST_Window {
|
||||
private:
|
||||
GHOST_SystemWayland *system_;
|
||||
struct GWL_Window *window_;
|
||||
bool is_debug_context_;
|
||||
|
||||
/**
|
||||
* \param type: The type of rendering context create.
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "GHOST_DropTargetWin32.hh"
|
||||
#include "GHOST_SystemWin32.hh"
|
||||
#include "GHOST_WindowManager.hh"
|
||||
#include "utf_winfunc.hh"
|
||||
#include "utfconv.hh"
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
# include "GHOST_ContextWGL.hh"
|
||||
|
@ -1185,7 +1185,6 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
|
||||
m_display,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
1,
|
||||
2,
|
||||
m_is_debug_context);
|
||||
|
@ -443,7 +443,7 @@ Application::~Application()
|
||||
}
|
||||
}
|
||||
|
||||
bool Application::processEvent(const GHOST_IEvent *event)
|
||||
bool Application::processEvent(GHOST_IEvent *event)
|
||||
{
|
||||
GHOST_IWindow *window = event->getWindow();
|
||||
bool handled = true;
|
||||
|
@ -11,9 +11,9 @@ set(INC_SYS
|
||||
)
|
||||
|
||||
set(SRC
|
||||
utfconv.cc
|
||||
utfconv.c
|
||||
|
||||
utfconv.hh
|
||||
utfconv.h
|
||||
)
|
||||
|
||||
set(LIB
|
||||
@ -24,8 +24,8 @@ set(LIB
|
||||
# ... because one day we might want to use it on other platforms.
|
||||
if(WIN32)
|
||||
list(APPEND SRC
|
||||
utf_winfunc.cc
|
||||
utf_winfunc.hh
|
||||
utf_winfunc.c
|
||||
utf_winfunc.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
# define _WIN32_IE 0x0501
|
||||
#endif
|
||||
|
||||
#include "utf_winfunc.hh"
|
||||
#include "utfconv.hh"
|
||||
#include "utf_winfunc.h"
|
||||
#include "utfconv.h"
|
||||
#include <io.h>
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
@ -6,7 +6,7 @@
|
||||
* \ingroup intern_utf_conv
|
||||
*/
|
||||
|
||||
#include "utfconv.hh"
|
||||
#include "utfconv.h"
|
||||
|
||||
size_t count_utf_8_from_16(const wchar_t *string16)
|
||||
{
|
@ -13,6 +13,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Counts how many bytes is required for future utf-8 string using utf-16
|
||||
* \param string16: pointer to working utf-16 string
|
||||
@ -86,4 +90,8 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
|
||||
} \
|
||||
(void)0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __UTFCONV_H__ */
|
@ -11,32 +11,23 @@ set(INC
|
||||
|
||||
set(INC_SYS
|
||||
${wayland-client_INCLUDE_DIRS}
|
||||
${wayland-egl_INCLUDE_DIRS}
|
||||
${wayland-cursor_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SRC
|
||||
intern/wayland_dynload_client.c
|
||||
intern/wayland_dynload_cursor.c
|
||||
intern/wayland_dynload_egl.c
|
||||
intern/wayland_dynload_utils.c
|
||||
|
||||
extern/wayland_dynload_API.h
|
||||
extern/wayland_dynload_client.h
|
||||
extern/wayland_dynload_cursor.h
|
||||
extern/wayland_dynload_egl.h
|
||||
intern/wayland_dynload_utils.h
|
||||
)
|
||||
|
||||
if(WITH_OPENGL_BACKEND)
|
||||
list(APPEND INC_SYS
|
||||
${wayland-egl_INCLUDE_DIRS}
|
||||
)
|
||||
list(APPEND SRC
|
||||
intern/wayland_dynload_egl.c
|
||||
|
||||
extern/wayland_dynload_egl.h
|
||||
)
|
||||
add_definitions(-DWITH_OPENGL_BACKEND)
|
||||
endif()
|
||||
|
||||
if(WITH_GHOST_WAYLAND_LIBDECOR)
|
||||
list(APPEND INC_SYS
|
||||
${libdecor_INCLUDE_DIRS}
|
||||
|
@ -20,10 +20,8 @@ void wayland_dynload_client_exit(void);
|
||||
bool wayland_dynload_cursor_init(bool verbose);
|
||||
void wayland_dynload_cursor_exit(void);
|
||||
|
||||
#ifdef WITH_OPENGL_BACKEND
|
||||
bool wayland_dynload_egl_init(bool verbose);
|
||||
void wayland_dynload_egl_exit(void);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
bool wayland_dynload_libdecor_init(bool verbose);
|
||||
|
@ -642,7 +642,7 @@ looks:
|
||||
contrast: {rgb: [0.7, 0.7, 0.7], master: 1}
|
||||
saturation: 1.15
|
||||
pivot: {contrast: -0.2}
|
||||
|
||||
|
||||
- !<Look>
|
||||
name: False Color - Punchy
|
||||
process_space: AgX Log
|
||||
@ -744,4 +744,4 @@ looks:
|
||||
style: log
|
||||
contrast: {rgb: [0.7, 0.7, 0.7], master: 1}
|
||||
saturation: 1.15
|
||||
pivot: {contrast: -0.2}
|
||||
pivot: {contrast: -0.2}
|
Binary file not shown.
Before Width: | Height: | Size: 714 KiB After Width: | Height: | Size: 1.1 MiB |
@ -588,7 +588,6 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
),
|
||||
"message": (),
|
||||
"heading": (),
|
||||
"placeholder": ((("text_ctxt",), _ctxt_to_ctxt),),
|
||||
}
|
||||
|
||||
context_kw_set = {}
|
||||
@ -622,8 +621,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
for arg_pos, (arg_kw, arg) in enumerate(func.parameters.items()):
|
||||
if (not arg.is_output) and (arg.type == 'STRING'):
|
||||
for msgid, msgctxts in context_kw_set.items():
|
||||
# The msgid can be missing if it is used in only some UILayout functions but not all
|
||||
if arg_kw in msgctxts and msgid in func_translate_args[func_id]:
|
||||
if arg_kw in msgctxts:
|
||||
func_translate_args[func_id][msgid][1][arg_kw] = arg_pos
|
||||
# The report() func of operators.
|
||||
for func_id, func in bpy.types.Operator.bl_rna.functions.items():
|
||||
|
@ -12,7 +12,6 @@ __all__ = (
|
||||
|
||||
import bpy
|
||||
from bpy.types import Action
|
||||
from dataclasses import dataclass
|
||||
|
||||
from typing import (
|
||||
List,
|
||||
@ -32,47 +31,11 @@ FCurveKey = Tuple[
|
||||
ListKeyframes = List[float]
|
||||
|
||||
|
||||
@dataclass
|
||||
class BakeOptions:
|
||||
only_selected: bool
|
||||
"""Only bake selected bones."""
|
||||
|
||||
do_pose: bool
|
||||
"""Bake pose channels"""
|
||||
|
||||
do_object: bool
|
||||
"""Bake objects."""
|
||||
|
||||
do_visual_keying: bool
|
||||
"""Use the final transformations for baking ('visual keying')."""
|
||||
|
||||
do_constraint_clear: bool
|
||||
"""Remove constraints after baking."""
|
||||
|
||||
do_parents_clear: bool
|
||||
"""Unparent after baking objects."""
|
||||
|
||||
do_clean: bool
|
||||
"""Remove redundant keyframes after baking."""
|
||||
|
||||
do_location: bool
|
||||
"""Bake location channels"""
|
||||
|
||||
do_rotation: bool
|
||||
"""Bake rotation channels"""
|
||||
|
||||
do_scale: bool
|
||||
"""Bake scale channels"""
|
||||
|
||||
do_bbone: bool
|
||||
"""Bake b-bone channels"""
|
||||
|
||||
|
||||
def bake_action(
|
||||
obj,
|
||||
*,
|
||||
action, frames,
|
||||
bake_options: BakeOptions
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
:arg obj: Object to bake.
|
||||
@ -86,13 +49,13 @@ def bake_action(
|
||||
:return: an action or None
|
||||
:rtype: :class:`bpy.types.Action`
|
||||
"""
|
||||
if not (bake_options.do_pose or bake_options.do_object):
|
||||
if not (kwargs.get("do_pose") or kwargs.get("do_object")):
|
||||
return None
|
||||
|
||||
action, = bake_action_objects(
|
||||
[(obj, action)],
|
||||
frames=frames,
|
||||
bake_options=bake_options
|
||||
**kwargs,
|
||||
)
|
||||
return action
|
||||
|
||||
@ -101,7 +64,7 @@ def bake_action_objects(
|
||||
object_action_pairs,
|
||||
*,
|
||||
frames,
|
||||
bake_options: BakeOptions
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
A version of :func:`bake_action_objects_iter` that takes frames and returns the output.
|
||||
@ -112,7 +75,7 @@ def bake_action_objects(
|
||||
:return: A sequence of Action or None types (aligned with `object_action_pairs`)
|
||||
:rtype: sequence of :class:`bpy.types.Action`
|
||||
"""
|
||||
iter = bake_action_objects_iter(object_action_pairs, bake_options=bake_options)
|
||||
iter = bake_action_objects_iter(object_action_pairs, **kwargs)
|
||||
iter.send(None)
|
||||
for frame in frames:
|
||||
iter.send(frame)
|
||||
@ -121,7 +84,7 @@ def bake_action_objects(
|
||||
|
||||
def bake_action_objects_iter(
|
||||
object_action_pairs,
|
||||
bake_options: BakeOptions
|
||||
**kwargs
|
||||
):
|
||||
"""
|
||||
An coroutine that bakes actions for multiple objects.
|
||||
@ -133,7 +96,7 @@ def bake_action_objects_iter(
|
||||
scene = bpy.context.scene
|
||||
frame_back = scene.frame_current
|
||||
iter_all = tuple(
|
||||
bake_action_iter(obj, action=action, bake_options=bake_options)
|
||||
bake_action_iter(obj, action=action, **kwargs)
|
||||
for (obj, action) in object_action_pairs
|
||||
)
|
||||
for iter in iter_all:
|
||||
@ -155,7 +118,13 @@ def bake_action_iter(
|
||||
obj,
|
||||
*,
|
||||
action,
|
||||
bake_options: BakeOptions
|
||||
only_selected=False,
|
||||
do_pose=True,
|
||||
do_object=True,
|
||||
do_visual_keying=True,
|
||||
do_constraint_clear=False,
|
||||
do_parents_clear=False,
|
||||
do_clean=False
|
||||
):
|
||||
"""
|
||||
An coroutine that bakes action for a single object.
|
||||
@ -165,8 +134,20 @@ def bake_action_iter(
|
||||
:arg action: An action to bake the data into, or None for a new action
|
||||
to be created.
|
||||
:type action: :class:`bpy.types.Action` or None
|
||||
:arg bake_options: Boolean options of what to include into the action bake.
|
||||
:type bake_options: :class: `anim_utils.BakeOptions`
|
||||
:arg only_selected: Only bake selected bones.
|
||||
:type only_selected: bool
|
||||
:arg do_pose: Bake pose channels.
|
||||
:type do_pose: bool
|
||||
:arg do_object: Bake objects.
|
||||
:type do_object: bool
|
||||
:arg do_visual_keying: Use the final transformations for baking ('visual keying')
|
||||
:type do_visual_keying: bool
|
||||
:arg do_constraint_clear: Remove constraints after baking.
|
||||
:type do_constraint_clear: bool
|
||||
:arg do_parents_clear: Unparent after baking objects.
|
||||
:type do_parents_clear: bool
|
||||
:arg do_clean: Remove redundant keyframes after baking.
|
||||
:type do_clean: bool
|
||||
|
||||
:return: an action or None
|
||||
:rtype: :class:`bpy.types.Action`
|
||||
@ -199,7 +180,7 @@ def bake_action_iter(
|
||||
matrix = {}
|
||||
bbones = {}
|
||||
for name, pbone in obj.pose.bones.items():
|
||||
if bake_options.do_visual_keying:
|
||||
if do_visual_keying:
|
||||
# Get the final transform of the bone in its own local space...
|
||||
matrix[name] = obj.convert_space(pose_bone=pbone, matrix=pbone.matrix,
|
||||
from_space='POSE', to_space='LOCAL')
|
||||
@ -211,8 +192,8 @@ def bake_action_iter(
|
||||
bbones[name] = {bb_prop: getattr(pbone, bb_prop) for bb_prop in BBONE_PROPS}
|
||||
return matrix, bbones
|
||||
|
||||
if bake_options.do_parents_clear:
|
||||
if bake_options.do_visual_keying:
|
||||
if do_parents_clear:
|
||||
if do_visual_keying:
|
||||
def obj_frame_info(obj):
|
||||
return obj.matrix_world.copy()
|
||||
else:
|
||||
@ -224,7 +205,7 @@ def bake_action_iter(
|
||||
else:
|
||||
return matrix.copy()
|
||||
else:
|
||||
if bake_options.do_visual_keying:
|
||||
if do_visual_keying:
|
||||
def obj_frame_info(obj):
|
||||
parent = obj.parent
|
||||
matrix = obj.matrix_world
|
||||
@ -240,9 +221,9 @@ def bake_action_iter(
|
||||
# Setup the Context
|
||||
|
||||
if obj.pose is None:
|
||||
bake_options.do_pose = False
|
||||
do_pose = False
|
||||
|
||||
if not (bake_options.do_pose or bake_options.do_object):
|
||||
if not (do_pose or do_object):
|
||||
raise Exception("Pose and object baking is disabled, no action needed")
|
||||
|
||||
pose_info = []
|
||||
@ -259,14 +240,14 @@ def bake_action_iter(
|
||||
if frame is None:
|
||||
break
|
||||
|
||||
if bake_options.do_pose:
|
||||
if do_pose:
|
||||
pose_info.append((frame, *pose_frame_info(obj)))
|
||||
if bake_options.do_object:
|
||||
if do_object:
|
||||
obj_info.append((frame, obj_frame_info(obj)))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Clean (store initial data)
|
||||
if bake_options.do_clean and action is not None:
|
||||
if do_clean and action is not None:
|
||||
clean_orig_data = {fcu: {p.co[1] for p in fcu.keyframe_points} for fcu in action.fcurves}
|
||||
else:
|
||||
clean_orig_data = {}
|
||||
@ -297,12 +278,12 @@ def bake_action_iter(
|
||||
|
||||
# pose
|
||||
lookup_fcurves = {(fcurve.data_path, fcurve.array_index): fcurve for fcurve in action.fcurves}
|
||||
if bake_options.do_pose:
|
||||
if do_pose:
|
||||
for name, pbone in obj.pose.bones.items():
|
||||
if bake_options.only_selected and not pbone.bone.select:
|
||||
if only_selected and not pbone.bone.select:
|
||||
continue
|
||||
|
||||
if bake_options.do_constraint_clear:
|
||||
if do_constraint_clear:
|
||||
while pbone.constraints:
|
||||
pbone.constraints.remove(pbone.constraints[0])
|
||||
|
||||
@ -319,17 +300,13 @@ def bake_action_iter(
|
||||
paths_bbprops = [(base_fcurve_path + bbprop) for bbprop in BBONE_PROPS]
|
||||
|
||||
keyframes = KeyframesCo()
|
||||
keyframes.add_paths(path_location, 3)
|
||||
keyframes.add_paths(path_quaternion, 4)
|
||||
keyframes.add_paths(path_axis_angle, 4)
|
||||
keyframes.add_paths(path_euler, 3)
|
||||
keyframes.add_paths(path_scale, 3)
|
||||
|
||||
if bake_options.do_location:
|
||||
keyframes.add_paths(path_location, 3)
|
||||
if bake_options.do_rotation:
|
||||
keyframes.add_paths(path_quaternion, 4)
|
||||
keyframes.add_paths(path_axis_angle, 4)
|
||||
keyframes.add_paths(path_euler, 3)
|
||||
if bake_options.do_scale:
|
||||
keyframes.add_paths(path_scale, 3)
|
||||
|
||||
if bake_options.do_bbone and pbone.bone.bbone_segments > 1:
|
||||
if pbone.bone.bbone_segments > 1:
|
||||
for prop_name, path in zip(BBONE_PROPS, paths_bbprops):
|
||||
keyframes.add_paths(path, BBONE_PROPS_LENGTHS[prop_name])
|
||||
|
||||
@ -338,35 +315,32 @@ def bake_action_iter(
|
||||
for (f, matrix, bbones) in pose_info:
|
||||
pbone.matrix_basis = matrix[name].copy()
|
||||
|
||||
if bake_options.do_location:
|
||||
keyframes.extend_co_values(path_location, 3, f, pbone.location)
|
||||
keyframes.extend_co_values(path_location, 3, f, pbone.location)
|
||||
|
||||
if bake_options.do_rotation:
|
||||
if rotation_mode == 'QUATERNION':
|
||||
if quat_prev is not None:
|
||||
quat = pbone.rotation_quaternion.copy()
|
||||
quat.make_compatible(quat_prev)
|
||||
pbone.rotation_quaternion = quat
|
||||
quat_prev = quat
|
||||
del quat
|
||||
else:
|
||||
quat_prev = pbone.rotation_quaternion.copy()
|
||||
keyframes.extend_co_values(path_quaternion, 4, f, pbone.rotation_quaternion)
|
||||
elif rotation_mode == 'AXIS_ANGLE':
|
||||
keyframes.extend_co_values(path_axis_angle, 4, f, pbone.rotation_axis_angle)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
euler = pbone.matrix_basis.to_euler(pbone.rotation_mode, euler_prev)
|
||||
pbone.rotation_euler = euler
|
||||
del euler
|
||||
euler_prev = pbone.rotation_euler.copy()
|
||||
keyframes.extend_co_values(path_euler, 3, f, pbone.rotation_euler)
|
||||
if rotation_mode == 'QUATERNION':
|
||||
if quat_prev is not None:
|
||||
quat = pbone.rotation_quaternion.copy()
|
||||
quat.make_compatible(quat_prev)
|
||||
pbone.rotation_quaternion = quat
|
||||
quat_prev = quat
|
||||
del quat
|
||||
else:
|
||||
quat_prev = pbone.rotation_quaternion.copy()
|
||||
keyframes.extend_co_values(path_quaternion, 4, f, pbone.rotation_quaternion)
|
||||
elif rotation_mode == 'AXIS_ANGLE':
|
||||
keyframes.extend_co_values(path_axis_angle, 4, f, pbone.rotation_axis_angle)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
euler = pbone.matrix_basis.to_euler(pbone.rotation_mode, euler_prev)
|
||||
pbone.rotation_euler = euler
|
||||
del euler
|
||||
euler_prev = pbone.rotation_euler.copy()
|
||||
keyframes.extend_co_values(path_euler, 3, f, pbone.rotation_euler)
|
||||
|
||||
if bake_options.do_scale:
|
||||
keyframes.extend_co_values(path_scale, 3, f, pbone.scale)
|
||||
keyframes.extend_co_values(path_scale, 3, f, pbone.scale)
|
||||
|
||||
# Bendy Bones
|
||||
if bake_options.do_bbone and pbone.bone.bbone_segments > 1:
|
||||
if pbone.bone.bbone_segments > 1:
|
||||
bbone_shape = bbones[name]
|
||||
for prop_index, prop_name in enumerate(BBONE_PROPS):
|
||||
prop_len = BBONE_PROPS_LENGTHS[prop_name]
|
||||
@ -385,8 +359,8 @@ def bake_action_iter(
|
||||
keyframes.insert_keyframes_into_existing_action(lookup_fcurves, total_new_keys, action, name)
|
||||
|
||||
# object. TODO. multiple objects
|
||||
if bake_options.do_object:
|
||||
if bake_options.do_constraint_clear:
|
||||
if do_object:
|
||||
if do_constraint_clear:
|
||||
while obj.constraints:
|
||||
obj.constraints.remove(obj.constraints[0])
|
||||
|
||||
@ -401,14 +375,11 @@ def bake_action_iter(
|
||||
path_scale = "scale"
|
||||
|
||||
keyframes = KeyframesCo()
|
||||
if bake_options.do_location:
|
||||
keyframes.add_paths(path_location, 3)
|
||||
if bake_options.do_rotation:
|
||||
keyframes.add_paths(path_quaternion, 4)
|
||||
keyframes.add_paths(path_axis_angle, 4)
|
||||
keyframes.add_paths(path_euler, 3)
|
||||
if bake_options.do_scale:
|
||||
keyframes.add_paths(path_scale, 3)
|
||||
keyframes.add_paths(path_location, 3)
|
||||
keyframes.add_paths(path_quaternion, 4)
|
||||
keyframes.add_paths(path_axis_angle, 4)
|
||||
keyframes.add_paths(path_euler, 3)
|
||||
keyframes.add_paths(path_scale, 3)
|
||||
|
||||
rotation_mode = obj.rotation_mode
|
||||
total_new_keys = len(obj_info)
|
||||
@ -416,44 +387,41 @@ def bake_action_iter(
|
||||
name = "Action Bake" # XXX: placeholder
|
||||
obj.matrix_basis = matrix
|
||||
|
||||
if bake_options.do_location:
|
||||
keyframes.extend_co_values(path_location, 3, f, obj.location)
|
||||
keyframes.extend_co_values(path_location, 3, f, obj.location)
|
||||
|
||||
if bake_options.do_rotation:
|
||||
if rotation_mode == 'QUATERNION':
|
||||
if quat_prev is not None:
|
||||
quat = obj.rotation_quaternion.copy()
|
||||
quat.make_compatible(quat_prev)
|
||||
obj.rotation_quaternion = quat
|
||||
quat_prev = quat
|
||||
del quat
|
||||
else:
|
||||
quat_prev = obj.rotation_quaternion.copy()
|
||||
keyframes.extend_co_values(path_quaternion, 4, f, obj.rotation_quaternion)
|
||||
if rotation_mode == 'QUATERNION':
|
||||
if quat_prev is not None:
|
||||
quat = obj.rotation_quaternion.copy()
|
||||
quat.make_compatible(quat_prev)
|
||||
obj.rotation_quaternion = quat
|
||||
quat_prev = quat
|
||||
del quat
|
||||
else:
|
||||
quat_prev = obj.rotation_quaternion.copy()
|
||||
keyframes.extend_co_values(path_quaternion, 4, f, obj.rotation_quaternion)
|
||||
|
||||
elif rotation_mode == 'AXIS_ANGLE':
|
||||
keyframes.extend_co_values(path_axis_angle, 4, f, obj.rotation_axis_angle)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
obj.rotation_euler = matrix.to_euler(obj.rotation_mode, euler_prev)
|
||||
euler_prev = obj.rotation_euler.copy()
|
||||
keyframes.extend_co_values(path_euler, 3, f, obj.rotation_euler)
|
||||
elif rotation_mode == 'AXIS_ANGLE':
|
||||
keyframes.extend_co_values(path_axis_angle, 4, f, obj.rotation_axis_angle)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
obj.rotation_euler = matrix.to_euler(obj.rotation_mode, euler_prev)
|
||||
euler_prev = obj.rotation_euler.copy()
|
||||
keyframes.extend_co_values(path_euler, 3, f, obj.rotation_euler)
|
||||
|
||||
if bake_options.do_scale:
|
||||
keyframes.extend_co_values(path_scale, 3, f, obj.scale)
|
||||
keyframes.extend_co_values(path_scale, 3, f, obj.scale)
|
||||
|
||||
if is_new_action:
|
||||
keyframes.insert_keyframes_into_new_action(total_new_keys, action, name)
|
||||
else:
|
||||
keyframes.insert_keyframes_into_existing_action(lookup_fcurves, total_new_keys, action, name)
|
||||
|
||||
if bake_options.do_parents_clear:
|
||||
if do_parents_clear:
|
||||
obj.parent = None
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Clean
|
||||
|
||||
if bake_options.do_clean:
|
||||
if do_clean:
|
||||
for fcu in action.fcurves:
|
||||
fcu_orig_data = clean_orig_data.get(fcu, set())
|
||||
|
||||
|
@ -139,8 +139,8 @@ def rna2xml(
|
||||
# check if the list contains native types
|
||||
subvalue_rna = value.path_resolve(prop, False)
|
||||
if type(subvalue_rna).__name__ == "bpy_prop_array":
|
||||
# Check if this is a 0-1 color (RGB, RGBA)
|
||||
# in that case write as a hexadecimal.
|
||||
# check if this is a 0-1 color (rgb, rgba)
|
||||
# in that case write as a hexadecimal
|
||||
prop_rna = value.bl_rna.properties[prop]
|
||||
if (prop_rna.subtype == 'COLOR_GAMMA' and
|
||||
prop_rna.hard_min == 0.0 and
|
||||
|
@ -4569,11 +4569,6 @@ def km_grease_pencil_paint(_params):
|
||||
)
|
||||
|
||||
items.extend([
|
||||
*_template_paint_radial_control("gpencil_paint"),
|
||||
("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("scalar", 0.9)]}),
|
||||
("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("scalar", 1.0 / 0.9)]}),
|
||||
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
("grease_pencil.brush_stroke", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
@ -4608,27 +4603,6 @@ def km_grease_pencil_edit(params):
|
||||
# Delete all active frames
|
||||
("grease_pencil.delete_frame", {"type": 'DEL', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("type", "ALL_FRAMES")]}),
|
||||
# Keyframe Menu
|
||||
op_menu("VIEW3D_MT_edit_greasepencil_animation", {"type": 'I', "value": 'PRESS'}),
|
||||
|
||||
# Transform Actions.
|
||||
*_template_items_transform_actions(params, use_bend=True, use_mirror=True, use_tosphere=True, use_shear=True),
|
||||
("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("mode", 'CURVE_SHRINKFATTEN')]}),
|
||||
("transform.transform", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'GPENCIL_OPACITY')]}),
|
||||
|
||||
# Proportional editing.
|
||||
*_template_items_proportional_editing(
|
||||
params, connected=True, toggle_data_path='tool_settings.use_proportional_edit'),
|
||||
|
||||
# Cyclical set
|
||||
("grease_pencil.cyclical_set", {"type": 'F', "value": 'PRESS'}, {"properties": [("type", "CLOSE")]}),
|
||||
("grease_pencil.cyclical_set", {"type": 'C', "value": 'PRESS',
|
||||
"alt": True}, {"properties": [("type", "TOGGLE")]}),
|
||||
|
||||
# Context menu
|
||||
*_template_items_context_menu("VIEW3D_MT_greasepencil_edit_context_menu", params.context_menu_event),
|
||||
])
|
||||
|
||||
return keymap
|
||||
@ -7281,18 +7255,6 @@ def km_3d_view_tool_shear(params):
|
||||
)
|
||||
|
||||
|
||||
def km_3d_view_tool_bend(params):
|
||||
return (
|
||||
"3D View Tool: Bend",
|
||||
{"space_type": 'VIEW_3D', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
# No need for `tool_modifier` since this takes all input.
|
||||
("transform.bend", params.tool_maybe_tweak_event,
|
||||
{"properties": [("release_confirm", True)]}),
|
||||
]},
|
||||
)
|
||||
|
||||
|
||||
def km_3d_view_tool_measure(params):
|
||||
return (
|
||||
"3D View Tool: Measure",
|
||||
@ -8594,7 +8556,6 @@ def generate_keymaps(params=None):
|
||||
km_3d_view_tool_rotate(params),
|
||||
km_3d_view_tool_scale(params),
|
||||
km_3d_view_tool_shear(params),
|
||||
km_3d_view_tool_bend(params),
|
||||
km_3d_view_tool_measure(params),
|
||||
km_3d_view_tool_interactive_add(params),
|
||||
km_3d_view_tool_pose_breakdowner(params),
|
||||
|
@ -252,43 +252,19 @@ class NLA_OT_bake(Operator):
|
||||
),
|
||||
default={'POSE'},
|
||||
)
|
||||
channel_types: EnumProperty(
|
||||
name="Channels",
|
||||
description="Which channels to bake",
|
||||
options={'ENUM_FLAG'},
|
||||
items=(
|
||||
('LOCATION', "Location", "Bake location channels"),
|
||||
('ROTATION', "Rotation", "Bake rotation channels"),
|
||||
('SCALE', "Scale", "Bake scale channels"),
|
||||
('BBONE', "B-Bone", "Bake b-bone channels"),
|
||||
),
|
||||
default={'LOCATION', 'ROTATION', 'SCALE', 'BBONE'},
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
from bpy_extras import anim_utils
|
||||
do_pose = 'POSE' in self.bake_types
|
||||
do_object = 'OBJECT' in self.bake_types
|
||||
|
||||
bake_options = anim_utils.BakeOptions(
|
||||
only_selected=self.only_selected,
|
||||
do_pose='POSE' in self.bake_types,
|
||||
do_object='OBJECT' in self.bake_types,
|
||||
do_visual_keying=self.visual_keying,
|
||||
do_constraint_clear=self.clear_constraints,
|
||||
do_parents_clear=self.clear_parents,
|
||||
do_clean=self.clean_curves,
|
||||
do_location='LOCATION' in self.channel_types,
|
||||
do_rotation='ROTATION' in self.channel_types,
|
||||
do_scale='SCALE' in self.channel_types,
|
||||
do_bbone='BBONE' in self.channel_types,
|
||||
)
|
||||
|
||||
if bake_options.do_pose and self.only_selected:
|
||||
if do_pose and self.only_selected:
|
||||
pose_bones = context.selected_pose_bones or []
|
||||
armatures = {pose_bone.id_data for pose_bone in pose_bones}
|
||||
objects = list(armatures)
|
||||
else:
|
||||
objects = context.selected_editable_objects
|
||||
if bake_options.do_pose and not bake_options.do_object:
|
||||
if do_pose and not do_object:
|
||||
objects = [obj for obj in objects if obj.pose is not None]
|
||||
|
||||
object_action_pairs = (
|
||||
@ -300,7 +276,13 @@ class NLA_OT_bake(Operator):
|
||||
actions = anim_utils.bake_action_objects(
|
||||
object_action_pairs,
|
||||
frames=range(self.frame_start, self.frame_end + 1, self.step),
|
||||
bake_options=bake_options
|
||||
only_selected=self.only_selected,
|
||||
do_pose=do_pose,
|
||||
do_object=do_object,
|
||||
do_visual_keying=self.visual_keying,
|
||||
do_constraint_clear=self.clear_constraints,
|
||||
do_parents_clear=self.clear_parents,
|
||||
do_clean=self.clean_curves,
|
||||
)
|
||||
|
||||
if not any(actions):
|
||||
|
@ -68,7 +68,7 @@ def geometry_modifier_poll(context):
|
||||
ob = context.object
|
||||
|
||||
# Test object support for geometry node modifier
|
||||
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE', 'FONT', 'CURVES', 'GREASEPENCIL'}:
|
||||
if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE', 'FONT', 'CURVES'}:
|
||||
return False
|
||||
|
||||
return True
|
||||
@ -311,7 +311,10 @@ class NewGeometryNodeGroupTool(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class ZoneOperator:
|
||||
class SimulationZoneOperator:
|
||||
input_node_type = 'GeometryNodeSimulationInput'
|
||||
output_node_type = 'GeometryNodeSimulationOutput'
|
||||
|
||||
@classmethod
|
||||
def get_output_node(cls, context):
|
||||
node = context.active_node
|
||||
@ -334,50 +337,57 @@ class ZoneOperator:
|
||||
return True
|
||||
|
||||
|
||||
class ZoneItemAddOperator:
|
||||
items_name = None
|
||||
active_index_name = None
|
||||
class SimulationZoneItemAddOperator(SimulationZoneOperator, Operator):
|
||||
"""Add a state item to the simulation zone"""
|
||||
bl_idname = "node.simulation_zone_item_add"
|
||||
bl_label = "Add State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
default_socket_type = 'GEOMETRY'
|
||||
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
items = getattr(node, self.items_name)
|
||||
state_items = node.state_items
|
||||
|
||||
# Remember index to move the item.
|
||||
old_active_index = getattr(node, self.active_index_name)
|
||||
if 0 <= old_active_index < len(items):
|
||||
old_active_item = items[old_active_index]
|
||||
dst_index = old_active_index + 1
|
||||
dst_type = old_active_item.socket_type
|
||||
dst_name = old_active_item.name
|
||||
if node.active_item:
|
||||
dst_index = node.active_index + 1
|
||||
dst_type = node.active_item.socket_type
|
||||
dst_name = node.active_item.name
|
||||
else:
|
||||
dst_index = len(items)
|
||||
dst_index = len(state_items)
|
||||
dst_type = self.default_socket_type
|
||||
# Empty name so it is based on the type.
|
||||
dst_name = ""
|
||||
items.new(dst_type, dst_name)
|
||||
items.move(len(items) - 1, dst_index)
|
||||
setattr(node, self.active_index_name, dst_index)
|
||||
state_items.new(dst_type, dst_name)
|
||||
state_items.move(len(state_items) - 1, dst_index)
|
||||
node.active_index = dst_index
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class ZoneItemRemoveOperator:
|
||||
items_name = None
|
||||
active_index_name = None
|
||||
class SimulationZoneItemRemoveOperator(SimulationZoneOperator, Operator):
|
||||
"""Remove a state item from the simulation zone"""
|
||||
bl_idname = "node.simulation_zone_item_remove"
|
||||
bl_label = "Remove State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
items = getattr(node, self.items_name)
|
||||
old_active_index = getattr(node, self.active_index_name)
|
||||
state_items = node.state_items
|
||||
|
||||
if 0 <= old_active_index < len(items):
|
||||
items.remove(items[old_active_index])
|
||||
if node.active_item:
|
||||
state_items.remove(node.active_item)
|
||||
node.active_index = min(node.active_index, len(state_items) - 1)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class ZoneMoveItemOperator:
|
||||
items_name = None
|
||||
active_index_name = None
|
||||
class SimulationZoneItemMoveOperator(SimulationZoneOperator, Operator):
|
||||
"""Move a simulation state item up or down in the list"""
|
||||
bl_idname = "node.simulation_zone_item_move"
|
||||
bl_label = "Move State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
direction: EnumProperty(
|
||||
name="Direction",
|
||||
@ -387,76 +397,116 @@ class ZoneMoveItemOperator:
|
||||
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
items = getattr(node, self.items_name)
|
||||
old_active_index = getattr(node, self.active_index_name)
|
||||
state_items = node.state_items
|
||||
|
||||
if self.direction == 'UP' and old_active_index > 0:
|
||||
items.move(old_active_index, old_active_index - 1)
|
||||
setattr(node, self.active_index_name, old_active_index - 1)
|
||||
elif self.direction == 'DOWN' and old_active_index < len(items) - 1:
|
||||
items.move(old_active_index, old_active_index + 1)
|
||||
setattr(node, self.active_index_name, old_active_index + 1)
|
||||
if self.direction == 'UP' and node.active_index > 0:
|
||||
state_items.move(node.active_index, node.active_index - 1)
|
||||
node.active_index = node.active_index - 1
|
||||
elif self.direction == 'DOWN' and node.active_index < len(state_items) - 1:
|
||||
state_items.move(node.active_index, node.active_index + 1)
|
||||
node.active_index = node.active_index + 1
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class SimulationZoneOperator(ZoneOperator):
|
||||
input_node_type = 'GeometryNodeSimulationInput'
|
||||
output_node_type = 'GeometryNodeSimulationOutput'
|
||||
|
||||
items_name = "state_items"
|
||||
active_index_name = "active_index"
|
||||
|
||||
|
||||
class SimulationZoneItemAddOperator(SimulationZoneOperator, ZoneItemAddOperator, Operator):
|
||||
"""Add a state item to the simulation zone"""
|
||||
bl_idname = "node.simulation_zone_item_add"
|
||||
bl_label = "Add State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
|
||||
class SimulationZoneItemRemoveOperator(SimulationZoneOperator, ZoneItemRemoveOperator, Operator):
|
||||
"""Remove a state item from the simulation zone"""
|
||||
bl_idname = "node.simulation_zone_item_remove"
|
||||
bl_label = "Remove State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
|
||||
class SimulationZoneItemMoveOperator(SimulationZoneOperator, ZoneMoveItemOperator, Operator):
|
||||
"""Move a simulation state item up or down in the list"""
|
||||
bl_idname = "node.simulation_zone_item_move"
|
||||
bl_label = "Move State Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
|
||||
class RepeatZoneOperator(ZoneOperator):
|
||||
class RepeatZoneOperator:
|
||||
input_node_type = 'GeometryNodeRepeatInput'
|
||||
output_node_type = 'GeometryNodeRepeatOutput'
|
||||
|
||||
items_name = "repeat_items"
|
||||
active_index_name = "active_index"
|
||||
@classmethod
|
||||
def get_output_node(cls, context):
|
||||
node = context.active_node
|
||||
if node.bl_idname == cls.input_node_type:
|
||||
return node.paired_output
|
||||
if node.bl_idname == cls.output_node_type:
|
||||
return node
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
space = context.space_data
|
||||
# Needs active node editor and a tree.
|
||||
if not space or space.type != 'NODE_EDITOR' or not space.edit_tree or space.edit_tree.library:
|
||||
return False
|
||||
node = context.active_node
|
||||
if node is None or node.bl_idname not in [cls.input_node_type, cls.output_node_type]:
|
||||
return False
|
||||
if cls.get_output_node(context) is None:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class RepeatZoneItemAddOperator(RepeatZoneOperator, ZoneItemAddOperator, Operator):
|
||||
class RepeatZoneItemAddOperator(RepeatZoneOperator, Operator):
|
||||
"""Add a repeat item to the repeat zone"""
|
||||
bl_idname = "node.repeat_zone_item_add"
|
||||
bl_label = "Add Repeat Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
default_socket_type = 'GEOMETRY'
|
||||
|
||||
class RepeatZoneItemRemoveOperator(RepeatZoneOperator, ZoneItemRemoveOperator, Operator):
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
repeat_items = node.repeat_items
|
||||
|
||||
# Remember index to move the item.
|
||||
if node.active_item:
|
||||
dst_index = node.active_index + 1
|
||||
dst_type = node.active_item.socket_type
|
||||
dst_name = node.active_item.name
|
||||
else:
|
||||
dst_index = len(repeat_items)
|
||||
dst_type = self.default_socket_type
|
||||
# Empty name so it is based on the type.
|
||||
dst_name = ""
|
||||
repeat_items.new(dst_type, dst_name)
|
||||
repeat_items.move(len(repeat_items) - 1, dst_index)
|
||||
node.active_index = dst_index
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RepeatZoneItemRemoveOperator(RepeatZoneOperator, Operator):
|
||||
"""Remove a repeat item from the repeat zone"""
|
||||
bl_idname = "node.repeat_zone_item_remove"
|
||||
bl_label = "Remove Repeat Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
repeat_items = node.repeat_items
|
||||
|
||||
class RepeatZoneItemMoveOperator(RepeatZoneOperator, ZoneMoveItemOperator, Operator):
|
||||
if node.active_item:
|
||||
repeat_items.remove(node.active_item)
|
||||
node.active_index = min(node.active_index, len(repeat_items) - 1)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RepeatZoneItemMoveOperator(RepeatZoneOperator, Operator):
|
||||
"""Move a repeat item up or down in the list"""
|
||||
bl_idname = "node.repeat_zone_item_move"
|
||||
bl_label = "Move Repeat Item"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
direction: EnumProperty(
|
||||
name="Direction",
|
||||
items=[('UP', "Up", ""), ('DOWN', "Down", "")],
|
||||
default='UP',
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
node = self.get_output_node(context)
|
||||
repeat_items = node.repeat_items
|
||||
|
||||
if self.direction == 'UP' and node.active_index > 0:
|
||||
repeat_items.move(node.active_index, node.active_index - 1)
|
||||
node.active_index = node.active_index - 1
|
||||
elif self.direction == 'DOWN' and node.active_index < len(repeat_items) - 1:
|
||||
repeat_items.move(node.active_index, node.active_index + 1)
|
||||
node.active_index = node.active_index + 1
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
classes = (
|
||||
NewGeometryNodesModifier,
|
||||
|
@ -1409,14 +1409,8 @@ rna_custom_property_subtype_vector_items = (
|
||||
rna_custom_property_subtype_none_item,
|
||||
('COLOR', "Linear Color", "Color in the linear space"),
|
||||
('COLOR_GAMMA', "Gamma-Corrected Color", "Color in the gamma corrected space"),
|
||||
('TRANSLATION', "Translation", ""),
|
||||
('DIRECTION', "Direction", ""),
|
||||
('VELOCITY', "Velocity", ""),
|
||||
('ACCELERATION', "Acceleration", ""),
|
||||
('EULER', "Euler Angles", "Euler rotation angles in radians"),
|
||||
('QUATERNION', "Quaternion Rotation", "Quaternion rotation (affects NLA blending)"),
|
||||
('AXISANGLE', "Axis-Angle", "Angle and axis to rotate around"),
|
||||
('XYZ', "XYZ", ""),
|
||||
)
|
||||
|
||||
rna_id_type_items = tuple((item.identifier, item.name, item.description, item.icon, item.value)
|
||||
@ -2689,9 +2683,6 @@ class WM_OT_batch_rename(Operator):
|
||||
('NODE', "Nodes", ""),
|
||||
('SEQUENCE_STRIP', "Sequence Strips", ""),
|
||||
('ACTION_CLIP', "Action Clips", ""),
|
||||
None,
|
||||
('SCENE', "Scenes", ""),
|
||||
('BRUSH', "Brushes", ""),
|
||||
),
|
||||
description="Type of data to rename",
|
||||
)
|
||||
@ -2888,26 +2879,6 @@ class WM_OT_batch_rename(Operator):
|
||||
"name",
|
||||
iface_("Action(s)"),
|
||||
)
|
||||
elif data_type == 'SCENE':
|
||||
data = (
|
||||
(
|
||||
# Outliner.
|
||||
cls._selected_ids_from_outliner_by_type(context, bpy.types.Scene)
|
||||
if ((space_type == 'OUTLINER') and only_selected) else [id for id in bpy.data.scenes if id.library is None]
|
||||
),
|
||||
"name",
|
||||
iface_("Scene(s)"),
|
||||
)
|
||||
elif data_type == 'BRUSH':
|
||||
data = (
|
||||
(
|
||||
# Outliner.
|
||||
cls._selected_ids_from_outliner_by_type(context, bpy.types.Brush)
|
||||
if ((space_type == 'OUTLINER') and only_selected) else [id for id in bpy.data.brushes if id.library is None]
|
||||
),
|
||||
"name",
|
||||
iface_("Brush(es)"),
|
||||
)
|
||||
elif data_type in object_data_type_attrs_map.keys():
|
||||
attr, descr, ty = object_data_type_attrs_map[data_type]
|
||||
data = (
|
||||
|
@ -217,7 +217,6 @@ class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu):
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSplitToInstances")
|
||||
node_add_menu.draw_assets_for_catalog(layout, "Geometry/Operations")
|
||||
|
||||
|
||||
@ -286,8 +285,6 @@ class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu):
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeImageInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeIsViewport")
|
||||
if context.preferences.experimental.use_grease_pencil_version3:
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputNamedLayerSelection")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeInputSceneTime")
|
||||
node_add_menu.add_node_type(layout, "GeometryNodeSelfObject")
|
||||
|
@ -170,7 +170,7 @@ class DATA_PT_gpencil_layers(DataButtonsPanel, Panel):
|
||||
col.prop(gpl, "opacity", text="Opacity", slider=True)
|
||||
|
||||
col = layout.row(align=True)
|
||||
col.prop(gpl, "use_lights", text="Lights")
|
||||
col.prop(gpl, "use_lights")
|
||||
|
||||
|
||||
class DATA_PT_gpencil_layer_masks(LayerDataButtonsPanel, GreasePencilLayerMasksPanel, Panel):
|
||||
|
@ -46,7 +46,7 @@ class DATA_PT_lightprobe(DataButtonsPanel, Panel):
|
||||
|
||||
# layout.prop(probe, "type")
|
||||
|
||||
if probe.type == 'VOLUME':
|
||||
if probe.type == 'GRID':
|
||||
col = layout.column()
|
||||
col.prop(probe, "influence_distance", text="Distance")
|
||||
col.prop(probe, "falloff")
|
||||
@ -57,7 +57,7 @@ class DATA_PT_lightprobe(DataButtonsPanel, Panel):
|
||||
sub.prop(probe, "grid_resolution_y", text="Y")
|
||||
sub.prop(probe, "grid_resolution_z", text="Z")
|
||||
|
||||
elif probe.type == 'PLANE':
|
||||
elif probe.type == 'PLANAR':
|
||||
col = layout.column()
|
||||
col.prop(probe, "influence_distance", text="Distance")
|
||||
col.prop(probe, "falloff")
|
||||
@ -74,12 +74,12 @@ class DATA_PT_lightprobe(DataButtonsPanel, Panel):
|
||||
col.prop(probe, "intensity")
|
||||
|
||||
sub = col.column(align=True)
|
||||
if probe.type != 'PLANE':
|
||||
if probe.type != 'PLANAR':
|
||||
sub.prop(probe, "clip_start", text="Clipping Start")
|
||||
else:
|
||||
sub.prop(probe, "clip_start", text="Clipping Offset")
|
||||
|
||||
if probe.type != 'PLANE':
|
||||
if probe.type != 'PLANAR':
|
||||
sub.prop(probe, "clip_end", text="End")
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ class DATA_PT_lightprobe_eevee_next(DataButtonsPanel, Panel):
|
||||
|
||||
probe = context.lightprobe
|
||||
|
||||
if probe.type == 'VOLUME':
|
||||
if probe.type == 'GRID':
|
||||
col = layout.column()
|
||||
|
||||
sub = col.column(align=True)
|
||||
@ -144,27 +144,15 @@ class DATA_PT_lightprobe_eevee_next(DataButtonsPanel, Panel):
|
||||
col.prop(probe, "grid_capture_indirect")
|
||||
col.prop(probe, "grid_capture_emission")
|
||||
|
||||
elif probe.type == 'SPHERE':
|
||||
elif probe.type == 'CUBEMAP':
|
||||
col = layout.column()
|
||||
col.prop(probe, "influence_type")
|
||||
|
||||
if probe.influence_type == 'ELIPSOID':
|
||||
influence_text = "Radius"
|
||||
else:
|
||||
influence_text = "Size"
|
||||
|
||||
col.prop(probe, "influence_distance", text=influence_text)
|
||||
col.prop(probe, "falloff")
|
||||
|
||||
col.prop(probe, "resolution")
|
||||
sub = layout.column(align=True)
|
||||
sub.prop(probe, "clip_start", text="Clipping Start")
|
||||
sub.prop(probe, "clip_end", text="End")
|
||||
|
||||
elif probe.type == 'PLANE':
|
||||
col = layout.column()
|
||||
row = col.row()
|
||||
col.prop(probe, "clip_start", text="Clipping Offset")
|
||||
col.prop(probe, "influence_distance", text="Distance")
|
||||
elif probe.type == 'PLANAR':
|
||||
# Currently unsupported
|
||||
pass
|
||||
else:
|
||||
# Currently unsupported
|
||||
@ -184,7 +172,7 @@ class DATA_PT_lightprobe_visibility(DataButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if probe.type == 'VOLUME':
|
||||
if probe.type == 'GRID':
|
||||
col.prop(probe, "visibility_buffer_bias", text="Bias")
|
||||
col.prop(probe, "visibility_bleed_bias", text="Bleed Bias")
|
||||
col.prop(probe, "visibility_blur", text="Blur")
|
||||
@ -197,12 +185,12 @@ class DATA_PT_lightprobe_visibility(DataButtonsPanel, Panel):
|
||||
class DATA_PT_lightprobe_parallax(DataButtonsPanel, Panel):
|
||||
bl_label = "Custom Parallax"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_RENDER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
engine = context.engine
|
||||
return context.lightprobe and context.lightprobe.type == 'SPHERE' and (engine in cls.COMPAT_ENGINES)
|
||||
return context.lightprobe and context.lightprobe.type == 'CUBEMAP' and (engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw_header(self, context):
|
||||
probe = context.lightprobe
|
||||
@ -239,16 +227,16 @@ class DATA_PT_lightprobe_display(DataButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
|
||||
if probe.type == 'PLANE':
|
||||
if probe.type == 'PLANAR':
|
||||
col.prop(ob, "empty_display_size", text="Arrow Size")
|
||||
col.prop(probe, "show_influence")
|
||||
col.prop(probe, "show_data")
|
||||
|
||||
if probe.type in {'VOLUME', 'SPHERE'}:
|
||||
if probe.type in {'GRID', 'CUBEMAP'}:
|
||||
col.prop(probe, "show_influence")
|
||||
col.prop(probe, "show_clip")
|
||||
|
||||
if probe.type == 'SPHERE':
|
||||
if probe.type == 'CUBEMAP':
|
||||
sub = col.column()
|
||||
sub.active = probe.use_custom_parallax
|
||||
sub.prop(probe, "show_parallax")
|
||||
|
@ -183,6 +183,33 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
|
||||
layout.template_ID(space, "pin_id")
|
||||
|
||||
|
||||
class DATA_PT_normals(MeshButtonsPanel, Panel):
|
||||
bl_label = "Normals"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {
|
||||
'BLENDER_RENDER',
|
||||
'BLENDER_EEVEE',
|
||||
'BLENDER_EEVEE_NEXT',
|
||||
'BLENDER_WORKBENCH',
|
||||
}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
||||
mesh = context.mesh
|
||||
|
||||
col = layout.column(align=False, heading="Auto Smooth")
|
||||
col.use_property_decorate = False
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.prop(mesh, "use_auto_smooth", text="")
|
||||
sub = sub.row(align=True)
|
||||
sub.active = mesh.use_auto_smooth and not mesh.has_custom_normals
|
||||
sub.prop(mesh, "auto_smooth_angle", text="")
|
||||
row.prop_decorator(mesh, "auto_smooth_angle")
|
||||
|
||||
|
||||
class DATA_PT_texture_space(MeshButtonsPanel, Panel):
|
||||
bl_label = "Texture Space"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@ -701,6 +728,7 @@ classes = (
|
||||
DATA_PT_uv_texture,
|
||||
DATA_PT_vertex_colors,
|
||||
DATA_PT_mesh_attributes,
|
||||
DATA_PT_normals,
|
||||
DATA_PT_texture_space,
|
||||
DATA_PT_remesh,
|
||||
DATA_PT_customdata,
|
||||
|
@ -57,8 +57,7 @@ class OBJECT_MT_modifier_add(ModifierAddMenu, Menu):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
ob_type = context.object.type
|
||||
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES',
|
||||
'FONT', 'VOLUME', 'POINTCLOUD', 'GREASEPENCIL'}
|
||||
geometry_nodes_supported = ob_type in {'MESH', 'CURVE', 'CURVES', 'FONT', 'VOLUME', 'POINTCLOUD'}
|
||||
|
||||
if layout.operator_context == 'EXEC_REGION_WIN':
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
|
@ -554,10 +554,7 @@ class GreasePencilMaterialsPanel:
|
||||
icon_link = 'MESH_DATA' if slot.link == 'DATA' else 'OBJECT_DATA'
|
||||
row.prop(slot, "link", icon=icon_link, icon_only=True)
|
||||
|
||||
if is_grease_pencil_version3 and ob.mode == 'EDIT':
|
||||
row = layout.row(align=True)
|
||||
row.operator("grease_pencil.stroke_change_color", text="Assign")
|
||||
elif not is_grease_pencil_version3 and ob.data.use_stroke_edit_mode:
|
||||
if not is_grease_pencil_version3 and ob.data.use_stroke_edit_mode:
|
||||
row = layout.row(align=True)
|
||||
row.operator("gpencil.stroke_change_color", text="Assign")
|
||||
row.operator("gpencil.material_select", text="Select").deselect = False
|
||||
|
@ -183,7 +183,7 @@ class EEVEE_MATERIAL_PT_volume(MaterialButtonsPanel, Panel):
|
||||
bl_translation_context = i18n_contexts.id_id
|
||||
bl_context = "material"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@ -201,29 +201,6 @@ class EEVEE_MATERIAL_PT_volume(MaterialButtonsPanel, Panel):
|
||||
panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Volume")
|
||||
|
||||
|
||||
class EEVEE_MATERIAL_PT_displacement(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Displacement"
|
||||
bl_translation_context = i18n_contexts.id_id
|
||||
bl_context = "material"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
engine = context.engine
|
||||
mat = context.material
|
||||
return mat and mat.use_nodes and (engine in cls.COMPAT_ENGINES) and not mat.grease_pencil
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.use_property_split = True
|
||||
|
||||
mat = context.material
|
||||
|
||||
panel_node_draw(layout, mat.node_tree, 'OUTPUT_MATERIAL', "Displacement")
|
||||
|
||||
|
||||
def draw_material_settings(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
@ -279,56 +256,21 @@ class EEVEE_NEXT_MATERIAL_PT_settings(MaterialButtonsPanel, Panel):
|
||||
|
||||
mat = context.material
|
||||
|
||||
layout.prop(mat, "use_backface_culling")
|
||||
layout.prop(mat, "blend_method")
|
||||
layout.prop(mat, "shadow_method")
|
||||
|
||||
row = layout.row()
|
||||
row.active = ((mat.blend_method == 'CLIP') or (mat.shadow_method == 'CLIP'))
|
||||
row.prop(mat, "alpha_threshold")
|
||||
|
||||
if mat.blend_method not in {'OPAQUE', 'CLIP', 'HASHED'}:
|
||||
layout.prop(mat, "show_transparent_back")
|
||||
|
||||
layout.prop(mat, "use_screen_refraction")
|
||||
layout.prop(mat, "pass_index")
|
||||
|
||||
|
||||
class EEVEE_NEXT_MATERIAL_PT_settings_surface(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Surface"
|
||||
bl_context = "material"
|
||||
bl_parent_id = "EEVEE_NEXT_MATERIAL_PT_settings"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
mat = context.material
|
||||
|
||||
col = layout.column(heading="Backface Culling")
|
||||
col.prop(mat, "use_backface_culling", text="Camera")
|
||||
col.prop(mat, "use_backface_culling_shadow", text="Shadow")
|
||||
|
||||
# TODO(fclem): Displacement option
|
||||
# TODO(fclem): Transparent shadow option
|
||||
|
||||
col = layout.column()
|
||||
col.prop(mat, "surface_render_method", text="Render Method")
|
||||
if mat.surface_render_method == 'BLENDED':
|
||||
col.prop(mat, "show_transparent_back", text="Transparency Overlap")
|
||||
elif mat.surface_render_method == 'DITHERED':
|
||||
col.prop(mat, "use_screen_refraction", text="Raytraced Refraction")
|
||||
|
||||
col = layout.column(heading="Light Probe Volume")
|
||||
col.prop(mat, "lightprobe_volume_single_sided", text="Single Sided")
|
||||
|
||||
|
||||
class EEVEE_NEXT_MATERIAL_PT_settings_volume(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Volume"
|
||||
bl_context = "material"
|
||||
bl_parent_id = "EEVEE_NEXT_MATERIAL_PT_settings"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
mat = context.material
|
||||
|
||||
layout.prop(mat, "volume_intersection_method", text="Intersection")
|
||||
|
||||
|
||||
class MATERIAL_PT_viewport(MaterialButtonsPanel, Panel):
|
||||
bl_label = "Viewport Display"
|
||||
bl_context = "material"
|
||||
@ -396,11 +338,8 @@ classes = (
|
||||
EEVEE_MATERIAL_PT_context_material,
|
||||
EEVEE_MATERIAL_PT_surface,
|
||||
EEVEE_MATERIAL_PT_volume,
|
||||
EEVEE_MATERIAL_PT_displacement,
|
||||
EEVEE_MATERIAL_PT_settings,
|
||||
EEVEE_NEXT_MATERIAL_PT_settings,
|
||||
EEVEE_NEXT_MATERIAL_PT_settings_surface,
|
||||
EEVEE_NEXT_MATERIAL_PT_settings_volume,
|
||||
MATERIAL_PT_lineart,
|
||||
MATERIAL_PT_viewport,
|
||||
EEVEE_MATERIAL_PT_viewport_settings,
|
||||
|
@ -395,7 +395,6 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel):
|
||||
col = layout.column(heading="Light Probes")
|
||||
col.prop(ob, "hide_probe_volume", text="Volume", toggle=False, invert_checkbox=True)
|
||||
col.prop(ob, "hide_probe_cubemap", text="Cubemap", toggle=False, invert_checkbox=True)
|
||||
col.prop(ob, "hide_probe_planar", text="Planar", toggle=False, invert_checkbox=True)
|
||||
|
||||
if ob.type == 'GPENCIL':
|
||||
col = layout.column(heading="Grease Pencil")
|
||||
|
@ -82,8 +82,6 @@ class UnifiedPaintPanel:
|
||||
return tool_settings.gpencil_vertex_paint
|
||||
elif mode == 'SCULPT_CURVES':
|
||||
return tool_settings.curves_sculpt
|
||||
elif mode == 'PAINT_GREASE_PENCIL':
|
||||
return tool_settings.gpencil_paint
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
@ -868,11 +866,6 @@ def brush_shared_settings(layout, context, brush, popover=False):
|
||||
strength = True
|
||||
direction = brush.curves_sculpt_tool in {'GROW_SHRINK', 'SELECTION_PAINT'}
|
||||
|
||||
# Grease Pencil #
|
||||
if mode == 'PAINT_GREASE_PENCIL':
|
||||
size = True
|
||||
strength = True
|
||||
|
||||
### Draw settings. ###
|
||||
ups = context.scene.tool_settings.unified_paint_settings
|
||||
|
||||
|
@ -177,8 +177,8 @@ class RENDER_PT_eevee_ambient_occlusion(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "use_gtao_bounce")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_horizon_scan(RenderButtonsPanel, Panel):
|
||||
bl_label = "Horizon Scan"
|
||||
class RENDER_PT_eevee_next_ambient_occlusion(RenderButtonsPanel, Panel):
|
||||
bl_label = "Ambient Occlusion"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@ -193,7 +193,8 @@ class RENDER_PT_eevee_next_horizon_scan(RenderButtonsPanel, Panel):
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "gtao_quality", text="Precision")
|
||||
col.prop(props, "gtao_distance")
|
||||
col.prop(props, "gtao_quality")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_motion_blur(RenderButtonsPanel, Panel):
|
||||
@ -255,7 +256,7 @@ class RENDER_PT_eevee_next_motion_blur(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "motion_blur_steps", text="Steps")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_motion_blur_curve(RenderButtonsPanel, Panel):
|
||||
class RENDER_PT_motion_blur_curve(RenderButtonsPanel, Panel):
|
||||
bl_label = "Shutter Curve"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_motion_blur"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@ -437,8 +438,8 @@ class RENDER_PT_eevee_volumetric_shadows(RenderButtonsPanel, Panel):
|
||||
layout.prop(props, "volumetric_shadow_samples", text="Samples")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_volumes(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumes"
|
||||
class RENDER_PT_eevee_next_volumetric(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumetrics"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@ -461,12 +462,11 @@ class RENDER_PT_eevee_next_volumes(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "volumetric_tile_size")
|
||||
col.prop(props, "volumetric_samples")
|
||||
col.prop(props, "volumetric_sample_distribution", text="Distribution")
|
||||
col.prop(props, "volumetric_ray_depth", text="Max Depth")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_volumes_lighting(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumes Lighting"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_volumes"
|
||||
class RENDER_PT_eevee_next_volumetric_lighting(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumetric Lighting"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_volumetric"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
@ -485,9 +485,9 @@ class RENDER_PT_eevee_next_volumes_lighting(RenderButtonsPanel, Panel):
|
||||
layout.prop(props, "volumetric_light_clamp", text="Light Clamping")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_volumes_shadows(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumes Shadows"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_volumes"
|
||||
class RENDER_PT_eevee_next_volumetric_shadows(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volumetric Shadows"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_volumetric"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw_header(self, context):
|
||||
@ -639,11 +639,11 @@ class EeveeRaytracingDenoisePanel(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "denoise_spatial")
|
||||
|
||||
col = layout.column()
|
||||
col.active = props.use_denoise and props.denoise_spatial
|
||||
col.active = props.denoise_spatial
|
||||
col.prop(props, "denoise_temporal")
|
||||
|
||||
col = layout.column()
|
||||
col.active = props.use_denoise and props.denoise_spatial and props.denoise_temporal
|
||||
col.active = props.denoise_spatial and props.denoise_temporal
|
||||
col.prop(props, "denoise_bilateral")
|
||||
|
||||
|
||||
@ -655,7 +655,7 @@ class RENDER_PT_eevee_next_raytracing_reflection(EeveeRaytracingOptionsPanel):
|
||||
def draw_header(self, context):
|
||||
layout = self.layout
|
||||
if context.scene.eevee.ray_split_settings == 'UNIFIED':
|
||||
layout.label(text="Reflection / Refraction / Diffuse")
|
||||
layout.label(text="Reflection & Refraction & Diffuse")
|
||||
else:
|
||||
layout.label(text="Reflection")
|
||||
|
||||
@ -762,26 +762,6 @@ class RENDER_PT_eevee_shadows(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "light_threshold")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_lights(RenderButtonsPanel, Panel):
|
||||
bl_label = "Lights"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
|
||||
scene = context.scene
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "light_threshold")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_shadows(RenderButtonsPanel, Panel):
|
||||
bl_label = "Shadows"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@ -805,13 +785,10 @@ class RENDER_PT_eevee_next_shadows(RenderButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "shadow_pool_size", text="Pool Size")
|
||||
|
||||
col = layout.column(heading="Tracing", align=True)
|
||||
col.prop(props, "shadow_ray_count", text="Rays")
|
||||
col.prop(props, "shadow_step_count", text="Steps")
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "shadow_normal_bias", text="Normal Bias")
|
||||
col.prop(props, "shadow_ray_count")
|
||||
col.prop(props, "shadow_step_count")
|
||||
col.prop(props, "shadow_normal_bias")
|
||||
col.prop(props, "light_threshold")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_sampling(RenderButtonsPanel, Panel):
|
||||
@ -842,43 +819,6 @@ class RENDER_PT_eevee_next_sampling(RenderButtonsPanel, Panel):
|
||||
bl_label = "Sampling"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_sampling_viewport(RenderButtonsPanel, Panel):
|
||||
bl_label = "Viewport"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_sampling"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
scene = context.scene
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "taa_samples", text="Samples")
|
||||
col.prop(props, "use_taa_reprojection", text="Temporal Reprojection")
|
||||
|
||||
# Add SSS sample count here.
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_sampling_render(RenderButtonsPanel, Panel):
|
||||
bl_label = "Render"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_sampling"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
@ -892,9 +832,11 @@ class RENDER_PT_eevee_next_sampling_render(RenderButtonsPanel, Panel):
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(props, "taa_render_samples", text="Samples")
|
||||
col.prop(props, "taa_render_samples", text="Render")
|
||||
col.prop(props, "taa_samples", text="Viewport")
|
||||
|
||||
# Add SSS sample count here.
|
||||
col = layout.column()
|
||||
col.prop(props, "use_taa_reprojection")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
|
||||
@ -916,7 +858,7 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
|
||||
|
||||
col = layout.column()
|
||||
col.operator("scene.light_cache_bake", text="Bake Indirect Lighting", icon='RENDER_STILL')
|
||||
col.operator("scene.light_cache_bake", text="Bake Cubemap Only", icon='LIGHTPROBE_SPHERE').subset = 'CUBEMAPS'
|
||||
col.operator("scene.light_cache_bake", text="Bake Cubemap Only", icon='LIGHTPROBE_CUBEMAP').subset = 'CUBEMAPS'
|
||||
col.operator("scene.light_cache_free", text="Delete Lighting Cache")
|
||||
|
||||
cache_info = scene.eevee.gi_cache_info
|
||||
@ -933,24 +875,11 @@ class RENDER_PT_eevee_indirect_lighting(RenderButtonsPanel, Panel):
|
||||
col.prop(props, "gi_filter_quality")
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_light_probes(RenderButtonsPanel, Panel):
|
||||
bl_label = "Light Probes"
|
||||
class RENDER_PT_eevee_next_indirect_lighting(RenderButtonsPanel, Panel):
|
||||
bl_label = "Indirect Lighting"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_light_probes_sphere(RenderButtonsPanel, Panel):
|
||||
bl_label = "Sphere"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_light_probes"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
@ -964,33 +893,11 @@ class RENDER_PT_eevee_next_light_probes_sphere(RenderButtonsPanel, Panel):
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "gi_cubemap_resolution", text="Resolution")
|
||||
col.operator("object.lightprobe_cache_bake", text="Bake Light Caches", icon='RENDER_STILL').subset = 'ALL'
|
||||
col.operator("object.lightprobe_cache_free", text="Delete Light Caches").subset = 'ALL'
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_light_probes_volume(RenderButtonsPanel, Panel):
|
||||
bl_label = "Volume"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_light_probes"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
scene = context.scene
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(props, "gi_irradiance_pool_size", text="Pool Size")
|
||||
|
||||
row = col.row(align=True)
|
||||
row.operator("object.lightprobe_cache_bake", text="Bake Volumes").subset = 'ALL'
|
||||
row.operator("object.lightprobe_cache_free", text="", icon='TRASH').subset = 'ALL'
|
||||
|
||||
|
||||
class RENDER_PT_eevee_indirect_lighting_display(RenderButtonsPanel, Panel):
|
||||
bl_label = "Display"
|
||||
@ -1018,6 +925,28 @@ class RENDER_PT_eevee_indirect_lighting_display(RenderButtonsPanel, Panel):
|
||||
row.prop(props, "gi_show_irradiance", text="", toggle=True)
|
||||
|
||||
|
||||
class RENDER_PT_eevee_next_indirect_lighting_display(RenderButtonsPanel, Panel):
|
||||
bl_label = "Display"
|
||||
bl_parent_id = "RENDER_PT_eevee_next_indirect_lighting"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return (context.engine in cls.COMPAT_ENGINES)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
scene = context.scene
|
||||
props = scene.eevee
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(props, "gi_irradiance_display_size", text="Irradiance Size")
|
||||
row.prop(props, "gi_show_irradiance", text="", toggle=True)
|
||||
|
||||
|
||||
class RENDER_PT_eevee_film(RenderButtonsPanel, Panel):
|
||||
bl_label = "Film"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
@ -1337,15 +1266,13 @@ classes = (
|
||||
RENDER_PT_context,
|
||||
RENDER_PT_eevee_sampling,
|
||||
RENDER_PT_eevee_next_sampling,
|
||||
RENDER_PT_eevee_next_sampling_viewport,
|
||||
RENDER_PT_eevee_next_sampling_render,
|
||||
RENDER_PT_eevee_ambient_occlusion,
|
||||
RENDER_PT_eevee_next_ambient_occlusion,
|
||||
RENDER_PT_eevee_bloom,
|
||||
RENDER_PT_eevee_depth_of_field,
|
||||
RENDER_PT_eevee_next_depth_of_field,
|
||||
RENDER_PT_eevee_subsurface_scattering,
|
||||
RENDER_PT_eevee_screen_space_reflections,
|
||||
RENDER_PT_eevee_next_horizon_scan,
|
||||
RENDER_PT_eevee_next_raytracing,
|
||||
RENDER_PT_eevee_next_raytracing_reflection,
|
||||
RENDER_PT_eevee_next_raytracing_refraction,
|
||||
@ -1357,25 +1284,23 @@ classes = (
|
||||
RENDER_PT_eevee_next_denoise_refraction,
|
||||
RENDER_PT_eevee_next_denoise_diffuse,
|
||||
RENDER_PT_eevee_motion_blur,
|
||||
RENDER_PT_eevee_next_motion_blur,
|
||||
RENDER_PT_motion_blur_curve,
|
||||
RENDER_PT_eevee_volumetric,
|
||||
RENDER_PT_eevee_volumetric_lighting,
|
||||
RENDER_PT_eevee_volumetric_shadows,
|
||||
RENDER_PT_eevee_next_volumes,
|
||||
RENDER_PT_eevee_next_volumes_lighting,
|
||||
RENDER_PT_eevee_next_volumes_shadows,
|
||||
RENDER_PT_eevee_next_volumetric,
|
||||
RENDER_PT_eevee_next_volumetric_lighting,
|
||||
RENDER_PT_eevee_next_volumetric_shadows,
|
||||
RENDER_PT_eevee_performance,
|
||||
RENDER_PT_eevee_hair,
|
||||
RENDER_PT_eevee_shadows,
|
||||
RENDER_PT_eevee_next_lights,
|
||||
RENDER_PT_eevee_next_shadows,
|
||||
RENDER_PT_eevee_indirect_lighting,
|
||||
RENDER_PT_eevee_indirect_lighting_display,
|
||||
RENDER_PT_eevee_next_light_probes,
|
||||
RENDER_PT_eevee_next_light_probes_sphere,
|
||||
RENDER_PT_eevee_next_light_probes_volume,
|
||||
RENDER_PT_eevee_next_indirect_lighting,
|
||||
RENDER_PT_eevee_next_indirect_lighting_display,
|
||||
RENDER_PT_eevee_film,
|
||||
RENDER_PT_eevee_next_motion_blur,
|
||||
RENDER_PT_eevee_next_motion_blur_curve,
|
||||
RENDER_PT_eevee_next_film,
|
||||
|
||||
|
||||
|
@ -125,7 +125,7 @@ class VIEWLAYER_PT_workbench_layer_passes_data(ViewLayerButtonsPanel, Panel):
|
||||
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Light"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@ -155,44 +155,6 @@ class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
|
||||
text="Ambient Occlusion")
|
||||
|
||||
|
||||
class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Light"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
view_layer = context.view_layer
|
||||
view_layer_eevee = view_layer.eevee
|
||||
|
||||
col = layout.column(heading="Diffuse", align=True)
|
||||
col.prop(view_layer, "use_pass_diffuse_direct", text="Light")
|
||||
col.prop(view_layer, "use_pass_diffuse_color", text="Color")
|
||||
|
||||
col = layout.column(heading="Specular", align=True)
|
||||
col.prop(view_layer, "use_pass_glossy_direct", text="Light")
|
||||
col.prop(view_layer, "use_pass_glossy_color", text="Color")
|
||||
|
||||
col = layout.column(heading="Volume", heading_ctxt=i18n_contexts.id_id, align=True)
|
||||
col.prop(view_layer_eevee, "use_pass_volume_direct", text="Light")
|
||||
|
||||
col = layout.column(heading="Other", align=True)
|
||||
col.prop(view_layer, "use_pass_emit", text="Emission")
|
||||
col.prop(view_layer, "use_pass_environment")
|
||||
col.prop(view_layer, "use_pass_shadow")
|
||||
col.prop(view_layer, "use_pass_ambient_occlusion",
|
||||
text="Ambient Occlusion")
|
||||
|
||||
col = layout.column()
|
||||
col.active = view_layer.use_pass_ambient_occlusion
|
||||
# TODO Move to view layer.
|
||||
col.prop(context.scene.eevee, "gtao_distance", text="Occlusion Distance")
|
||||
|
||||
|
||||
class VIEWLAYER_PT_eevee_layer_passes_effects(ViewLayerButtonsPanel, Panel):
|
||||
bl_label = "Effects"
|
||||
bl_parent_id = "VIEWLAYER_PT_layer_passes"
|
||||
|
@ -149,7 +149,7 @@ class EEVEE_WORLD_PT_volume(WorldButtonsPanel, Panel):
|
||||
|
||||
|
||||
class EEVEE_WORLD_PT_probe(WorldButtonsPanel, Panel):
|
||||
bl_label = "Light Probe"
|
||||
bl_label = "Probe"
|
||||
bl_translation_context = i18n_contexts.id_id
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
COMPAT_ENGINES = {'BLENDER_EEVEE_NEXT'}
|
||||
|
@ -841,7 +841,7 @@ class DOPESHEET_PT_gpencil_mode(LayersDopeSheetPanel, Panel):
|
||||
row.prop(gpl, "opacity", text="Opacity", slider=True)
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "use_lights", text="Lights")
|
||||
row.prop(gpl, "use_lights")
|
||||
|
||||
|
||||
class DOPESHEET_PT_gpencil_layer_masks(LayersDopeSheetPanel, GreasePencilLayerMasksPanel, Panel):
|
||||
|
@ -991,19 +991,16 @@ class NODE_PT_node_tree_properties(Panel):
|
||||
col.prop(group, "is_tool")
|
||||
|
||||
|
||||
def draw_socket_item_in_list(uilist, layout, item, icon):
|
||||
if uilist.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
row = layout.row(align=True)
|
||||
row.template_node_socket(color=item.color)
|
||||
row.prop(item, "name", text="", emboss=False, icon_value=icon)
|
||||
elif uilist.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.template_node_socket(color=item.color)
|
||||
|
||||
|
||||
class NODE_UL_simulation_zone_items(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||
draw_socket_item_in_list(self, layout, item, icon)
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
row = layout.row(align=True)
|
||||
|
||||
row.template_node_socket(color=item.color)
|
||||
row.prop(item, "name", text="", emboss=False, icon_value=icon)
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.template_node_socket(color=item.color)
|
||||
|
||||
|
||||
class NODE_PT_simulation_zone_items(Panel):
|
||||
@ -1075,7 +1072,13 @@ class NODE_PT_simulation_zone_items(Panel):
|
||||
|
||||
class NODE_UL_repeat_zone_items(bpy.types.UIList):
|
||||
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||
draw_socket_item_in_list(self, layout, item, icon)
|
||||
if self.layout_type in {'DEFAULT', 'COMPACT'}:
|
||||
row = layout.row(align=True)
|
||||
row.template_node_socket(color=item.color)
|
||||
row.prop(item, "name", text="", emboss=False, icon_value=icon)
|
||||
elif self.layout_type == 'GRID':
|
||||
layout.alignment = 'CENTER'
|
||||
layout.template_node_socket(color=item.color)
|
||||
|
||||
|
||||
class NODE_PT_repeat_zone_items(Panel):
|
||||
|
@ -366,16 +366,6 @@ class _defs_transform:
|
||||
draw_settings=draw_settings,
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def bend():
|
||||
return dict(
|
||||
idname="builtin.bend",
|
||||
label="Bend",
|
||||
icon="ops.gpencil.edit_bend",
|
||||
widget=None,
|
||||
keymap="3D View Tool: Bend",
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def transform():
|
||||
def draw_settings(context, layout, tool):
|
||||
@ -1754,11 +1744,21 @@ class _defs_paint_grease_pencil:
|
||||
|
||||
@ToolDef.from_fn
|
||||
def erase():
|
||||
def draw_settings(context, layout, _tool):
|
||||
paint = context.tool_settings.gpencil_paint
|
||||
brush = paint.brush
|
||||
if not brush:
|
||||
return
|
||||
layout.prop(brush.gpencil_settings, "eraser_mode", expand=True)
|
||||
if brush.gpencil_settings.eraser_mode == 'HARD':
|
||||
layout.prop(brush.gpencil_settings, "use_keep_caps_eraser")
|
||||
layout.prop(brush.gpencil_settings, "use_active_layer_only")
|
||||
return dict(
|
||||
idname="builtin_brush.Erase",
|
||||
label="Erase",
|
||||
icon="brush.gpencil_draw.erase",
|
||||
data_block='ERASE',
|
||||
draw_settings=draw_settings,
|
||||
)
|
||||
|
||||
|
||||
@ -3022,18 +3022,6 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel):
|
||||
],
|
||||
'EDIT_GREASE_PENCIL': [
|
||||
*_tools_select,
|
||||
_defs_view3d_generic.cursor,
|
||||
None,
|
||||
*_tools_transform,
|
||||
None,
|
||||
_defs_edit_curve.curve_radius,
|
||||
_defs_transform.bend,
|
||||
(
|
||||
_defs_transform.shear,
|
||||
_defs_edit_mesh.tosphere,
|
||||
),
|
||||
None,
|
||||
*_tools_annotate,
|
||||
],
|
||||
'PARTICLE': [
|
||||
*_tools_select,
|
||||
|
@ -159,7 +159,7 @@ class TOPBAR_PT_gpencil_layers(Panel):
|
||||
icon='MOD_MASK' if gpl.use_mask_layer else 'LAYER_ACTIVE')
|
||||
|
||||
srow = col.row(align=True)
|
||||
srow.prop(gpl, "use_lights", text="Lights")
|
||||
srow.prop(gpl, "use_lights")
|
||||
|
||||
col = row.column()
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user