Merge branch 'master' into temp-pbvh-vbos
This commit is contained in:
256
CMakeLists.txt
256
CMakeLists.txt
@@ -1022,9 +1022,9 @@ if(WITH_CPU_SIMD)
|
||||
set(COMPILER_SSE2_FLAG)
|
||||
|
||||
# Test Neon first since macOS Arm can compile and run x86-64 SSE binaries.
|
||||
TEST_NEON_SUPPORT()
|
||||
test_neon_support()
|
||||
if(NOT SUPPORT_NEON_BUILD)
|
||||
TEST_SSE_SUPPORT(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
test_sse_support(COMPILER_SSE_FLAG COMPILER_SSE2_FLAG)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1089,7 +1089,7 @@ if(WITH_INTERNATIONAL)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Enable SIMD support if detected by TEST_SSE_SUPPORT() or TEST_NEON_SUPPORT().
|
||||
# Enable SIMD support if detected by `test_sse_support()` or `test_neon_support()`.
|
||||
#
|
||||
# This is done globally, so that all modules can use it if available, and
|
||||
# because these are used in headers used by many modules.
|
||||
@@ -1097,7 +1097,7 @@ if(WITH_CPU_SIMD)
|
||||
if(SUPPORT_NEON_BUILD)
|
||||
# Neon
|
||||
if(SSE2NEON_FOUND)
|
||||
blender_include_dirs_sys("${SSE2NEON_INCLUDE_DIRS}")
|
||||
include_directories(SYSTEM "${SSE2NEON_INCLUDE_DIRS}")
|
||||
add_definitions(-DWITH_SSE2NEON)
|
||||
endif()
|
||||
else()
|
||||
@@ -1271,7 +1271,11 @@ endif()
|
||||
# Configure Python
|
||||
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_definitions(-DPy_ENABLE_SHARED)
|
||||
# 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()
|
||||
|
||||
|
||||
@@ -1399,89 +1403,89 @@ endif()
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_VLA -Werror=vla)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_VLA -Werror=vla)
|
||||
# system headers sometimes do this, disable for now, was: -Werror=strict-prototypes
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNDEF -Wundef)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_RESTRICT -Wrestrict)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_LOGICAL_OP -Wlogical-op)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_UNDEF -Wundef)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_RESTRICT -Wrestrict)
|
||||
|
||||
# C-only.
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_NULL -Wnonnull)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ABSOLUTE_VALUE -Wabsolute-value)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_NULL -Wnonnull)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ABSOLUTE_VALUE -Wabsolute-value)
|
||||
|
||||
# gcc 4.2 gives annoying warnings on every file with this
|
||||
if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.3")
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
|
||||
endif()
|
||||
|
||||
# versions before gcc4.6 give many BLI_math warnings
|
||||
if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.6")
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_REDUNDANT_DECLS -Wredundant-decls)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_REDUNDANT_DECLS -Wredundant-decls)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_REDUNDANT_DECLS -Wredundant-decls)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_REDUNDANT_DECLS -Wredundant-decls)
|
||||
endif()
|
||||
|
||||
# versions before gcc4.8 include global name-space.
|
||||
if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.8")
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_SHADOW -Wshadow)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_SHADOW -Wshadow)
|
||||
endif()
|
||||
|
||||
# disable because it gives warnings for printf() & friends.
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
|
||||
# add_check_c_compiler_flag(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
|
||||
|
||||
if(NOT APPLE)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
|
||||
endif()
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_TYPE_LIMITS -Wtype-limits)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_FORMAT_SIGN -Wformat-signedness)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_LOGICAL_OP -Wlogical-op)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_TYPE_LIMITS -Wtype-limits)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_WRITE_STRINGS -Wwrite-strings)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_FORMAT_SIGN -Wformat-signedness)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
|
||||
|
||||
# gcc 4.2 gives annoying warnings on every file with this
|
||||
if(NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.3")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized)
|
||||
endif()
|
||||
|
||||
# causes too many warnings
|
||||
if(NOT APPLE)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNDEF -Wundef)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_MISSING_DECLARATIONS -Wmissing-declarations)
|
||||
endif()
|
||||
|
||||
# Use 'ATTR_FALLTHROUGH' macro to suppress.
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "7.0"))
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_IMPLICIT_FALLTHROUGH -Wimplicit-fallthrough=5)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1497,102 +1501,102 @@ if(CMAKE_COMPILER_IS_GNUCC)
|
||||
# If code in `./extern/` needs to suppress these flags that can be done on a case-by-case basis.
|
||||
|
||||
# flags to undo strict flags
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_TYPE_LIMITS -Wno-type-limits)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_IN_BOOL_CONTEXT -Wno-int-in-bool-context)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_FORMAT -Wno-format)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_SWITCH -Wno-switch)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_TYPE_LIMITS -Wno-type-limits)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_IN_BOOL_CONTEXT -Wno-int-in-bool-context)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_FORMAT -Wno-format)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_SWITCH -Wno-switch)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CLASS_MEMACCESS -Wno-class-memaccess)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CLASS_MEMACCESS -Wno-class-memaccess)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-uninitialized)
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCC AND (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "7.0"))
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_IMPLICIT_FALLTHROUGH -Wno-implicit-fallthrough)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_IMPLICIT_FALLTHROUGH -Wno-implicit-fallthrough)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_ERROR_UNUSED_BUT_SET_VARIABLE -Wno-error=unused-but-set-variable)
|
||||
endif()
|
||||
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
|
||||
# strange, clang complains these are not supported, but then uses them.
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_IMPLICIT_FUNCTION_DECLARATION -Werror=implicit-function-declaration)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ERROR_RETURN_TYPE -Werror=return-type)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_STRICT_PROTOTYPES -Wstrict-prototypes)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_MISSING_PROTOTYPES -Wmissing-prototypes)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_PARAMETER -Wunused-parameter)
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
# Using C++20 features while having C++17 as the project language isn't allowed by MSVC.
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_CXX20_DESIGNATOR -Wc++20-designator)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_CXX20_DESIGNATOR -Wc++20-designator)
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_AUTOLOGICAL_COMPARE -Wno-tautological-compare)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_CHAR_SUBSCRIPTS -Wno-char-subscripts)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_OVERLOADED_VIRTUAL -Wno-overloaded-virtual) # we get a lot of these, if its a problem a dev needs to look into it.
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
# Apple Clang (tested on version 12) doesn't support this flag while LLVM Clang 11 does.
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override)
|
||||
|
||||
# gives too many unfixable warnings
|
||||
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
# add_check_c_compiler_flag(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
# add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
|
||||
|
||||
# ---------------------
|
||||
# Suppress Strict Flags
|
||||
|
||||
# flags to undo strict flags
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
|
||||
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INCOMPAT_PTR_DISCARD_QUAL -Wno-incompatible-pointer-types-discards-qualifiers)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_TO_VOID_POINTER_CAST -Wno-int-to-void-pointer-cast)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_PROTOTYPES -Wno-missing-prototypes)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DUPLICATE_ENUM -Wno-duplicate-enum)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNDEF -Wno-undef)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_NORETURN -Wno-missing-noreturn)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_VARIABLE_DECLARATIONS -Wno-missing-variable-declarations)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INCOMPAT_PTR_DISCARD_QUAL -Wno-incompatible-pointer-types-discards-qualifiers)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_FUNCTION -Wno-unused-function)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_INT_TO_VOID_POINTER_CAST -Wno-int-to-void-pointer-cast)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_PROTOTYPES -Wno-missing-prototypes)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DUPLICATE_ENUM -Wno-duplicate-enum)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNDEF -Wno-undef)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_MISSING_NORETURN -Wno-missing-noreturn)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_BUT_SET_VARIABLE -Wno-unused-but-set-variable)
|
||||
add_check_c_compiler_flag(C_REMOVE_STRICT_FLAGS C_WARN_NO_DEPRECATED_DECLARATIONS -Wno-deprecated-declarations)
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PRIVATE_FIELD -Wno-unused-private-field)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CXX11_NARROWING -Wno-c++11-narrowing)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_NON_VIRTUAL_DTOR -Wno-non-virtual-dtor)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_REORDER -Wno-reorder)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNDEFINED_VAR_TEMPLATE -Wno-undefined-var-template)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_INSTANTIATION_AFTER_SPECIALIZATION -Wno-instantiation-after-specialization)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_PRIVATE_FIELD -Wno-unused-private-field)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_CXX11_NARROWING -Wno-c++11-narrowing)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_NON_VIRTUAL_DTOR -Wno-non-virtual-dtor)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_VARIABLE -Wno-unused-variable)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_REORDER -Wno-reorder)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_COMMENT -Wno-comment)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNUSED_TYPEDEFS -Wno-unused-local-typedefs)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_UNDEFINED_VAR_TEMPLATE -Wno-undefined-var-template)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_INSTANTIATION_AFTER_SPECIALIZATION -Wno-instantiation-after-specialization)
|
||||
add_check_cxx_compiler_flag(CXX_REMOVE_STRICT_FLAGS CXX_WARN_NO_MISLEADING_INDENTATION -Wno-misleading-indentation)
|
||||
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_ALL -Wall)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_POINTER_ARITH -Wpointer-arith)
|
||||
add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_UNKNOWN_PRAGMAS -Wno-unknown-pragmas)
|
||||
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_ALL -Wall)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_INVALID_OFFSETOF -Wno-invalid-offsetof)
|
||||
add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare)
|
||||
|
||||
# disable numbered, false positives
|
||||
string(APPEND C_WARNINGS " -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199")
|
||||
@@ -1705,8 +1709,8 @@ endif()
|
||||
|
||||
if(WITH_COMPILER_SHORT_FILE_MACRO)
|
||||
# Use '-fmacro-prefix-map' for Clang and GCC (MSVC doesn't support this).
|
||||
ADD_CHECK_C_COMPILER_FLAG(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CXX_PREFIX_MAP_FLAGS CXX_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
|
||||
add_check_c_compiler_flag(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
|
||||
add_check_cxx_compiler_flag(CXX_PREFIX_MAP_FLAGS CXX_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar)
|
||||
if(C_MACRO_PREFIX_MAP AND CXX_MACRO_PREFIX_MAP)
|
||||
if(APPLE)
|
||||
if(XCODE AND ${XCODE_VERSION} VERSION_LESS 12.0)
|
||||
|
@@ -364,7 +364,7 @@ all: .FORCE
|
||||
$(BUILD_COMMAND) -C "$(BUILD_DIR)" -j $(NPROCS) install
|
||||
@echo
|
||||
@echo Edit build configuration with: \"$(BUILD_DIR)/CMakeCache.txt\" run make again to rebuild.
|
||||
@if test "$(BLENDER_IS_PYTHON_MODULE)" == ""; then \
|
||||
@if test -z "$(BLENDER_IS_PYTHON_MODULE)"; then \
|
||||
echo Blender successfully built, run from: $(BLENDER_BIN); \
|
||||
else \
|
||||
echo Blender successfully built as a Python module, \"bpy\" can be imported from: $(BLENDER_BIN_DIR); \
|
||||
|
@@ -40,12 +40,10 @@ macro(BLENDER_SRC_GTEST_EX)
|
||||
set(MANIFEST "${CMAKE_BINARY_DIR}/tests.exe.manifest")
|
||||
endif()
|
||||
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
|
||||
add_executable(${TARGET_NAME} ${ARG_SRC} ${MANIFEST})
|
||||
setup_platform_linker_flags(${TARGET_NAME})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE ${GFLAGS_DEFINES})
|
||||
target_compile_definitions(${TARGET_NAME} PRIVATE ${GLOG_DEFINES})
|
||||
target_include_directories(${TARGET_NAME} PUBLIC "${TEST_INC}")
|
||||
target_include_directories(${TARGET_NAME} SYSTEM PUBLIC "${TEST_INC_SYS}")
|
||||
target_link_libraries(${TARGET_NAME} ${ARG_EXTRA_LIBS} ${PLATFORM_LINKLIBS})
|
||||
|
@@ -150,10 +150,10 @@ endif()
|
||||
# BUILD_PLATFORM is taken from CMake
|
||||
# but BUILD_DATE and BUILD_TIME are platform dependent
|
||||
if(NOT BUILD_DATE)
|
||||
STRING(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC)
|
||||
string(TIMESTAMP BUILD_DATE "%Y-%m-%d" UTC)
|
||||
endif()
|
||||
if(NOT BUILD_TIME)
|
||||
STRING(TIMESTAMP BUILD_TIME "%H:%M:%S" UTC)
|
||||
string(TIMESTAMP BUILD_TIME "%H:%M:%S" UTC)
|
||||
endif()
|
||||
|
||||
# Write a file with the BUILD_HASH define
|
||||
|
@@ -134,12 +134,11 @@ endfunction()
|
||||
|
||||
# Nicer makefiles with -I/1/foo/ instead of -I/1/2/3/../../foo/
|
||||
# use it instead of include_directories()
|
||||
function(blender_include_dirs
|
||||
includes
|
||||
)
|
||||
function(absolute_include_dirs
|
||||
includes_absolute)
|
||||
|
||||
set(_ALL_INCS "")
|
||||
foreach(_INC ${ARGV})
|
||||
foreach(_INC ${ARGN})
|
||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||
list(APPEND _ALL_INCS ${_ABS_INC})
|
||||
# for checking for invalid includes, disable for regular use
|
||||
@@ -147,22 +146,24 @@ function(blender_include_dirs
|
||||
# message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
|
||||
# endif()
|
||||
endforeach()
|
||||
include_directories(${_ALL_INCS})
|
||||
|
||||
set(${includes_absolute} ${_ALL_INCS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(blender_include_dirs_sys
|
||||
includes
|
||||
function(blender_target_include_dirs
|
||||
name
|
||||
)
|
||||
|
||||
set(_ALL_INCS "")
|
||||
foreach(_INC ${ARGV})
|
||||
get_filename_component(_ABS_INC ${_INC} ABSOLUTE)
|
||||
list(APPEND _ALL_INCS ${_ABS_INC})
|
||||
# if(NOT EXISTS "${_ABS_INC}/")
|
||||
# message(FATAL_ERROR "Include not found: ${_ABS_INC}/")
|
||||
# endif()
|
||||
endforeach()
|
||||
include_directories(SYSTEM ${_ALL_INCS})
|
||||
absolute_include_dirs(_ALL_INCS ${ARGN})
|
||||
target_include_directories(${name} PRIVATE ${_ALL_INCS})
|
||||
endfunction()
|
||||
|
||||
function(blender_target_include_dirs_sys
|
||||
name
|
||||
)
|
||||
|
||||
absolute_include_dirs(_ALL_INCS ${ARGN})
|
||||
target_include_directories(${name} SYSTEM PRIVATE ${_ALL_INCS})
|
||||
endfunction()
|
||||
|
||||
# Set include paths for header files included with "*.h" syntax.
|
||||
@@ -268,13 +269,11 @@ function(blender_add_lib__impl
|
||||
|
||||
# message(STATUS "Configuring library ${name}")
|
||||
|
||||
# include_directories(${includes})
|
||||
# include_directories(SYSTEM ${includes_sys})
|
||||
blender_include_dirs("${includes}")
|
||||
blender_include_dirs_sys("${includes_sys}")
|
||||
|
||||
add_library(${name} ${sources})
|
||||
|
||||
blender_target_include_dirs(${name} ${includes})
|
||||
blender_target_include_dirs_sys(${name} ${includes_sys})
|
||||
|
||||
# On Windows certain libraries have two sets of binaries: one for debug builds and one for
|
||||
# release builds. The root of this requirement goes into ABI, I believe, but that's outside
|
||||
# of a scope of this comment.
|
||||
@@ -382,7 +381,7 @@ function(blender_add_test_suite)
|
||||
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
# Figure out the release dir, as some tests need files from there.
|
||||
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
|
||||
get_blender_test_install_dir(TEST_INSTALL_DIR)
|
||||
if(APPLE)
|
||||
set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION})
|
||||
else()
|
||||
@@ -418,13 +417,6 @@ function(blender_add_test_lib
|
||||
library_deps
|
||||
)
|
||||
|
||||
# Not currently supported for Python module due to different required
|
||||
# Python link flags.
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_custom_target(${name})
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_cc_flags_custom_test(${name} PARENT_SCOPE)
|
||||
|
||||
# Otherwise external projects will produce warnings that we cannot fix.
|
||||
@@ -432,21 +424,21 @@ function(blender_add_test_lib
|
||||
|
||||
# This duplicates logic that's also in GTestTesting.cmake, macro BLENDER_SRC_GTEST_EX.
|
||||
# TODO(Sybren): deduplicate after the general approach in D7649 has been approved.
|
||||
LIST(APPEND includes
|
||||
list(APPEND includes
|
||||
${CMAKE_SOURCE_DIR}/tests/gtests
|
||||
)
|
||||
LIST(APPEND includes_sys
|
||||
list(APPEND includes_sys
|
||||
${GLOG_INCLUDE_DIRS}
|
||||
${GFLAGS_INCLUDE_DIRS}
|
||||
${CMAKE_SOURCE_DIR}/extern/gtest/include
|
||||
${CMAKE_SOURCE_DIR}/extern/gmock/include
|
||||
)
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
|
||||
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
|
||||
|
||||
target_compile_definitions(${name} PRIVATE ${GFLAGS_DEFINES})
|
||||
target_compile_definitions(${name} PRIVATE ${GLOG_DEFINES})
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
|
||||
|
||||
blender_add_test_suite(
|
||||
@@ -471,28 +463,21 @@ function(blender_add_test_executable
|
||||
library_deps
|
||||
)
|
||||
|
||||
# Not currently supported for Python module due to different required
|
||||
# Python link flags.
|
||||
if(WITH_PYTHON_MODULE)
|
||||
add_custom_target(${name})
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_cc_flags_custom_test(${name} PARENT_SCOPE)
|
||||
|
||||
## Otherwise external projects will produce warnings that we cannot fix.
|
||||
remove_strict_flags()
|
||||
|
||||
include_directories(${includes})
|
||||
include_directories(${includes_sys})
|
||||
|
||||
BLENDER_SRC_GTEST_EX(
|
||||
blender_src_gtest_ex(
|
||||
NAME ${name}
|
||||
SRC "${sources}"
|
||||
EXTRA_LIBS "${library_deps}"
|
||||
SKIP_ADD_TEST
|
||||
)
|
||||
|
||||
blender_target_include_dirs(${name}_test ${includes})
|
||||
blender_target_include_dirs_sys(${name}_test ${includes_sys})
|
||||
|
||||
blender_add_test_suite(
|
||||
TARGET ${name}_test
|
||||
SUITE_NAME ${name}
|
||||
@@ -527,6 +512,11 @@ function(setup_platform_linker_flags
|
||||
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS}")
|
||||
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " ${PLATFORM_LINKFLAGS_RELEASE}")
|
||||
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " ${PLATFORM_LINKFLAGS_DEBUG}")
|
||||
|
||||
get_target_property(target_type ${target} TYPE)
|
||||
if (target_type STREQUAL "EXECUTABLE")
|
||||
set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS_EXECUTABLE}")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Platform specific libraries for targets.
|
||||
@@ -774,7 +764,7 @@ function(ADD_CHECK_C_COMPILER_FLAG
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
CHECK_C_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
|
||||
check_c_compiler_flag("${_FLAG}" "${_CACHE_VAR}")
|
||||
if(${_CACHE_VAR})
|
||||
# message(STATUS "Using CFLAG: ${_FLAG}")
|
||||
set(${_CFLAGS} "${${_CFLAGS}} ${_FLAG}" PARENT_SCOPE)
|
||||
@@ -791,7 +781,7 @@ function(ADD_CHECK_CXX_COMPILER_FLAG
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
CHECK_CXX_COMPILER_FLAG("${_FLAG}" "${_CACHE_VAR}")
|
||||
check_cxx_compiler_flag("${_FLAG}" "${_CACHE_VAR}")
|
||||
if(${_CACHE_VAR})
|
||||
# message(STATUS "Using CXXFLAG: ${_FLAG}")
|
||||
set(${_CXXFLAGS} "${${_CXXFLAGS}} ${_FLAG}" PARENT_SCOPE)
|
||||
@@ -809,9 +799,11 @@ function(get_blender_version)
|
||||
# - BLENDER_VERSION_PATCH
|
||||
# - BLENDER_VERSION_CYCLE (alpha, beta, rc, release)
|
||||
|
||||
# So cmake depends on BKE_blender.h, beware of inf-loops!
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender_version.h.done)
|
||||
# So CMAKE depends on `BKE_blender.h`, beware of infinite-loops!
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h
|
||||
${CMAKE_BINARY_DIR}/source/blender/blenkernel/BKE_blender_version.h.done
|
||||
)
|
||||
|
||||
file(STRINGS ${CMAKE_SOURCE_DIR}/source/blender/blenkernel/BKE_blender_version.h _contents REGEX "^#define[ \t]+BLENDER_.*$")
|
||||
|
||||
|
@@ -17,9 +17,9 @@ set(CPACK_PACKAGE_VENDOR ${PROJECT_VENDOR})
|
||||
set(CPACK_PACKAGE_CONTACT ${PROJECT_CONTACT})
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING")
|
||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${MAJOR_VERSION}")
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${MINOR_VERSION}")
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${PATCH_VERSION}")
|
||||
|
||||
|
||||
# Get the build revision, note that this can get out-of-sync, so for packaging run cmake first.
|
||||
|
@@ -352,10 +352,6 @@ endif()
|
||||
|
||||
if(WITH_CYCLES AND WITH_CYCLES_EMBREE)
|
||||
find_package(Embree 3.8.0 REQUIRED)
|
||||
# Increase stack size for Embree, only works for executables.
|
||||
if(NOT WITH_PYTHON_MODULE)
|
||||
string(APPEND PLATFORM_LINKFLAGS " -Wl,-stack_size,0x100000")
|
||||
endif()
|
||||
|
||||
# Embree static library linking can mix up SSE and AVX symbols, causing
|
||||
# crashes on macOS systems with older CPUs that don't have AVX. Using
|
||||
@@ -475,6 +471,9 @@ string(APPEND PLATFORM_LINKFLAGS
|
||||
string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++")
|
||||
string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
|
||||
|
||||
# Make stack size more similar to Embree, required for Embree.
|
||||
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
||||
|
||||
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
|
@@ -770,6 +770,39 @@ if(WITH_GHOST_WAYLAND)
|
||||
endif()
|
||||
|
||||
pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner)
|
||||
|
||||
# When using dynamic loading, headers generated
|
||||
# from older versions of `wayland-scanner` aren't compatible.
|
||||
if(WITH_GHOST_WAYLAND_DYNLOAD)
|
||||
execute_process(
|
||||
COMMAND ${WAYLAND_SCANNER} --version
|
||||
# The version is written to the `stderr`.
|
||||
ERROR_VARIABLE _wayland_scanner_out
|
||||
ERROR_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(NOT "${_wayland_scanner_out}" STREQUAL "")
|
||||
string(
|
||||
REGEX REPLACE
|
||||
"^wayland-scanner[ \t]+([0-9]+)\.([0-9]+).*"
|
||||
"\\1.\\2"
|
||||
_wayland_scanner_ver
|
||||
"${_wayland_scanner_out}"
|
||||
)
|
||||
if("${_wayland_scanner_ver}" VERSION_LESS "1.20")
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Found ${WAYLAND_SCANNER} version \"${_wayland_scanner_ver}\", "
|
||||
"the minimum version is 1.20!"
|
||||
)
|
||||
endif()
|
||||
unset(_wayland_scanner_ver)
|
||||
else()
|
||||
message(WARNING "Unable to access the version from ${WAYLAND_SCANNER}, continuing.")
|
||||
endif()
|
||||
unset(_wayland_scanner_out)
|
||||
endif()
|
||||
# End wayland-scanner version check.
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1056,7 +1089,7 @@ function(CONFIGURE_ATOMIC_LIB_IF_NEEDED)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
CONFIGURE_ATOMIC_LIB_IF_NEEDED()
|
||||
configure_atomic_lib_if_needed()
|
||||
|
||||
if(PLATFORM_BUNDLED_LIBRARIES)
|
||||
# For the installed Python module and installed Blender executable, we set the
|
||||
|
@@ -26,7 +26,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
set(OPENMP_FOUND ON)
|
||||
set(OpenMP_C_FLAGS "/clang:-fopenmp")
|
||||
set(OpenMP_CXX_FLAGS "/clang:-fopenmp")
|
||||
GET_FILENAME_COMPONENT(LLVMROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM;]" ABSOLUTE CACHE)
|
||||
get_filename_component(LLVMROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM;]" ABSOLUTE CACHE)
|
||||
set(CLANG_OPENMP_DLL "${LLVMROOT}/bin/libomp.dll")
|
||||
set(CLANG_OPENMP_LIB "${LLVMROOT}/lib/libomp.lib")
|
||||
if(NOT EXISTS "${CLANG_OPENMP_DLL}")
|
||||
@@ -767,7 +767,7 @@ if(WITH_TBB)
|
||||
endif()
|
||||
|
||||
# used in many places so include globally, like OpenGL
|
||||
blender_include_dirs_sys("${PTHREADS_INCLUDE_DIRS}")
|
||||
include_directories(SYSTEM "${PTHREADS_INCLUDE_DIRS}")
|
||||
|
||||
set(WINTAB_INC ${LIBDIR}/wintab/include)
|
||||
|
||||
@@ -874,8 +874,8 @@ endif()
|
||||
|
||||
if(WINDOWS_PYTHON_DEBUG)
|
||||
# Include the system scripts in the blender_python_system_scripts project.
|
||||
FILE(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" )
|
||||
ADD_CUSTOM_TARGET(blender_python_system_scripts SOURCES ${inFiles})
|
||||
file(GLOB_RECURSE inFiles "${CMAKE_SOURCE_DIR}/release/scripts/*.*" )
|
||||
add_custom_target(blender_python_system_scripts SOURCES ${inFiles})
|
||||
foreach(_source IN ITEMS ${inFiles})
|
||||
get_filename_component(_source_path "${_source}" PATH)
|
||||
string(REPLACE "${CMAKE_SOURCE_DIR}/release/scripts/" "" _source_path "${_source_path}")
|
||||
@@ -895,8 +895,8 @@ if(WINDOWS_PYTHON_DEBUG)
|
||||
endif()
|
||||
|
||||
file(TO_CMAKE_PATH ${USER_SCRIPTS_ROOT} USER_SCRIPTS_ROOT)
|
||||
FILE(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
|
||||
ADD_CUSTOM_TARGET(blender_python_user_scripts SOURCES ${inFiles})
|
||||
file(GLOB_RECURSE inFiles "${USER_SCRIPTS_ROOT}/*.*" )
|
||||
add_custom_target(blender_python_user_scripts SOURCES ${inFiles})
|
||||
foreach(_source IN ITEMS ${inFiles})
|
||||
get_filename_component(_source_path "${_source}" PATH)
|
||||
string(REPLACE "${USER_SCRIPTS_ROOT}" "" _source_path "${_source_path}")
|
||||
|
@@ -210,8 +210,10 @@ def main() -> None:
|
||||
if f.endswith(".whl"):
|
||||
# No apparent way to override this ABI version with setuptools, so rename.
|
||||
sys_py = "cp%d%d" % (sys.version_info.major, sys.version_info.minor)
|
||||
sys_py_abi = sys_py + sys.abiflags
|
||||
blender_py = "cp%d%d" % (python_version_number[0], python_version_number[1])
|
||||
renamed_f = f.replace(sys_py, blender_py)
|
||||
|
||||
renamed_f = f.replace(sys_py_abi, blender_py).replace(sys_py, blender_py)
|
||||
|
||||
os.rename(os.path.join(dist_dir, f), os.path.join(output_dir, renamed_f))
|
||||
|
||||
|
@@ -19,6 +19,8 @@ from typing import Iterable, TextIO, Optional, Any, Union
|
||||
SKIP_NAMES = {
|
||||
".gitignore",
|
||||
".gitmodules",
|
||||
".gitattributes",
|
||||
".git-blame-ignore-revs",
|
||||
".arcconfig",
|
||||
".svn",
|
||||
}
|
||||
@@ -154,7 +156,11 @@ def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None:
|
||||
|
||||
|
||||
def create_tarball(
|
||||
version: make_utils.BlenderVersion, tarball: Path, manifest: Path, blender_srcdir: Path, packages_dir: Optional[Path]
|
||||
version: make_utils.BlenderVersion,
|
||||
tarball: Path,
|
||||
manifest: Path,
|
||||
blender_srcdir: Path,
|
||||
packages_dir: Optional[Path],
|
||||
) -> None:
|
||||
print(f'Creating archive: "{tarball}" ...', end="", flush=True)
|
||||
command = ["tar"]
|
||||
|
@@ -134,7 +134,6 @@ batch = batch_for_shader(shader, 'LINES', {"pos": coords})
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (1, 1, 0, 1))
|
||||
batch.draw(shader)
|
||||
|
||||
|
@@ -58,7 +58,6 @@ batch = batch_for_shader(
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
matrix = bpy.context.region_data.perspective_matrix
|
||||
shader.uniform_float("u_ViewProjectionMatrix", matrix)
|
||||
shader.uniform_float("u_Scale", 10)
|
||||
|
@@ -41,7 +41,6 @@ batch = batch_for_shader(shader, 'TRIS', {"position": coords})
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
matrix = bpy.context.region_data.perspective_matrix
|
||||
shader.uniform_float("viewProjectionMatrix", matrix)
|
||||
shader.uniform_float("brightness", 0.5)
|
||||
|
@@ -22,7 +22,6 @@ batch = batch_for_shader(shader, 'LINES', {"pos": coords}, indices=indices)
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (1, 0, 0, 1))
|
||||
batch.draw(shader)
|
||||
|
||||
|
@@ -18,7 +18,6 @@ batch = batch_for_shader(shader, 'TRIS', {"pos": vertices}, indices=indices)
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (0, 0.5, 0.5, 1.0))
|
||||
batch.draw(shader)
|
||||
|
||||
|
@@ -56,7 +56,6 @@ batch = batch_for_shader(
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
shader.uniform_sampler("image", texture)
|
||||
batch.draw(shader)
|
||||
|
||||
|
@@ -76,7 +76,6 @@ batch = batch_for_shader(
|
||||
|
||||
|
||||
def draw():
|
||||
shader.bind()
|
||||
shader.uniform_float("modelMatrix", Matrix.Translation((1, 2, 3)) @ Matrix.Scale(3, 4))
|
||||
shader.uniform_float("viewProjectionMatrix", bpy.context.region_data.perspective_matrix)
|
||||
shader.uniform_sampler("image", offscreen.texture_color)
|
||||
|
@@ -1,11 +1,11 @@
|
||||
sphinx==5.0.1
|
||||
sphinx==5.1.1
|
||||
|
||||
# Sphinx dependencies that are important
|
||||
Jinja2==3.1.2
|
||||
Pygments==2.12.0
|
||||
Pygments==2.13.0
|
||||
docutils==0.17.1
|
||||
snowballstemmer==2.2.0
|
||||
babel==2.10.1
|
||||
babel==2.10.3
|
||||
requests==2.27.1
|
||||
|
||||
# Only needed to match the theme used for the official documentation.
|
||||
|
@@ -78,9 +78,10 @@ Signal Handlers
|
||||
to cancel a render and a crash log is not written in the event of a crash.
|
||||
|
||||
Startup and Preferences
|
||||
When the ``bpy`` module loads, the file is not empty as you might expect,
|
||||
there is a default cube, camera and light. If you wish to start from a blank file use:
|
||||
``bpy.ops.wm.read_factory_settings(use_empty=True)``.
|
||||
When the ``bpy`` module loads it contains the default startup scene
|
||||
(instead of an "empty" blend-file as you might expect), so there is a default cube, camera and light.
|
||||
|
||||
If you wish to start from an empty file use: ``bpy.ops.wm.read_factory_settings(use_empty=True)``.
|
||||
|
||||
The users startup and preferences are ignored to prevent your local configuration from impacting scripts behavior.
|
||||
The Python module behaves as if ``--factory-startup`` was passed as a command line argument.
|
||||
@@ -101,9 +102,10 @@ Limitations
|
||||
Most constraints of Blender as an application still apply:
|
||||
|
||||
Reloading Unsupported
|
||||
Reloading via ``importlib.reload`` will raise an exception instead of reloading and resetting the module.
|
||||
Reloading the ``bpy`` module via ``importlib.reload`` will raise an exception
|
||||
instead of reloading and resetting the module.
|
||||
|
||||
The operator ``bpy.ops.wm.read_factory_settings()`` can be used to reset the internal state.
|
||||
Instead, the operator ``bpy.ops.wm.read_factory_settings()`` can be used to reset the internal state.
|
||||
|
||||
Single Blend File Restriction
|
||||
Only a single ``.blend`` file can be edited at a time.
|
||||
|
@@ -36,7 +36,7 @@ if(WITH_CYCLES_NATIVE_ONLY)
|
||||
)
|
||||
|
||||
if(NOT MSVC)
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_march_native "-march=native")
|
||||
add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_march_native "-march=native")
|
||||
if(_has_march_native)
|
||||
set(CYCLES_KERNEL_FLAGS "-march=native")
|
||||
else()
|
||||
@@ -45,18 +45,18 @@ if(WITH_CYCLES_NATIVE_ONLY)
|
||||
unset(_has_march_native)
|
||||
else()
|
||||
if(NOT MSVC_NATIVE_ARCH_FLAGS)
|
||||
TRY_RUN(
|
||||
arch_run_result
|
||||
arch_compile_result
|
||||
${CMAKE_CURRENT_BINARY_DIR}/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/msvc_arch_flags.c
|
||||
COMPILE_OUTPUT_VARIABLE arch_compile_output
|
||||
RUN_OUTPUT_VARIABLE arch_run_output
|
||||
)
|
||||
if(arch_compile_result AND "${arch_run_result}" EQUAL "0")
|
||||
string(STRIP ${arch_run_output} arch_run_output)
|
||||
set(MSVC_NATIVE_ARCH_FLAGS ${arch_run_output} CACHE STRING "MSVC Native architecture flags")
|
||||
endif()
|
||||
try_run(
|
||||
arch_run_result
|
||||
arch_compile_result
|
||||
${CMAKE_CURRENT_BINARY_DIR}/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/msvc_arch_flags.c
|
||||
COMPILE_OUTPUT_VARIABLE arch_compile_output
|
||||
RUN_OUTPUT_VARIABLE arch_run_output
|
||||
)
|
||||
if(arch_compile_result AND "${arch_run_result}" EQUAL "0")
|
||||
string(STRIP ${arch_run_output} arch_run_output)
|
||||
set(MSVC_NATIVE_ARCH_FLAGS ${arch_run_output} CACHE STRING "MSVC Native architecture flags")
|
||||
endif()
|
||||
endif()
|
||||
set(CYCLES_KERNEL_FLAGS "${MSVC_NATIVE_ARCH_FLAGS}")
|
||||
endif()
|
||||
@@ -364,7 +364,7 @@ endif()
|
||||
|
||||
# Warnings
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
|
||||
add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_no_error_unused_macros "-Wno-error=unused-macros")
|
||||
unset(_has_no_error_unused_macros)
|
||||
endif()
|
||||
|
||||
|
@@ -13,7 +13,7 @@ def _configure_argument_parser():
|
||||
action='store_true')
|
||||
parser.add_argument("--cycles-device",
|
||||
help="Set the device to use for Cycles, overriding user preferences and the scene setting."
|
||||
"Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP' or 'METAL'."
|
||||
"Valid options are 'CPU', 'CUDA', 'OPTIX', 'HIP', 'ONEAPI', or 'METAL'."
|
||||
"Additionally, you can append '+CPU' to any GPU type for hybrid rendering.",
|
||||
default=None)
|
||||
return parser
|
||||
|
@@ -1084,23 +1084,23 @@ static void create_subd_mesh(Scene *scene,
|
||||
|
||||
const int edges_num = b_mesh.edges.length();
|
||||
|
||||
if (edges_num != 0) {
|
||||
if (edges_num != 0 && b_mesh.edge_creases.length() > 0) {
|
||||
size_t num_creases = 0;
|
||||
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
const float *creases = static_cast<float *>(b_mesh.edge_creases[0].ptr.data);
|
||||
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
if (b_edge.crease != 0) {
|
||||
if (creases[i] != 0.0f) {
|
||||
num_creases++;
|
||||
}
|
||||
}
|
||||
|
||||
mesh->reserve_subd_creases(num_creases);
|
||||
|
||||
const MEdge *edges = static_cast<MEdge *>(b_mesh.edges[0].ptr.data);
|
||||
for (int i = 0; i < edges_num; i++) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
if (b_edge.crease != 0) {
|
||||
mesh->add_edge_crease(b_edge.v1, b_edge.v2, float(b_edge.crease) / 255.0f);
|
||||
if (creases[i] != 0.0f) {
|
||||
const MEdge &b_edge = edges[i];
|
||||
mesh->add_edge_crease(b_edge.v1, b_edge.v2, creases[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -515,7 +515,7 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder,
|
||||
int dim,
|
||||
float pos)
|
||||
{
|
||||
/* initialize boundboxes */
|
||||
/* Initialize bounding-boxes. */
|
||||
BoundBox left_bounds = BoundBox::empty;
|
||||
BoundBox right_bounds = BoundBox::empty;
|
||||
|
||||
|
@@ -69,6 +69,7 @@ if(CYCLES_STANDALONE_REPOSITORY)
|
||||
_set_default(BOOST_ROOT "${_cycles_lib_dir}/boost")
|
||||
_set_default(BLOSC_ROOT_DIR "${_cycles_lib_dir}/blosc")
|
||||
_set_default(EMBREE_ROOT_DIR "${_cycles_lib_dir}/embree")
|
||||
_set_default(EPOXY_ROOT_DIR "${_cycles_lib_dir}/epoxy")
|
||||
_set_default(IMATH_ROOT_DIR "${_cycles_lib_dir}/imath")
|
||||
_set_default(GLEW_ROOT_DIR "${_cycles_lib_dir}/glew")
|
||||
_set_default(JPEG_ROOT "${_cycles_lib_dir}/jpeg")
|
||||
@@ -91,7 +92,11 @@ if(CYCLES_STANDALONE_REPOSITORY)
|
||||
_set_default(USD_ROOT_DIR "${_cycles_lib_dir}/usd")
|
||||
_set_default(WEBP_ROOT_DIR "${_cycles_lib_dir}/webp")
|
||||
_set_default(ZLIB_ROOT "${_cycles_lib_dir}/zlib")
|
||||
_set_default(LEVEL_ZERO_ROOT_DIR "${_cycles_lib_dir}/level-zero")
|
||||
if(WIN32)
|
||||
set(LEVEL_ZERO_ROOT_DIR ${_cycles_lib_dir}/level_zero)
|
||||
else()
|
||||
set(LEVEL_ZERO_ROOT_DIR ${_cycles_lib_dir}/level-zero)
|
||||
endif()
|
||||
_set_default(SYCL_ROOT_DIR "${_cycles_lib_dir}/dpcpp")
|
||||
|
||||
# Ignore system libraries
|
||||
@@ -197,17 +202,17 @@ endif()
|
||||
if(CYCLES_STANDALONE_REPOSITORY)
|
||||
if(MSVC AND EXISTS ${_cycles_lib_dir})
|
||||
set(OPENEXR_INCLUDE_DIR ${OPENEXR_ROOT_DIR}/include)
|
||||
set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_ROOT_DIR}/include/OpenEXR)
|
||||
set(OPENEXR_INCLUDE_DIRS ${OPENEXR_INCLUDE_DIR} ${OPENEXR_ROOT_DIR}/include/OpenEXR ${IMATH_ROOT_DIR}/include ${IMATH_ROOT_DIR}/include/Imath)
|
||||
set(OPENEXR_LIBRARIES
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/OpenEXR_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/OpenEXRCore_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/Iex_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/Half_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/IlmImf_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/Imath_s.lib
|
||||
optimized ${IMATH_ROOT_DIR}/lib/Imath_s.lib
|
||||
optimized ${OPENEXR_ROOT_DIR}/lib/IlmThread_s.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/OpenEXR_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/OpenEXRCore_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/Iex_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/Half_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/IlmImf_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/Imath_s_d.lib
|
||||
debug ${IMATH_ROOT_DIR}/lib/Imath_s_d.lib
|
||||
debug ${OPENEXR_ROOT_DIR}/lib/IlmThread_s_d.lib
|
||||
)
|
||||
else()
|
||||
@@ -319,8 +324,8 @@ if(CYCLES_STANDALONE_REPOSITORY)
|
||||
if(NOT BOOST_VERSION)
|
||||
message(FATAL_ERROR "Unable to determine Boost version")
|
||||
endif()
|
||||
set(BOOST_POSTFIX "vc141-mt-x64-${BOOST_VERSION}.lib")
|
||||
set(BOOST_DEBUG_POSTFIX "vc141-mt-gd-x64-${BOOST_VERSION}.lib")
|
||||
set(BOOST_POSTFIX "vc142-mt-x64-${BOOST_VERSION}.lib")
|
||||
set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}.lib")
|
||||
set(BOOST_LIBRARIES
|
||||
optimized ${BOOST_ROOT}/lib/libboost_date_time-${BOOST_POSTFIX}
|
||||
optimized ${BOOST_ROOT}/lib/libboost_iostreams-${BOOST_POSTFIX}
|
||||
@@ -459,6 +464,7 @@ if(CYCLES_STANDALONE_REPOSITORY AND WITH_CYCLES_NANOVDB)
|
||||
|
||||
if(MSVC AND EXISTS ${_cycles_lib_dir})
|
||||
set(NANOVDB_INCLUDE_DIR ${NANOVDB_ROOT_DIR}/include)
|
||||
set(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR})
|
||||
else()
|
||||
find_package(NanoVDB REQUIRED)
|
||||
endif()
|
||||
|
@@ -169,13 +169,13 @@ macro(cycles_install_libraries target)
|
||||
FILES
|
||||
${TBB_ROOT_DIR}/bin/tbb_debug${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${OPENVDB_ROOT_DIR}/bin/openvdb_d${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
DESTINATION $<TARGET_FILE_DIR:${target}>)
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
install(
|
||||
FILES
|
||||
${TBB_ROOT_DIR}/bin/tbb${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
${OPENVDB_ROOT_DIR}/bin/openvdb${CMAKE_SHARED_LIBRARY_SUFFIX}
|
||||
DESTINATION $<TARGET_FILE_DIR:${target}>)
|
||||
DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
@@ -529,7 +529,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
||||
endif()
|
||||
if(DEFINED cuda_nvcc_executable AND DEFINED cuda_toolkit_root_dir)
|
||||
# Compile regular kernel
|
||||
CYCLES_CUDA_KERNEL_ADD(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
|
||||
cycles_cuda_kernel_add(${arch} ${prev_arch} kernel "" "${cuda_sources}" FALSE)
|
||||
|
||||
if(WITH_CYCLES_CUDA_BUILD_SERIAL)
|
||||
set(prev_arch ${arch})
|
||||
@@ -611,7 +611,7 @@ if(WITH_CYCLES_HIP_BINARIES AND WITH_CYCLES_DEVICE_HIP)
|
||||
|
||||
foreach(arch ${CYCLES_HIP_BINARIES_ARCH})
|
||||
# Compile regular kernel
|
||||
CYCLES_HIP_KERNEL_ADD(${arch} kernel "" "${hip_sources}" FALSE)
|
||||
cycles_hip_kernel_add(${arch} kernel "" "${hip_sources}" FALSE)
|
||||
endforeach()
|
||||
|
||||
add_custom_target(cycles_kernel_hip ALL DEPENDS ${hip_fatbins})
|
||||
@@ -696,11 +696,11 @@ if(WITH_CYCLES_DEVICE_OPTIX AND WITH_CYCLES_CUDA_BINARIES)
|
||||
delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${output}" ${CYCLES_INSTALL_PATH}/lib)
|
||||
endmacro()
|
||||
|
||||
CYCLES_OPTIX_KERNEL_ADD(
|
||||
cycles_optix_kernel_add(
|
||||
kernel_optix
|
||||
"device/optix/kernel.cu"
|
||||
"")
|
||||
CYCLES_OPTIX_KERNEL_ADD(
|
||||
cycles_optix_kernel_add(
|
||||
kernel_optix_shader_raytrace
|
||||
"device/optix/kernel_shader_raytrace.cu"
|
||||
"--keep-device-functions")
|
||||
@@ -950,8 +950,8 @@ endif()
|
||||
|
||||
# Warnings to avoid using doubles in the kernel.
|
||||
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
|
||||
ADD_CHECK_CXX_COMPILER_FLAG(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
|
||||
add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_cxxflag_float_conversion "-Werror=float-conversion")
|
||||
add_check_cxx_compiler_flag(CMAKE_CXX_FLAGS _has_cxxflag_double_promotion "-Werror=double-promotion")
|
||||
unset(_has_cxxflag_float_conversion)
|
||||
unset(_has_cxxflag_double_promotion)
|
||||
endif()
|
||||
|
@@ -53,6 +53,9 @@ ccl_device_inline ccl_private ShaderClosure *bsdf_alloc(ccl_private ShaderData *
|
||||
{
|
||||
kernel_assert(isfinite_safe(weight));
|
||||
|
||||
/* No negative weights allowed. */
|
||||
weight = max(weight, zero_float3());
|
||||
|
||||
const float sample_weight = fabsf(average(weight));
|
||||
|
||||
/* Use comparison this way to help dealing with non-finite weight: if the average is not finite
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#define CCL_NAMESPACE_END
|
||||
|
||||
#include <cstdint>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef __NODES_MAX_GROUP__
|
||||
# define __NODES_MAX_GROUP__ NODE_GROUP_LEVEL_MAX
|
||||
@@ -174,21 +175,15 @@ using sycl::half;
|
||||
#define fmodf(x, y) sycl::fmod((x), (y))
|
||||
#define lgammaf(x) sycl::lgamma((x))
|
||||
|
||||
#define __forceinline __attribute__((always_inline))
|
||||
|
||||
/* Types */
|
||||
#include "util/half.h"
|
||||
#include "util/types.h"
|
||||
|
||||
/* NOTE(@nsirgien): Declaring these functions after types headers is very important because they
|
||||
* include oneAPI headers, which transitively include math.h headers which will cause redefinitions
|
||||
* of the math defines because math.h also uses them and having them defined before math.h include
|
||||
* is actually UB. */
|
||||
/* Use fast math functions - get them from sycl::native namespace for native math function
|
||||
* implementations */
|
||||
#define cosf(x) sycl::native::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)))
|
||||
#define logf(x) sycl::native::log(((float)(x)))
|
||||
#define expf(x) sycl::native::exp(((float)(x)))
|
||||
|
||||
#define __forceinline __attribute__((always_inline))
|
||||
|
||||
/* Types */
|
||||
#include "util/half.h"
|
||||
#include "util/types.h"
|
||||
|
@@ -101,7 +101,7 @@ if(WITH_CYCLES_OSL)
|
||||
cycles_kernel_osl
|
||||
)
|
||||
|
||||
SET_PROPERTY(SOURCE osl.cpp PROPERTY COMPILE_FLAGS ${RTTI_DISABLE_FLAGS})
|
||||
set_property(SOURCE osl.cpp PROPERTY COMPILE_FLAGS ${RTTI_DISABLE_FLAGS})
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCOLORIO)
|
||||
|
@@ -780,7 +780,7 @@ static bool to_scene_linear_transform(OCIO::ConstConfigRcPtr &config,
|
||||
{
|
||||
OCIO::ConstProcessorRcPtr processor;
|
||||
try {
|
||||
processor = config->getProcessor(OCIO::ROLE_SCENE_LINEAR, colorspace);
|
||||
processor = config->getProcessor("scene_linear", colorspace);
|
||||
}
|
||||
catch (OCIO::Exception &) {
|
||||
return false;
|
||||
@@ -834,7 +834,7 @@ void ShaderManager::init_xyz_transforms()
|
||||
#ifdef WITH_OCIO
|
||||
/* Get from OpenColorO config if it has the required roles. */
|
||||
OCIO::ConstConfigRcPtr config = OCIO::GetCurrentConfig();
|
||||
if (!(config && config->hasRole(OCIO::ROLE_SCENE_LINEAR))) {
|
||||
if (!(config && config->hasRole("scene_linear"))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -59,5 +59,5 @@ if(NOT APPLE)
|
||||
endif()
|
||||
|
||||
if(WITH_GTESTS)
|
||||
BLENDER_SRC_GTEST(cycles "${SRC}" "${LIB}")
|
||||
blender_src_gtest(cycles "${SRC}" "${LIB}")
|
||||
endif()
|
||||
|
@@ -9,7 +9,7 @@
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
#define CYCLES_VERSION_MAJOR 3
|
||||
#define CYCLES_VERSION_MINOR 2
|
||||
#define CYCLES_VERSION_MINOR 4
|
||||
#define CYCLES_VERSION_PATCH 0
|
||||
|
||||
#define CYCLES_MAKE_VERSION_STRING2(a, b, c) #a "." #b "." #c
|
||||
@@ -19,7 +19,7 @@ CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Blender libraries version compatible with this version */
|
||||
|
||||
#define CYCLES_BLENDER_LIBRARIES_VERSION 3.1
|
||||
#define CYCLES_BLENDER_LIBRARIES_VERSION 3.3
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
|
@@ -281,7 +281,7 @@ class GHOST_ISystem {
|
||||
const bool stereoVisual) = 0;
|
||||
|
||||
/**
|
||||
* Updates the resolution while in fullscreen mode.
|
||||
* Updates the resolution while in full-screen mode.
|
||||
* \param setting: The new setting of the display.
|
||||
* \param window: Window displayed in full screen.
|
||||
*
|
||||
|
@@ -121,7 +121,8 @@ typedef enum {
|
||||
GHOST_kModifierKeyRightAlt,
|
||||
GHOST_kModifierKeyLeftControl,
|
||||
GHOST_kModifierKeyRightControl,
|
||||
GHOST_kModifierKeyOS,
|
||||
GHOST_kModifierKeyLeftOS,
|
||||
GHOST_kModifierKeyRightOS,
|
||||
GHOST_kModifierKeyNum
|
||||
} GHOST_TModifierKey;
|
||||
|
||||
@@ -320,13 +321,18 @@ typedef enum {
|
||||
GHOST_kKeyBackslash = 0x5C,
|
||||
GHOST_kKeyAccentGrave = '`',
|
||||
|
||||
#define _GHOST_KEY_MODIFIER_MIN GHOST_kKeyLeftShift
|
||||
/* Modifiers: See #GHOST_KEY_MODIFIER_CHECK. */
|
||||
GHOST_kKeyLeftShift = 0x100,
|
||||
GHOST_kKeyRightShift,
|
||||
GHOST_kKeyLeftControl,
|
||||
GHOST_kKeyRightControl,
|
||||
GHOST_kKeyLeftAlt,
|
||||
GHOST_kKeyRightAlt,
|
||||
GHOST_kKeyOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyLeftOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyRightOS,
|
||||
#define _GHOST_KEY_MODIFIER_MAX GHOST_kKeyRightOS
|
||||
|
||||
GHOST_kKeyGrLess, /* German PC only! */
|
||||
GHOST_kKeyApp, /* Also known as menu key. */
|
||||
|
||||
@@ -400,6 +406,12 @@ typedef enum {
|
||||
GHOST_kKeyMediaLast
|
||||
} GHOST_TKey;
|
||||
|
||||
#define GHOST_KEY_MODIFIER_NUM ((_GHOST_KEY_MODIFIER_MAX - _GHOST_KEY_MODIFIER_MIN) + 1)
|
||||
#define GHOST_KEY_MODIFIER_TO_INDEX(key) ((unsigned int)(key)-_GHOST_KEY_MODIFIER_MIN)
|
||||
#define GHOST_KEY_MODIFIER_FROM_INDEX(key) \
|
||||
(GHOST_TKey)(((unsigned int)(key) + _GHOST_KEY_MODIFIER_MIN))
|
||||
#define GHOST_KEY_MODIFIER_CHECK(key) (GHOST_KEY_MODIFIER_TO_INDEX(key) < GHOST_KEY_MODIFIER_NUM)
|
||||
|
||||
typedef enum {
|
||||
/** Grab not set. */
|
||||
GHOST_kGrabDisable = 0,
|
||||
|
@@ -36,19 +36,19 @@ class GHOST_Context : public GHOST_IContext {
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers() = 0;
|
||||
virtual GHOST_TSuccess swapBuffers() override = 0;
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext() = 0;
|
||||
virtual GHOST_TSuccess activateDrawingContext() override = 0;
|
||||
|
||||
/**
|
||||
* Release the drawing context of the calling thread.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess releaseDrawingContext() = 0;
|
||||
virtual GHOST_TSuccess releaseDrawingContext() override = 0;
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
@@ -130,7 +130,7 @@ class GHOST_Context : public GHOST_IContext {
|
||||
* Gets the OpenGL frame-buffer associated with the OpenGL context
|
||||
* \return The ID of an OpenGL frame-buffer object.
|
||||
*/
|
||||
virtual unsigned int getDefaultFramebuffer()
|
||||
virtual unsigned int getDefaultFramebuffer() override
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@@ -9,8 +9,13 @@
|
||||
|
||||
#include "GHOST_Context.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <Metal/Metal.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
|
||||
@class CAMetalLayer;
|
||||
@class MTLCommandQueue;
|
||||
@class MTLDevice;
|
||||
@class MTLRenderPipelineState;
|
||||
@class MTLTexture;
|
||||
@class NSOpenGLContext;
|
||||
@@ -36,62 +41,89 @@ class GHOST_ContextCGL : public GHOST_Context {
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess swapBuffers();
|
||||
GHOST_TSuccess swapBuffers() override;
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess activateDrawingContext();
|
||||
GHOST_TSuccess activateDrawingContext() override;
|
||||
|
||||
/**
|
||||
* Release the drawing context of the calling thread.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess releaseDrawingContext();
|
||||
GHOST_TSuccess releaseDrawingContext() override;
|
||||
|
||||
unsigned int getDefaultFramebuffer();
|
||||
unsigned int getDefaultFramebuffer() override;
|
||||
|
||||
/**
|
||||
* Call immediately after new to initialize. If this fails then immediately delete the object.
|
||||
* \return Indication as to whether initialization has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess initializeDrawingContext();
|
||||
GHOST_TSuccess initializeDrawingContext() override;
|
||||
|
||||
/**
|
||||
* Removes references to native handles from this context and then returns
|
||||
* \return GHOST_kSuccess if it is OK for the parent to release the handles and
|
||||
* GHOST_kFailure if releasing the handles will interfere with sharing
|
||||
*/
|
||||
GHOST_TSuccess releaseNativeHandles();
|
||||
GHOST_TSuccess releaseNativeHandles() override;
|
||||
|
||||
/**
|
||||
* Sets the swap interval for #swapBuffers.
|
||||
* \param interval: The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess setSwapInterval(int interval);
|
||||
GHOST_TSuccess setSwapInterval(int interval) override;
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for #swapBuffers.
|
||||
* \param intervalOut: Variable to store the swap interval if it can be read.
|
||||
* \return Whether the swap interval can be read.
|
||||
*/
|
||||
GHOST_TSuccess getSwapInterval(int &);
|
||||
GHOST_TSuccess getSwapInterval(int &) override;
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window.
|
||||
* Needed whenever the window is changed.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess updateDrawingContext();
|
||||
GHOST_TSuccess updateDrawingContext() override;
|
||||
|
||||
/**
|
||||
* Returns a texture that Metal code can use as a render target. The current
|
||||
* contents of this texture will be composited on top of the frame-buffer
|
||||
* each time `swapBuffers` is called.
|
||||
*/
|
||||
id<MTLTexture> metalOverlayTexture();
|
||||
|
||||
/**
|
||||
* Return a pointer to the Metal command queue used by this context.
|
||||
*/
|
||||
MTLCommandQueue *metalCommandQueue();
|
||||
|
||||
/**
|
||||
* Return a pointer to the Metal device associated with this context.
|
||||
*/
|
||||
MTLDevice *metalDevice();
|
||||
|
||||
/**
|
||||
* Register present callback
|
||||
*/
|
||||
void metalRegisterPresentCallback(void (*callback)(
|
||||
MTLRenderPassDescriptor *, id<MTLRenderPipelineState>, id<MTLTexture>, id<CAMetalDrawable>));
|
||||
|
||||
private:
|
||||
/** Metal state */
|
||||
/* Set this flag to `true` when rendering with Metal API for Viewport.
|
||||
* TODO(Metal): This should be assigned to externally. */
|
||||
bool m_useMetalForRendering = false;
|
||||
NSView *m_metalView;
|
||||
CAMetalLayer *m_metalLayer;
|
||||
MTLCommandQueue *m_metalCmdQueue;
|
||||
MTLRenderPipelineState *m_metalRenderPipeline;
|
||||
bool m_ownsMetalDevice;
|
||||
|
||||
/** OpenGL state, for GPUs that don't support Metal */
|
||||
NSOpenGLView *m_openGLView;
|
||||
@@ -103,8 +135,30 @@ class GHOST_ContextCGL : public GHOST_Context {
|
||||
unsigned int m_defaultFramebuffer;
|
||||
|
||||
/** The virtualized default frame-buffer's texture. */
|
||||
MTLTexture *m_defaultFramebufferMetalTexture;
|
||||
/**
|
||||
* Texture that you can render into with Metal. The texture will be
|
||||
* composited on top of `m_defaultFramebufferMetalTexture` whenever
|
||||
* `swapBuffers` is called.
|
||||
*/
|
||||
static const int METAL_SWAPCHAIN_SIZE = 3;
|
||||
struct MTLSwapchainTexture {
|
||||
id<MTLTexture> texture;
|
||||
unsigned int index;
|
||||
};
|
||||
MTLSwapchainTexture m_defaultFramebufferMetalTexture[METAL_SWAPCHAIN_SIZE];
|
||||
unsigned int current_swapchain_index = 0;
|
||||
|
||||
/* Present callback.
|
||||
* We use this such that presentation can be controlled from within the Metal
|
||||
* Context. This is required for optimal performance and clean control flow.
|
||||
* Also helps ensure flickering does not occur by present being dependent
|
||||
* on existing submissions. */
|
||||
void (*contextPresentCallback)(MTLRenderPassDescriptor *,
|
||||
id<MTLRenderPipelineState>,
|
||||
id<MTLTexture>,
|
||||
id<CAMetalDrawable>);
|
||||
|
||||
int mtl_SwapInterval;
|
||||
const bool m_debug;
|
||||
|
||||
/** The first created OpenGL context (for sharing display lists) */
|
||||
@@ -117,4 +171,5 @@ class GHOST_ContextCGL : public GHOST_Context {
|
||||
void metalInitFramebuffer();
|
||||
void metalUpdateFramebuffer();
|
||||
void metalSwapBuffers();
|
||||
void initClear();
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -114,7 +114,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr
|
||||
|
||||
/* Count total number of file paths in buffer. */
|
||||
for (int i = 0; i <= dropBufferSize; i++) {
|
||||
if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
|
||||
if (ELEM(dropBuffer[i], 0, '\n', '\r')) {
|
||||
if (curLength) {
|
||||
totPaths++;
|
||||
curLength = 0;
|
||||
@@ -131,7 +131,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(unsigned char *dropBuffer, int dr
|
||||
|
||||
curLength = 0;
|
||||
for (int i = 0; i <= dropBufferSize; i++) {
|
||||
if (dropBuffer[i] == 0 || dropBuffer[i] == '\n' || dropBuffer[i] == '\r') {
|
||||
if (ELEM(dropBuffer[i], 0, '\n', '\r')) {
|
||||
if (curLength) {
|
||||
char *curPath = (char *)malloc(curLength + 1);
|
||||
char *decodedPath;
|
||||
@@ -182,7 +182,7 @@ void *GHOST_DropTargetX11::getGhostData(Atom dropType,
|
||||
data = decodedPath;
|
||||
}
|
||||
}
|
||||
else if (dropType == dndTypePlainText || dropType == dndTypeOctetStream) {
|
||||
else if (ELEM(dropType, dndTypePlainText, dndTypeOctetStream)) {
|
||||
m_draggedObjectType = GHOST_kDragnDropTypeString;
|
||||
data = tmpBuffer;
|
||||
needsFree = false;
|
||||
|
@@ -220,8 +220,11 @@ void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
|
||||
case GHOST_kKeyRightAlt:
|
||||
tstr = "RightAlt";
|
||||
break;
|
||||
case GHOST_kKeyOS:
|
||||
tstr = "OS";
|
||||
case GHOST_kKeyLeftOS:
|
||||
tstr = "LeftOS";
|
||||
break;
|
||||
case GHOST_kKeyRightOS:
|
||||
tstr = "RightOS";
|
||||
break;
|
||||
case GHOST_kKeyApp:
|
||||
tstr = "App";
|
||||
|
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "GHOST_ModifierKeys.h"
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
GHOST_ModifierKeys::GHOST_ModifierKeys()
|
||||
{
|
||||
@@ -42,11 +43,15 @@ GHOST_TKey GHOST_ModifierKeys::getModifierKeyCode(GHOST_TModifierKey mask)
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
key = GHOST_kKeyRightControl;
|
||||
break;
|
||||
case GHOST_kModifierKeyOS:
|
||||
key = GHOST_kKeyOS;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
key = GHOST_kKeyLeftOS;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
key = GHOST_kKeyRightOS;
|
||||
break;
|
||||
default:
|
||||
// Should not happen
|
||||
/* Should not happen. */
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
key = GHOST_kKeyUnknown;
|
||||
break;
|
||||
}
|
||||
@@ -68,9 +73,12 @@ bool GHOST_ModifierKeys::get(GHOST_TModifierKey mask) const
|
||||
return m_LeftControl;
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
return m_RightControl;
|
||||
case GHOST_kModifierKeyOS:
|
||||
return m_OS;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
return m_LeftOS;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
return m_RightOS;
|
||||
default:
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -96,10 +104,14 @@ void GHOST_ModifierKeys::set(GHOST_TModifierKey mask, bool down)
|
||||
case GHOST_kModifierKeyRightControl:
|
||||
m_RightControl = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyOS:
|
||||
m_OS = down;
|
||||
case GHOST_kModifierKeyLeftOS:
|
||||
m_LeftOS = down;
|
||||
break;
|
||||
case GHOST_kModifierKeyRightOS:
|
||||
m_RightOS = down;
|
||||
break;
|
||||
default:
|
||||
GHOST_ASSERT(0, "Invalid key!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +124,8 @@ void GHOST_ModifierKeys::clear()
|
||||
m_RightAlt = false;
|
||||
m_LeftControl = false;
|
||||
m_RightControl = false;
|
||||
m_OS = false;
|
||||
m_LeftOS = false;
|
||||
m_RightOS = false;
|
||||
}
|
||||
|
||||
bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
@@ -120,5 +133,5 @@ bool GHOST_ModifierKeys::equals(const GHOST_ModifierKeys &keys) const
|
||||
return (m_LeftShift == keys.m_LeftShift) && (m_RightShift == keys.m_RightShift) &&
|
||||
(m_LeftAlt == keys.m_LeftAlt) && (m_RightAlt == keys.m_RightAlt) &&
|
||||
(m_LeftControl == keys.m_LeftControl) && (m_RightControl == keys.m_RightControl) &&
|
||||
(m_OS == keys.m_OS);
|
||||
(m_LeftOS == keys.m_LeftOS) && (m_RightOS == keys.m_RightOS);
|
||||
}
|
||||
|
@@ -55,18 +55,19 @@ struct GHOST_ModifierKeys {
|
||||
*/
|
||||
bool equals(const GHOST_ModifierKeys &keys) const;
|
||||
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_LeftShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_RightShift : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_LeftAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_RightAlt : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_LeftControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_RightControl : 1;
|
||||
/** Bitfield that stores the appropriate key state. */
|
||||
uint8_t m_OS : 1;
|
||||
/** Bit-field that stores the appropriate key state. */
|
||||
uint8_t m_LeftOS : 1;
|
||||
uint8_t m_RightOS : 1;
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@
|
||||
#include "GHOST_System.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdio> /* just for printf */
|
||||
#include <cstdio> /* Just for #printf. */
|
||||
|
||||
#include "GHOST_DisplayManager.h"
|
||||
#include "GHOST_EventManager.h"
|
||||
|
@@ -123,7 +123,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
const bool stereoVisual);
|
||||
|
||||
/**
|
||||
* Updates the resolution while in fullscreen mode.
|
||||
* Updates the resolution while in full-screen mode.
|
||||
* \param setting: The new setting of the display.
|
||||
* \param window: Window displayed in full screen.
|
||||
*
|
||||
@@ -369,7 +369,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
virtual GHOST_TSuccess exit();
|
||||
|
||||
/**
|
||||
* Creates a fullscreen window.
|
||||
* Creates a full-screen window.
|
||||
* \param window: The window created.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
@@ -399,7 +399,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
GHOST_EventPrinter *m_eventPrinter;
|
||||
#endif // WITH_GHOST_DEBUG
|
||||
|
||||
/** Settings of the display before the display went fullscreen. */
|
||||
/** Settings of the display before the display went full-screen. */
|
||||
GHOST_DisplaySetting m_preFullScreenSetting;
|
||||
|
||||
/** Which tablet API to use. */
|
||||
|
@@ -79,7 +79,7 @@ class GHOST_SystemCocoa : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent (embedder) window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -856,7 +856,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(int32_t x, int32_t y)
|
||||
|
||||
GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
{
|
||||
keys.set(GHOST_kModifierKeyOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftOS, (m_modifierMask & NSEventModifierFlagCommand) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (m_modifierMask & NSEventModifierFlagOption) ? true : false);
|
||||
keys.set(GHOST_kModifierKeyLeftShift,
|
||||
(m_modifierMask & NSEventModifierFlagShift) ? true : false);
|
||||
@@ -1020,7 +1020,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
|
||||
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown :
|
||||
GHOST_kEventKeyUp,
|
||||
window,
|
||||
GHOST_kKeyOS,
|
||||
GHOST_kKeyLeftOS,
|
||||
false));
|
||||
}
|
||||
|
||||
@@ -1901,7 +1901,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
|
||||
[event timestamp] * 1000,
|
||||
(modifiers & NSEventModifierFlagCommand) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp,
|
||||
window,
|
||||
GHOST_kKeyOS,
|
||||
GHOST_kKeyLeftOS,
|
||||
false));
|
||||
}
|
||||
|
||||
|
@@ -5,22 +5,17 @@
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
|
||||
#include "GHOST_SystemPathsUnix.h"
|
||||
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
// For timing
|
||||
|
||||
/* For timing. */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdio> /* for fprintf only */
|
||||
#include <cstdlib> /* for exit */
|
||||
|
||||
#include <pwd.h> /* for get home without use getenv() */
|
||||
#include <pwd.h> /* For get home without use `getenv()`. */
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
@@ -161,7 +161,8 @@ GHOST_TSuccess GHOST_SystemSDL::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
keys.set(GHOST_kModifierKeyRightControl, (mod & KMOD_RCTRL) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, (mod & KMOD_LALT) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, (mod & KMOD_RALT) != 0);
|
||||
keys.set(GHOST_kModifierKeyOS, (mod & (KMOD_LGUI | KMOD_RGUI)) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftOS, (mod & KMOD_LGUI) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightOS, (mod & KMOD_RGUI) != 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -219,8 +220,8 @@ static GHOST_TKey convertSDLKey(SDL_Scancode key)
|
||||
GXMAP(type, SDL_SCANCODE_RCTRL, GHOST_kKeyRightControl);
|
||||
GXMAP(type, SDL_SCANCODE_LALT, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type, SDL_SCANCODE_RALT, GHOST_kKeyRightAlt);
|
||||
GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyOS);
|
||||
GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyOS);
|
||||
GXMAP(type, SDL_SCANCODE_LGUI, GHOST_kKeyLeftOS);
|
||||
GXMAP(type, SDL_SCANCODE_RGUI, GHOST_kKeyRightOS);
|
||||
GXMAP(type, SDL_SCANCODE_APPLICATION, GHOST_kKeyApp);
|
||||
|
||||
GXMAP(type, SDL_SCANCODE_INSERT, GHOST_kKeyInsert);
|
||||
|
@@ -86,10 +86,6 @@ static void output_handle_done(void *data, struct wl_output *wl_output);
|
||||
static bool use_gnome_confine_hack = false;
|
||||
#endif
|
||||
|
||||
#define XKB_STATE_MODS_ALL \
|
||||
(enum xkb_state_component)(XKB_STATE_MODS_DEPRESSED | XKB_STATE_MODS_LATCHED | \
|
||||
XKB_STATE_MODS_LOCKED | XKB_STATE_MODS_EFFECTIVE)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Inline Event Codes
|
||||
*
|
||||
@@ -126,6 +122,69 @@ static bool use_gnome_confine_hack = false;
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Modifier Table
|
||||
*
|
||||
* Convenient access to modifier key values, allow looping over modifier keys.
|
||||
* \{ */
|
||||
|
||||
enum {
|
||||
MOD_INDEX_SHIFT = 0,
|
||||
MOD_INDEX_ALT = 1,
|
||||
MOD_INDEX_CTRL = 2,
|
||||
MOD_INDEX_OS = 3,
|
||||
};
|
||||
#define MOD_INDEX_NUM (MOD_INDEX_OS + 1)
|
||||
|
||||
struct GWL_ModifierInfo {
|
||||
/** Only for printing messages. */
|
||||
const char *display_name;
|
||||
const char *xkb_id;
|
||||
GHOST_TKey key_l, key_r;
|
||||
GHOST_TModifierKey mod_l, mod_r;
|
||||
};
|
||||
|
||||
static const GWL_ModifierInfo g_modifier_info_table[MOD_INDEX_NUM] = {
|
||||
[MOD_INDEX_SHIFT] =
|
||||
{
|
||||
.display_name = "Shift",
|
||||
.xkb_id = XKB_MOD_NAME_SHIFT,
|
||||
.key_l = GHOST_kKeyLeftShift,
|
||||
.key_r = GHOST_kKeyRightShift,
|
||||
.mod_l = GHOST_kModifierKeyLeftShift,
|
||||
.mod_r = GHOST_kModifierKeyRightShift,
|
||||
},
|
||||
[MOD_INDEX_ALT] =
|
||||
{
|
||||
.display_name = "Alt",
|
||||
.xkb_id = XKB_MOD_NAME_ALT,
|
||||
.key_l = GHOST_kKeyLeftAlt,
|
||||
.key_r = GHOST_kKeyRightAlt,
|
||||
.mod_l = GHOST_kModifierKeyLeftAlt,
|
||||
.mod_r = GHOST_kModifierKeyRightAlt,
|
||||
},
|
||||
[MOD_INDEX_CTRL] =
|
||||
{
|
||||
.display_name = "Control",
|
||||
.xkb_id = XKB_MOD_NAME_CTRL,
|
||||
.key_l = GHOST_kKeyLeftControl,
|
||||
.key_r = GHOST_kKeyRightControl,
|
||||
.mod_l = GHOST_kModifierKeyLeftControl,
|
||||
.mod_r = GHOST_kModifierKeyRightControl,
|
||||
},
|
||||
[MOD_INDEX_OS] =
|
||||
{
|
||||
.display_name = "OS",
|
||||
.xkb_id = XKB_MOD_NAME_LOGO,
|
||||
.key_l = GHOST_kKeyLeftOS,
|
||||
.key_r = GHOST_kKeyRightOS,
|
||||
.mod_l = GHOST_kModifierKeyLeftOS,
|
||||
.mod_r = GHOST_kModifierKeyRightOS,
|
||||
},
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Private Types & Defines
|
||||
* \{ */
|
||||
@@ -267,6 +326,15 @@ struct GWL_SeatStateKeyboard {
|
||||
struct wl_surface *wl_surface = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store held keys (only modifiers), could store other keys in the future.
|
||||
*
|
||||
* Needed as #GWL_Seat.xkb_state doesn't store which modifier keys are held.
|
||||
*/
|
||||
struct WGL_KeyboardDepressedState {
|
||||
int16_t mods[GHOST_KEY_MODIFIER_NUM] = {0};
|
||||
};
|
||||
|
||||
struct GWL_Seat {
|
||||
GHOST_SystemWayland *system = nullptr;
|
||||
|
||||
@@ -314,19 +382,15 @@ struct GWL_Seat {
|
||||
*/
|
||||
struct xkb_state *xkb_state_empty_with_numlock = nullptr;
|
||||
|
||||
/** Keys held matching `xkb_state`. */
|
||||
struct WGL_KeyboardDepressedState key_depressed;
|
||||
|
||||
/**
|
||||
* Cache result of `xkb_keymap_mod_get_index`
|
||||
* so every time a modifier is accessed a string lookup isn't required.
|
||||
* Be sure to check for #XKB_MOD_INVALID before using.
|
||||
*/
|
||||
struct {
|
||||
xkb_mod_index_t shift; /* #XKB_MOD_NAME_SHIFT */
|
||||
xkb_mod_index_t caps; /* #XKB_MOD_NAME_CAPS */
|
||||
xkb_mod_index_t ctrl; /* #XKB_MOD_NAME_CTRL */
|
||||
xkb_mod_index_t alt; /* #XKB_MOD_NAME_ALT */
|
||||
xkb_mod_index_t num; /* #XKB_MOD_NAME_NUM */
|
||||
xkb_mod_index_t logo; /* #XKB_MOD_NAME_LOGO */
|
||||
} xkb_keymap_mod_index;
|
||||
xkb_mod_index_t xkb_keymap_mod_index[MOD_INDEX_NUM];
|
||||
|
||||
struct {
|
||||
/** Key repetition in character per second. */
|
||||
@@ -613,8 +677,8 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
||||
GXMAP(gkey, XKB_KEY_Control_R, GHOST_kKeyRightControl);
|
||||
GXMAP(gkey, XKB_KEY_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(gkey, XKB_KEY_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(gkey, XKB_KEY_Super_R, GHOST_kKeyRightOS);
|
||||
GXMAP(gkey, XKB_KEY_Menu, GHOST_kKeyApp);
|
||||
|
||||
GXMAP(gkey, XKB_KEY_Caps_Lock, GHOST_kKeyCapsLock);
|
||||
@@ -861,6 +925,78 @@ static wl_buffer *ghost_wl_buffer_create_for_image(struct wl_shm *shm,
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Private Keyboard Depressed Key Tracking
|
||||
*
|
||||
* Don't track physical key-codes because there may be multiple keyboards connected.
|
||||
* Instead, count the number of #GHOST_kKey are pressed.
|
||||
* This may seem susceptible to bugs with sticky-keys however XKB works this way internally.
|
||||
* \{ */
|
||||
|
||||
static CLG_LogRef LOG_WL_KEYBOARD_DEPRESSED_STATE = {"ghost.wl.keyboard.depressed"};
|
||||
#define LOG (&LOG_WL_KEYBOARD_DEPRESSED_STATE)
|
||||
|
||||
static void keyboard_depressed_state_reset(GWL_Seat *seat)
|
||||
{
|
||||
for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
|
||||
seat->key_depressed.mods[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void keyboard_depressed_state_key_event(GWL_Seat *seat,
|
||||
const GHOST_TKey gkey,
|
||||
const GHOST_TEventType etype)
|
||||
{
|
||||
if (GHOST_KEY_MODIFIER_CHECK(gkey)) {
|
||||
const int index = GHOST_KEY_MODIFIER_TO_INDEX(gkey);
|
||||
int16_t &value = seat->key_depressed.mods[index];
|
||||
if (etype == GHOST_kEventKeyUp) {
|
||||
value -= 1;
|
||||
if (UNLIKELY(value < 0)) {
|
||||
CLOG_WARN(LOG, "modifier (%d) has negative keys held (%d)!", index, value);
|
||||
value = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
value += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void keyboard_depressed_state_push_events_from_change(
|
||||
GWL_Seat *seat, const WGL_KeyboardDepressedState &key_depressed_prev)
|
||||
{
|
||||
GHOST_IWindow *win = ghost_wl_surface_user_data(seat->keyboard.wl_surface);
|
||||
GHOST_SystemWayland *system = seat->system;
|
||||
|
||||
/* Separate key up and down into separate passes so key down events always come after key up.
|
||||
* Do this so users of GHOST can use the last pressed or released modifier to check
|
||||
* if the modifier is held instead of counting modifiers pressed as is done here,
|
||||
* this isn't perfect but works well enough in practice. */
|
||||
for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
|
||||
for (int d = seat->key_depressed.mods[i] - key_depressed_prev.mods[i]; d < 0; d++) {
|
||||
const GHOST_TKey gkey = GHOST_KEY_MODIFIER_FROM_INDEX(i);
|
||||
seat->system->pushEvent(
|
||||
new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyUp, win, gkey, false));
|
||||
|
||||
CLOG_INFO(LOG, 2, "modifier (%d) up", i);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < GHOST_KEY_MODIFIER_NUM; i++) {
|
||||
for (int d = seat->key_depressed.mods[i] - key_depressed_prev.mods[i]; d > 0; d--) {
|
||||
const GHOST_TKey gkey = GHOST_KEY_MODIFIER_FROM_INDEX(i);
|
||||
seat->system->pushEvent(
|
||||
new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
|
||||
CLOG_INFO(LOG, 2, "modifier (%d) down", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef LOG
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Listener (Relative Motion), #zwp_relative_pointer_v1_listener
|
||||
*
|
||||
@@ -2127,12 +2263,12 @@ static void keyboard_handle_keymap(void *data,
|
||||
}
|
||||
}
|
||||
|
||||
seat->xkb_keymap_mod_index.shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
|
||||
seat->xkb_keymap_mod_index.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
|
||||
seat->xkb_keymap_mod_index.ctrl = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
|
||||
seat->xkb_keymap_mod_index.alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
|
||||
seat->xkb_keymap_mod_index.num = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_NUM);
|
||||
seat->xkb_keymap_mod_index.logo = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_LOGO);
|
||||
for (int i = 0; i < MOD_INDEX_NUM; i++) {
|
||||
const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
|
||||
seat->xkb_keymap_mod_index[i] = xkb_keymap_mod_get_index(keymap, mod_info.xkb_id);
|
||||
}
|
||||
|
||||
keyboard_depressed_state_reset(seat);
|
||||
|
||||
xkb_keymap_unref(keymap);
|
||||
}
|
||||
@@ -2158,48 +2294,23 @@ static void keyboard_handle_enter(void *data,
|
||||
seat->keyboard.serial = serial;
|
||||
seat->keyboard.wl_surface = wl_surface;
|
||||
|
||||
if (keys->size != 0) {
|
||||
/* If there are any keys held when activating the window,
|
||||
* modifiers will be compared against the seat state,
|
||||
* only enabling modifiers that were previously disabled. */
|
||||
/* If there are any keys held when activating the window,
|
||||
* modifiers will be compared against the seat state,
|
||||
* only enabling modifiers that were previously disabled. */
|
||||
WGL_KeyboardDepressedState key_depressed_prev = seat->key_depressed;
|
||||
keyboard_depressed_state_reset(seat);
|
||||
|
||||
const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_ALL);
|
||||
uint32_t *key;
|
||||
WL_ARRAY_FOR_EACH (key, keys) {
|
||||
const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
|
||||
const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, key_code);
|
||||
GHOST_TKey gkey = GHOST_kKeyUnknown;
|
||||
|
||||
#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
|
||||
#define MOD_TEST_CASE(xkb_key, ghost_key, mod_index) \
|
||||
case xkb_key: \
|
||||
if (!MOD_TEST(state, seat->xkb_keymap_mod_index.mod_index)) { \
|
||||
gkey = ghost_key; \
|
||||
} \
|
||||
break
|
||||
|
||||
switch (sym) {
|
||||
MOD_TEST_CASE(XKB_KEY_Shift_L, GHOST_kKeyLeftShift, shift);
|
||||
MOD_TEST_CASE(XKB_KEY_Shift_R, GHOST_kKeyRightShift, shift);
|
||||
MOD_TEST_CASE(XKB_KEY_Control_L, GHOST_kKeyLeftControl, ctrl);
|
||||
MOD_TEST_CASE(XKB_KEY_Control_R, GHOST_kKeyRightControl, ctrl);
|
||||
MOD_TEST_CASE(XKB_KEY_Alt_L, GHOST_kKeyLeftAlt, alt);
|
||||
MOD_TEST_CASE(XKB_KEY_Alt_R, GHOST_kKeyRightAlt, alt);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_L, GHOST_kKeyOS, logo);
|
||||
MOD_TEST_CASE(XKB_KEY_Super_R, GHOST_kKeyOS, logo);
|
||||
}
|
||||
|
||||
#undef MOD_TEST
|
||||
#undef MOD_TEST_CASE
|
||||
|
||||
if (gkey != GHOST_kKeyUnknown) {
|
||||
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface);
|
||||
GHOST_SystemWayland *system = seat->system;
|
||||
seat->system->pushEvent(
|
||||
new GHOST_EventKey(system->getMilliSeconds(), GHOST_kEventKeyDown, win, gkey, false));
|
||||
}
|
||||
uint32_t *key;
|
||||
WL_ARRAY_FOR_EACH (key, keys) {
|
||||
const xkb_keycode_t key_code = *key + EVDEV_OFFSET;
|
||||
const xkb_keysym_t sym = xkb_state_key_get_one_sym(seat->xkb_state, key_code);
|
||||
const GHOST_TKey gkey = xkb_map_gkey_or_scan_code(sym, *key);
|
||||
if (gkey != GHOST_kKeyUnknown) {
|
||||
keyboard_depressed_state_key_event(seat, gkey, GHOST_kEventKeyDown);
|
||||
}
|
||||
}
|
||||
|
||||
keyboard_depressed_state_push_events_from_change(seat, key_depressed_prev);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2373,6 +2484,8 @@ static void keyboard_handle_key(void *data,
|
||||
|
||||
seat->data_source_serial = serial;
|
||||
|
||||
keyboard_depressed_state_key_event(seat, gkey, etype);
|
||||
|
||||
if (wl_surface *wl_surface_focus = seat->keyboard.wl_surface) {
|
||||
GHOST_IWindow *win = ghost_wl_surface_user_data(wl_surface_focus);
|
||||
seat->system->pushEvent(
|
||||
@@ -2818,24 +2931,24 @@ static void global_handle_add(void *data,
|
||||
bool found = true;
|
||||
|
||||
struct GWL_Display *display = static_cast<struct GWL_Display *>(data);
|
||||
if (!strcmp(interface, wl_compositor_interface.name)) {
|
||||
if (STREQ(interface, wl_compositor_interface.name)) {
|
||||
display->compositor = static_cast<wl_compositor *>(
|
||||
wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3));
|
||||
}
|
||||
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
|
||||
/* Pass. */
|
||||
#else
|
||||
else if (!strcmp(interface, xdg_wm_base_interface.name)) {
|
||||
else if (STREQ(interface, xdg_wm_base_interface.name)) {
|
||||
display->xdg_shell = static_cast<xdg_wm_base *>(
|
||||
wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1));
|
||||
xdg_wm_base_add_listener(display->xdg_shell, &shell_listener, nullptr);
|
||||
}
|
||||
else if (!strcmp(interface, zxdg_decoration_manager_v1_interface.name)) {
|
||||
else if (STREQ(interface, zxdg_decoration_manager_v1_interface.name)) {
|
||||
display->xdg_decoration_manager = static_cast<zxdg_decoration_manager_v1 *>(
|
||||
wl_registry_bind(wl_registry, name, &zxdg_decoration_manager_v1_interface, 1));
|
||||
}
|
||||
#endif /* !WITH_GHOST_WAYLAND_LIBDECOR. */
|
||||
else if (!strcmp(interface, zxdg_output_manager_v1_interface.name)) {
|
||||
else if (STREQ(interface, zxdg_output_manager_v1_interface.name)) {
|
||||
display->xdg_output_manager = static_cast<zxdg_output_manager_v1 *>(
|
||||
wl_registry_bind(wl_registry, name, &zxdg_output_manager_v1_interface, 2));
|
||||
for (GWL_Output *output : display->outputs) {
|
||||
@@ -2844,7 +2957,7 @@ static void global_handle_add(void *data,
|
||||
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(interface, wl_output_interface.name)) {
|
||||
else if (STREQ(interface, wl_output_interface.name)) {
|
||||
GWL_Output *output = new GWL_Output;
|
||||
output->wl_output = static_cast<wl_output *>(
|
||||
wl_registry_bind(wl_registry, name, &wl_output_interface, 2));
|
||||
@@ -2860,7 +2973,7 @@ static void global_handle_add(void *data,
|
||||
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(interface, wl_seat_interface.name)) {
|
||||
else if (STREQ(interface, wl_seat_interface.name)) {
|
||||
GWL_Seat *seat = new GWL_Seat;
|
||||
seat->system = display->system;
|
||||
seat->xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
@@ -2870,23 +2983,23 @@ static void global_handle_add(void *data,
|
||||
display->seats.push_back(seat);
|
||||
wl_seat_add_listener(seat->wl_seat, &seat_listener, seat);
|
||||
}
|
||||
else if (!strcmp(interface, wl_shm_interface.name)) {
|
||||
else if (STREQ(interface, wl_shm_interface.name)) {
|
||||
display->shm = static_cast<wl_shm *>(
|
||||
wl_registry_bind(wl_registry, name, &wl_shm_interface, 1));
|
||||
}
|
||||
else if (!strcmp(interface, wl_data_device_manager_interface.name)) {
|
||||
else if (STREQ(interface, wl_data_device_manager_interface.name)) {
|
||||
display->data_device_manager = static_cast<wl_data_device_manager *>(
|
||||
wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, 3));
|
||||
}
|
||||
else if (!strcmp(interface, zwp_tablet_manager_v2_interface.name)) {
|
||||
else if (STREQ(interface, zwp_tablet_manager_v2_interface.name)) {
|
||||
display->tablet_manager = static_cast<zwp_tablet_manager_v2 *>(
|
||||
wl_registry_bind(wl_registry, name, &zwp_tablet_manager_v2_interface, 1));
|
||||
}
|
||||
else if (!strcmp(interface, zwp_relative_pointer_manager_v1_interface.name)) {
|
||||
else if (STREQ(interface, zwp_relative_pointer_manager_v1_interface.name)) {
|
||||
display->relative_pointer_manager = static_cast<zwp_relative_pointer_manager_v1 *>(
|
||||
wl_registry_bind(wl_registry, name, &zwp_relative_pointer_manager_v1_interface, 1));
|
||||
}
|
||||
else if (!strcmp(interface, zwp_pointer_constraints_v1_interface.name)) {
|
||||
else if (STREQ(interface, zwp_pointer_constraints_v1_interface.name)) {
|
||||
display->pointer_constraints = static_cast<zwp_pointer_constraints_v1 *>(
|
||||
wl_registry_bind(wl_registry, name, &zwp_pointer_constraints_v1_interface, 1));
|
||||
}
|
||||
@@ -3048,33 +3161,43 @@ GHOST_TSuccess GHOST_SystemWayland::getModifierKeys(GHOST_ModifierKeys &keys) co
|
||||
|
||||
GWL_Seat *seat = d->seats[0];
|
||||
|
||||
bool val;
|
||||
const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_DEPRESSED);
|
||||
|
||||
/* NOTE: XKB doesn't differentiate between left/right modifiers
|
||||
* for it's internal modifier state storage. */
|
||||
const xkb_mod_mask_t state = xkb_state_serialize_mods(seat->xkb_state, XKB_STATE_MODS_ALL);
|
||||
/* Use local #WGL_KeyboardDepressedState to check which key is pressed.
|
||||
* Use XKB as the source of truth, if there is any discrepancy. */
|
||||
for (int i = 0; i < MOD_INDEX_NUM; i++) {
|
||||
if (UNLIKELY(seat->xkb_keymap_mod_index[i] == XKB_MOD_INVALID)) {
|
||||
continue;
|
||||
}
|
||||
const GWL_ModifierInfo &mod_info = g_modifier_info_table[i];
|
||||
const bool val = (state & (1 << seat->xkb_keymap_mod_index[i])) != 0;
|
||||
bool val_l = seat->key_depressed.mods[GHOST_KEY_MODIFIER_TO_INDEX(mod_info.key_l)] > 0;
|
||||
bool val_r = seat->key_depressed.mods[GHOST_KEY_MODIFIER_TO_INDEX(mod_info.key_r)] > 0;
|
||||
|
||||
#define MOD_TEST(state, mod) ((mod != XKB_MOD_INVALID) && (state & (1 << mod)))
|
||||
/* This shouldn't be needed, but guard against any possibility of modifiers being stuck.
|
||||
* Warn so if this happens it can be investigated. */
|
||||
if (val) {
|
||||
if (UNLIKELY(!(val_l || val_r))) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (held keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
/* Picking the left is arbitrary. */
|
||||
val_l = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (UNLIKELY(val_l || val_r)) {
|
||||
CLOG_WARN(&LOG_WL_KEYBOARD_DEPRESSED_STATE,
|
||||
"modifier (%s) state is inconsistent (released keys do not match XKB)",
|
||||
mod_info.display_name);
|
||||
val_l = false;
|
||||
val_r = false;
|
||||
}
|
||||
}
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.shift);
|
||||
keys.set(GHOST_kModifierKeyLeftShift, val);
|
||||
keys.set(GHOST_kModifierKeyRightShift, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.alt);
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, val);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.ctrl);
|
||||
keys.set(GHOST_kModifierKeyLeftControl, val);
|
||||
keys.set(GHOST_kModifierKeyRightControl, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.logo);
|
||||
keys.set(GHOST_kModifierKeyOS, val);
|
||||
|
||||
val = MOD_TEST(state, seat->xkb_keymap_mod_index.num);
|
||||
keys.set(GHOST_kModifierKeyNum, val);
|
||||
|
||||
#undef MOD_TEST
|
||||
keys.set(mod_info.mod_l, val_l);
|
||||
keys.set(mod_info.mod_r, val_r);
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
@@ -456,14 +456,11 @@ GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) cons
|
||||
down = HIBYTE(::GetKeyState(VK_RCONTROL)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightControl, down);
|
||||
|
||||
bool lwindown = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
|
||||
bool rwindown = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
|
||||
if (lwindown || rwindown) {
|
||||
keys.set(GHOST_kModifierKeyOS, true);
|
||||
}
|
||||
else {
|
||||
keys.set(GHOST_kModifierKeyOS, false);
|
||||
}
|
||||
down = HIBYTE(::GetKeyState(VK_LWIN)) != 0;
|
||||
keys.set(GHOST_kModifierKeyLeftOS, down);
|
||||
down = HIBYTE(::GetKeyState(VK_RWIN)) != 0;
|
||||
keys.set(GHOST_kModifierKeyRightOS, down);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
@@ -751,8 +748,10 @@ GHOST_TKey GHOST_SystemWin32::convertKey(short vKey, short scanCode, short exten
|
||||
key = (extend) ? GHOST_kKeyRightAlt : GHOST_kKeyLeftAlt;
|
||||
break;
|
||||
case VK_LWIN:
|
||||
key = GHOST_kKeyLeftOS;
|
||||
break;
|
||||
case VK_RWIN:
|
||||
key = GHOST_kKeyOS;
|
||||
key = GHOST_kKeyRightOS;
|
||||
break;
|
||||
case VK_APPS:
|
||||
key = GHOST_kKeyApp;
|
||||
@@ -1137,12 +1136,18 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
||||
GHOST_TKey key = system->hardKey(raw, &key_down);
|
||||
GHOST_EventKey *event;
|
||||
|
||||
/* NOTE(@campbellbarton): key repeat in WIN32 also applies to modifier-keys.
|
||||
* Check for this case and filter out modifier-repeat.
|
||||
* Typically keyboard events are *not* filtered as part of GHOST's event handling.
|
||||
* As other GHOST back-ends don't have the behavior, it's simplest not to send them through.
|
||||
* Ideally it would be possible to check the key-map for keys that repeat but this doesn't look
|
||||
* to be supported. */
|
||||
bool is_repeat = false;
|
||||
bool is_repeated_modifier = false;
|
||||
if (key_down) {
|
||||
if (system->m_keycode_last_repeat_key == vk) {
|
||||
is_repeat = true;
|
||||
is_repeated_modifier = (key >= GHOST_kKeyLeftShift && key <= GHOST_kKeyRightAlt);
|
||||
is_repeated_modifier = GHOST_KEY_MODIFIER_CHECK(key);
|
||||
}
|
||||
system->m_keycode_last_repeat_key = vk;
|
||||
}
|
||||
|
@@ -105,7 +105,7 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param glSettings: Misc OpenGL settings.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used fullscreen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -1065,7 +1065,8 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
case GHOST_kKeyLeftShift:
|
||||
case GHOST_kKeyRightControl:
|
||||
case GHOST_kKeyLeftControl:
|
||||
case GHOST_kKeyOS:
|
||||
case GHOST_kKeyLeftOS:
|
||||
case GHOST_kKeyRightOS:
|
||||
case GHOST_kKey0:
|
||||
case GHOST_kKey1:
|
||||
case GHOST_kKey2:
|
||||
@@ -1600,9 +1601,10 @@ GHOST_TSuccess GHOST_SystemX11::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
keys.set(GHOST_kModifierKeyLeftAlt, ((m_keyboard_vector[alt_l >> 3] >> (alt_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightAlt, ((m_keyboard_vector[alt_r >> 3] >> (alt_r & 7)) & 1) != 0);
|
||||
/* super (windows) - only one GHOST-kModifierKeyOS, so mapping to either */
|
||||
keys.set(GHOST_kModifierKeyOS,
|
||||
(((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) ||
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1)) != 0);
|
||||
keys.set(GHOST_kModifierKeyLeftOS,
|
||||
((m_keyboard_vector[super_l >> 3] >> (super_l & 7)) & 1) != 0);
|
||||
keys.set(GHOST_kModifierKeyRightOS,
|
||||
((m_keyboard_vector[super_r >> 3] >> (super_r & 7)) & 1) != 0);
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -1818,8 +1820,8 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
|
||||
GXMAP(type, XK_Control_R, GHOST_kKeyRightControl);
|
||||
GXMAP(type, XK_Alt_L, GHOST_kKeyLeftAlt);
|
||||
GXMAP(type, XK_Alt_R, GHOST_kKeyRightAlt);
|
||||
GXMAP(type, XK_Super_L, GHOST_kKeyOS);
|
||||
GXMAP(type, XK_Super_R, GHOST_kKeyOS);
|
||||
GXMAP(type, XK_Super_L, GHOST_kKeyLeftOS);
|
||||
GXMAP(type, XK_Super_R, GHOST_kKeyRightOS);
|
||||
|
||||
GXMAP(type, XK_Insert, GHOST_kKeyInsert);
|
||||
GXMAP(type, XK_Delete, GHOST_kKeyDelete);
|
||||
|
@@ -115,7 +115,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
* \param state: The state of the window when opened.
|
||||
* \param type: The type of drawing context installed in this window.
|
||||
* \param stereoVisual: Create a stereo visual for quad buffered stereo.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used full*screen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
* \param parentWindow: Parent (embedder) window.
|
||||
* \return The new window (or 0 if creation failed).
|
||||
*/
|
||||
|
@@ -92,6 +92,11 @@ GHOST_TSuccess GHOST_Window::getSwapInterval(int &intervalOut)
|
||||
return m_context->getSwapInterval(intervalOut);
|
||||
}
|
||||
|
||||
GHOST_Context *GHOST_Window::getContext()
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
unsigned int GHOST_Window::getDefaultFramebuffer()
|
||||
{
|
||||
return (m_context) ? m_context->getDefaultFramebuffer() : 0;
|
||||
|
@@ -29,7 +29,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param height: The height of the window.
|
||||
* \param state: The state the window is initially opened with.
|
||||
* \param wantStereoVisual: Stereo visual for quad buffered stereo.
|
||||
* \param exclusive: Use to show the window ontop and ignore others (used full-screen).
|
||||
* \param exclusive: Use to show the window on top and ignore others (used full-screen).
|
||||
*/
|
||||
GHOST_Window(uint32_t width,
|
||||
uint32_t height,
|
||||
@@ -72,7 +72,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* Returns indication as to whether the window is valid.
|
||||
* \return The validity of the window.
|
||||
*/
|
||||
virtual bool getValid() const
|
||||
virtual bool getValid() const override
|
||||
{
|
||||
return m_context != NULL;
|
||||
}
|
||||
@@ -81,15 +81,15 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* Returns the associated OS object/handle
|
||||
* \return The associated OS object/handle
|
||||
*/
|
||||
virtual void *getOSWindow() const;
|
||||
virtual void *getOSWindow() const override;
|
||||
|
||||
/**
|
||||
* Returns the current cursor shape.
|
||||
* \return The current cursor shape.
|
||||
*/
|
||||
inline GHOST_TStandardCursor getCursorShape() const;
|
||||
inline GHOST_TStandardCursor getCursorShape() const override;
|
||||
|
||||
inline bool isDialog() const
|
||||
inline bool isDialog() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param cursorShape: The new cursor shape type id.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape);
|
||||
GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) override;
|
||||
|
||||
/**
|
||||
* Set the shape of the cursor to a custom cursor.
|
||||
@@ -115,15 +115,15 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
int sizey,
|
||||
int hotX,
|
||||
int hotY,
|
||||
bool canInvertColor);
|
||||
bool canInvertColor) override;
|
||||
|
||||
GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap);
|
||||
GHOST_TSuccess getCursorBitmap(GHOST_CursorBitmapRef *bitmap) override;
|
||||
|
||||
/**
|
||||
* Returns the visibility state of the cursor.
|
||||
* \return The visibility state of the cursor.
|
||||
*/
|
||||
inline bool getCursorVisibility() const;
|
||||
inline bool getCursorVisibility() const override;
|
||||
inline GHOST_TGrabCursorMode getCursorGrabMode() const;
|
||||
inline bool getCursorGrabModeIsWarp() const;
|
||||
inline GHOST_TAxisFlag getCursorGrabAxis() const;
|
||||
@@ -136,7 +136,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param visible: The new visibility state of the cursor.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
GHOST_TSuccess setCursorVisibility(bool visible);
|
||||
GHOST_TSuccess setCursorVisibility(bool visible) override;
|
||||
|
||||
/**
|
||||
* Sets the cursor grab.
|
||||
@@ -146,28 +146,28 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode,
|
||||
GHOST_TAxisFlag wrap_axis,
|
||||
GHOST_Rect *bounds,
|
||||
int32_t mouse_ungrab_xy[2]);
|
||||
int32_t mouse_ungrab_xy[2]) override;
|
||||
|
||||
/**
|
||||
* Gets the cursor grab region, if unset the window is used.
|
||||
* reset when grab is disabled.
|
||||
*/
|
||||
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds);
|
||||
GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) override;
|
||||
|
||||
void getCursorGrabState(GHOST_TGrabCursorMode &mode,
|
||||
GHOST_TAxisFlag &axis_flag,
|
||||
GHOST_Rect &bounds,
|
||||
bool &use_software_cursor);
|
||||
bool &use_software_cursor) override;
|
||||
/**
|
||||
* Return true when a software cursor should be used.
|
||||
*/
|
||||
bool getCursorGrabUseSoftwareDisplay();
|
||||
bool getCursorGrabUseSoftwareDisplay() override;
|
||||
|
||||
/**
|
||||
* Sets the progress bar value displayed in the window/application icon
|
||||
* \param progress: The progress percentage (0.0 to 1.0).
|
||||
*/
|
||||
virtual GHOST_TSuccess setProgressBar(float /*progress*/)
|
||||
virtual GHOST_TSuccess setProgressBar(float /*progress*/) override
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
@@ -175,7 +175,7 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
/**
|
||||
* Hides the progress bar in the icon
|
||||
*/
|
||||
virtual GHOST_TSuccess endProgressBar()
|
||||
virtual GHOST_TSuccess endProgressBar() override
|
||||
{
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
@@ -185,43 +185,43 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param interval: The swap interval to use.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
GHOST_TSuccess setSwapInterval(int interval);
|
||||
GHOST_TSuccess setSwapInterval(int interval) override;
|
||||
|
||||
/**
|
||||
* Gets the current swap interval for #swapBuffers.
|
||||
* \return An integer.
|
||||
*/
|
||||
GHOST_TSuccess getSwapInterval(int &intervalOut);
|
||||
GHOST_TSuccess getSwapInterval(int &intervalOut) override;
|
||||
|
||||
/**
|
||||
* Tells if the ongoing drag'n'drop object can be accepted upon mouse drop
|
||||
*/
|
||||
void setAcceptDragOperation(bool canAccept);
|
||||
void setAcceptDragOperation(bool canAccept) override;
|
||||
|
||||
/**
|
||||
* Returns acceptance of the dropped object
|
||||
* Usually called by the "object dropped" event handling function
|
||||
*/
|
||||
bool canAcceptDragOperation() const;
|
||||
bool canAcceptDragOperation() const override;
|
||||
|
||||
/**
|
||||
* Sets the window "modified" status, indicating unsaved changes
|
||||
* \param isUnsavedChanges: Unsaved changes or not.
|
||||
* \return Indication of success.
|
||||
*/
|
||||
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges);
|
||||
virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) override;
|
||||
|
||||
/**
|
||||
* Gets the window "modified" status, indicating unsaved changes
|
||||
* \return True if there are unsaved changes
|
||||
*/
|
||||
virtual bool getModifiedState();
|
||||
virtual bool getModifiedState() override;
|
||||
|
||||
/**
|
||||
* Returns the type of drawing context used in this window.
|
||||
* \return The current type of drawing context.
|
||||
*/
|
||||
inline GHOST_TDrawingContextType getDrawingContextType();
|
||||
inline GHOST_TDrawingContextType getDrawingContextType() override;
|
||||
|
||||
/**
|
||||
* Tries to install a rendering context in this window.
|
||||
@@ -230,19 +230,19 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* \param type: The type of rendering context installed.
|
||||
* \return Indication as to whether installation has succeeded.
|
||||
*/
|
||||
GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type);
|
||||
GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) override;
|
||||
|
||||
/**
|
||||
* Swaps front and back buffers of a window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess swapBuffers();
|
||||
virtual GHOST_TSuccess swapBuffers() override;
|
||||
|
||||
/**
|
||||
* Activates the drawing context of this window.
|
||||
* \return A boolean success indicator.
|
||||
*/
|
||||
virtual GHOST_TSuccess activateDrawingContext();
|
||||
virtual GHOST_TSuccess activateDrawingContext() override;
|
||||
|
||||
/**
|
||||
* Updates the drawing context of this window. Needed
|
||||
@@ -251,17 +251,23 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
*/
|
||||
GHOST_TSuccess updateDrawingContext();
|
||||
|
||||
/**
|
||||
* Get the drawing context associated with this window.
|
||||
*\return Pointer to the context object.
|
||||
*/
|
||||
GHOST_Context *getContext();
|
||||
|
||||
/**
|
||||
* Gets the OpenGL frame-buffer associated with the window's contents.
|
||||
* \return The ID of an OpenGL frame-buffer object.
|
||||
*/
|
||||
virtual unsigned int getDefaultFramebuffer();
|
||||
virtual unsigned int getDefaultFramebuffer() override;
|
||||
|
||||
/**
|
||||
* Returns the window user data.
|
||||
* \return The window user data.
|
||||
*/
|
||||
inline GHOST_TUserDataPtr getUserData() const
|
||||
inline GHOST_TUserDataPtr getUserData() const override
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
@@ -270,12 +276,12 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* Changes the window user data.
|
||||
* \param userData: The window user data.
|
||||
*/
|
||||
void setUserData(const GHOST_TUserDataPtr userData)
|
||||
void setUserData(const GHOST_TUserDataPtr userData) override
|
||||
{
|
||||
m_userData = userData;
|
||||
}
|
||||
|
||||
float getNativePixelSize(void)
|
||||
float getNativePixelSize(void) override
|
||||
{
|
||||
if (m_nativePixelSize > 0.0f)
|
||||
return m_nativePixelSize;
|
||||
@@ -286,18 +292,18 @@ class GHOST_Window : public GHOST_IWindow {
|
||||
* Returns the recommended DPI for this window.
|
||||
* \return The recommended DPI for this window.
|
||||
*/
|
||||
virtual inline uint16_t getDPIHint()
|
||||
virtual inline uint16_t getDPIHint() override
|
||||
{
|
||||
return 96;
|
||||
}
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
virtual void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed)
|
||||
virtual void beginIME(int32_t x, int32_t y, int32_t w, int32_t h, bool completed) override
|
||||
{
|
||||
/* do nothing temporarily if not in windows */
|
||||
}
|
||||
|
||||
virtual void endIME()
|
||||
virtual void endIME() override
|
||||
{
|
||||
/* do nothing temporarily if not in windows */
|
||||
}
|
||||
|
@@ -719,7 +719,7 @@ void GHOST_WindowCocoa::setNativePixelSize(void)
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Fullscreen switch is not actual fullscreen with display capture.
|
||||
* \note Full-screen switch is not actual fullscreen with display capture.
|
||||
* As this capture removes all OS X window manager features.
|
||||
*
|
||||
* Instead, the menu bar and the dock are hidden, and the window is made border-less and enlarged.
|
||||
|
@@ -113,13 +113,13 @@ class GHOST_WindowManager {
|
||||
/** The list of windows managed */
|
||||
std::vector<GHOST_IWindow *> m_windows;
|
||||
|
||||
/** Window in fullscreen state. There can be only one of this which is not in or window list. */
|
||||
/** Window in full-screen state. There can be only one of this which is not in or window list. */
|
||||
GHOST_IWindow *m_fullScreenWindow;
|
||||
|
||||
/** The active window. */
|
||||
GHOST_IWindow *m_activeWindow;
|
||||
|
||||
/** Window that was active before entering fullscreen state. */
|
||||
/** Window that was active before entering full-screen state. */
|
||||
GHOST_IWindow *m_activeWindowBeforeFullScreen;
|
||||
|
||||
#ifdef WITH_CXX_GUARDEDALLOC
|
||||
|
@@ -226,7 +226,7 @@
|
||||
[super drawRect:rect];
|
||||
systemCocoa->handleWindowEvent(GHOST_kEventWindowUpdate, associatedWindow);
|
||||
|
||||
/* For some cases like entering fullscreen we need to redraw immediately
|
||||
/* For some cases like entering full-screen we need to redraw immediately
|
||||
* so our window does not show blank during the animation */
|
||||
if (associatedWindow->getImmediateDraw())
|
||||
systemCocoa->dispatchEvents();
|
||||
|
@@ -217,7 +217,7 @@ GHOST_WindowX11::GHOST_WindowX11(GHOST_SystemX11 *system,
|
||||
* So, m_post_init indicate that we need wait for the MapNotify
|
||||
* event and then set the Window state to the m_post_state.
|
||||
*/
|
||||
else if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
|
||||
else if (!ELEM(state, GHOST_kWindowStateNormal, GHOST_kWindowStateMinimized)) {
|
||||
m_post_init = True;
|
||||
m_post_state = state;
|
||||
}
|
||||
@@ -1605,7 +1605,7 @@ uint16_t GHOST_WindowX11::getDPIHint()
|
||||
|
||||
int success = XrmGetResource(xrdb, "Xft.dpi", "Xft.Dpi", &type, &val);
|
||||
if (success && type) {
|
||||
if (strcmp(type, "String") == 0) {
|
||||
if (STREQ(type, "String")) {
|
||||
return atoi((char *)val.addr);
|
||||
}
|
||||
}
|
||||
|
@@ -208,3 +208,32 @@
|
||||
(void)0
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name String Macros
|
||||
* \{ */
|
||||
|
||||
/* Macro to convert a value to string in the preprocessor:
|
||||
* - `STRINGIFY_ARG`: gives the argument as a string
|
||||
* - `STRINGIFY_APPEND`: appends any argument 'b' onto the string argument 'a',
|
||||
* used by `STRINGIFY` because some preprocessors warn about zero arguments.
|
||||
* - `STRINGIFY`: gives the argument's value as a string. */
|
||||
|
||||
#define STRINGIFY_ARG(x) "" #x
|
||||
#define STRINGIFY_APPEND(a, b) "" a #b
|
||||
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
|
||||
|
||||
/* generic strcmp macros */
|
||||
#if defined(_MSC_VER)
|
||||
# define strcasecmp _stricmp
|
||||
# define strncasecmp _strnicmp
|
||||
#endif
|
||||
|
||||
#define STREQ(a, b) (strcmp(a, b) == 0)
|
||||
#define STRCASEEQ(a, b) (strcasecmp(a, b) == 0)
|
||||
#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
|
||||
#define STRCASEEQLEN(a, b, n) (strncasecmp(a, b, n) == 0)
|
||||
|
||||
#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
|
||||
|
||||
/** \} */
|
||||
|
@@ -315,7 +315,7 @@ bool processEvent(GHOST_EventHandle hEvent, GHOST_TUserDataPtr userData)
|
||||
} break;
|
||||
case GHOST_kKeyF:
|
||||
if (!GHOST_GetFullScreen(shSystem)) {
|
||||
/* Begin fullscreen mode */
|
||||
/* Begin full-screen mode. */
|
||||
setting.bpp = 24;
|
||||
setting.frequency = 85;
|
||||
setting.xPixels = 640;
|
||||
|
@@ -323,7 +323,7 @@ MainWindow *mainwindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
MainWindow *mw = MEM_callocN(sizeof(*mw), "mainwindow_new");
|
||||
|
||||
mw->gpu_context = GPU_context_create(win);
|
||||
mw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
mw->app = app;
|
||||
@@ -578,7 +578,7 @@ LoggerWindow *loggerwindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
LoggerWindow *lw = MEM_callocN(sizeof(*lw), "loggerwindow_new");
|
||||
|
||||
lw->gpu_context = GPU_context_create(win);
|
||||
lw->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
int bbox[2][2];
|
||||
@@ -780,7 +780,7 @@ ExtraWindow *extrawindow_new(MultiTestApp *app)
|
||||
if (win) {
|
||||
ExtraWindow *ew = MEM_callocN(sizeof(*ew), "mainwindow_new");
|
||||
|
||||
ew->gpu_context = GPU_context_create(win);
|
||||
ew->gpu_context = GPU_context_create(win, NULL);
|
||||
GPU_init();
|
||||
|
||||
ew->app = app;
|
||||
|
@@ -7,6 +7,7 @@ endif()
|
||||
|
||||
set(INC
|
||||
.
|
||||
..
|
||||
../atomic
|
||||
)
|
||||
|
||||
|
@@ -139,8 +139,8 @@ void radixsort(std::vector<T> &data, std::vector<T> &data2, KeyGetter getKey)
|
||||
|
||||
static void float_add_atomic(float *val, float add)
|
||||
{
|
||||
/* Hacky, but atomic floats are only supported from C++20 onwards.
|
||||
* This works in practise since std::atomic<uint32_t> is really just an uint32_t in memory,
|
||||
/* Hacky, but atomic floats are only supported from C++20 onward.
|
||||
* This works in practice since `std::atomic<uint32_t>` is really just an `uint32_t` in memory,
|
||||
* so this cast lets us do a 32-bit CAS operation (which is used to build the atomic float
|
||||
* operation) without needing any external libraries or compiler-specific builtins. */
|
||||
std::atomic<uint32_t> *atomic_val = reinterpret_cast<std::atomic<uint32_t> *>(val);
|
||||
|
@@ -401,7 +401,7 @@ template<typename Mesh> class Mikktspace {
|
||||
});
|
||||
|
||||
std::stable_partition(triangles.begin(), triangles.end(), [](const Triangle &tri) {
|
||||
return tri.markDegenerate;
|
||||
return !tri.markDegenerate;
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -130,8 +130,10 @@ vec4 apply_dither(vec4 col, vec2 uv)
|
||||
* \{ */
|
||||
|
||||
/* Prototypes: Implementation is generaterd and defined after. */
|
||||
#ifndef GPU_METAL /* Forward declaration invalid in MSL. */
|
||||
vec4 OCIO_to_scene_linear(vec4 pixel);
|
||||
vec4 OCIO_to_display(vec4 pixel);
|
||||
#endif
|
||||
|
||||
vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay)
|
||||
{
|
||||
|
@@ -81,11 +81,11 @@ if(WITH_OPENSUBDIV)
|
||||
)
|
||||
endif()
|
||||
|
||||
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
|
||||
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
|
||||
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
|
||||
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
|
||||
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
|
||||
opensubdiv_define_component(OPENSUBDIV_HAS_OPENMP)
|
||||
opensubdiv_define_component(OPENSUBDIV_HAS_OPENCL)
|
||||
opensubdiv_define_component(OPENSUBDIV_HAS_CUDA)
|
||||
opensubdiv_define_component(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
|
||||
opensubdiv_define_component(OPENSUBDIV_HAS_GLSL_COMPUTE)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DNOMINMAX)
|
||||
@@ -110,7 +110,6 @@ if(WITH_GTESTS AND WITH_OPENSUBDIV)
|
||||
|
||||
add_definitions(${GFLAGS_DEFINES})
|
||||
add_definitions(${GLOG_DEFINES})
|
||||
add_definitions(-DBLENDER_GFLAGS_NAMESPACE=${GFLAGS_NAMESPACE})
|
||||
|
||||
blender_add_test_executable(opensubdiv_mesh_topology_test "internal/topology/mesh_topology_test.cc" "${INC}" "${INC_SYS}" "${LIB};bf_intern_opensubdiv")
|
||||
endif()
|
||||
|
@@ -29,7 +29,7 @@ RE_DEF_COMPLETE = re.compile(
|
||||
def reduce_newlines(text):
|
||||
"""Reduces multiple newlines to a single newline.
|
||||
|
||||
:param text: text with multiple newlines
|
||||
:arg text: text with multiple newlines
|
||||
:type text: str
|
||||
:returns: text with single newlines
|
||||
:rtype: str
|
||||
@@ -43,7 +43,7 @@ def reduce_newlines(text):
|
||||
def reduce_spaces(text):
|
||||
"""Reduces multiple whitespaces to a single space.
|
||||
|
||||
:param text: text with multiple spaces
|
||||
:arg text: text with multiple spaces
|
||||
:type text: str
|
||||
:returns: text with single spaces
|
||||
:rtype: str
|
||||
@@ -57,7 +57,7 @@ def reduce_spaces(text):
|
||||
def get_doc(obj):
|
||||
"""Get the doc string or comments for an object.
|
||||
|
||||
:param object: object
|
||||
:arg object: object
|
||||
:returns: doc string
|
||||
:rtype: str
|
||||
|
||||
@@ -71,11 +71,11 @@ def get_doc(obj):
|
||||
def get_argspec(func, *, strip_self=True, doc=None, source=None):
|
||||
"""Get argument specifications.
|
||||
|
||||
:param strip_self: strip `self` from argspec
|
||||
:arg strip_self: strip `self` from argspec
|
||||
:type strip_self: bool
|
||||
:param doc: doc string of func (optional)
|
||||
:arg doc: doc string of func (optional)
|
||||
:type doc: str
|
||||
:param source: source code of func (optional)
|
||||
:arg source: source code of func (optional)
|
||||
:type source: str
|
||||
:returns: argument specification
|
||||
:rtype: str
|
||||
@@ -131,11 +131,11 @@ def get_argspec(func, *, strip_self=True, doc=None, source=None):
|
||||
def complete(line, cursor, namespace):
|
||||
"""Complete callable with calltip.
|
||||
|
||||
:param line: incomplete text line
|
||||
:arg line: incomplete text line
|
||||
:type line: str
|
||||
:param cursor: current character position
|
||||
:arg cursor: current character position
|
||||
:type cursor: int
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:returns: (matches, world, scrollback)
|
||||
:rtype: (list of str, str, str)
|
||||
|
@@ -76,7 +76,7 @@ def module_list(path):
|
||||
Return the list containing the names of the modules available in
|
||||
the given folder.
|
||||
|
||||
:param path: folder path
|
||||
:arg path: folder path
|
||||
:type path: str
|
||||
:returns: modules
|
||||
:rtype: list
|
||||
@@ -107,7 +107,7 @@ def complete(line):
|
||||
"""
|
||||
Returns a list containing the completion possibilities for an import line.
|
||||
|
||||
:param line:
|
||||
:arg line:
|
||||
|
||||
incomplete line which contains an import statement::
|
||||
|
||||
|
@@ -27,9 +27,9 @@ def is_struct_seq(obj):
|
||||
def complete_names(word, namespace):
|
||||
"""Complete variable names or attributes
|
||||
|
||||
:param word: word to be completed
|
||||
:arg word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
@@ -50,12 +50,12 @@ def complete_indices(word, namespace, *, obj=None, base=None):
|
||||
* integer numbers for list
|
||||
* any keys for dictionary
|
||||
|
||||
:param word: word to be completed
|
||||
:arg word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:param obj: object evaluated from base
|
||||
:param base: sub-string which can be evaluated into an object.
|
||||
:arg obj: object evaluated from base
|
||||
:arg base: sub-string which can be evaluated into an object.
|
||||
:type base: str
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
@@ -103,11 +103,11 @@ def complete(word, namespace, *, private=True):
|
||||
"""Complete word within a namespace with the standard rlcompleter
|
||||
module. Also supports index or key access [].
|
||||
|
||||
:param word: word to be completed
|
||||
:arg word: word to be completed
|
||||
:type word: str
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private attribute/methods should be returned
|
||||
:arg private: whether private attribute/methods should be returned
|
||||
:type private: bool
|
||||
:returns: completion matches
|
||||
:rtype: list of str
|
||||
|
@@ -43,13 +43,13 @@ def complete(line, cursor, namespace, private):
|
||||
* index completion for lists and dictionaries
|
||||
* module completion (from/import)
|
||||
|
||||
:param line: incomplete text line
|
||||
:arg line: incomplete text line
|
||||
:type line: str
|
||||
:param cursor: current character position
|
||||
:arg cursor: current character position
|
||||
:type cursor: int
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private variables should be listed
|
||||
:arg private: whether private variables should be listed
|
||||
:type private: bool
|
||||
:returns: list of completions, word
|
||||
:rtype: list, str
|
||||
@@ -82,13 +82,13 @@ def expand(line, cursor, namespace, *, private=True):
|
||||
"""This method is invoked when the user asks autocompletion,
|
||||
e.g. when Ctrl+Space is clicked.
|
||||
|
||||
:param line: incomplete text line
|
||||
:arg line: incomplete text line
|
||||
:type line: str
|
||||
:param cursor: current character position
|
||||
:arg cursor: current character position
|
||||
:type cursor: int
|
||||
:param namespace: namespace
|
||||
:arg namespace: namespace
|
||||
:type namespace: dict
|
||||
:param private: whether private variables should be listed
|
||||
:arg private: whether private variables should be listed
|
||||
:type private: bool
|
||||
:returns:
|
||||
|
||||
|
@@ -173,7 +173,7 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
|
||||
mode = context.active_object.mode
|
||||
# See: BKE_paint_get_tool_prop_id_from_paintmode
|
||||
if space_type == 'IMAGE_EDITOR':
|
||||
if context.space_data.ui_mode == 'PAINT':
|
||||
if context.space_data.mode == 'PAINT':
|
||||
attr = "image_tool"
|
||||
else:
|
||||
attr = None
|
||||
@@ -200,7 +200,7 @@ def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
|
||||
properties=kmi_hack_brush_select_properties,
|
||||
include={'KEYBOARD'},
|
||||
)[1]
|
||||
elif mode in {'PARTICLE_EDIT', 'SCULPT_GPENCIL'}:
|
||||
elif mode in {'EDIT', 'PARTICLE_EDIT', 'SCULPT_GPENCIL'}:
|
||||
# Doesn't use brushes
|
||||
pass
|
||||
else:
|
||||
|
@@ -61,9 +61,18 @@ import sys as _sys
|
||||
import addon_utils as _addon_utils
|
||||
|
||||
_preferences = _bpy.context.preferences
|
||||
_script_module_dirs = "startup", "modules"
|
||||
_is_factory_startup = _bpy.app.factory_startup
|
||||
|
||||
# Directories added to the start of `sys.path` for all of Blender's "scripts" directories.
|
||||
_script_module_dirs = "startup", "modules"
|
||||
|
||||
# Base scripts, this points to the directory containing: "modules" & "startup" (see `_script_module_dirs`).
|
||||
# In Blender's code-base this is `./release/scripts`.
|
||||
#
|
||||
# NOTE: in virtually all cases this should match `BLENDER_SYSTEM_SCRIPTS` as this script is it's self a system script,
|
||||
# it must be in the `BLENDER_SYSTEM_SCRIPTS` by definition and there is no need for a look-up from `_bpy_script_paths`.
|
||||
_script_base_dir = _os.path.dirname(_os.path.dirname(_os.path.dirname(_os.path.dirname(__file__))))
|
||||
|
||||
|
||||
def execfile(filepath, *, mod=None):
|
||||
"""
|
||||
@@ -324,12 +333,6 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
)
|
||||
|
||||
|
||||
# base scripts
|
||||
_scripts = (
|
||||
_os.path.dirname(_os.path.dirname(_os.path.dirname(__file__))),
|
||||
)
|
||||
|
||||
|
||||
def script_path_user():
|
||||
"""returns the env var and falls back to home dir or None"""
|
||||
path = _user_resource('SCRIPTS')
|
||||
@@ -350,19 +353,20 @@ def script_paths(*, subdir=None, user_pref=True, check_all=False, use_user=True)
|
||||
:type subdir: string
|
||||
:arg user_pref: Include the user preference script path.
|
||||
:type user_pref: bool
|
||||
:arg check_all: Include local, user and system paths rather just the paths
|
||||
blender uses.
|
||||
:arg check_all: Include local, user and system paths rather just the paths Blender uses.
|
||||
:type check_all: bool
|
||||
:return: script paths.
|
||||
:rtype: list
|
||||
"""
|
||||
scripts = list(_scripts)
|
||||
scripts = []
|
||||
|
||||
# Only paths Blender uses.
|
||||
# Only script paths Blender uses.
|
||||
#
|
||||
# Needed this is needed even when 'check_all' is enabled,
|
||||
# so the 'BLENDER_SYSTEM_SCRIPTS' environment variable will be used.
|
||||
base_paths = _bpy_script_paths()
|
||||
# This is needed even when `check_all` is enabled.
|
||||
# NOTE: Use `_script_base_dir` instead of `_bpy_script_paths()[0]` as it's taken from this files path.
|
||||
base_paths = (_script_base_dir, )
|
||||
if use_user:
|
||||
base_paths += _bpy_script_paths()[1:]
|
||||
|
||||
# Defined to be (system, user) so we can skip the second if needed.
|
||||
if not use_user:
|
||||
|
@@ -742,7 +742,6 @@ class Gizmo(StructRNA):
|
||||
matrix = self.matrix_world
|
||||
|
||||
batch, shader = shape
|
||||
shader.bind()
|
||||
|
||||
if select_id is not None:
|
||||
gpu.select.load_id(select_id)
|
||||
|
@@ -78,7 +78,6 @@ def draw_texture_2d(texture, position, width, height):
|
||||
gpu.matrix.scale((width, height))
|
||||
|
||||
shader = gpu.shader.from_builtin('IMAGE')
|
||||
shader.bind()
|
||||
|
||||
if isinstance(texture, int):
|
||||
# Call the legacy bgl to not break the existing API
|
||||
|
@@ -149,78 +149,6 @@ class NODE_OT_add_node(NodeAddOperator, Operator):
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
|
||||
class NODE_OT_add_search(NodeAddOperator, Operator):
|
||||
'''Add a node to the active tree'''
|
||||
bl_idname = "node.add_search"
|
||||
bl_label = "Search and Add Node"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
bl_property = "node_item"
|
||||
|
||||
_enum_item_hack = []
|
||||
|
||||
# Create an enum list from node items
|
||||
def node_enum_items(self, context):
|
||||
import nodeitems_utils
|
||||
|
||||
enum_items = NODE_OT_add_search._enum_item_hack
|
||||
enum_items.clear()
|
||||
|
||||
for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
|
||||
if isinstance(item, nodeitems_utils.NodeItem):
|
||||
enum_items.append(
|
||||
(str(index),
|
||||
item.label,
|
||||
"",
|
||||
index,
|
||||
))
|
||||
return enum_items
|
||||
|
||||
# Look up the item based on index
|
||||
def find_node_item(self, context):
|
||||
import nodeitems_utils
|
||||
|
||||
node_item = int(self.node_item)
|
||||
for index, item in enumerate(nodeitems_utils.node_items_iter(context)):
|
||||
if index == node_item:
|
||||
return item
|
||||
return None
|
||||
|
||||
node_item: EnumProperty(
|
||||
name="Node Type",
|
||||
description="Node type",
|
||||
items=NODE_OT_add_search.node_enum_items,
|
||||
)
|
||||
|
||||
def execute(self, context):
|
||||
item = self.find_node_item(context)
|
||||
|
||||
# no need to keep
|
||||
self._enum_item_hack.clear()
|
||||
|
||||
if item:
|
||||
# apply settings from the node item
|
||||
for setting in item.settings.items():
|
||||
ops = self.settings.add()
|
||||
ops.name = setting[0]
|
||||
ops.value = setting[1]
|
||||
|
||||
self.create_node(context, item.nodetype)
|
||||
|
||||
if self.use_transform:
|
||||
bpy.ops.node.translate_attach_remove_on_cancel(
|
||||
'INVOKE_DEFAULT')
|
||||
|
||||
return {'FINISHED'}
|
||||
else:
|
||||
return {'CANCELLED'}
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.store_mouse_cursor(context, event)
|
||||
# Delayed execution in the search popup
|
||||
context.window_manager.invoke_search_popup(self)
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
class NODE_OT_collapse_hide_unused_toggle(Operator):
|
||||
'''Toggle collapsed nodes and hide unused sockets'''
|
||||
bl_idname = "node.collapse_hide_unused_toggle"
|
||||
@@ -276,7 +204,6 @@ classes = (
|
||||
NodeSetting,
|
||||
|
||||
NODE_OT_add_node,
|
||||
NODE_OT_add_search,
|
||||
NODE_OT_collapse_hide_unused_toggle,
|
||||
NODE_OT_tree_path_parent,
|
||||
)
|
||||
|
@@ -503,11 +503,15 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
||||
else:
|
||||
col.operator("mesh.customdata_bevel_weight_vertex_add", icon='ADD')
|
||||
|
||||
col = layout.column(heading="Store")
|
||||
if me.has_crease_edge:
|
||||
col.operator("mesh.customdata_crease_edge_clear", icon='X')
|
||||
else:
|
||||
col.operator("mesh.customdata_crease_edge_add", icon='ADD')
|
||||
|
||||
col.enabled = obj is not None and obj.mode != 'EDIT'
|
||||
col.prop(me, "use_customdata_vertex_crease", text="Vertex Crease")
|
||||
col.prop(me, "use_customdata_edge_crease", text="Edge Crease")
|
||||
if me.has_crease_vertex:
|
||||
col.operator("mesh.customdata_crease_vertex_clear", icon='X')
|
||||
else:
|
||||
col.operator("mesh.customdata_crease_vertex_add", icon='ADD')
|
||||
|
||||
|
||||
class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel):
|
||||
|
@@ -318,6 +318,7 @@ class DOPESHEET_MT_view(Menu):
|
||||
st = context.space_data
|
||||
|
||||
layout.prop(st, "show_region_ui")
|
||||
layout.prop(st, "show_region_hud")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@@ -537,10 +537,12 @@ class IMAGE_MT_pivot_pie(Menu):
|
||||
layout = self.layout
|
||||
pie = layout.menu_pie()
|
||||
|
||||
pie.prop_enum(context.space_data, "pivot_point", value='CENTER')
|
||||
pie.prop_enum(context.space_data, "pivot_point", value='CURSOR')
|
||||
pie.prop_enum(context.space_data, "pivot_point", value='INDIVIDUAL_ORIGINS')
|
||||
pie.prop_enum(context.space_data, "pivot_point", value='MEDIAN')
|
||||
sima = context.space_data
|
||||
|
||||
pie.prop_enum(sima, "pivot_point", value='CENTER')
|
||||
pie.prop_enum(sima, "pivot_point", value='CURSOR')
|
||||
pie.prop_enum(sima, "pivot_point", value='INDIVIDUAL_ORIGINS')
|
||||
pie.prop_enum(sima, "pivot_point", value='MEDIAN')
|
||||
|
||||
|
||||
class IMAGE_MT_uvs_snap_pie(Menu):
|
||||
@@ -1531,15 +1533,26 @@ class IMAGE_PT_overlay_guides(Panel):
|
||||
|
||||
if overlay.show_grid_background:
|
||||
layout.use_property_split = True
|
||||
|
||||
col = layout.column(align=False, heading="Grid Over Image")
|
||||
col.use_property_decorate = False
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.prop(uvedit, "show_grid_over_image", text="")
|
||||
sub.active = sima.image is not None
|
||||
|
||||
col = layout.column(align=False, heading="Fixed Subdivisions")
|
||||
col.use_property_decorate = False
|
||||
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
sub.prop(uvedit, "use_custom_grid", text="")
|
||||
sub = sub.row(align=True)
|
||||
sub.active = uvedit.use_custom_grid
|
||||
sub.prop(uvedit, "custom_grid_subdivisions", text="")
|
||||
if uvedit.use_custom_grid:
|
||||
row = layout.row()
|
||||
row.use_property_split = True
|
||||
row.use_property_decorate = False
|
||||
sub = sub.row(align=True)
|
||||
sub.prop(uvedit, "custom_grid_subdivisions", text="")
|
||||
|
||||
row = layout.row()
|
||||
row.use_property_split = True
|
||||
|
@@ -88,6 +88,7 @@ class NLA_MT_view(Menu):
|
||||
st = context.space_data
|
||||
|
||||
layout.prop(st, "show_region_ui")
|
||||
layout.prop(st, "show_region_hud")
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "use_realtime_update")
|
||||
|
@@ -54,7 +54,7 @@ class OUTLINER_HT_header(Header):
|
||||
icon='FILTER',
|
||||
)
|
||||
|
||||
if display_mode in {'LIBRARIES' 'ORPHAN_DATA'}:
|
||||
if display_mode in {'LIBRARIES', 'ORPHAN_DATA'}:
|
||||
row.prop(space, "use_filter_id_type", text="", icon='FILTER')
|
||||
sub = row.row(align=True)
|
||||
sub.active = space.use_filter_id_type
|
||||
|
@@ -120,6 +120,10 @@ class TIME_MT_view(Menu):
|
||||
scene = context.scene
|
||||
st = context.space_data
|
||||
|
||||
layout.prop(st, "show_region_hud")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_seconds")
|
||||
layout.prop(st, "show_locked_time")
|
||||
|
||||
|
@@ -1605,19 +1605,6 @@ class VIEW3D_PT_tools_grease_pencil_brush_advanced(View3DPanel, Panel):
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "fill_layer_mode", text="Layers")
|
||||
|
||||
col.separator()
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "extend_stroke_factor")
|
||||
row.prop(
|
||||
gp_settings,
|
||||
"show_fill_extend",
|
||||
icon='HIDE_OFF' if gp_settings.show_fill_extend else 'HIDE_ON',
|
||||
text="",
|
||||
)
|
||||
|
||||
col.separator()
|
||||
col.prop(gp_settings, "fill_leak", text="Leak Size")
|
||||
|
||||
col.separator()
|
||||
col.prop(gp_settings, "fill_simplify_level", text="Simplify")
|
||||
if gp_settings.fill_draw_mode != 'STROKE':
|
||||
@@ -1878,6 +1865,35 @@ class VIEW3D_PT_tools_grease_pencil_brush_paint_falloff(GreasePencilBrushFalloff
|
||||
return (settings and settings.brush and settings.brush.curve and gptool == 'TINT')
|
||||
|
||||
|
||||
class VIEW3D_PT_tools_grease_pencil_brush_gap_closure(View3DPanel, Panel):
|
||||
bl_context = ".greasepencil_paint"
|
||||
bl_parent_id = 'VIEW3D_PT_tools_grease_pencil_brush_advanced'
|
||||
bl_label = "Gap Closure"
|
||||
bl_category = "Tool"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
brush = context.tool_settings.gpencil_paint.brush
|
||||
return brush is not None and brush.gpencil_tool == 'FILL'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
brush = tool_settings.gpencil_paint.brush
|
||||
gp_settings = brush.gpencil_settings
|
||||
|
||||
col = layout.column()
|
||||
|
||||
col.prop(gp_settings, "extend_stroke_factor", text="Size")
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "fill_extend_mode", text="Mode")
|
||||
row = col.row(align=True)
|
||||
row.prop(gp_settings, "show_fill_extend", text="Visual Aids")
|
||||
|
||||
|
||||
# Grease Pencil stroke sculpting tools
|
||||
class GreasePencilSculptPanel:
|
||||
bl_context = ".greasepencil_sculpt"
|
||||
@@ -2430,6 +2446,7 @@ classes = (
|
||||
VIEW3D_PT_tools_grease_pencil_brush_post_processing,
|
||||
VIEW3D_PT_tools_grease_pencil_brush_random,
|
||||
VIEW3D_PT_tools_grease_pencil_brush_stabilizer,
|
||||
VIEW3D_PT_tools_grease_pencil_brush_gap_closure,
|
||||
VIEW3D_PT_tools_grease_pencil_paint_appearance,
|
||||
VIEW3D_PT_tools_grease_pencil_sculpt_select,
|
||||
VIEW3D_PT_tools_grease_pencil_sculpt_settings,
|
||||
|
@@ -117,6 +117,7 @@ def mesh_node_items(context):
|
||||
yield NodeItem("GeometryNodeMeshToCurve")
|
||||
yield NodeItem("GeometryNodeMeshToPoints")
|
||||
yield NodeItem("GeometryNodeMeshToVolume")
|
||||
yield NodeItem("GeometryNodeSampleNearestSurface")
|
||||
yield NodeItem("GeometryNodeScaleElements")
|
||||
yield NodeItem("GeometryNodeSplitEdges")
|
||||
yield NodeItem("GeometryNodeSubdivideMesh")
|
||||
@@ -128,6 +129,7 @@ def mesh_node_items(context):
|
||||
yield NodeItem("GeometryNodeInputMeshEdgeVertices")
|
||||
yield NodeItem("GeometryNodeInputMeshFaceArea")
|
||||
yield NodeItem("GeometryNodeInputMeshFaceNeighbors")
|
||||
yield NodeItem("GeometryNodeMeshFaceSetBoundaries")
|
||||
yield NodeItem("GeometryNodeInputMeshFaceIsPlanar")
|
||||
yield NodeItem("GeometryNodeInputShadeSmooth")
|
||||
yield NodeItem("GeometryNodeInputMeshIsland")
|
||||
@@ -153,6 +155,8 @@ def geometry_node_items(context):
|
||||
yield NodeItem("GeometryNodeJoinGeometry")
|
||||
yield NodeItem("GeometryNodeMergeByDistance")
|
||||
yield NodeItem("GeometryNodeRaycast")
|
||||
yield NodeItem("GeometryNodeSampleIndex")
|
||||
yield NodeItem("GeometryNodeSampleNearest")
|
||||
yield NodeItem("GeometryNodeSeparateComponents")
|
||||
yield NodeItem("GeometryNodeSeparateGeometry")
|
||||
yield NodeItem("GeometryNodeTransform")
|
||||
@@ -240,6 +244,7 @@ def point_node_items(context):
|
||||
space = context.space_data
|
||||
if not space:
|
||||
return
|
||||
yield NodeItem("GeometryNodeDistributePointsInVolume")
|
||||
yield NodeItem("GeometryNodeDistributePointsOnFaces")
|
||||
yield NodeItem("GeometryNodePoints")
|
||||
yield NodeItem("GeometryNodePointsToVertices")
|
||||
@@ -259,8 +264,9 @@ def node_group_items(context):
|
||||
|
||||
yield NodeItemCustom(draw=group_tools_draw)
|
||||
|
||||
yield NodeItem("NodeGroupInput", poll=group_input_output_item_poll)
|
||||
yield NodeItem("NodeGroupOutput", poll=group_input_output_item_poll)
|
||||
if group_input_output_item_poll(context):
|
||||
yield NodeItem("NodeGroupInput")
|
||||
yield NodeItem("NodeGroupOutput")
|
||||
|
||||
ntree = space.edit_tree
|
||||
if not ntree:
|
||||
@@ -647,7 +653,6 @@ geometry_node_categories = [
|
||||
NodeItem("GeometryNodeCaptureAttribute"),
|
||||
NodeItem("GeometryNodeAttributeDomainSize"),
|
||||
NodeItem("GeometryNodeAttributeStatistic"),
|
||||
NodeItem("GeometryNodeAttributeTransfer"),
|
||||
NodeItem("GeometryNodeRemoveAttribute"),
|
||||
NodeItem("GeometryNodeStoreNamedAttribute"),
|
||||
]),
|
||||
|
@@ -19,7 +19,6 @@ def draw_callback_px(self, context):
|
||||
gpu.state.blend_set('ALPHA')
|
||||
gpu.state.line_width_set(2.0)
|
||||
batch = batch_for_shader(shader, 'LINE_STRIP', {"pos": self.mouse_path})
|
||||
shader.bind()
|
||||
shader.uniform_float("color", (0.0, 0.0, 0.0, 0.5))
|
||||
batch.draw(shader)
|
||||
|
||||
|
@@ -171,8 +171,8 @@ IFACEMETHODIMP CBlendThumb::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE
|
||||
}
|
||||
*pdwAlpha = WTSAT_ARGB;
|
||||
|
||||
/* Scale down the thumbnail if required. */
|
||||
if ((unsigned)thumb.width > cx || (unsigned)thumb.height > cx) {
|
||||
/* Scale up the thumbnail if required. */
|
||||
if ((unsigned)thumb.width < cx && (unsigned)thumb.height < cx) {
|
||||
float scale = 1.0f / (std::max(thumb.width, thumb.height) / (float)cx);
|
||||
LONG NewWidth = (LONG)(thumb.width * scale);
|
||||
LONG NewHeight = (LONG)(thumb.height * scale);
|
||||
|
@@ -69,7 +69,7 @@ void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size);
|
||||
|
||||
void BLF_aspect(int fontid, float x, float y, float z);
|
||||
void BLF_position(int fontid, float x, float y, float z);
|
||||
void BLF_size(int fontid, float size, int dpi);
|
||||
void BLF_size(int fontid, float size);
|
||||
|
||||
/* Goal: small but useful color API. */
|
||||
|
||||
@@ -303,7 +303,6 @@ void BLF_thumb_preview(const char *filepath,
|
||||
|
||||
/* blf_default.c */
|
||||
|
||||
void BLF_default_dpi(int dpi);
|
||||
void BLF_default_size(float size);
|
||||
void BLF_default_set(int fontid);
|
||||
/**
|
||||
|
@@ -63,8 +63,6 @@ int BLF_init(void)
|
||||
global_font[i] = NULL;
|
||||
}
|
||||
|
||||
BLF_default_dpi(72);
|
||||
|
||||
return blf_font_init();
|
||||
}
|
||||
|
||||
@@ -361,12 +359,12 @@ void BLF_position(int fontid, float x, float y, float z)
|
||||
}
|
||||
}
|
||||
|
||||
void BLF_size(int fontid, float size, int dpi)
|
||||
void BLF_size(int fontid, float size)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
||||
if (font) {
|
||||
blf_font_size(font, size, dpi);
|
||||
blf_font_size(font, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,7 +910,6 @@ void BLF_state_print(int fontid)
|
||||
printf("fontid %d %p\n", fontid, (void *)font);
|
||||
printf(" name: '%s'\n", font->name);
|
||||
printf(" size: %f\n", font->size);
|
||||
printf(" dpi: %u\n", font->dpi);
|
||||
printf(" pos: %d %d %d\n", UNPACK3(font->pos));
|
||||
printf(" aspect: (%d) %.6f %.6f %.6f\n",
|
||||
(font->flags & BLF_ROTATION) != 0,
|
||||
|
@@ -20,15 +20,9 @@
|
||||
|
||||
/* Default size and dpi, for BLF_draw_default. */
|
||||
static int global_font_default = -1;
|
||||
static int global_font_dpi = 72;
|
||||
/* Keep in sync with `UI_DEFAULT_TEXT_POINTS` */
|
||||
static float global_font_size = 11.0f;
|
||||
|
||||
void BLF_default_dpi(int dpi)
|
||||
{
|
||||
global_font_dpi = dpi;
|
||||
}
|
||||
|
||||
void BLF_default_size(float size)
|
||||
{
|
||||
global_font_size = size;
|
||||
@@ -51,7 +45,7 @@ int BLF_set_default(void)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
|
||||
BLF_size(global_font_default, global_font_size, global_font_dpi);
|
||||
BLF_size(global_font_default, global_font_size * U.dpi_fac);
|
||||
|
||||
return global_font_default;
|
||||
}
|
||||
@@ -59,7 +53,7 @@ int BLF_set_default(void)
|
||||
void BLF_draw_default(float x, float y, float z, const char *str, const size_t str_len)
|
||||
{
|
||||
ASSERT_DEFAULT_SET;
|
||||
BLF_size(global_font_default, global_font_size, global_font_dpi);
|
||||
BLF_size(global_font_default, global_font_size * U.dpi_fac);
|
||||
BLF_position(global_font_default, x, y, z);
|
||||
BLF_draw(global_font_default, str, str_len);
|
||||
}
|
||||
|
@@ -1300,7 +1300,6 @@ static void blf_font_fill(FontBLF *font)
|
||||
font->clip_rec.ymin = 0;
|
||||
font->clip_rec.ymax = 0;
|
||||
font->flags = 0;
|
||||
font->dpi = 0;
|
||||
font->size = 0;
|
||||
BLI_listbase_clear(&font->cache);
|
||||
font->kerning_cache = NULL;
|
||||
@@ -1346,7 +1345,9 @@ bool blf_ensure_face(FontBLF *font)
|
||||
if (font->mem) {
|
||||
err = FT_New_Memory_Face(font->ft_lib, font->mem, (FT_Long)font->mem_size, 0, &font->face);
|
||||
}
|
||||
font->face->generic.data = font;
|
||||
if (!err) {
|
||||
font->face->generic.data = font;
|
||||
}
|
||||
BLI_mutex_unlock(&ft_lib_mutex);
|
||||
}
|
||||
|
||||
@@ -1611,8 +1612,8 @@ void blf_ensure_size(FontBLF *font)
|
||||
scaler.width = 0;
|
||||
scaler.height = round_fl_to_uint(font->size * 64.0f);
|
||||
scaler.pixel = 0;
|
||||
scaler.x_res = font->dpi;
|
||||
scaler.y_res = font->dpi;
|
||||
scaler.x_res = BLF_DPI;
|
||||
scaler.y_res = BLF_DPI;
|
||||
if (FTC_Manager_LookupSize(ftc_manager, &scaler, &font->ft_size) == FT_Err_Ok) {
|
||||
font->ft_size->generic.data = (void *)font;
|
||||
font->ft_size->generic.finalizer = blf_size_finalizer;
|
||||
@@ -1622,7 +1623,7 @@ void blf_ensure_size(FontBLF *font)
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
|
||||
bool blf_font_size(FontBLF *font, float size, uint dpi)
|
||||
bool blf_font_size(FontBLF *font, float size)
|
||||
{
|
||||
if (!blf_ensure_face(font)) {
|
||||
return false;
|
||||
@@ -1633,15 +1634,15 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
|
||||
/* Adjust our new size to be on even 64ths. */
|
||||
size = (float)ft_size / 64.0f;
|
||||
|
||||
if (font->size != size || font->dpi != dpi) {
|
||||
if (font->size != size) {
|
||||
if (font->flags & BLF_CACHED) {
|
||||
FTC_ScalerRec scaler = {0};
|
||||
scaler.face_id = font;
|
||||
scaler.width = 0;
|
||||
scaler.height = ft_size;
|
||||
scaler.pixel = 0;
|
||||
scaler.x_res = dpi;
|
||||
scaler.y_res = dpi;
|
||||
scaler.x_res = BLF_DPI;
|
||||
scaler.y_res = BLF_DPI;
|
||||
if (FTC_Manager_LookupSize(ftc_manager, &scaler, &font->ft_size) != FT_Err_Ok) {
|
||||
return false;
|
||||
}
|
||||
@@ -1649,7 +1650,7 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
|
||||
font->ft_size->generic.finalizer = blf_size_finalizer;
|
||||
}
|
||||
else {
|
||||
if (FT_Set_Char_Size(font->face, 0, ft_size, dpi, dpi) != FT_Err_Ok) {
|
||||
if (FT_Set_Char_Size(font->face, 0, ft_size, BLF_DPI, BLF_DPI) != FT_Err_Ok) {
|
||||
return false;
|
||||
}
|
||||
font->ft_size = font->face->size;
|
||||
@@ -1657,7 +1658,6 @@ bool blf_font_size(FontBLF *font, float size, uint dpi)
|
||||
}
|
||||
|
||||
font->size = size;
|
||||
font->dpi = dpi;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -63,11 +63,11 @@ static FT_Fixed to_16dot16(double val)
|
||||
/** \name Glyph Cache
|
||||
* \{ */
|
||||
|
||||
static GlyphCacheBLF *blf_glyph_cache_find(const FontBLF *font, const float size, uint dpi)
|
||||
static GlyphCacheBLF *blf_glyph_cache_find(const FontBLF *font, const float size)
|
||||
{
|
||||
GlyphCacheBLF *gc = (GlyphCacheBLF *)font->cache.first;
|
||||
while (gc) {
|
||||
if (gc->size == size && gc->dpi == dpi && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
if (gc->size == size && (gc->bold == ((font->flags & BLF_BOLD) != 0)) &&
|
||||
(gc->italic == ((font->flags & BLF_ITALIC) != 0)) &&
|
||||
(gc->char_weight == font->char_weight) && (gc->char_slant == font->char_slant) &&
|
||||
(gc->char_width == font->char_width) && (gc->char_spacing == font->char_spacing)) {
|
||||
@@ -85,7 +85,6 @@ static GlyphCacheBLF *blf_glyph_cache_new(FontBLF *font)
|
||||
gc->next = NULL;
|
||||
gc->prev = NULL;
|
||||
gc->size = font->size;
|
||||
gc->dpi = font->dpi;
|
||||
gc->bold = ((font->flags & BLF_BOLD) != 0);
|
||||
gc->italic = ((font->flags & BLF_ITALIC) != 0);
|
||||
gc->char_weight = font->char_weight;
|
||||
@@ -122,7 +121,7 @@ GlyphCacheBLF *blf_glyph_cache_acquire(FontBLF *font)
|
||||
{
|
||||
BLI_mutex_lock(&font->glyph_cache_mutex);
|
||||
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size, font->dpi);
|
||||
GlyphCacheBLF *gc = blf_glyph_cache_find(font, font->size);
|
||||
|
||||
if (!gc) {
|
||||
gc = blf_glyph_cache_new(font);
|
||||
@@ -967,7 +966,7 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
|
||||
int fixed_width)
|
||||
{
|
||||
if (glyph_font != settings_font) {
|
||||
blf_font_size(glyph_font, settings_font->size, settings_font->dpi);
|
||||
blf_font_size(glyph_font, settings_font->size);
|
||||
}
|
||||
|
||||
blf_ensure_size(glyph_font);
|
||||
|
@@ -25,6 +25,13 @@ struct rcti;
|
||||
/* Maximum number of bytes to use for cached data nodes. 0 is default of 200,000. */
|
||||
#define BLF_CACHE_BYTES 400000
|
||||
|
||||
/* We assume square pixels at a fixed DPI of 72, scaling only the size. Therefore
|
||||
* font size = points = pixels, i.e. a size of 20 will result in a 20-pixel EM square.
|
||||
* Although we could use the actual monitor DPI instead, we would then have to scale
|
||||
* the size to cancel that out. Other libraries like Skia use this same fixed value.
|
||||
*/
|
||||
#define BLF_DPI 72
|
||||
|
||||
extern struct FontBLF *global_font[BLF_MAX_FONT];
|
||||
|
||||
void blf_batch_draw_begin(struct FontBLF *font);
|
||||
@@ -70,7 +77,7 @@ void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, si
|
||||
/**
|
||||
* Change font's output size. Returns true if successful in changing the size.
|
||||
*/
|
||||
bool blf_font_size(struct FontBLF *font, float size, unsigned int dpi);
|
||||
bool blf_font_size(struct FontBLF *font, float size);
|
||||
|
||||
void blf_font_draw(struct FontBLF *font,
|
||||
const char *str,
|
||||
|
@@ -142,9 +142,6 @@ typedef struct GlyphCacheBLF {
|
||||
/** Font size. */
|
||||
float size;
|
||||
|
||||
/** DPI. */
|
||||
unsigned int dpi;
|
||||
|
||||
float char_weight;
|
||||
float char_slant;
|
||||
float char_width;
|
||||
@@ -300,9 +297,6 @@ typedef struct FontBLF {
|
||||
/** The width to wrap the text, see #BLF_WORD_WRAP. */
|
||||
int wrap_width;
|
||||
|
||||
/** Font DPI (default 72). */
|
||||
unsigned int dpi;
|
||||
|
||||
/** Font size. */
|
||||
float size;
|
||||
|
||||
|
@@ -40,7 +40,6 @@ void BLF_thumb_preview(const char *filepath,
|
||||
const int h,
|
||||
const int channels)
|
||||
{
|
||||
const uint dpi = 72;
|
||||
const int font_size_min = 6;
|
||||
int font_size_curr;
|
||||
/* shrink 1/th each line */
|
||||
@@ -84,7 +83,7 @@ void BLF_thumb_preview(const char *filepath,
|
||||
int draw_str_i18_count = 0;
|
||||
|
||||
CLAMP_MIN(font_size_curr, font_size_min);
|
||||
if (!blf_font_size(font, (float)font_size_curr, dpi)) {
|
||||
if (!blf_font_size(font, (float)font_size_curr)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -94,7 +93,7 @@ void BLF_thumb_preview(const char *filepath,
|
||||
|
||||
font->pos[1] -= (int)((float)blf_font_ascender(font) * 1.1f);
|
||||
|
||||
/* We fallback to default english strings in case not enough chars are available in current
|
||||
/* We fallback to default English strings in case not enough chars are available in current
|
||||
* font for given translated string (useful in non-Latin i18n context, like Chinese,
|
||||
* since many fonts will then show nothing but ugly 'missing char' in their preview).
|
||||
* Does not handle all cases, but much better than nothing.
|
||||
|
@@ -104,9 +104,6 @@ struct DerivedMesh {
|
||||
int num_alloc;
|
||||
} looptris;
|
||||
|
||||
/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
|
||||
char cd_flag;
|
||||
|
||||
short tangent_mask; /* which tangent layers are calculated */
|
||||
|
||||
/** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
|
||||
|
@@ -16,6 +16,10 @@
|
||||
|
||||
struct Mesh;
|
||||
struct PointCloud;
|
||||
namespace blender::fn {
|
||||
class MultiFunction;
|
||||
class GField;
|
||||
} // namespace blender::fn
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
@@ -162,6 +166,27 @@ template<typename T> struct AttributeReader {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* A utility to make sure attribute values are valid, for attributes like "material_index" which
|
||||
* can only be positive, or attributes that represent enum options. This is usually only necessary
|
||||
* when writing attributes from an untrusted/arbitrary user input.
|
||||
*/
|
||||
struct AttributeValidator {
|
||||
/**
|
||||
* Single input, single output function that corrects attribute values if necessary.
|
||||
*/
|
||||
const fn::MultiFunction *function;
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return this->function != nullptr;
|
||||
}
|
||||
/**
|
||||
* Return a field that creates corrected attribute values.
|
||||
*/
|
||||
fn::GField validate_field_if_necessary(const fn::GField &field) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Result when looking up an attribute from some geometry with read and write access. After writing
|
||||
* to the attribute, the #finish method has to be called. This may invalidate caches based on this
|
||||
@@ -239,7 +264,9 @@ template<typename T> struct SpanAttributeWriter {
|
||||
*/
|
||||
void finish()
|
||||
{
|
||||
this->span.save();
|
||||
if (this->span.varray()) {
|
||||
this->span.save();
|
||||
}
|
||||
if (this->tag_modified_fn) {
|
||||
this->tag_modified_fn();
|
||||
}
|
||||
@@ -314,7 +341,9 @@ struct GSpanAttributeWriter {
|
||||
|
||||
void finish()
|
||||
{
|
||||
this->span.save();
|
||||
if (this->span.varray()) {
|
||||
this->span.save();
|
||||
}
|
||||
if (this->tag_modified_fn) {
|
||||
this->tag_modified_fn();
|
||||
}
|
||||
@@ -343,7 +372,7 @@ struct AttributeAccessorFunctions {
|
||||
eAttrDomain to_domain);
|
||||
bool (*for_all)(const void *owner,
|
||||
FunctionRef<bool(const AttributeIDRef &, const AttributeMetaData &)> fn);
|
||||
|
||||
AttributeValidator (*lookup_validator)(const void *owner, const AttributeIDRef &attribute_id);
|
||||
GAttributeWriter (*lookup_for_write)(void *owner, const AttributeIDRef &attribute_id);
|
||||
bool (*remove)(void *owner, const AttributeIDRef &attribute_id);
|
||||
bool (*add)(void *owner,
|
||||
@@ -497,6 +526,14 @@ class AttributeAccessor {
|
||||
return VArray<T>::ForSingle(default_value, this->domain_size(domain));
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as the generic version above, but should be used when the type is known at compile time.
|
||||
*/
|
||||
AttributeValidator lookup_validator(const AttributeIDRef &attribute_id) const
|
||||
{
|
||||
return fn_->lookup_validator(owner_, attribute_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate data from one domain to another.
|
||||
*/
|
||||
@@ -659,6 +696,8 @@ class MutableAttributeAccessor : public AttributeAccessor {
|
||||
* The "only" in the name indicates that the caller should not read existing values from the
|
||||
* span. If the attribute is not stored as span internally, the existing values won't be copied
|
||||
* over to the span.
|
||||
*
|
||||
* For trivial types, the values in a newly created attribute will not be initialized.
|
||||
*/
|
||||
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain,
|
||||
@@ -671,7 +710,9 @@ class MutableAttributeAccessor : public AttributeAccessor {
|
||||
SpanAttributeWriter<T> lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id,
|
||||
const eAttrDomain domain)
|
||||
{
|
||||
AttributeWriter<T> attribute = this->lookup_or_add_for_write<T>(attribute_id, domain);
|
||||
AttributeWriter<T> attribute = this->lookup_or_add_for_write<T>(
|
||||
attribute_id, domain, AttributeInitConstruct());
|
||||
|
||||
if (attribute) {
|
||||
return SpanAttributeWriter<T>{std::move(attribute), false};
|
||||
}
|
||||
|
@@ -45,6 +45,58 @@ inline void convert_to_static_type(const eCustomDataType data_type, const Func &
|
||||
convert_to_static_type(cpp_type, func);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Mix two values of the same type.
|
||||
*
|
||||
* This is just basic linear interpolation.
|
||||
* \{ */
|
||||
|
||||
template<typename T> T mix2(float factor, const T &a, const T &b);
|
||||
|
||||
template<> inline bool mix2(const float factor, const bool &a, const bool &b)
|
||||
{
|
||||
return ((1.0f - factor) * a + factor * b) >= 0.5f;
|
||||
}
|
||||
|
||||
template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
|
||||
{
|
||||
return static_cast<int8_t>(std::round((1.0f - factor) * a + factor * b));
|
||||
}
|
||||
|
||||
template<> inline int mix2(const float factor, const int &a, const int &b)
|
||||
{
|
||||
return static_cast<int>(std::round((1.0f - factor) * a + factor * b));
|
||||
}
|
||||
|
||||
template<> inline float mix2(const float factor, const float &a, const float &b)
|
||||
{
|
||||
return (1.0f - factor) * a + factor * b;
|
||||
}
|
||||
|
||||
template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Mix three values of the same type.
|
||||
*
|
||||
@@ -117,53 +169,85 @@ inline ColorGeometry4b mix3(const float3 &weights,
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Mix two values of the same type.
|
||||
/** \name Mix four values of the same type.
|
||||
*
|
||||
* This is just basic linear interpolation.
|
||||
* \{ */
|
||||
|
||||
template<typename T> T mix2(float factor, const T &a, const T &b);
|
||||
template<typename T>
|
||||
T mix4(const float4 &weights, const T &v0, const T &v1, const T &v2, const T &v3);
|
||||
|
||||
template<> inline bool mix2(const float factor, const bool &a, const bool &b)
|
||||
template<>
|
||||
inline int8_t mix4(
|
||||
const float4 &weights, const int8_t &v0, const int8_t &v1, const int8_t &v2, const int8_t &v3)
|
||||
{
|
||||
return ((1.0f - factor) * a + factor * b) >= 0.5f;
|
||||
}
|
||||
|
||||
template<> inline int8_t mix2(const float factor, const int8_t &a, const int8_t &b)
|
||||
{
|
||||
return static_cast<int8_t>(std::round((1.0f - factor) * a + factor * b));
|
||||
}
|
||||
|
||||
template<> inline int mix2(const float factor, const int &a, const int &b)
|
||||
{
|
||||
return static_cast<int>(std::round((1.0f - factor) * a + factor * b));
|
||||
}
|
||||
|
||||
template<> inline float mix2(const float factor, const float &a, const float &b)
|
||||
{
|
||||
return (1.0f - factor) * a + factor * b;
|
||||
}
|
||||
|
||||
template<> inline float2 mix2(const float factor, const float2 &a, const float2 &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
}
|
||||
|
||||
template<> inline float3 mix2(const float factor, const float3 &a, const float3 &b)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
return static_cast<int8_t>(
|
||||
std::round(weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4f mix2(const float factor, const ColorGeometry4f &a, const ColorGeometry4f &b)
|
||||
inline bool mix4(
|
||||
const float4 &weights, const bool &v0, const bool &v1, const bool &v2, const bool &v3)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
return (weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3) >= 0.5f;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4b mix2(const float factor, const ColorGeometry4b &a, const ColorGeometry4b &b)
|
||||
inline int mix4(const float4 &weights, const int &v0, const int &v1, const int &v2, const int &v3)
|
||||
{
|
||||
return math::interpolate(a, b, factor);
|
||||
return static_cast<int>(
|
||||
std::round(weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3));
|
||||
}
|
||||
|
||||
template<>
|
||||
inline float mix4(
|
||||
const float4 &weights, const float &v0, const float &v1, const float &v2, const float &v3)
|
||||
{
|
||||
return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline float2 mix4(
|
||||
const float4 &weights, const float2 &v0, const float2 &v1, const float2 &v2, const float2 &v3)
|
||||
{
|
||||
return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline float3 mix4(
|
||||
const float4 &weights, const float3 &v0, const float3 &v1, const float3 &v2, const float3 &v3)
|
||||
{
|
||||
return weights.x * v0 + weights.y * v1 + weights.z * v2 + weights.w * v3;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4f mix4(const float4 &weights,
|
||||
const ColorGeometry4f &v0,
|
||||
const ColorGeometry4f &v1,
|
||||
const ColorGeometry4f &v2,
|
||||
const ColorGeometry4f &v3)
|
||||
{
|
||||
ColorGeometry4f result;
|
||||
interp_v4_v4v4v4v4(result, v0, v1, v2, v3, weights);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline ColorGeometry4b mix4(const float4 &weights,
|
||||
const ColorGeometry4b &v0,
|
||||
const ColorGeometry4b &v1,
|
||||
const ColorGeometry4b &v2,
|
||||
const ColorGeometry4b &v3)
|
||||
{
|
||||
const float4 v0_f{&v0.r};
|
||||
const float4 v1_f{&v1.r};
|
||||
const float4 v2_f{&v2.r};
|
||||
const float4 v3_f{&v3.r};
|
||||
float4 mixed;
|
||||
interp_v4_v4v4v4v4(mixed, v0_f, v1_f, v2_f, v3_f, weights);
|
||||
return ColorGeometry4b{static_cast<uint8_t>(mixed[0]),
|
||||
static_cast<uint8_t>(mixed[1]),
|
||||
static_cast<uint8_t>(mixed[2]),
|
||||
static_cast<uint8_t>(mixed[3])};
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@@ -30,8 +30,8 @@ extern "C" {
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
* was written with too new a version. */
|
||||
#define BLENDER_FILE_MIN_VERSION 300
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 43
|
||||
#define BLENDER_FILE_MIN_VERSION 304
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 0
|
||||
|
||||
/** User readable version string. */
|
||||
const char *BKE_blender_version_string(void);
|
||||
|
@@ -218,7 +218,7 @@ class CurvesGeometry : public ::CurvesGeometry {
|
||||
|
||||
/**
|
||||
* How many evaluated points to create for each segment when evaluating Bezier,
|
||||
* Catmull Rom, and NURBS curves. On the curve domain.
|
||||
* Catmull Rom, and NURBS curves. On the curve domain. Values must be one or greater.
|
||||
*/
|
||||
VArray<int> resolution() const;
|
||||
/** Mutable access to curve resolution. Call #tag_topology_changed after changes. */
|
||||
@@ -709,7 +709,7 @@ void interpolate_to_evaluated(const GSpan src,
|
||||
const Span<int> evaluated_offsets,
|
||||
GMutableSpan dst);
|
||||
|
||||
void calculate_basis(const float parameter, float r_weights[4]);
|
||||
void calculate_basis(const float parameter, float4 &r_weights);
|
||||
|
||||
/**
|
||||
* Interpolate the control point values for the given parameter on the piecewise segment.
|
||||
@@ -720,22 +720,15 @@ void calculate_basis(const float parameter, float r_weights[4]);
|
||||
template<typename T>
|
||||
T interpolate(const T &a, const T &b, const T &c, const T &d, const float parameter)
|
||||
{
|
||||
float n[4];
|
||||
BLI_assert(0.0f <= parameter && parameter <= 1.0f);
|
||||
float4 n;
|
||||
calculate_basis(parameter, n);
|
||||
/* TODO: Use DefaultMixer or other generic mixing in the basis evaluation function to simplify
|
||||
* supporting more types. */
|
||||
if constexpr (!is_same_any_v<T, float, float2, float3, float4, int8_t, int, int64_t>) {
|
||||
T return_value;
|
||||
attribute_math::DefaultMixer<T> mixer({&return_value, 1});
|
||||
mixer.mix_in(0, a, n[0] * 0.5f);
|
||||
mixer.mix_in(0, b, n[1] * 0.5f);
|
||||
mixer.mix_in(0, c, n[2] * 0.5f);
|
||||
mixer.mix_in(0, d, n[3] * 0.5f);
|
||||
mixer.finalize();
|
||||
return return_value;
|
||||
if constexpr (is_same_any_v<T, float, float2, float3>) {
|
||||
/* Save multiplications by adjusting weights after mix. */
|
||||
return 0.5f * attribute_math::mix4<T>(n, a, b, c, d);
|
||||
}
|
||||
else {
|
||||
return 0.5f * (a * n[0] + b * n[1] + c * n[2] + d * n[3]);
|
||||
return attribute_math::mix4<T>(n * 0.5f, a, b, c, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -326,8 +326,8 @@ void copy_point_data(const CurvesGeometry &src_curves,
|
||||
template<typename T>
|
||||
void copy_point_data(const CurvesGeometry &src_curves,
|
||||
const CurvesGeometry &dst_curves,
|
||||
const IndexMask src_curve_selection,
|
||||
const Span<T> src,
|
||||
IndexMask src_curve_selection,
|
||||
Span<T> src,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
copy_point_data(src_curves, dst_curves, src_curve_selection, GSpan(src), GMutableSpan(dst));
|
||||
@@ -340,13 +340,27 @@ void fill_points(const CurvesGeometry &curves,
|
||||
|
||||
template<typename T>
|
||||
void fill_points(const CurvesGeometry &curves,
|
||||
const IndexMask curve_selection,
|
||||
IndexMask curve_selection,
|
||||
const T &value,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
fill_points(curves, curve_selection, &value, dst);
|
||||
}
|
||||
|
||||
void fill_points(const CurvesGeometry &curves,
|
||||
Span<IndexRange> curve_ranges,
|
||||
GPointer value,
|
||||
GMutableSpan dst);
|
||||
|
||||
template<typename T>
|
||||
void fill_points(const CurvesGeometry &curves,
|
||||
Span<IndexRange> curve_ranges,
|
||||
const T &value,
|
||||
MutableSpan<T> dst)
|
||||
{
|
||||
fill_points(curves, curve_ranges, &value, dst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy only the information on the point domain, but not the offsets or any point attributes,
|
||||
* meant for operations that change the number of points but not the number of curves.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user