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:
Brecht Van Lommel 2023-10-30 21:38:10 +01:00
parent b26f176d1a
commit 39107b3133
1348 changed files with 18793 additions and 33630 deletions

@ -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

@ -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)

@ -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")

@ -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)

@ -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