Compare commits
374 Commits
node-edito
...
wintab-log
Author | SHA1 | Date | |
---|---|---|---|
98f3090952 | |||
a8f37763ca | |||
dbc054bb88 | |||
abb07a38b8 | |||
c88c331384 | |||
![]() |
187e217b5a | ||
fa1868ae97 | |||
c3b641613c | |||
0732a9f1b2 | |||
87833f8f95 | |||
b35ba22d84 | |||
c6e6a9046e | |||
ee8b284d11 | |||
![]() |
c317f111c1 | ||
2fcd3f0296 | |||
1917d0345e | |||
ebfad93039 | |||
3a48147b8a | |||
0b15353baa | |||
f3eecfe386 | |||
026de343e3 | |||
f8d219dfd4 | |||
6ff0d59967 | |||
feaf309de7 | |||
f4e3b1e573 | |||
e3bdb189a7 | |||
ab063db34d | |||
3f1111b2a8 | |||
ad9fd47d7b | |||
01234b430b | |||
956c539e59 | |||
d3a792431e | |||
53ba9f01e2 | |||
1725bfc3cb | |||
6a3bd04e42 | |||
8af2c87f7e | |||
cd39e3dec1 | |||
338be95874 | |||
9ac56bad4c | |||
67ee87a6e9 | |||
53e1442ac2 | |||
e1d6219731 | |||
dc3b7602ee | |||
d086570c7a | |||
4947aa29db | |||
d443dcc733 | |||
6f158f834d | |||
445d506ac9 | |||
![]() |
b11a463e4f | ||
b665ad8621 | |||
41af27c582 | |||
47473bee34 | |||
b9ccfb89ce | |||
ce64cfd6ed | |||
3cf39c09bf | |||
4246898ad3 | |||
2851602052 | |||
4968a0bdf9 | |||
![]() |
f383cad329 | ||
002d563bbb | |||
4d91808710 | |||
4044c29069 | |||
54d651c344 | |||
19df0e3cfd | |||
b2510b9e20 | |||
feb6fd632f | |||
a1c3e45100 | |||
b45cee1aaf | |||
5df6b4004c | |||
5f71b1edd5 | |||
80083ac773 | |||
0cd34967c0 | |||
6afafc46f6 | |||
2d75b39b64 | |||
eee3529eaf | |||
859b3ff346 | |||
bce482f476 | |||
d9b1592c88 | |||
3462b4c7ae | |||
2d60c496a2 | |||
513f566b40 | |||
b5e5fbcfc8 | |||
3da25dc625 | |||
f3c5a84bb9 | |||
033641aa74 | |||
f9aea19d98 | |||
d52b7dbe26 | |||
3e6f2c7a99 | |||
f7022fc73f | |||
8a048593ca | |||
b6030711a2 | |||
638c16f410 | |||
682a74e090 | |||
aee04d4960 | |||
4c19fe4707 | |||
4998ceebfc | |||
408726000a | |||
![]() |
e0f2f07d1e | ||
![]() |
6d73d98fb6 | ||
03a83b4eb5 | |||
![]() |
ea4309925f | ||
a9d5c8f97f | |||
847b66e81d | |||
b8cf8e0bc2 | |||
80bc819d50 | |||
adefdbc9df | |||
7c68147709 | |||
060d668ae6 | |||
6c1fdd52c1 | |||
3caafd24a9 | |||
c4958bc540 | |||
2e8d7fa7ee | |||
253c5d25f7 | |||
c290ac2ab1 | |||
af4167441b | |||
50a4b9d502 | |||
5f0d4fef91 | |||
68b06208d2 | |||
f3c88f8ba5 | |||
![]() |
e178a273fa | ||
94c4a9995e | |||
4b673ebb99 | |||
577d6d3f87 | |||
ed4222258e | |||
7c1bb239be | |||
56db09e2fd | |||
1388e9de8a | |||
a971409d5a | |||
ccd5f80550 | |||
8ff6322152 | |||
6db290641e | |||
286bd87445 | |||
eb85de027c | |||
78693d524c | |||
e7003bc965 | |||
c73be23e17 | |||
845f4cebad | |||
d03b26edbd | |||
a1cc7042a7 | |||
247abdbf41 | |||
b37093de7b | |||
45d59e0df5 | |||
0cebe554d1 | |||
af3d7123c9 | |||
3953b82030 | |||
88aa056d1a | |||
b66600b9f3 | |||
b406b6717f | |||
94084b2d3c | |||
00fc110d3f | |||
1c0a490d0e | |||
c3fa7b7e4f | |||
4b36c5b1a7 | |||
3385c04598 | |||
9fed00341e | |||
![]() |
ed4b2ba75a | ||
2209321f78 | |||
be8a201a16 | |||
0b0c7ca017 | |||
c8e331f450 | |||
4891da8ae2 | |||
1a5fa2b319 | |||
143a81ccce | |||
c29afa5156 | |||
732e8c723e | |||
![]() |
6bb980b0f4 | ||
8e84938dd0 | |||
a4f840e15b | |||
fcc844f8fb | |||
![]() |
b3f0dc2907 | ||
71997921c4 | |||
0c75a98561 | |||
![]() |
174ed69c1b | ||
7c8b9c7a9a | |||
62906cdbea | |||
7f570a7174 | |||
9cd2e80d5d | |||
462bd81399 | |||
819152527f | |||
89e2b441ed | |||
ae34808114 | |||
fdad77d73d | |||
0a361eb5ec | |||
2ba804d7b7 | |||
5dc0fd08a7 | |||
2053e1f533 | |||
4ae06b6123 | |||
013fc69ea8 | |||
3bf98d1cec | |||
9ce49af32e | |||
1f251b7a27 | |||
61fdc45034 | |||
bf7f918a0e | |||
fe0fa7cec6 | |||
![]() |
4a540b9b48 | ||
fcbb20286a | |||
d08e925ef1 | |||
bcff0ef9ca | |||
2e5671a959 | |||
aadd355028 | |||
3de6fe0b3e | |||
e9b4de43d8 | |||
90b0fb135f | |||
8a1860bd9a | |||
6bef255904 | |||
8083527f90 | |||
1d2eb461b5 | |||
![]() |
b84707df17 | ||
ada47c4772 | |||
748475b943 | |||
b21db5e698 | |||
![]() |
5add6f2ed9 | ||
c9dc55301c | |||
a19c9e9351 | |||
![]() |
2db09f67a4 | ||
03544ed54f | |||
54a03d4247 | |||
84adc23941 | |||
0f68e5c30a | |||
5181bc46b3 | |||
452590571c | |||
ab38223047 | |||
f731bce6cd | |||
4c3bb60d0f | |||
9ff4e0068f | |||
84e98ba182 | |||
8e58f93215 | |||
aab4794512 | |||
952d6663e0 | |||
7b0c8097a7 | |||
b313525c1b | |||
d75e45d10c | |||
bd87ba90e6 | |||
![]() |
7bc5246156 | ||
f6c5af3d47 | |||
c8fcea0c33 | |||
20ece8736f | |||
![]() |
b4adb85933 | ||
605ce623be | |||
![]() |
7b30a3e98d | ||
![]() |
7b76a160a4 | ||
0eb9351296 | |||
![]() |
2330cec2c6 | ||
fe22635bf6 | |||
c0367b19e2 | |||
4adbe31e2f | |||
1fb2eaf1c5 | |||
2f280d4b92 | |||
e9c8ae767a | |||
![]() |
7fc220517f | ||
![]() |
28617bb167 | ||
84f025c6fd | |||
![]() |
066f5a4469 | ||
![]() |
d07cc5e680 | ||
![]() |
162cf8e81d | ||
![]() |
fd5c94c48a | ||
![]() |
2724d08cf5 | ||
![]() |
461ba4438f | ||
d581c1b304 | |||
e8a4bddef4 | |||
fbd889ec28 | |||
509e0c5b76 | |||
7b62a54230 | |||
![]() |
53c98e45cf | ||
bcefce33f2 | |||
9df1e0cad5 | |||
aa0bd29546 | |||
1a72ee4cbe | |||
e4ef8cbf7e | |||
5fa6cdb77a | |||
5304c6ed7d | |||
b669fd376a | |||
4d4608363c | |||
7141eb75ef | |||
b282a065f1 | |||
![]() |
4f81b4b4ce | ||
a3226bdf3e | |||
![]() |
d96e9de9de | ||
93fd07e19c | |||
5f19646d7e | |||
675677ec67 | |||
![]() |
df2a19eac7 | ||
2856f3b583 | |||
965bd53e02 | |||
05f15645ec | |||
cb0cab48ef | |||
029fb002dd | |||
4443c4082e | |||
bda8887e0c | |||
5575aba025 | |||
25d8ce16b5 | |||
59553d47c0 | |||
84af1eaa92 | |||
059f19d821 | |||
0f156a2436 | |||
f42a501c61 | |||
d8b8b4d7e2 | |||
14f3b2cdad | |||
f546b0800b | |||
92ae3ff84c | |||
5954b351f0 | |||
33c4eefabb | |||
![]() |
6e999e08ab | ||
ec98bb318b | |||
3a7ab62eac | |||
1f55e12206 | |||
ea3895558d | |||
![]() |
e4c6da29b2 | ||
4ced8900f5 | |||
f087a225dc | |||
dd98f6b55c | |||
b18a214ecb | |||
d7c812f15b | |||
3ba16afa1e | |||
8c3f4f7edf | |||
307f8c8e76 | |||
8bd09b1d77 | |||
f29a738e23 | |||
c18ff180e3 | |||
22ee056c3a | |||
f5a2d93224 | |||
a31bd2609f | |||
![]() |
2e19649bb9 | ||
7124c66340 | |||
![]() |
259b9c73d0 | ||
08b0de45f3 | |||
![]() |
2246d456aa | ||
9553ba1373 | |||
a2ebbeb836 | |||
5b014911a5 | |||
23fd576cf8 | |||
43464c94f4 | |||
322a614497 | |||
340c535dbf | |||
088ea59b7e | |||
cac9828ae3 | |||
9e9d45ae16 | |||
89d0cc3a0c | |||
e54a4b355e | |||
933c2cffd6 | |||
ed1fc9d96b | |||
496045fc30 | |||
f651cc6c4e | |||
0efb627bbd | |||
1b07b7a068 | |||
0abce91940 | |||
2e46a8c864 | |||
ef5a362a5b | |||
a6715213c3 | |||
482465e18a | |||
b0ec1d2747 | |||
1ef33be2d4 | |||
d2aee304e8 | |||
6e56b42faa | |||
1c6e338d59 | |||
7313b243f2 | |||
1182c26978 | |||
8cbff7093d | |||
0fcc063fd9 | |||
1949643ee5 | |||
7bf9d2c580 | |||
4a9c5c60b7 | |||
0e285fa23c | |||
214a78a46f | |||
f87f8532c3 | |||
3da0b52c97 | |||
785a518ebe | |||
2bf56f7fbb | |||
93a865dde7 | |||
72d2355af5 | |||
dfac5a63bd | |||
c87327ddeb | |||
7ca5ba14b5 | |||
51bf1680bd |
@@ -836,7 +836,7 @@ if(WITH_PYTHON)
|
||||
# because UNIX will search for the old Python paths which may not exist.
|
||||
# giving errors about missing paths before this case is met.
|
||||
if(DEFINED PYTHON_VERSION AND "${PYTHON_VERSION}" VERSION_LESS "3.9")
|
||||
message(FATAL_ERROR "At least Python 3.9 is required to build")
|
||||
message(FATAL_ERROR "At least Python 3.9 is required to build, but found Python ${PYTHON_VERSION}")
|
||||
endif()
|
||||
|
||||
file(GLOB RESULT "${CMAKE_SOURCE_DIR}/release/scripts/addons")
|
||||
|
@@ -79,6 +79,7 @@ if(WIN32)
|
||||
# Normal collection of build artifacts
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb_debug.lib ${HARVEST_TARGET}/tbb/lib/tbb_debug.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/bin/tbb_debug.dll ${HARVEST_TARGET}/tbb/bin/tbb_debug.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc_debug.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc_debug.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbbmalloc_proxy_debug.lib ${HARVEST_TARGET}/tbb/lib/tbbmalloc_proxy_debug.lib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/bin/tbbmalloc_debug.dll ${HARVEST_TARGET}/tbb/bin/tbbmalloc_debug.dll
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/bin/tbbmalloc_proxy_debug.dll ${HARVEST_TARGET}/tbb/bin/tbbmalloc_proxy_debug.dll
|
||||
|
@@ -432,9 +432,9 @@ set(USD_HASH 1dd1e2092d085ed393c1f7c450a4155a)
|
||||
set(USD_HASH_TYPE MD5)
|
||||
set(USD_FILE usd-v${USD_VERSION}.tar.gz)
|
||||
|
||||
set(OIDN_VERSION 1.3.0)
|
||||
set(OIDN_VERSION 1.4.0)
|
||||
set(OIDN_URI https://github.com/OpenImageDenoise/oidn/releases/download/v${OIDN_VERSION}/oidn-${OIDN_VERSION}.src.tar.gz)
|
||||
set(OIDN_HASH 301a5a0958d375a942014df0679b9270)
|
||||
set(OIDN_HASH 421824019becc5b664a22a2b98332bc5)
|
||||
set(OIDN_HASH_TYPE MD5)
|
||||
set(OIDN_FILE oidn-${OIDN_VERSION}.src.tar.gz)
|
||||
|
||||
|
@@ -553,10 +553,10 @@ EMBREE_FORCE_BUILD=false
|
||||
EMBREE_FORCE_REBUILD=false
|
||||
EMBREE_SKIP=false
|
||||
|
||||
OIDN_VERSION="1.3.0"
|
||||
OIDN_VERSION_SHORT="1.3"
|
||||
OIDN_VERSION_MIN="1.3.0"
|
||||
OIDN_VERSION_MAX="1.4"
|
||||
OIDN_VERSION="1.4.0"
|
||||
OIDN_VERSION_SHORT="1.4"
|
||||
OIDN_VERSION_MIN="1.4.0"
|
||||
OIDN_VERSION_MAX="1.5"
|
||||
OIDN_FORCE_BUILD=false
|
||||
OIDN_FORCE_REBUILD=false
|
||||
OIDN_SKIP=false
|
||||
@@ -565,7 +565,7 @@ ISPC_VERSION="1.14.1"
|
||||
|
||||
FFMPEG_VERSION="4.4"
|
||||
FFMPEG_VERSION_SHORT="4.4"
|
||||
FFMPEG_VERSION_MIN="4.4"
|
||||
FFMPEG_VERSION_MIN="3.0"
|
||||
FFMPEG_VERSION_MAX="5.0"
|
||||
FFMPEG_FORCE_BUILD=false
|
||||
FFMPEG_FORCE_REBUILD=false
|
||||
|
@@ -1,33 +1,3 @@
|
||||
diff -Naur oidn-1.3.0/cmake/FindTBB.cmake external_openimagedenoise/cmake/FindTBB.cmake
|
||||
--- oidn-1.3.0/cmake/FindTBB.cmake 2021-02-04 16:20:26 -0700
|
||||
+++ external_openimagedenoise/cmake/FindTBB.cmake 2021-02-12 09:35:53 -0700
|
||||
@@ -332,20 +332,22 @@
|
||||
${TBB_ROOT}/lib/${TBB_ARCH}/${TBB_VCVER}
|
||||
${TBB_ROOT}/lib
|
||||
)
|
||||
-
|
||||
# On Windows, also search the DLL so that the client may install it.
|
||||
file(GLOB DLL_NAMES
|
||||
${TBB_ROOT}/bin/${TBB_ARCH}/${TBB_VCVER}/${LIB_NAME}.dll
|
||||
${TBB_ROOT}/bin/${LIB_NAME}.dll
|
||||
+ ${TBB_ROOT}/lib/${LIB_NAME}.dll
|
||||
${TBB_ROOT}/redist/${TBB_ARCH}/${TBB_VCVER}/${LIB_NAME}.dll
|
||||
${TBB_ROOT}/redist/${TBB_ARCH}/${TBB_VCVER}/${LIB_NAME_GLOB1}.dll
|
||||
${TBB_ROOT}/redist/${TBB_ARCH}/${TBB_VCVER}/${LIB_NAME_GLOB2}.dll
|
||||
${TBB_ROOT}/../redist/${TBB_ARCH}/tbb/${TBB_VCVER}/${LIB_NAME}.dll
|
||||
${TBB_ROOT}/../redist/${TBB_ARCH}_win/tbb/${TBB_VCVER}/${LIB_NAME}.dll
|
||||
)
|
||||
- list(GET DLL_NAMES 0 DLL_NAME)
|
||||
- get_filename_component(${BIN_DIR_VAR} "${DLL_NAME}" DIRECTORY)
|
||||
- set(${DLL_VAR} "${DLL_NAME}" CACHE PATH "${COMPONENT_NAME} ${BUILD_CONFIG} dll path")
|
||||
+ if (DLL_NAMES)
|
||||
+ list(GET DLL_NAMES 0 DLL_NAME)
|
||||
+ get_filename_component(${BIN_DIR_VAR} "${DLL_NAME}" DIRECTORY)
|
||||
+ set(${DLL_VAR} "${DLL_NAME}" CACHE PATH "${COMPONENT_NAME} ${BUILD_CONFIG} dll path")
|
||||
+ endif()
|
||||
elseif(APPLE)
|
||||
set(LIB_PATHS ${TBB_ROOT}/lib)
|
||||
else()
|
||||
--- external_openimagedenoise/cmake/oidn_ispc.cmake 2021-02-15 17:29:34.000000000 +0100
|
||||
+++ external_openimagedenoise/cmake/oidn_ispc.cmake2 2021-02-15 17:29:28.000000000 +0100
|
||||
@@ -98,7 +98,7 @@
|
||||
|
@@ -20,8 +20,24 @@ if(NOT CLANG_ROOT_DIR AND NOT $ENV{CLANG_ROOT_DIR} STREQUAL "")
|
||||
set(CLANG_ROOT_DIR $ENV{CLANG_ROOT_DIR})
|
||||
endif()
|
||||
|
||||
if(NOT LLVM_ROOT_DIR)
|
||||
if(DEFINED LLVM_VERSION)
|
||||
message(running llvm-config-${LLVM_VERSION})
|
||||
find_program(LLVM_CONFIG llvm-config-${LLVM_VERSION})
|
||||
endif()
|
||||
if(NOT LLVM_CONFIG)
|
||||
find_program(LLVM_CONFIG llvm-config)
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND ${LLVM_CONFIG} --prefix
|
||||
OUTPUT_VARIABLE LLVM_ROOT_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
set(LLVM_ROOT_DIR ${LLVM_ROOT_DIR} CACHE PATH "Path to the LLVM installation")
|
||||
endif()
|
||||
|
||||
set(_CLANG_SEARCH_DIRS
|
||||
${CLANG_ROOT_DIR}
|
||||
${LLVM_ROOT_DIR}
|
||||
/opt/lib/clang
|
||||
)
|
||||
|
||||
|
@@ -472,8 +472,7 @@ if(NOT GFLAGS_FOUND)
|
||||
gflags_report_not_found(
|
||||
"Could not find gflags include directory, set GFLAGS_INCLUDE_DIR "
|
||||
"to directory containing gflags/gflags.h")
|
||||
endif(NOT GFLAGS_INCLUDE_DIR OR
|
||||
NOT EXISTS ${GFLAGS_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
find_library(GFLAGS_LIBRARY NAMES gflags
|
||||
PATHS ${GFLAGS_LIBRARY_DIR_HINTS}
|
||||
@@ -484,8 +483,7 @@ if(NOT GFLAGS_FOUND)
|
||||
gflags_report_not_found(
|
||||
"Could not find gflags library, set GFLAGS_LIBRARY "
|
||||
"to full path to libgflags.")
|
||||
endif(NOT GFLAGS_LIBRARY OR
|
||||
NOT EXISTS ${GFLAGS_LIBRARY})
|
||||
endif()
|
||||
|
||||
# gflags typically requires a threading library (which is OS dependent), note
|
||||
# that this defines the CMAKE_THREAD_LIBS_INIT variable. If we are able to
|
||||
@@ -560,8 +558,7 @@ if(NOT GFLAGS_FOUND)
|
||||
gflags_report_not_found(
|
||||
"Caller defined GFLAGS_INCLUDE_DIR:"
|
||||
" ${GFLAGS_INCLUDE_DIR} does not contain gflags/gflags.h header.")
|
||||
endif(GFLAGS_INCLUDE_DIR AND
|
||||
NOT EXISTS ${GFLAGS_INCLUDE_DIR}/gflags/gflags.h)
|
||||
endif()
|
||||
# TODO: This regex for gflags library is pretty primitive, we use lowercase
|
||||
# for comparison to handle Windows using CamelCase library names, could
|
||||
# this check be better?
|
||||
@@ -571,8 +568,7 @@ if(NOT GFLAGS_FOUND)
|
||||
gflags_report_not_found(
|
||||
"Caller defined GFLAGS_LIBRARY: "
|
||||
"${GFLAGS_LIBRARY} does not match gflags.")
|
||||
endif(GFLAGS_LIBRARY AND
|
||||
NOT "${LOWERCASE_GFLAGS_LIBRARY}" MATCHES ".*gflags[^/]*")
|
||||
endif()
|
||||
|
||||
gflags_reset_find_library_prefix()
|
||||
|
||||
|
@@ -40,7 +40,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(NanoVDB DEFAULT_MSG
|
||||
|
||||
IF(NANOVDB_FOUND)
|
||||
SET(NANOVDB_INCLUDE_DIRS ${NANOVDB_INCLUDE_DIR})
|
||||
ENDIF(NANOVDB_FOUND)
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
NANOVDB_INCLUDE_DIR
|
||||
|
@@ -46,7 +46,7 @@ SET(_opencollada_FIND_COMPONENTS
|
||||
)
|
||||
|
||||
# Fedora openCOLLADA package links these statically
|
||||
# note that order is important here ot it wont link
|
||||
# note that order is important here or it won't link
|
||||
SET(_opencollada_FIND_STATIC_COMPONENTS
|
||||
buffer
|
||||
ftoa
|
||||
|
@@ -44,7 +44,7 @@ SET(PYTHON_LINKFLAGS "-Xlinker -export-dynamic" CACHE STRING "Linker flags for p
|
||||
MARK_AS_ADVANCED(PYTHON_LINKFLAGS)
|
||||
|
||||
|
||||
# if the user passes these defines as args, we dont want to overwrite
|
||||
# if the user passes these defines as args, we don't want to overwrite
|
||||
SET(_IS_INC_DEF OFF)
|
||||
SET(_IS_INC_CONF_DEF OFF)
|
||||
SET(_IS_LIB_DEF OFF)
|
||||
@@ -143,7 +143,7 @@ IF((NOT _IS_INC_DEF) OR (NOT _IS_INC_CONF_DEF) OR (NOT _IS_LIB_DEF) OR (NOT _IS_
|
||||
SET(_PYTHON_ABI_FLAGS "${_CURRENT_ABI_FLAGS}")
|
||||
break()
|
||||
ELSE()
|
||||
# ensure we dont find values from 2 different ABI versions
|
||||
# ensure we don't find values from 2 different ABI versions
|
||||
IF(NOT _IS_INC_DEF)
|
||||
UNSET(PYTHON_INCLUDE_DIR CACHE)
|
||||
ENDIF()
|
||||
|
@@ -40,7 +40,7 @@ FIND_PACKAGE_HANDLE_STANDARD_ARGS(sse2neon DEFAULT_MSG
|
||||
|
||||
IF(SSE2NEON_FOUND)
|
||||
SET(SSE2NEON_INCLUDE_DIRS ${SSE2NEON_INCLUDE_DIR})
|
||||
ENDIF(SSE2NEON_FOUND)
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
SSE2NEON_INCLUDE_DIR
|
||||
|
@@ -305,7 +305,7 @@ def file_check_arg_sizes(tu):
|
||||
for i, node_child in enumerate(children):
|
||||
children = list(node_child.get_children())
|
||||
|
||||
# skip if we dont have an index...
|
||||
# skip if we don't have an index...
|
||||
size_def = args_size_definition.get(i, -1)
|
||||
|
||||
if size_def == -1:
|
||||
@@ -354,7 +354,7 @@ def file_check_arg_sizes(tu):
|
||||
filepath # always the same but useful when running threaded
|
||||
))
|
||||
|
||||
# we dont really care what we are looking at, just scan entire file for
|
||||
# we don't really care what we are looking at, just scan entire file for
|
||||
# function calls.
|
||||
|
||||
def recursive_func_call_check(node):
|
||||
|
@@ -694,7 +694,7 @@ macro(message_first_run)
|
||||
endmacro()
|
||||
|
||||
# when we have warnings as errors applied globally this
|
||||
# needs to be removed for some external libs which we dont maintain.
|
||||
# needs to be removed for some external libs which we don't maintain.
|
||||
|
||||
# utility macro
|
||||
macro(remove_cc_flag
|
||||
@@ -794,7 +794,7 @@ macro(remove_extra_strict_flags)
|
||||
endmacro()
|
||||
|
||||
# note, we can only append flags on a single file so we need to negate the options.
|
||||
# at the moment we cant shut up ffmpeg deprecations, so use this, but will
|
||||
# at the moment we can't shut up ffmpeg deprecations, so use this, but will
|
||||
# probably add more removals here.
|
||||
macro(remove_strict_c_flags_file
|
||||
filenames)
|
||||
@@ -963,14 +963,6 @@ macro(blender_project_hack_post)
|
||||
unset(_reset_standard_cflags_rel)
|
||||
unset(_reset_standard_cxxflags_rel)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# workaround for omission in cmake 2.8.4's GNU.cmake, fixed in 2.8.5
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if(NOT DARWIN)
|
||||
set(CMAKE_INCLUDE_SYSTEM_FLAG_C "-isystem ")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
# pair of macros to allow libraries to be specify files to install, but to
|
||||
|
@@ -388,6 +388,10 @@ endif()
|
||||
|
||||
if(WITH_TBB)
|
||||
find_package(TBB)
|
||||
if(NOT TBB_FOUND)
|
||||
message(WARNING "TBB not found, disabling WITH_TBB")
|
||||
set(WITH_TBB OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_POTRACE)
|
||||
|
@@ -457,6 +457,10 @@ endif()
|
||||
|
||||
if(WITH_TBB)
|
||||
find_package_wrapper(TBB)
|
||||
if(NOT TBB_FOUND)
|
||||
message(WARNING "TBB not found, disabling WITH_TBB")
|
||||
set(WITH_TBB OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_XR_OPENXR)
|
||||
|
@@ -261,8 +261,10 @@ if(NOT DEFINED LIBDIR)
|
||||
else()
|
||||
message(FATAL_ERROR "32 bit compiler detected, blender no longer provides pre-build libraries for 32 bit windows, please set the LIBDIR cmake variable to your own library folder")
|
||||
endif()
|
||||
# Can be 1910..1912
|
||||
if(MSVC_VERSION GREATER 1919)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.29.30130)
|
||||
message(STATUS "Visual Studio 2022 detected.")
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
|
||||
elseif(MSVC_VERSION GREATER 1919)
|
||||
message(STATUS "Visual Studio 2019 detected.")
|
||||
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc15)
|
||||
elseif(MSVC_VERSION GREATER 1909)
|
||||
@@ -679,6 +681,7 @@ if(WITH_TBB)
|
||||
set(TBB_INCLUDE_DIR ${LIBDIR}/tbb/include)
|
||||
set(TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR})
|
||||
if(WITH_TBB_MALLOC_PROXY)
|
||||
set(TBB_MALLOC_LIBRARIES optimized ${LIBDIR}/tbb/lib/tbbmalloc.lib debug ${LIBDIR}/tbb/lib/tbbmalloc_debug.lib)
|
||||
add_definitions(-DWITH_TBB_MALLOC)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -6,6 +6,9 @@ if %ERRORLEVEL% EQU 0 goto DetectionComplete
|
||||
call "%~dp0\detect_msvc2019.cmd"
|
||||
if %ERRORLEVEL% EQU 0 goto DetectionComplete
|
||||
|
||||
call "%~dp0\detect_msvc2022.cmd"
|
||||
if %ERRORLEVEL% EQU 0 goto DetectionComplete
|
||||
|
||||
echo Compiler Detection failed. Use verbose switch for more information.
|
||||
exit /b 1
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
if "%BUILD_VS_YEAR%"=="2017" set BUILD_VS_LIBDIRPOST=vc15
|
||||
if "%BUILD_VS_YEAR%"=="2019" set BUILD_VS_LIBDIRPOST=vc15
|
||||
if "%BUILD_VS_YEAR%"=="2022" set BUILD_VS_LIBDIRPOST=vc15
|
||||
|
||||
set BUILD_VS_SVNDIR=win64_%BUILD_VS_LIBDIRPOST%
|
||||
set BUILD_VS_LIBDIR="%BLENDER_DIR%..\lib\%BUILD_VS_SVNDIR%"
|
||||
|
@@ -19,10 +19,10 @@ if "%WITH_PYDEBUG%"=="1" (
|
||||
set PYDEBUG_CMAKE_ARGS=-DWINDOWS_PYTHON_DEBUG=On
|
||||
)
|
||||
|
||||
if "%BUILD_VS_YEAR%"=="2019" (
|
||||
set BUILD_PLATFORM_SELECT=-A %MSBUILD_PLATFORM%
|
||||
) else (
|
||||
if "%BUILD_VS_YEAR%"=="2017" (
|
||||
set BUILD_GENERATOR_POST=%WINDOWS_ARCH%
|
||||
) else (
|
||||
set BUILD_PLATFORM_SELECT=-A %MSBUILD_PLATFORM%
|
||||
)
|
||||
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%BUILD_GENERATOR_POST%" %BUILD_PLATFORM_SELECT% %TESTS_CMAKE_ARGS% %CLANG_CMAKE_ARGS% %ASAN_CMAKE_ARGS% %PYDEBUG_CMAKE_ARGS%
|
||||
|
3
build_files/windows/detect_msvc2022.cmd
Normal file
3
build_files/windows/detect_msvc2022.cmd
Normal file
@@ -0,0 +1,3 @@
|
||||
set BUILD_VS_VER=17
|
||||
set BUILD_VS_YEAR=2022
|
||||
call "%~dp0\detect_msvc_vswhere.cmd"
|
@@ -66,6 +66,14 @@ if NOT "%1" == "" (
|
||||
) else if "%1" == "2019b" (
|
||||
set BUILD_VS_YEAR=2019
|
||||
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
|
||||
) else if "%1" == "2022" (
|
||||
set BUILD_VS_YEAR=2022
|
||||
) else if "%1" == "2022pre" (
|
||||
set BUILD_VS_YEAR=2022
|
||||
set VSWHERE_ARGS=-prerelease
|
||||
) else if "%1" == "2022b" (
|
||||
set BUILD_VS_YEAR=2022
|
||||
set VSWHERE_ARGS=-products Microsoft.VisualStudio.Product.BuildTools
|
||||
) else if "%1" == "packagename" (
|
||||
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -DCPACK_OVERRIDE_PACKAGENAME="%2"
|
||||
shift /1
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# Doxyfile 1.8.16
|
||||
# Doxyfile 1.9.1
|
||||
|
||||
# This file describes the settings to be used by the documentation system
|
||||
# doxygen (www.doxygen.org) for a project.
|
||||
@@ -38,7 +38,7 @@ PROJECT_NAME = Blender
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER = "V3.0"
|
||||
PROJECT_NUMBER = V3.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
@@ -227,6 +227,14 @@ QT_AUTOBRIEF = NO
|
||||
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
|
||||
# By default Python docstrings are displayed as preformatted text and doxygen's
|
||||
# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the
|
||||
# doxygen's special commands can be used and the contents of the docstring
|
||||
# documentation blocks is shown as doxygen documentation.
|
||||
# The default value is: YES.
|
||||
|
||||
PYTHON_DOCSTRING = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
|
||||
# documentation from any documented member that it re-implements.
|
||||
# The default value is: YES.
|
||||
@@ -263,12 +271,6 @@ TAB_SIZE = 4
|
||||
|
||||
ALIASES =
|
||||
|
||||
# This tag can be used to specify a number of word-keyword mappings (TCL only).
|
||||
# A mapping has the form "name=value". For example adding "class=itcl::class"
|
||||
# will allow you to use the command class in the itcl::class meaning.
|
||||
|
||||
TCL_SUBST =
|
||||
|
||||
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
|
||||
# only. Doxygen will then generate output that is more tailored for C. For
|
||||
# instance, some of the names that are used will be different. The list of all
|
||||
@@ -309,19 +311,22 @@ OPTIMIZE_OUTPUT_SLICE = NO
|
||||
# parses. With this tag you can assign which parser to use for a given
|
||||
# extension. Doxygen has a built-in mapping, but you can override or extend it
|
||||
# using this tag. The format is ext=language, where ext is a file extension, and
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice,
|
||||
# language is one of the parsers supported by doxygen: IDL, Java, JavaScript,
|
||||
# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL,
|
||||
# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran:
|
||||
# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser
|
||||
# tries to guess whether the code is fixed or free formatted code, this is the
|
||||
# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat
|
||||
# .inc files as Fortran files (default is PHP), and .f files as C (default is
|
||||
# Fortran), use: inc=Fortran f=C.
|
||||
# default for Fortran type files). For instance to make doxygen treat .inc files
|
||||
# as Fortran files (default is PHP), and .f files as C (default is Fortran),
|
||||
# use: inc=Fortran f=C.
|
||||
#
|
||||
# Note: For files without extension you can use no_extension as a placeholder.
|
||||
#
|
||||
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
|
||||
# the files are not read by doxygen.
|
||||
# the files are not read by doxygen. When specifying no_extension you should add
|
||||
# * to the FILE_PATTERNS.
|
||||
#
|
||||
# Note see also the list of default file extension mappings.
|
||||
|
||||
EXTENSION_MAPPING =
|
||||
|
||||
@@ -455,6 +460,19 @@ TYPEDEF_HIDES_STRUCT = NO
|
||||
|
||||
LOOKUP_CACHE_SIZE = 3
|
||||
|
||||
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
|
||||
# during processing. When set to 0 doxygen will based this on the number of
|
||||
# cores available in the system. You can set it explicitly to a value larger
|
||||
# than 0 to get more control over the balance between CPU load and processing
|
||||
# speed. At this moment only the input processing can be done using multiple
|
||||
# threads. Since this is still an experimental feature the default is set to 1,
|
||||
# which efficively disables parallel processing. Please report any issues you
|
||||
# encounter. Generating dot graphs in parallel is controlled by the
|
||||
# DOT_NUM_THREADS setting.
|
||||
# Minimum value: 0, maximum value: 32, default value: 1.
|
||||
|
||||
NUM_PROC_THREADS = 1
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -518,6 +536,13 @@ EXTRACT_LOCAL_METHODS = NO
|
||||
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
|
||||
# If this flag is set to YES, the name of an unnamed parameter in a declaration
|
||||
# will be determined by the corresponding definition. By default unnamed
|
||||
# parameters remain unnamed in the output.
|
||||
# The default value is: YES.
|
||||
|
||||
RESOLVE_UNNAMED_PARAMS = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
|
||||
# undocumented members inside documented classes or files. If set to NO these
|
||||
# members will be included in the various overviews, but no documentation
|
||||
@@ -535,8 +560,8 @@ HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
|
||||
# (class|struct|union) declarations. If set to NO, these declarations will be
|
||||
# included in the documentation.
|
||||
# declarations. If set to NO, these declarations will be included in the
|
||||
# documentation.
|
||||
# The default value is: NO.
|
||||
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
@@ -555,11 +580,18 @@ HIDE_IN_BODY_DOCS = NO
|
||||
|
||||
INTERNAL_DOCS = YES
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
|
||||
# names in lower-case letters. If set to YES, upper-case letters are also
|
||||
# allowed. This is useful if you have classes or files whose names only differ
|
||||
# in case and if your file system supports case sensitive file names. Windows
|
||||
# (including Cygwin) ands Mac users are advised to set this option to NO.
|
||||
# With the correct setting of option CASE_SENSE_NAMES doxygen will better be
|
||||
# able to match the capabilities of the underlying filesystem. In case the
|
||||
# filesystem is case sensitive (i.e. it supports files in the same directory
|
||||
# whose names only differ in casing), the option must be set to YES to properly
|
||||
# deal with such files in case they appear in the input. For filesystems that
|
||||
# are not case sensitive the option should be be set to NO to properly deal with
|
||||
# output files written for symbols that only differ in casing, such as for two
|
||||
# classes, one named CLASS and the other named Class, and to also support
|
||||
# references to files without having to specify the exact matching casing. On
|
||||
# Windows (including Cygwin) and MacOS, users should typically set this option
|
||||
# to NO, whereas on Linux or other Unix flavors it should typically be set to
|
||||
# YES.
|
||||
# The default value is: system dependent.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
@@ -798,7 +830,10 @@ WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
|
||||
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
|
||||
# a warning is encountered.
|
||||
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
|
||||
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
|
||||
# at the end of the doxygen process doxygen will return with a non-zero status.
|
||||
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
|
||||
# The default value is: NO.
|
||||
|
||||
WARN_AS_ERROR = NO
|
||||
@@ -840,8 +875,8 @@ INPUT = doxygen.main.h \
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
|
||||
# possible encodings.
|
||||
# documentation (see:
|
||||
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
|
||||
# The default value is: UTF-8.
|
||||
|
||||
INPUT_ENCODING = UTF-8
|
||||
@@ -854,11 +889,15 @@ INPUT_ENCODING = UTF-8
|
||||
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
|
||||
# read by doxygen.
|
||||
#
|
||||
# Note the list of default checked file patterns might differ from the list of
|
||||
# default file extension mappings.
|
||||
#
|
||||
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
|
||||
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
|
||||
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
|
||||
# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
|
||||
# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment),
|
||||
# *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, *.vhdl,
|
||||
# *.ucf, *.qsf and *.ice.
|
||||
|
||||
FILE_PATTERNS =
|
||||
|
||||
@@ -1086,13 +1125,6 @@ VERBATIM_HEADERS = YES
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
|
||||
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
|
||||
# which the alphabetical index list will be split.
|
||||
# Minimum value: 1, maximum value: 20, default value: 5.
|
||||
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all classes will
|
||||
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
|
||||
# can be used to specify a prefix (or a list of prefixes) that should be ignored
|
||||
@@ -1231,9 +1263,9 @@ HTML_TIMESTAMP = YES
|
||||
|
||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||
# documentation will contain a main index with vertical navigation menus that
|
||||
# are dynamically created via Javascript. If disabled, the navigation index will
|
||||
# are dynamically created via JavaScript. If disabled, the navigation index will
|
||||
# consists of multiple levels of tabs that are statically embedded in every HTML
|
||||
# page. Disable this option to support browsers that do not have Javascript,
|
||||
# page. Disable this option to support browsers that do not have JavaScript,
|
||||
# like the Qt help browser.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
@@ -1263,10 +1295,11 @@ HTML_INDEX_NUM_ENTRIES = 100
|
||||
|
||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
|
||||
# generated that can be used as input for Apple's Xcode 3 integrated development
|
||||
# environment (see: https://developer.apple.com/xcode/), introduced with OSX
|
||||
# 10.5 (Leopard). To create a documentation set, doxygen will generate a
|
||||
# Makefile in the HTML output directory. Running make will produce the docset in
|
||||
# that directory and running make install will install the docset in
|
||||
# environment (see:
|
||||
# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To
|
||||
# create a documentation set, doxygen will generate a Makefile in the HTML
|
||||
# output directory. Running make will produce the docset in that directory and
|
||||
# running make install will install the docset in
|
||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
|
||||
# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy
|
||||
# genXcode/_index.html for more information.
|
||||
@@ -1308,8 +1341,8 @@ DOCSET_PUBLISHER_NAME = Publisher
|
||||
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
|
||||
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
|
||||
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
|
||||
# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on
|
||||
# Windows.
|
||||
# (see:
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=21138) on Windows.
|
||||
#
|
||||
# The HTML Help Workshop contains a compiler that can convert all HTML output
|
||||
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
|
||||
@@ -1339,7 +1372,7 @@ CHM_FILE = blender.chm
|
||||
HHC_LOCATION = "C:/Program Files (x86)/HTML Help Workshop/hhc.exe"
|
||||
|
||||
# The GENERATE_CHI flag controls if a separate .chi index file is generated
|
||||
# (YES) or that it should be included in the master .chm file (NO).
|
||||
# (YES) or that it should be included in the main .chm file (NO).
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
|
||||
|
||||
@@ -1384,7 +1417,8 @@ QCH_FILE =
|
||||
|
||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
|
||||
# Project output. For more information please see Qt Help Project / Namespace
|
||||
# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace).
|
||||
# The default value is: org.doxygen.Project.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
@@ -1392,8 +1426,8 @@ QHP_NAMESPACE = org.doxygen.Project
|
||||
|
||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
|
||||
# Help Project output. For more information please see Qt Help Project / Virtual
|
||||
# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-
|
||||
# folders).
|
||||
# Folders (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders).
|
||||
# The default value is: doc.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
@@ -1401,16 +1435,16 @@ QHP_VIRTUAL_FOLDER = doc
|
||||
|
||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
|
||||
# filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_NAME =
|
||||
|
||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
|
||||
# custom filter to add. For more information please see Qt Help Project / Custom
|
||||
# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-
|
||||
# filters).
|
||||
# Filters (see:
|
||||
# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters).
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHP_CUST_FILTER_ATTRS =
|
||||
@@ -1422,9 +1456,9 @@ QHP_CUST_FILTER_ATTRS =
|
||||
|
||||
QHP_SECT_FILTER_ATTRS =
|
||||
|
||||
# The QHG_LOCATION tag can be used to specify the location of Qt's
|
||||
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
|
||||
# generated .qhp file.
|
||||
# The QHG_LOCATION tag can be used to specify the location (absolute path
|
||||
# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to
|
||||
# run qhelpgenerator on the generated .qhp file.
|
||||
# This tag requires that the tag GENERATE_QHP is set to YES.
|
||||
|
||||
QHG_LOCATION =
|
||||
@@ -1501,6 +1535,17 @@ TREEVIEW_WIDTH = 246
|
||||
|
||||
EXT_LINKS_IN_WINDOW = NO
|
||||
|
||||
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
|
||||
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
|
||||
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
|
||||
# the HTML output. These images will generally look nicer at scaled resolutions.
|
||||
# Possible values are: png (the default) and svg (looks nicer but requires the
|
||||
# pdf2svg or inkscape tool).
|
||||
# The default value is: png.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_FORMULA_FORMAT = png
|
||||
|
||||
# Use this tag to change the font size of LaTeX formulas included as images in
|
||||
# the HTML documentation. When you change the font size after a successful
|
||||
# doxygen run you need to manually remove any form_*.png images from the HTML
|
||||
@@ -1521,8 +1566,14 @@ FORMULA_FONTSIZE = 10
|
||||
|
||||
FORMULA_TRANSPARENT = YES
|
||||
|
||||
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
|
||||
# to create new LaTeX commands to be used in formulas as building blocks. See
|
||||
# the section "Including formulas" for details.
|
||||
|
||||
FORMULA_MACROFILE =
|
||||
|
||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
|
||||
# https://www.mathjax.org) which uses client side Javascript for the rendering
|
||||
# https://www.mathjax.org) which uses client side JavaScript for the rendering
|
||||
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
|
||||
# installed or if you want to formulas look prettier in the HTML output. When
|
||||
# enabled you may also need to install MathJax separately and configure the path
|
||||
@@ -1534,7 +1585,7 @@ USE_MATHJAX = NO
|
||||
|
||||
# When MathJax is enabled you can set the default output format to be used for
|
||||
# the MathJax output. See the MathJax site (see:
|
||||
# http://docs.mathjax.org/en/latest/output.html) for more details.
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details.
|
||||
# Possible values are: HTML-CSS (which is slower, but has the best
|
||||
# compatibility), NativeMML (i.e. MathML) and SVG.
|
||||
# The default value is: HTML-CSS.
|
||||
@@ -1550,7 +1601,7 @@ MATHJAX_FORMAT = HTML-CSS
|
||||
# Content Delivery Network so you can quickly see the result without installing
|
||||
# MathJax. However, it is strongly recommended to install a local copy of
|
||||
# MathJax from https://www.mathjax.org before deployment.
|
||||
# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/.
|
||||
# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
MATHJAX_RELPATH = http://www.mathjax.org/mathjax
|
||||
@@ -1564,7 +1615,8 @@ MATHJAX_EXTENSIONS =
|
||||
|
||||
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
|
||||
# of code that will be used on startup of the MathJax code. See the MathJax site
|
||||
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
|
||||
# (see:
|
||||
# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an
|
||||
# example see the documentation.
|
||||
# This tag requires that the tag USE_MATHJAX is set to YES.
|
||||
|
||||
@@ -1592,7 +1644,7 @@ MATHJAX_CODEFILE =
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
|
||||
# implemented using a web server instead of a web client using Javascript. There
|
||||
# implemented using a web server instead of a web client using JavaScript. There
|
||||
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
|
||||
# setting. When disabled, doxygen will generate a PHP script for searching and
|
||||
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
|
||||
@@ -1611,7 +1663,8 @@ SERVER_BASED_SEARCH = NO
|
||||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: https://xapian.org/).
|
||||
# Xapian (see:
|
||||
# https://xapian.org/).
|
||||
#
|
||||
# See the section "External Indexing and Searching" for details.
|
||||
# The default value is: NO.
|
||||
@@ -1624,8 +1677,9 @@ EXTERNAL_SEARCH = NO
|
||||
#
|
||||
# Doxygen ships with an example indexer (doxyindexer) and search engine
|
||||
# (doxysearch.cgi) which are based on the open source search engine library
|
||||
# Xapian (see: https://xapian.org/). See the section "External Indexing and
|
||||
# Searching" for details.
|
||||
# Xapian (see:
|
||||
# https://xapian.org/). See the section "External Indexing and Searching" for
|
||||
# details.
|
||||
# This tag requires that the tag SEARCHENGINE is set to YES.
|
||||
|
||||
SEARCHENGINE_URL =
|
||||
@@ -1789,9 +1843,11 @@ LATEX_EXTRA_FILES =
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
|
||||
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
|
||||
# higher quality PDF documentation.
|
||||
# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as
|
||||
# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX
|
||||
# files. Set this option to YES, to get a higher quality PDF documentation.
|
||||
#
|
||||
# See also section LATEX_CMD_NAME for selecting the engine.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag GENERATE_LATEX is set to YES.
|
||||
|
||||
@@ -2126,7 +2182,8 @@ INCLUDE_FILE_PATTERNS =
|
||||
# recursively expanded use the := operator instead of the = operator.
|
||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||
|
||||
PREDEFINED = BUILD_DATE
|
||||
PREDEFINED = BUILD_DATE \
|
||||
DOXYGEN=1
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||
# tag can be used to specify a list of macro names that should be expanded. The
|
||||
@@ -2303,10 +2360,32 @@ UML_LOOK = YES
|
||||
# but if the number exceeds 15, the total amount of fields shown is limited to
|
||||
# 10.
|
||||
# Minimum value: 0, maximum value: 100, default value: 10.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
UML_LIMIT_NUM_FIELDS = 10
|
||||
|
||||
# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and
|
||||
# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS
|
||||
# tag is set to YES, doxygen will add type and arguments for attributes and
|
||||
# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen
|
||||
# will not generate fields with class member information in the UML graphs. The
|
||||
# class diagrams will look similar to the default class diagrams but using UML
|
||||
# notation for the relationships.
|
||||
# Possible values are: NO, YES and NONE.
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag UML_LOOK is set to YES.
|
||||
|
||||
DOT_UML_DETAILS = NO
|
||||
|
||||
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
|
||||
# to display on a single line. If the actual line length exceeds this threshold
|
||||
# significantly it will wrapped across multiple lines. Some heuristics are apply
|
||||
# to avoid ugly line breaks.
|
||||
# Minimum value: 0, maximum value: 1000, default value: 17.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_WRAP_THRESHOLD = 17
|
||||
|
||||
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
|
||||
# collaboration graphs will show the relations between templates and their
|
||||
# instances.
|
||||
@@ -2496,9 +2575,11 @@ DOT_MULTI_TARGETS = YES
|
||||
|
||||
GENERATE_LEGEND = YES
|
||||
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
|
||||
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate
|
||||
# files that are used to generate the various graphs.
|
||||
#
|
||||
# Note: This setting is not only used for dot files but also for msc and
|
||||
# plantuml temporary files.
|
||||
# The default value is: YES.
|
||||
# This tag requires that the tag HAVE_DOT is set to YES.
|
||||
|
||||
DOT_CLEANUP = YES
|
||||
|
@@ -29,7 +29,7 @@ with offscreen.bind():
|
||||
amount = 10
|
||||
for i in range(-amount, amount + 1):
|
||||
x_pos = i / amount
|
||||
draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, 200)
|
||||
draw_circle_2d((x_pos, 0.0), (1, 1, 1, 1), 0.5, segments=200)
|
||||
|
||||
|
||||
# Drawing the generated texture in 3D space
|
||||
|
@@ -34,7 +34,9 @@ with offscreen.bind():
|
||||
for i in range(RING_AMOUNT):
|
||||
draw_circle_2d(
|
||||
(random.uniform(-1, 1), random.uniform(-1, 1)),
|
||||
(1, 1, 1, 1), random.uniform(0.1, 1), 20)
|
||||
(1, 1, 1, 1), random.uniform(0.1, 1),
|
||||
segments=20,
|
||||
)
|
||||
|
||||
buffer = fb.read_color(0, 0, WIDTH, HEIGHT, 4, 0, 'UBYTE')
|
||||
|
||||
|
@@ -1,2 +1,13 @@
|
||||
Sphinx==3.5.3
|
||||
sphinx==3.5.4
|
||||
|
||||
# Sphinx dependencies that are important
|
||||
Jinja2==2.11.3
|
||||
Pygments==2.9.0
|
||||
docutils==0.16
|
||||
snowballstemmer==2.1.0
|
||||
babel==2.9.1
|
||||
requests==2.25.1
|
||||
|
||||
# Only needed to match the theme used for the official documentation.
|
||||
# Without this theme, the default theme will be used.
|
||||
sphinx_rtd_theme==0.5.2
|
||||
|
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
@@ -1,3 +1,3 @@
|
||||
|
||||
|
||||
#define MANTA_GIT_VERSION "commit 9c505cd22e289b98c9aa717efba8ef3201c7e458"
|
||||
#define MANTA_GIT_VERSION "commit 8fbebe02459b7f72575872c20961f7cb757db408"
|
||||
|
13
extern/mantaflow/preprocessed/kernel.h
vendored
13
extern/mantaflow/preprocessed/kernel.h
vendored
@@ -71,6 +71,19 @@ class ParticleBase;
|
||||
for (int j = bnd; j < (grid).getSizeY() - bnd; ++j) \
|
||||
for (int i = bnd; i < (grid).getSizeX() - bnd; ++i)
|
||||
|
||||
#define FOR_NEIGHBORS_BND(grid, radius, bnd) \
|
||||
for (int zj = ((grid).is3D() ? std::max(bnd, k - radius) : 0); \
|
||||
zj <= ((grid).is3D() ? std::min(k + radius, (grid).getSizeZ() - 1 - bnd) : 0); \
|
||||
zj++) \
|
||||
for (int yj = std::max(bnd, j - radius); \
|
||||
yj <= std::min(j + radius, (grid).getSizeY() - 1 - bnd); \
|
||||
yj++) \
|
||||
for (int xj = std::max(bnd, i - radius); \
|
||||
xj <= std::min(i + radius, (grid).getSizeX() - 1 - bnd); \
|
||||
xj++)
|
||||
|
||||
#define FOR_NEIGHBORS(grid, radius) FOR_NEIGHBORS_BND(grid, radius, 0)
|
||||
|
||||
//! Basic data structure for kernel data, initialized based on kernel type (e.g. single, idx, etc).
|
||||
struct KernelBase {
|
||||
int maxX, maxY, maxZ, minZ, maxT, minT;
|
||||
|
92
extern/mantaflow/preprocessed/plugin/flip.cpp
vendored
92
extern/mantaflow/preprocessed/plugin/flip.cpp
vendored
@@ -822,33 +822,29 @@ struct ComputeUnionLevelsetPindex : public KernelBase {
|
||||
{
|
||||
const Vec3 gridPos = Vec3(i, j, k) + Vec3(0.5); // shifted by half cell
|
||||
Real phiv = radius * 1.0; // outside
|
||||
const int r = int(radius) + 1;
|
||||
|
||||
int r = int(radius) + 1;
|
||||
int rZ = phi.is3D() ? r : 0;
|
||||
for (int zj = k - rZ; zj <= k + rZ; zj++)
|
||||
for (int yj = j - r; yj <= j + r; yj++)
|
||||
for (int xj = i - r; xj <= i + r; xj++) {
|
||||
if (!phi.isInBounds(Vec3i(xj, yj, zj)))
|
||||
continue;
|
||||
FOR_NEIGHBORS(phi, r)
|
||||
{
|
||||
|
||||
// note, for the particle indices in indexSys the access is periodic (ie, dont skip for
|
||||
// eg inBounds(sx,10,10)
|
||||
IndexInt isysIdxS = index.index(xj, yj, zj);
|
||||
IndexInt pStart = index(isysIdxS), pEnd = 0;
|
||||
if (phi.isInBounds(isysIdxS + 1))
|
||||
pEnd = index(isysIdxS + 1);
|
||||
else
|
||||
pEnd = indexSys.size();
|
||||
// note, for the particle indices in indexSys the access is periodic (ie, dont skip for eg
|
||||
// inBounds(sx,10,10)
|
||||
IndexInt isysIdxS = index.index(xj, yj, zj);
|
||||
IndexInt pStart = index(isysIdxS), pEnd = 0;
|
||||
if (phi.isInBounds(isysIdxS + 1))
|
||||
pEnd = index(isysIdxS + 1);
|
||||
else
|
||||
pEnd = indexSys.size();
|
||||
|
||||
// now loop over particles in cell
|
||||
for (IndexInt p = pStart; p < pEnd; ++p) {
|
||||
const int psrc = indexSys[p].sourceIndex;
|
||||
if (ptype && ((*ptype)[psrc] & exclude))
|
||||
continue;
|
||||
const Vec3 pos = parts[psrc].pos;
|
||||
phiv = std::min(phiv, fabs(norm(gridPos - pos)) - radius);
|
||||
}
|
||||
}
|
||||
// now loop over particles in cell
|
||||
for (IndexInt p = pStart; p < pEnd; ++p) {
|
||||
const int psrc = indexSys[p].sourceIndex;
|
||||
if (ptype && ((*ptype)[psrc] & exclude))
|
||||
continue;
|
||||
const Vec3 pos = parts[psrc].pos;
|
||||
phiv = std::min(phiv, fabs(norm(gridPos - pos)) - radius);
|
||||
}
|
||||
}
|
||||
phi(i, j, k) = phiv;
|
||||
}
|
||||
inline const Grid<int> &getArg0()
|
||||
@@ -1026,39 +1022,35 @@ struct ComputeAveragedLevelsetWeight : public KernelBase {
|
||||
|
||||
// loop over neighborhood, similar to ComputeUnionLevelsetPindex
|
||||
const Real sradiusInv = 1. / (4. * radius * radius);
|
||||
int r = int(1. * radius) + 1;
|
||||
int rZ = phi.is3D() ? r : 0;
|
||||
const int r = int(radius) + 1;
|
||||
// accumulators
|
||||
Real wacc = 0.;
|
||||
Vec3 pacc = Vec3(0.);
|
||||
Real racc = 0.;
|
||||
|
||||
for (int zj = k - rZ; zj <= k + rZ; zj++)
|
||||
for (int yj = j - r; yj <= j + r; yj++)
|
||||
for (int xj = i - r; xj <= i + r; xj++) {
|
||||
if (!phi.isInBounds(Vec3i(xj, yj, zj)))
|
||||
continue;
|
||||
FOR_NEIGHBORS(phi, r)
|
||||
{
|
||||
|
||||
IndexInt isysIdxS = index.index(xj, yj, zj);
|
||||
IndexInt pStart = index(isysIdxS), pEnd = 0;
|
||||
if (phi.isInBounds(isysIdxS + 1))
|
||||
pEnd = index(isysIdxS + 1);
|
||||
else
|
||||
pEnd = indexSys.size();
|
||||
for (IndexInt p = pStart; p < pEnd; ++p) {
|
||||
IndexInt psrc = indexSys[p].sourceIndex;
|
||||
if (ptype && ((*ptype)[psrc] & exclude))
|
||||
continue;
|
||||
IndexInt isysIdxS = index.index(xj, yj, zj);
|
||||
IndexInt pStart = index(isysIdxS), pEnd = 0;
|
||||
if (phi.isInBounds(isysIdxS + 1))
|
||||
pEnd = index(isysIdxS + 1);
|
||||
else
|
||||
pEnd = indexSys.size();
|
||||
for (IndexInt p = pStart; p < pEnd; ++p) {
|
||||
IndexInt psrc = indexSys[p].sourceIndex;
|
||||
if (ptype && ((*ptype)[psrc] & exclude))
|
||||
continue;
|
||||
|
||||
Vec3 pos = parts[psrc].pos;
|
||||
Real s = normSquare(gridPos - pos) * sradiusInv;
|
||||
// Real w = std::max(0., cubed(1.-s) );
|
||||
Real w = std::max(0., (1. - s)); // a bit smoother
|
||||
wacc += w;
|
||||
racc += radius * w;
|
||||
pacc += pos * w;
|
||||
}
|
||||
}
|
||||
Vec3 pos = parts[psrc].pos;
|
||||
Real s = normSquare(gridPos - pos) * sradiusInv;
|
||||
// Real w = std::max(0., cubed(1.-s) );
|
||||
Real w = std::max(0., (1. - s)); // a bit smoother
|
||||
wacc += w;
|
||||
racc += radius * w;
|
||||
pacc += pos * w;
|
||||
}
|
||||
}
|
||||
|
||||
if (wacc > VECTOR_EPSILON) {
|
||||
racc /= wacc;
|
||||
|
@@ -234,10 +234,10 @@ void subdivideMesh(
|
||||
normalize(ne2);
|
||||
|
||||
// Real thisArea = sqrMag(cross(-e2,e0));
|
||||
// small angle approximation says sin(x) = arcsin(x) = x,
|
||||
// arccos(x) = pi/2 - arcsin(x),
|
||||
// cos(x) = dot(A,B),
|
||||
// so angle is approximately 1 - dot(A,B).
|
||||
// small angle approximation says sin(x) = arcsin(x) = x,
|
||||
// arccos(x) = pi/2 - arcsin(x),
|
||||
// cos(x) = dot(A,B),
|
||||
// so angle is approximately 1 - dot(A,B).
|
||||
Real angle[3];
|
||||
angle[0] = 1.0 - dot(ne0, -ne2);
|
||||
angle[1] = 1.0 - dot(ne1, -ne0);
|
||||
|
@@ -2287,10 +2287,9 @@ struct knFlipComputePotentialTrappedAir : public KernelBase {
|
||||
const Vec3 &vj = scaleFromManta * v.getCentered(x, y, z);
|
||||
const Vec3 xij = xi - xj;
|
||||
const Vec3 vij = vi - vj;
|
||||
Real h = !pot.is3D() ?
|
||||
1.414 * radius :
|
||||
1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius for h, due
|
||||
// to squared resp. cubic neighbor area
|
||||
Real h = !pot.is3D() ? 1.414 * radius :
|
||||
1.732 * radius; // estimate sqrt(2)*radius resp. sqrt(3)*radius
|
||||
// for h, due to squared resp. cubic neighbor area
|
||||
vdiff += norm(vij) * (1 - dot(getNormalized(vij), getNormalized(xij))) *
|
||||
(1 - norm(xij) / h);
|
||||
}
|
||||
|
@@ -132,7 +132,7 @@ def init():
|
||||
_workaround_buggy_drivers()
|
||||
|
||||
path = os.path.dirname(__file__)
|
||||
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', '')))
|
||||
user_path = os.path.dirname(os.path.abspath(bpy.utils.user_resource('CONFIG', path='')))
|
||||
|
||||
_cycles.init(path, user_path, bpy.app.background)
|
||||
_parse_command_line()
|
||||
|
@@ -34,12 +34,17 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
||||
bool *use_portal)
|
||||
{
|
||||
/* test if we need to sync */
|
||||
Light *light;
|
||||
ObjectKey key(b_parent, persistent_id, b_ob_instance, false);
|
||||
BL::Light b_light(b_ob.data());
|
||||
|
||||
Light *light = light_map.find(key);
|
||||
|
||||
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
||||
* specific depsgraph update (T88515). This also mimics the behavior for Objects. */
|
||||
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
||||
|
||||
/* Update if either object or light data changed. */
|
||||
if (!light_map.add_or_update(&light, b_ob, b_parent, key)) {
|
||||
if (!tfm_updated && !light_map.add_or_update(&light, b_ob, b_parent, key)) {
|
||||
Shader *shader;
|
||||
if (!shader_map.add_or_update(&shader, b_light)) {
|
||||
if (light->get_is_portal())
|
||||
|
@@ -289,11 +289,10 @@ static PyObject *render_func(PyObject * /*self*/, PyObject *args)
|
||||
RNA_pointer_create(NULL, &RNA_Depsgraph, (ID *)PyLong_AsVoidPtr(pydepsgraph), &depsgraphptr);
|
||||
BL::Depsgraph b_depsgraph(depsgraphptr);
|
||||
|
||||
/* Allow Blender to execute other Python scripts, and isolate TBB tasks so we
|
||||
* don't get deadlocks with Blender threads accessing shared data like images. */
|
||||
/* Allow Blender to execute other Python scripts. */
|
||||
python_thread_state_save(&session->python_thread_state);
|
||||
|
||||
tbb::this_task_arena::isolate([&] { session->render(b_depsgraph); });
|
||||
session->render(b_depsgraph);
|
||||
|
||||
python_thread_state_restore(&session->python_thread_state);
|
||||
|
||||
@@ -330,8 +329,7 @@ static PyObject *bake_func(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
python_thread_state_save(&session->python_thread_state);
|
||||
|
||||
tbb::this_task_arena::isolate(
|
||||
[&] { session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height); });
|
||||
session->bake(b_depsgraph, b_object, pass_type, pass_filter, width, height);
|
||||
|
||||
python_thread_state_restore(&session->python_thread_state);
|
||||
|
||||
@@ -377,7 +375,7 @@ static PyObject *reset_func(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
python_thread_state_save(&session->python_thread_state);
|
||||
|
||||
tbb::this_task_arena::isolate([&] { session->reset_session(b_data, b_depsgraph); });
|
||||
session->reset_session(b_data, b_depsgraph);
|
||||
|
||||
python_thread_state_restore(&session->python_thread_state);
|
||||
|
||||
@@ -399,7 +397,7 @@ static PyObject *sync_func(PyObject * /*self*/, PyObject *args)
|
||||
|
||||
python_thread_state_save(&session->python_thread_state);
|
||||
|
||||
tbb::this_task_arena::isolate([&] { session->synchronize(b_depsgraph); });
|
||||
session->synchronize(b_depsgraph);
|
||||
|
||||
python_thread_state_restore(&session->python_thread_state);
|
||||
|
||||
|
@@ -1196,16 +1196,18 @@ class OptiXDevice : public CUDADevice {
|
||||
|
||||
const CUDAContextScope scope(cuContext);
|
||||
|
||||
const bool use_fast_trace_bvh = (bvh->params.bvh_type == SceneParams::BVH_STATIC);
|
||||
|
||||
// Compute memory usage
|
||||
OptixAccelBufferSizes sizes = {};
|
||||
OptixAccelBuildOptions options = {};
|
||||
options.operation = operation;
|
||||
if (background) {
|
||||
// Prefer best performance and lowest memory consumption in background
|
||||
if (use_fast_trace_bvh) {
|
||||
VLOG(2) << "Using fast to trace OptiX BVH";
|
||||
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION;
|
||||
}
|
||||
else {
|
||||
// Prefer fast updates in viewport
|
||||
VLOG(2) << "Using fast to update OptiX BVH";
|
||||
options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD | OPTIX_BUILD_FLAG_ALLOW_UPDATE;
|
||||
}
|
||||
|
||||
@@ -1253,15 +1255,16 @@ class OptiXDevice : public CUDADevice {
|
||||
out_data.device_pointer,
|
||||
sizes.outputSizeInBytes,
|
||||
&out_handle,
|
||||
background ? &compacted_size_prop : NULL,
|
||||
background ? 1 : 0));
|
||||
use_fast_trace_bvh ? &compacted_size_prop : NULL,
|
||||
use_fast_trace_bvh ? 1 : 0));
|
||||
bvh->traversable_handle = static_cast<uint64_t>(out_handle);
|
||||
|
||||
// Wait for all operations to finish
|
||||
check_result_cuda_ret(cuStreamSynchronize(NULL));
|
||||
|
||||
// Compact acceleration structure to save memory (do not do this in viewport for faster builds)
|
||||
if (background) {
|
||||
// Compact acceleration structure to save memory (only if using fast trace as the
|
||||
// OPTIX_BUILD_FLAG_ALLOW_COMPACTION flag is only set in this case).
|
||||
if (use_fast_trace_bvh) {
|
||||
uint64_t compacted_size = sizes.outputSizeInBytes;
|
||||
check_result_cuda_ret(
|
||||
cuMemcpyDtoH(&compacted_size, compacted_size_prop.result, sizeof(compacted_size)));
|
||||
@@ -1306,6 +1309,8 @@ class OptiXDevice : public CUDADevice {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool use_fast_trace_bvh = (bvh->params.bvh_type == SceneParams::BVH_STATIC);
|
||||
|
||||
free_bvh_memory_delayed();
|
||||
|
||||
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
|
||||
@@ -1315,10 +1320,10 @@ class OptiXDevice : public CUDADevice {
|
||||
if (!bvh->params.top_level) {
|
||||
assert(bvh->objects.size() == 1 && bvh->geometry.size() == 1);
|
||||
|
||||
// Refit is only possible in viewport for now (because AS is built with
|
||||
// OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above)
|
||||
OptixBuildOperation operation = OPTIX_BUILD_OPERATION_BUILD;
|
||||
if (refit && !background) {
|
||||
/* Refit is only possible when using fast to trace BVH (because AS is built with
|
||||
* OPTIX_BUILD_FLAG_ALLOW_UPDATE only there, see above). */
|
||||
if (refit && !use_fast_trace_bvh) {
|
||||
assert(bvh_optix->traversable_handle != 0);
|
||||
operation = OPTIX_BUILD_OPERATION_UPDATE;
|
||||
}
|
||||
|
@@ -736,13 +736,14 @@ static void process_uvs(CachedData &cache,
|
||||
const IV2fGeomParam::Sample &sample,
|
||||
double time)
|
||||
{
|
||||
if (scope != kFacevaryingScope) {
|
||||
if (scope != kFacevaryingScope && scope != kVaryingScope && scope != kVertexScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
const array<int> *uv_loops = cache.uv_loops.data_for_time_no_check(time).get_data_or_null();
|
||||
|
||||
if (!uv_loops) {
|
||||
/* It's ok to not have loop indices, as long as the scope is not face-varying. */
|
||||
if (!uv_loops && scope == kFacevaryingScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -766,9 +767,27 @@ static void process_uvs(CachedData &cache,
|
||||
const uint32_t *indices = sample.getIndices()->get();
|
||||
const V2f *values = sample.getVals()->get();
|
||||
|
||||
for (const int uv_loop_index : *uv_loops) {
|
||||
const uint32_t index = indices[uv_loop_index];
|
||||
*data_float2++ = make_float2(values[index][0], values[index][1]);
|
||||
if (scope == kFacevaryingScope) {
|
||||
for (const int uv_loop_index : *uv_loops) {
|
||||
const uint32_t index = indices[uv_loop_index];
|
||||
*data_float2++ = make_float2(values[index][0], values[index][1]);
|
||||
}
|
||||
}
|
||||
else if (scope == kVaryingScope || scope == kVertexScope) {
|
||||
if (triangles) {
|
||||
for (size_t i = 0; i < triangles->size(); i++) {
|
||||
const int3 t = (*triangles)[i];
|
||||
*data_float2++ = make_float2(values[t.x][0], values[t.x][1]);
|
||||
*data_float2++ = make_float2(values[t.y][0], values[t.y][1]);
|
||||
*data_float2++ = make_float2(values[t.z][0], values[t.z][1]);
|
||||
}
|
||||
}
|
||||
else if (corners) {
|
||||
for (size_t i = 0; i < corners->size(); i++) {
|
||||
const int c = (*corners)[i];
|
||||
*data_float2++ = make_float2(values[c][0], values[c][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attribute.data.add_data(data, time);
|
||||
|
@@ -15,7 +15,7 @@
|
||||
if(WITH_GTESTS)
|
||||
Include(GTestTesting)
|
||||
|
||||
# Otherwise we get warnings here that we cant fix in external projects
|
||||
# Otherwise we get warnings here that we can't fix in external projects
|
||||
remove_strict_flags()
|
||||
endif()
|
||||
|
||||
|
@@ -93,42 +93,23 @@ void my_guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
||||
#endif
|
||||
|
||||
FFMPEG_INLINE
|
||||
void my_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
|
||||
int64_t timestamp_from_pts_or_dts(int64_t pts, int64_t dts)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
AVStream *st = s->streams[i];
|
||||
|
||||
st->cur_dts = av_rescale(timestamp,
|
||||
st->time_base.den * (int64_t)ref_st->time_base.num,
|
||||
st->time_base.num * (int64_t)ref_st->time_base.den);
|
||||
}
|
||||
}
|
||||
|
||||
FFMPEG_INLINE
|
||||
void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
|
||||
{
|
||||
my_update_cur_dts(s, ref_st, timestamp);
|
||||
}
|
||||
|
||||
FFMPEG_INLINE
|
||||
int64_t av_get_pts_from_frame(AVFormatContext *avctx, AVFrame *picture)
|
||||
{
|
||||
int64_t pts;
|
||||
pts = picture->pts;
|
||||
|
||||
/* Some videos do not have any pts values, use dts instead in those cases if
|
||||
* possible. Usually when this happens dts can act as pts because as all frames
|
||||
* should then be presented in their decoded in order. IE pts == dts. */
|
||||
if (pts == AV_NOPTS_VALUE) {
|
||||
pts = picture->pkt_dts;
|
||||
return dts;
|
||||
}
|
||||
if (pts == AV_NOPTS_VALUE) {
|
||||
pts = 0;
|
||||
}
|
||||
|
||||
(void)avctx;
|
||||
return pts;
|
||||
}
|
||||
|
||||
FFMPEG_INLINE
|
||||
int64_t av_get_pts_from_frame(AVFrame *picture)
|
||||
{
|
||||
return timestamp_from_pts_or_dts(picture->pts, picture->pkt_dts);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Deinterlace code block
|
||||
*
|
||||
|
@@ -370,6 +370,7 @@ elseif(WIN32)
|
||||
intern/GHOST_DropTargetWin32.cpp
|
||||
intern/GHOST_SystemWin32.cpp
|
||||
intern/GHOST_WindowWin32.cpp
|
||||
intern/GHOST_Wintab.cpp
|
||||
|
||||
intern/GHOST_ContextD3D.h
|
||||
intern/GHOST_DisplayManagerWin32.h
|
||||
@@ -377,6 +378,7 @@ elseif(WIN32)
|
||||
intern/GHOST_SystemWin32.h
|
||||
intern/GHOST_TaskbarWin32.h
|
||||
intern/GHOST_WindowWin32.h
|
||||
intern/GHOST_Wintab.h
|
||||
)
|
||||
|
||||
if(NOT WITH_GL_EGL)
|
||||
@@ -481,10 +483,12 @@ if(WITH_XR_OPENXR)
|
||||
shlwapi
|
||||
)
|
||||
elseif(UNIX AND NOT APPLE)
|
||||
list(APPEND XR_PLATFORM_DEFINES
|
||||
-DXR_OS_LINUX
|
||||
-DXR_USE_PLATFORM_XLIB
|
||||
)
|
||||
list(APPEND XR_PLATFORM_DEFINES -DXR_OS_LINUX)
|
||||
if (WITH_GL_EGL)
|
||||
list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_EGL)
|
||||
else()
|
||||
list(APPEND XR_PLATFORM_DEFINES -DXR_USE_PLATFORM_XLIB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_definitions(-DWITH_XR_OPENXR ${XR_PLATFORM_DEFINES})
|
||||
|
@@ -105,7 +105,9 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
GHOST_kTabletAutomatic = 0,
|
||||
GHOST_kTabletNative,
|
||||
/* Show as Windows Ink to users to match "Use Windows Ink" in tablet utilities,
|
||||
* but we use the dependent Windows Pointer API. */
|
||||
GHOST_kTabletWinPointer,
|
||||
GHOST_kTabletWintab,
|
||||
} GHOST_TTabletAPI;
|
||||
|
||||
@@ -168,7 +170,7 @@ typedef enum {
|
||||
GHOST_kButtonMaskRight,
|
||||
GHOST_kButtonMaskButton4,
|
||||
GHOST_kButtonMaskButton5,
|
||||
/* Trackballs and programmable buttons */
|
||||
/* Trackballs and programmable buttons. */
|
||||
GHOST_kButtonMaskButton6,
|
||||
GHOST_kButtonMaskButton7,
|
||||
GHOST_kButtonNumMasks
|
||||
@@ -177,15 +179,15 @@ typedef enum {
|
||||
typedef enum {
|
||||
GHOST_kEventUnknown = 0,
|
||||
|
||||
GHOST_kEventCursorMove, /// Mouse move event
|
||||
GHOST_kEventButtonDown, /// Mouse button event
|
||||
GHOST_kEventButtonUp, /// Mouse button event
|
||||
GHOST_kEventWheel, /// Mouse wheel event
|
||||
GHOST_kEventTrackpad, /// Trackpad event
|
||||
GHOST_kEventCursorMove, /* Mouse move event. */
|
||||
GHOST_kEventButtonDown, /* Mouse button event. */
|
||||
GHOST_kEventButtonUp, /* Mouse button event. */
|
||||
GHOST_kEventWheel, /* Mouse wheel event. */
|
||||
GHOST_kEventTrackpad, /* Trackpad event. */
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
GHOST_kEventNDOFMotion, /// N degree of freedom device motion event
|
||||
GHOST_kEventNDOFButton, /// N degree of freedom device button event
|
||||
GHOST_kEventNDOFMotion, /* N degree of freedom device motion event. */
|
||||
GHOST_kEventNDOFButton, /* N degree of freedom device button event. */
|
||||
#endif
|
||||
|
||||
GHOST_kEventKeyDown,
|
||||
@@ -207,8 +209,8 @@ typedef enum {
|
||||
GHOST_kEventDraggingExited,
|
||||
GHOST_kEventDraggingDropDone,
|
||||
|
||||
GHOST_kEventOpenMainFile, // Needed for Cocoa to open double-clicked .blend file at startup
|
||||
GHOST_kEventNativeResolutionChange, // Needed for Cocoa when window moves to other display
|
||||
GHOST_kEventOpenMainFile, /* Needed for Cocoa to open double-clicked .blend file at startup. */
|
||||
GHOST_kEventNativeResolutionChange, /* Needed for Cocoa when window moves to other display. */
|
||||
|
||||
GHOST_kEventTimer,
|
||||
|
||||
@@ -281,7 +283,7 @@ typedef enum {
|
||||
GHOST_kKeyPeriod = '.',
|
||||
GHOST_kKeySlash = '/',
|
||||
|
||||
// Number keys
|
||||
/* Number keys. */
|
||||
GHOST_kKey0 = '0',
|
||||
GHOST_kKey1,
|
||||
GHOST_kKey2,
|
||||
@@ -296,7 +298,7 @@ typedef enum {
|
||||
GHOST_kKeySemicolon = ';',
|
||||
GHOST_kKeyEqual = '=',
|
||||
|
||||
// Character keys
|
||||
/* Character keys. */
|
||||
GHOST_kKeyA = 'A',
|
||||
GHOST_kKeyB,
|
||||
GHOST_kKeyC,
|
||||
@@ -335,9 +337,9 @@ typedef enum {
|
||||
GHOST_kKeyRightControl,
|
||||
GHOST_kKeyLeftAlt,
|
||||
GHOST_kKeyRightAlt,
|
||||
GHOST_kKeyOS, // Command key on Apple, Windows key(s) on Windows
|
||||
GHOST_kKeyGrLess, // German PC only!
|
||||
GHOST_kKeyApp, /* Also known as menu key. */
|
||||
GHOST_kKeyOS, /* Command key on Apple, Windows key(s) on Windows. */
|
||||
GHOST_kKeyGrLess, /* German PC only! */
|
||||
GHOST_kKeyApp, /* Also known as menu key. */
|
||||
|
||||
GHOST_kKeyCapsLock,
|
||||
GHOST_kKeyNumLock,
|
||||
@@ -358,7 +360,7 @@ typedef enum {
|
||||
GHOST_kKeyUpPage,
|
||||
GHOST_kKeyDownPage,
|
||||
|
||||
// Numpad keys
|
||||
/* Numpad keys. */
|
||||
GHOST_kKeyNumpad0,
|
||||
GHOST_kKeyNumpad1,
|
||||
GHOST_kKeyNumpad2,
|
||||
@@ -376,7 +378,7 @@ typedef enum {
|
||||
GHOST_kKeyNumpadAsterisk,
|
||||
GHOST_kKeyNumpadSlash,
|
||||
|
||||
// Function keys
|
||||
/* Function keys. */
|
||||
GHOST_kKeyF1,
|
||||
GHOST_kKeyF2,
|
||||
GHOST_kKeyF3,
|
||||
@@ -402,7 +404,7 @@ typedef enum {
|
||||
GHOST_kKeyF23,
|
||||
GHOST_kKeyF24,
|
||||
|
||||
// Multimedia keypad buttons
|
||||
/* Multimedia keypad buttons. */
|
||||
GHOST_kKeyMediaPlay,
|
||||
GHOST_kKeyMediaStop,
|
||||
GHOST_kKeyMediaFirst,
|
||||
@@ -479,9 +481,9 @@ typedef struct {
|
||||
|
||||
typedef enum {
|
||||
GHOST_kDragnDropTypeUnknown = 0,
|
||||
GHOST_kDragnDropTypeFilenames, /*Array of strings representing file names (full path) */
|
||||
GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string */
|
||||
GHOST_kDragnDropTypeBitmap /*Bitmap image data */
|
||||
GHOST_kDragnDropTypeFilenames, /* Array of strings representing file names (full path). */
|
||||
GHOST_kDragnDropTypeString, /* Unformatted text UTF-8 string. */
|
||||
GHOST_kDragnDropTypeBitmap /* Bitmap image data. */
|
||||
} GHOST_TDragnDropTypes;
|
||||
|
||||
typedef struct {
|
||||
@@ -527,18 +529,23 @@ typedef enum {
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
typedef struct {
|
||||
/** N-degree of freedom device data v3 [GSoC 2010] */
|
||||
// Each component normally ranges from -1 to +1, but can exceed that.
|
||||
// These use blender standard view coordinates, with positive rotations being CCW about the axis.
|
||||
float tx, ty, tz; // translation
|
||||
float rx, ry, rz; // rotation:
|
||||
// axis = (rx,ry,rz).normalized
|
||||
// amount = (rx,ry,rz).magnitude [in revolutions, 1.0 = 360 deg]
|
||||
float dt; // time since previous NDOF Motion event
|
||||
GHOST_TProgress progress; // Starting, InProgress or Finishing (for modal handlers)
|
||||
/* Each component normally ranges from -1 to +1, but can exceed that.
|
||||
* These use blender standard view coordinates,
|
||||
* with positive rotations being CCW about the axis. */
|
||||
/* translation: */
|
||||
float tx, ty, tz;
|
||||
/* rotation:
|
||||
* - `axis = (rx,ry,rz).normalized`
|
||||
* - `amount = (rx,ry,rz).magnitude` [in revolutions, 1.0 = 360 deg]. */
|
||||
float rx, ry, rz;
|
||||
/** Time since previous NDOF Motion event */
|
||||
float dt;
|
||||
/** Starting, #GHOST_kInProgress or #GHOST_kFinishing (for modal handlers) */
|
||||
GHOST_TProgress progress;
|
||||
} GHOST_TEventNDOFMotionData;
|
||||
|
||||
typedef enum { GHOST_kPress, GHOST_kRelease } GHOST_TButtonAction;
|
||||
// good for mouse or other buttons too, hmmm?
|
||||
/* Good for mouse or other buttons too, hmmm? */
|
||||
|
||||
typedef struct {
|
||||
GHOST_TButtonAction action;
|
||||
@@ -561,7 +568,7 @@ typedef struct {
|
||||
*/
|
||||
/** The ascii code for the key event ('\0' if none). */
|
||||
char ascii;
|
||||
/** The unicode character. if the length is 6, not NULL terminated if all 6 are set */
|
||||
/** The unicode character. if the length is 6, not NULL terminated if all 6 are set. */
|
||||
char utf8_buf[6];
|
||||
|
||||
/** Generated by auto-repeat. */
|
||||
@@ -594,7 +601,8 @@ typedef void *GHOST_TEmbedderWindowID;
|
||||
#endif // _WIN32
|
||||
|
||||
#ifndef _WIN32
|
||||
// I can't use "Window" from "<X11/Xlib.h>" because it conflits with Window defined in winlay.h
|
||||
/* I can't use "Window" from `X11/Xlib.h`
|
||||
* because it conflicts with Window defined in `winlay.h`. */
|
||||
typedef int GHOST_TEmbedderWindowID;
|
||||
#endif // _WIN32
|
||||
|
||||
@@ -642,8 +650,10 @@ typedef void *(*GHOST_XrGraphicsContextBindFn)(void);
|
||||
typedef void (*GHOST_XrGraphicsContextUnbindFn)(GHOST_ContextHandle graphics_context);
|
||||
typedef void (*GHOST_XrDrawViewFn)(const struct GHOST_XrDrawViewInfo *draw_view, void *customdata);
|
||||
|
||||
/* An array of GHOST_TXrGraphicsBinding items defining the candidate bindings to use. The first
|
||||
* available candidate will be chosen, so order defines priority. */
|
||||
/**
|
||||
* An array of #GHOST_TXrGraphicsBinding items defining the candidate bindings to use.
|
||||
* The first available candidate will be chosen, so order defines priority.
|
||||
*/
|
||||
typedef const GHOST_TXrGraphicsBinding *GHOST_XrGraphicsBindingCandidates;
|
||||
|
||||
typedef struct {
|
||||
@@ -684,7 +694,7 @@ typedef struct GHOST_XrDrawViewInfo {
|
||||
float angle_up, angle_down;
|
||||
} fov;
|
||||
|
||||
/** Set if the buffer should be submitted with a srgb transfer applied. */
|
||||
/** Set if the buffer should be submitted with a SRGB transfer applied. */
|
||||
char expects_srgb_buffer;
|
||||
} GHOST_XrDrawViewInfo;
|
||||
|
||||
@@ -734,7 +744,7 @@ typedef struct GHOST_XrActionSpaceInfo {
|
||||
typedef struct GHOST_XrActionBindingInfo {
|
||||
const char *action_name;
|
||||
GHOST_TUns32 count_interaction_paths;
|
||||
/** Interaction path: User (subaction) path + component path. */
|
||||
/** Interaction path: User (sub-action) path + component path. */
|
||||
const char **interaction_paths;
|
||||
} GHOST_XrActionBindingInfo;
|
||||
|
||||
|
@@ -149,6 +149,9 @@ static bool egl_chk(bool result, const char *file = NULL, int line = 0, const ch
|
||||
static_cast<unsigned int>(error),
|
||||
code ? code : "<Unknown>",
|
||||
msg ? msg : "<Unknown>");
|
||||
(void)(file);
|
||||
(void)(line);
|
||||
(void)(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -285,6 +288,21 @@ GHOST_TSuccess GHOST_ContextEGL::getSwapInterval(int &intervalOut)
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
EGLDisplay GHOST_ContextEGL::getDisplay() const
|
||||
{
|
||||
return m_display;
|
||||
}
|
||||
|
||||
EGLConfig GHOST_ContextEGL::getConfig() const
|
||||
{
|
||||
return m_config;
|
||||
}
|
||||
|
||||
EGLContext GHOST_ContextEGL::getContext() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_ContextEGL::activateDrawingContext()
|
||||
{
|
||||
if (m_display) {
|
||||
@@ -456,9 +474,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
|
||||
attrib_list.push_back(EGL_NONE);
|
||||
|
||||
EGLConfig config;
|
||||
|
||||
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &config, 1, &num_config)))
|
||||
if (!EGL_CHK(::eglChooseConfig(m_display, &(attrib_list[0]), &m_config, 1, &num_config)))
|
||||
goto error;
|
||||
|
||||
// A common error is to assume that ChooseConfig worked because it returned EGL_TRUE
|
||||
@@ -466,7 +482,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
goto error;
|
||||
|
||||
if (m_nativeWindow != 0) {
|
||||
m_surface = ::eglCreateWindowSurface(m_display, config, m_nativeWindow, NULL);
|
||||
m_surface = ::eglCreateWindowSurface(m_display, m_config, m_nativeWindow, NULL);
|
||||
}
|
||||
else {
|
||||
static const EGLint pb_attrib_list[] = {
|
||||
@@ -476,7 +492,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
1,
|
||||
EGL_NONE,
|
||||
};
|
||||
m_surface = ::eglCreatePbufferSurface(m_display, config, pb_attrib_list);
|
||||
m_surface = ::eglCreatePbufferSurface(m_display, m_config, pb_attrib_list);
|
||||
}
|
||||
|
||||
if (!EGL_CHK(m_surface != EGL_NO_SURFACE))
|
||||
@@ -577,7 +593,7 @@ GHOST_TSuccess GHOST_ContextEGL::initializeDrawingContext()
|
||||
|
||||
attrib_list.push_back(EGL_NONE);
|
||||
|
||||
m_context = ::eglCreateContext(m_display, config, m_sharedContext, &(attrib_list[0]));
|
||||
m_context = ::eglCreateContext(m_display, m_config, m_sharedContext, &(attrib_list[0]));
|
||||
|
||||
if (!EGL_CHK(m_context != EGL_NO_CONTEXT))
|
||||
goto error;
|
||||
|
@@ -36,6 +36,9 @@
|
||||
#endif
|
||||
|
||||
class GHOST_ContextEGL : public GHOST_Context {
|
||||
/* XR code needs low level graphics data to send to OpenXR. */
|
||||
friend class GHOST_XrGraphicsBindingOpenGL;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -100,6 +103,12 @@ class GHOST_ContextEGL : public GHOST_Context {
|
||||
*/
|
||||
GHOST_TSuccess getSwapInterval(int &intervalOut);
|
||||
|
||||
EGLDisplay getDisplay() const;
|
||||
|
||||
EGLConfig getConfig() const;
|
||||
|
||||
EGLContext getContext() const;
|
||||
|
||||
private:
|
||||
bool initContextEGLEW();
|
||||
|
||||
@@ -117,6 +126,7 @@ class GHOST_ContextEGL : public GHOST_Context {
|
||||
EGLContext m_context;
|
||||
EGLSurface m_surface;
|
||||
EGLDisplay m_display;
|
||||
EGLConfig m_config;
|
||||
|
||||
EGLint m_swap_interval;
|
||||
|
||||
|
@@ -52,6 +52,13 @@
|
||||
# define GHOST_PRINTF(x, ...)
|
||||
#endif // WITH_GHOST_DEBUG
|
||||
|
||||
#include <stdio.h> //for printf()
|
||||
#define WINTAB_PRINTF(x, ...) \
|
||||
{ \
|
||||
printf(x, __VA_ARGS__); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
#ifdef WITH_ASSERT_ABORT
|
||||
# include <stdio.h> //for fprintf()
|
||||
# include <stdlib.h> //for abort()
|
||||
|
@@ -160,7 +160,7 @@ GHOST_TSuccess GHOST_DisplayManagerSDL::setCurrentDisplaySetting(
|
||||
else {
|
||||
/* this is a problem for the BGE player :S, perhaps SDL2 will resolve at some point.
|
||||
* we really need SDL_SetDisplayModeForDisplay() to become an API func! - campbell */
|
||||
printf("no windows available, cant fullscreen\n");
|
||||
printf("no windows available, can't fullscreen\n");
|
||||
|
||||
/* do not fail, we will try again later when the window is created - wander */
|
||||
return GHOST_kSuccess;
|
||||
|
@@ -31,7 +31,11 @@ class GHOST_IXrGraphicsBinding {
|
||||
public:
|
||||
union {
|
||||
#if defined(WITH_GHOST_X11)
|
||||
# if defined(WITH_GL_EGL)
|
||||
XrGraphicsBindingEGLMNDX egl;
|
||||
# else
|
||||
XrGraphicsBindingOpenGLXlibKHR glx;
|
||||
# endif
|
||||
#elif defined(WIN32)
|
||||
XrGraphicsBindingOpenGLWin32KHR wgl;
|
||||
XrGraphicsBindingD3D11KHR d3d11;
|
||||
|
@@ -239,7 +239,7 @@ class GHOST_System : public GHOST_ISystem {
|
||||
* Set which tablet API to use. Only affects Windows, other platforms have a single API.
|
||||
* \param api: Enum indicating which API to use.
|
||||
*/
|
||||
void setTabletAPI(GHOST_TTabletAPI api);
|
||||
virtual void setTabletAPI(GHOST_TTabletAPI api) override;
|
||||
GHOST_TTabletAPI getTabletAPI(void);
|
||||
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
|
@@ -376,7 +376,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis());
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
// cant use setCursorPosition because the mouse may have no focus!
|
||||
// can't use setCursorPosition because the mouse may have no focus!
|
||||
if (x_new != x_root || y_new != y_root) {
|
||||
if (1) { //xme.time > m_last_warp) {
|
||||
/* when wrapping we don't need to add an event because the
|
||||
|
@@ -139,7 +139,6 @@ static void initRawInput()
|
||||
#undef DEVICE_COUNT
|
||||
}
|
||||
|
||||
typedef HRESULT(API *GHOST_WIN32_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
|
||||
typedef BOOL(API *GHOST_WIN32_EnableNonClientDpiScaling)(HWND);
|
||||
|
||||
GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
@@ -867,15 +866,174 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
|
||||
{
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
if (type == GHOST_kEventButtonDown) {
|
||||
window->updateMouseCapture(MousePressed);
|
||||
}
|
||||
else if (type == GHOST_kEventButtonUp) {
|
||||
window->updateMouseCapture(MouseReleased);
|
||||
GHOST_TabletData td = window->getTabletData();
|
||||
|
||||
/* Move mouse to button event position. */
|
||||
if (window->getTabletData().Active != GHOST_kTabletModeNone) {
|
||||
/* Tablet should be handling in between mouse moves, only move to event position. */
|
||||
DWORD msgPos = ::GetMessagePos();
|
||||
int msgPosX = GET_X_LPARAM(msgPos);
|
||||
int msgPosY = GET_Y_LPARAM(msgPos);
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
::GetMessageTime(), GHOST_kEventCursorMove, window, msgPosX, msgPosY, td));
|
||||
|
||||
if (type == GHOST_kEventButtonDown) {
|
||||
WINTAB_PRINTF("%p OS button down\n", window->getHWND());
|
||||
}
|
||||
else if (type == GHOST_kEventButtonUp) {
|
||||
WINTAB_PRINTF("%p OS button up\n", window->getHWND());
|
||||
}
|
||||
}
|
||||
|
||||
return new GHOST_EventButton(
|
||||
system->getMilliSeconds(), type, window, mask, window->getTabletData());
|
||||
window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
|
||||
return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
|
||||
{
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (!wt) {
|
||||
return;
|
||||
}
|
||||
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
std::vector<GHOST_WintabInfoWin32> wintabInfo;
|
||||
wt->getInput(wintabInfo);
|
||||
|
||||
/* Wintab provided coordinates are untrusted until a Wintab and Win32 button down event match.
|
||||
* This is checked on every button down event, and revoked if there is a mismatch. This can
|
||||
* happen when Wintab incorrectly scales cursor position or is in mouse mode.
|
||||
*
|
||||
* If Wintab was never trusted while processing this Win32 event, a fallback Ghost cursor move
|
||||
* event is created at the position of the Win32 WT_PACKET event. */
|
||||
bool mouseMoveHandled;
|
||||
bool useWintabPos;
|
||||
mouseMoveHandled = useWintabPos = wt->trustCoordinates();
|
||||
|
||||
for (GHOST_WintabInfoWin32 &info : wintabInfo) {
|
||||
switch (info.type) {
|
||||
case GHOST_kEventCursorMove: {
|
||||
if (!useWintabPos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
|
||||
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown: {
|
||||
WINTAB_PRINTF("%p wintab button down", window->getHWND());
|
||||
|
||||
UINT message;
|
||||
switch (info.button) {
|
||||
case GHOST_kButtonMaskLeft:
|
||||
message = WM_LBUTTONDOWN;
|
||||
break;
|
||||
case GHOST_kButtonMaskRight:
|
||||
message = WM_RBUTTONDOWN;
|
||||
break;
|
||||
case GHOST_kButtonMaskMiddle:
|
||||
message = WM_MBUTTONDOWN;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
|
||||
* in. Only issue button events if we can steal an equivalent Win32 button event from the
|
||||
* event queue. */
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, window->getHWND(), message, message, PM_NOYIELD) &&
|
||||
msg.message != WM_QUIT) {
|
||||
|
||||
/* Test for Win32/Wintab button down match. */
|
||||
useWintabPos = wt->testCoordinates(msg.pt.x, msg.pt.y, info.x, info.y);
|
||||
if (!useWintabPos) {
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
WINTAB_PRINTF(" ... but associated to system button mismatched position\n");
|
||||
}
|
||||
|
||||
WINTAB_PRINTF(" ... associated to system button\n");
|
||||
|
||||
/* Steal the Win32 event which was previously peeked. */
|
||||
PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD);
|
||||
|
||||
/* Move cursor to button location, to prevent incorrect cursor position when
|
||||
* transitioning from unsynchronized Win32 to Wintab cursor control. */
|
||||
wt->mapWintabToSysCoordinates(info.x, info.y, info.x, info.y);
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
|
||||
|
||||
window->updateMouseCapture(MousePressed);
|
||||
system->pushEvent(
|
||||
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
|
||||
|
||||
mouseMoveHandled = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
WINTAB_PRINTF(" ... but no system button\n");
|
||||
}
|
||||
}
|
||||
case GHOST_kEventButtonUp: {
|
||||
WINTAB_PRINTF("%p wintab button up", window->getHWND());
|
||||
if (!useWintabPos) {
|
||||
WINTAB_PRINTF(" ... but Wintab position isn't trusted\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
UINT message;
|
||||
switch (info.button) {
|
||||
case GHOST_kButtonMaskLeft:
|
||||
message = WM_LBUTTONUP;
|
||||
break;
|
||||
case GHOST_kButtonMaskRight:
|
||||
message = WM_RBUTTONUP;
|
||||
break;
|
||||
case GHOST_kButtonMaskMiddle:
|
||||
message = WM_MBUTTONUP;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wintab buttons are modal, but the API does not inform us what mode a pressed button is
|
||||
* in. Only issue button events if we can steal an equivalent Win32 button event from the
|
||||
* event queue. */
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
|
||||
msg.message != WM_QUIT) {
|
||||
|
||||
WINTAB_PRINTF(" ... associated to system button\n");
|
||||
window->updateMouseCapture(MouseReleased);
|
||||
system->pushEvent(
|
||||
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
|
||||
}
|
||||
else {
|
||||
WINTAB_PRINTF(" ... but no system button\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback cursor movement if Wintab position were never trusted while processing this event. */
|
||||
if (!mouseMoveHandled) {
|
||||
DWORD pos = GetMessagePos();
|
||||
int x = GET_X_LPARAM(pos);
|
||||
int y = GET_Y_LPARAM(pos);
|
||||
|
||||
/* TODO supply tablet data */
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
system->getMilliSeconds(), GHOST_kEventCursorMove, window, x, y, GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processPointerEvent(
|
||||
@@ -883,7 +1041,7 @@ void GHOST_SystemWin32::processPointerEvent(
|
||||
{
|
||||
/* Pointer events might fire when changing windows for a device which is set to use Wintab, even
|
||||
* when when Wintab is left enabled but set to the bottom of Wintab overlap order. */
|
||||
if (!window->useTabletAPI(GHOST_kTabletNative)) {
|
||||
if (!window->usingTabletAPI(GHOST_kTabletWinPointer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -894,20 +1052,21 @@ void GHOST_SystemWin32::processPointerEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!pointerInfo[0].isPrimary) {
|
||||
eventHandled = true;
|
||||
return; // For multi-touch displays we ignore these events
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case WM_POINTERENTER:
|
||||
window->m_tabletInRange = true;
|
||||
system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
pointerInfo[0].pixelLocation.x,
|
||||
pointerInfo[0].pixelLocation.y,
|
||||
pointerInfo[0].tabletData));
|
||||
case WM_POINTERUPDATE:
|
||||
/* Coalesced pointer events are reverse chronological order, reorder chronologically.
|
||||
* Only contiguous move events are coalesced. */
|
||||
for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) {
|
||||
system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
pointerInfo[i].pixelLocation.x,
|
||||
pointerInfo[i].pixelLocation.y,
|
||||
pointerInfo[i].tabletData));
|
||||
}
|
||||
|
||||
/* Leave event unhandled so that system cursor is moved. */
|
||||
|
||||
break;
|
||||
case WM_POINTERDOWN:
|
||||
/* Move cursor to point of contact because GHOST_EventButton does not include position. */
|
||||
@@ -923,18 +1082,10 @@ void GHOST_SystemWin32::processPointerEvent(
|
||||
pointerInfo[0].buttonMask,
|
||||
pointerInfo[0].tabletData));
|
||||
window->updateMouseCapture(MousePressed);
|
||||
break;
|
||||
case WM_POINTERUPDATE:
|
||||
/* Coalesced pointer events are reverse chronological order, reorder chronologically.
|
||||
* Only contiguous move events are coalesced. */
|
||||
for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) {
|
||||
system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
pointerInfo[i].pixelLocation.x,
|
||||
pointerInfo[i].pixelLocation.y,
|
||||
pointerInfo[i].tabletData));
|
||||
}
|
||||
|
||||
/* Mark event handled so that mouse button events are not generated. */
|
||||
eventHandled = true;
|
||||
|
||||
break;
|
||||
case WM_POINTERUP:
|
||||
system->pushEvent(new GHOST_EventButton(pointerInfo[0].time,
|
||||
@@ -943,16 +1094,14 @@ void GHOST_SystemWin32::processPointerEvent(
|
||||
pointerInfo[0].buttonMask,
|
||||
pointerInfo[0].tabletData));
|
||||
window->updateMouseCapture(MouseReleased);
|
||||
break;
|
||||
case WM_POINTERLEAVE:
|
||||
window->m_tabletInRange = false;
|
||||
|
||||
/* Mark event handled so that mouse button events are not generated. */
|
||||
eventHandled = true;
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
eventHandled = true;
|
||||
system->setCursorPosition(pointerInfo[0].pixelLocation.x, pointerInfo[0].pixelLocation.y);
|
||||
}
|
||||
|
||||
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
|
||||
@@ -960,18 +1109,14 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
||||
GHOST_TInt32 x_screen, y_screen;
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
if (window->m_tabletInRange) {
|
||||
if (window->useTabletAPI(GHOST_kTabletNative)) {
|
||||
/* Tablet input handled in WM_POINTER* events. WM_MOUSEMOVE events in response to tablet
|
||||
* input aren't normally generated when using WM_POINTER events, but manually moving the
|
||||
* system cursor as we do in WM_POINTER handling does. */
|
||||
return NULL;
|
||||
}
|
||||
if (window->getTabletData().Active != GHOST_kTabletModeNone) {
|
||||
/* While pen devices are in range, cursor movement is handled by tablet input processing. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
system->getCursorPosition(x_screen, y_screen);
|
||||
|
||||
if (window->getCursorGrabModeIsWarp() && !window->m_tabletInRange) {
|
||||
if (window->getCursorGrabModeIsWarp()) {
|
||||
GHOST_TInt32 x_new = x_screen;
|
||||
GHOST_TInt32 y_new = y_screen;
|
||||
GHOST_TInt32 x_accum, y_accum;
|
||||
@@ -983,7 +1128,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
||||
}
|
||||
|
||||
/* Could also clamp to screen bounds wrap with a window outside the view will fail atm.
|
||||
* Use offset of 8 in case the window is at screen bounds. */
|
||||
* Use inset in case the window is at screen bounds. */
|
||||
bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis());
|
||||
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
@@ -999,7 +1144,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
||||
window,
|
||||
x_screen + x_accum,
|
||||
y_screen + y_accum,
|
||||
window->getTabletData());
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1008,7 +1153,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
||||
window,
|
||||
x_screen,
|
||||
y_screen,
|
||||
window->getTabletData());
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1118,6 +1263,23 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
||||
return event;
|
||||
}
|
||||
|
||||
GHOST_Event *GHOST_SystemWin32::processWindowSizeEvent(GHOST_WindowWin32 *window)
|
||||
{
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
GHOST_Event *sizeEvent = new GHOST_Event(
|
||||
system->getMilliSeconds(), GHOST_kEventWindowSize, window);
|
||||
|
||||
/* We get WM_SIZE before we fully init. Do not dispatch before we are continuously resizing. */
|
||||
if (window->m_inLiveResize) {
|
||||
system->pushEvent(sizeEvent);
|
||||
system->dispatchEvents();
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return sizeEvent;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
|
||||
GHOST_WindowWin32 *window)
|
||||
{
|
||||
@@ -1125,7 +1287,6 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type,
|
||||
|
||||
if (type == GHOST_kEventWindowActivate) {
|
||||
system->getWindowManager()->setActiveWindow(window);
|
||||
window->bringTabletContextToFront();
|
||||
}
|
||||
|
||||
return new GHOST_Event(system->getMilliSeconds(), type, window);
|
||||
@@ -1153,6 +1314,31 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType,
|
||||
system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
|
||||
{
|
||||
GHOST_System::setTabletAPI(api);
|
||||
|
||||
/* If API is set to WinPointer (Windows Ink), unload Wintab so that trouble drivers don't disable
|
||||
* Windows Ink. Load Wintab when API is Automatic because decision logic relies on knowing
|
||||
* whether a Wintab device is present. */
|
||||
const bool loadWintab = GHOST_kTabletWinPointer != api;
|
||||
GHOST_WindowManager *wm = getWindowManager();
|
||||
|
||||
for (GHOST_IWindow *win : wm->getWindows()) {
|
||||
GHOST_WindowWin32 *windowWin32 = (GHOST_WindowWin32 *)win;
|
||||
if (loadWintab) {
|
||||
windowWin32->loadWintab(GHOST_kWindowStateMinimized != windowWin32->getState());
|
||||
|
||||
if (windowWin32->usingTabletAPI(GHOST_kTabletWintab)) {
|
||||
windowWin32->resetPointerPenInfo();
|
||||
}
|
||||
}
|
||||
else {
|
||||
windowWin32->closeWintab();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax)
|
||||
{
|
||||
minmax->ptMinTrackSize.x = 320;
|
||||
@@ -1387,33 +1573,133 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
case SC_KEYMENU:
|
||||
eventHandled = true;
|
||||
break;
|
||||
case SC_RESTORE:
|
||||
case SC_RESTORE: {
|
||||
::ShowWindow(hwnd, SW_RESTORE);
|
||||
window->setState(window->getState());
|
||||
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->enable();
|
||||
}
|
||||
|
||||
eventHandled = true;
|
||||
break;
|
||||
}
|
||||
case SC_MAXIMIZE: {
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->enable();
|
||||
}
|
||||
/* Don't report event as handled so that default handling occurs. */
|
||||
break;
|
||||
}
|
||||
case SC_MINIMIZE: {
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->disable();
|
||||
}
|
||||
/* Don't report event as handled so that default handling occurs. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Wintab events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WT_PACKET:
|
||||
window->processWin32TabletEvent(wParam, lParam);
|
||||
case WT_CSRCHANGE: {
|
||||
WINTAB_PRINTF("%p WT_CSRCHANGE\n", window->getHWND());
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->updateCursorInfo();
|
||||
}
|
||||
eventHandled = true;
|
||||
break;
|
||||
case WT_CSRCHANGE:
|
||||
case WT_PROXIMITY:
|
||||
window->processWin32TabletInitEvent();
|
||||
}
|
||||
case WT_PROXIMITY: {
|
||||
WINTAB_PRINTF(
|
||||
"%p WT_PROXIMITY loword (!0 enter 0 leave context): %d, hiword (!0 enter !0 leave "
|
||||
"hardware): %d\n",
|
||||
window->getHWND(),
|
||||
LOWORD(lParam),
|
||||
HIWORD(lParam));
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
bool inRange = LOWORD(lParam);
|
||||
if (inRange) {
|
||||
/* Some devices don't emit WT_CSRCHANGE events, so update cursor info here. */
|
||||
wt->updateCursorInfo();
|
||||
}
|
||||
else {
|
||||
wt->leaveRange();
|
||||
}
|
||||
}
|
||||
eventHandled = true;
|
||||
break;
|
||||
}
|
||||
case WT_INFOCHANGE: {
|
||||
WINTAB_PRINTF("%p WT_INFOCHANGE\n", window->getHWND());
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->processInfoChange(lParam);
|
||||
|
||||
if (window->usingTabletAPI(GHOST_kTabletWintab)) {
|
||||
window->resetPointerPenInfo();
|
||||
}
|
||||
}
|
||||
eventHandled = true;
|
||||
break;
|
||||
}
|
||||
case WT_PACKET:
|
||||
processWintabEvent(window);
|
||||
eventHandled = true;
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Wintab events, debug
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WT_CTXOPEN:
|
||||
WINTAB_PRINTF("%p WT_CTXOPEN\n", window->getHWND());
|
||||
break;
|
||||
case WT_CTXCLOSE:
|
||||
WINTAB_PRINTF("%p WT_CTXCLOSE\n", window->getHWND());
|
||||
break;
|
||||
case WT_CTXUPDATE:
|
||||
WINTAB_PRINTF("%p WT_CTXUPDATE\n", window->getHWND());
|
||||
break;
|
||||
case WT_CTXOVERLAP:
|
||||
switch (lParam) {
|
||||
case CXS_DISABLED:
|
||||
WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_DISABLED\n", window->getHWND());
|
||||
break;
|
||||
case CXS_OBSCURED:
|
||||
WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_OBSCURED\n", window->getHWND());
|
||||
break;
|
||||
case CXS_ONTOP:
|
||||
WINTAB_PRINTF("%p WT_CTXOVERLAP CXS_ONTOP\n", window->getHWND());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Pointer events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WM_POINTERENTER:
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUPDATE:
|
||||
case WM_POINTERDOWN:
|
||||
case WM_POINTERUP:
|
||||
case WM_POINTERLEAVE:
|
||||
processPointerEvent(msg, window, wParam, lParam, eventHandled);
|
||||
break;
|
||||
case WM_POINTERLEAVE: {
|
||||
GHOST_TUns32 pointerId = GET_POINTERID_WPARAM(wParam);
|
||||
POINTER_INFO pointerInfo;
|
||||
if (!GetPointerInfo(pointerId, &pointerInfo)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Reset pointer pen info if pen device has left tracking range. */
|
||||
if (pointerInfo.pointerType == PT_PEN && !IS_POINTER_INRANGE_WPARAM(wParam)) {
|
||||
window->resetPointerPenInfo();
|
||||
eventHandled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Mouse events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1452,7 +1738,21 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
if (!window->m_mousePresent) {
|
||||
WINTAB_PRINTF("%p mouse enter\n", window->getHWND());
|
||||
TRACKMOUSEEVENT tme = {sizeof(tme)};
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwnd;
|
||||
TrackMouseEvent(&tme);
|
||||
window->m_mousePresent = true;
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->gainFocus();
|
||||
}
|
||||
}
|
||||
|
||||
event = processCursorEvent(window);
|
||||
|
||||
break;
|
||||
case WM_MOUSEWHEEL: {
|
||||
/* The WM_MOUSEWHEEL message is sent to the focus window
|
||||
@@ -1462,14 +1762,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* since DefWindowProc propagates it up the parent chain
|
||||
* until it finds a window that processes it.
|
||||
*/
|
||||
|
||||
/* Get the window under the mouse and send event to its queue. */
|
||||
POINT mouse_pos = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
|
||||
HWND mouse_hwnd = ChildWindowFromPoint(HWND_DESKTOP, mouse_pos);
|
||||
GHOST_WindowWin32 *mouse_window = (GHOST_WindowWin32 *)::GetWindowLongPtr(mouse_hwnd,
|
||||
GWLP_USERDATA);
|
||||
|
||||
processWheelEvent(mouse_window ? mouse_window : window, wParam, lParam);
|
||||
processWheelEvent(window, wParam, lParam);
|
||||
eventHandled = true;
|
||||
#ifdef BROKEN_PEEK_TOUCHPAD
|
||||
PostMessage(hwnd, WM_USER, 0, 0);
|
||||
@@ -1494,7 +1787,18 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
window->loadCursor(true, GHOST_kStandardCursorDefault);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSELEAVE: {
|
||||
WINTAB_PRINTF("%p mouse leave\n", window->getHWND());
|
||||
window->m_mousePresent = false;
|
||||
if (window->getTabletData().Active == GHOST_kTabletModeNone) {
|
||||
processCursorEvent(window);
|
||||
}
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
wt->loseFocus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Mouse events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1542,7 +1846,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* will not be dispatched to OUR active window if we minimize one of OUR windows. */
|
||||
if (LOWORD(wParam) == WA_INACTIVE)
|
||||
window->lostMouseCapture();
|
||||
window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam));
|
||||
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
@@ -1584,6 +1888,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
/* Let DefWindowProc handle it. */
|
||||
break;
|
||||
case WM_SIZING:
|
||||
event = processWindowSizeEvent(window);
|
||||
break;
|
||||
case WM_SIZE:
|
||||
/* The WM_SIZE message is sent to a window after its size has changed.
|
||||
* The WM_SIZE and WM_MOVE messages are not sent if an application handles the
|
||||
@@ -1591,15 +1897,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* to perform any move or size change processing during the WM_WINDOWPOSCHANGED
|
||||
* message without calling DefWindowProc.
|
||||
*/
|
||||
/* we get first WM_SIZE before we fully init.
|
||||
* So, do not dispatch before we continuously resizing. */
|
||||
if (window->m_inLiveResize) {
|
||||
system->pushEvent(processWindowEvent(GHOST_kEventWindowSize, window));
|
||||
system->dispatchEvents();
|
||||
}
|
||||
else {
|
||||
event = processWindowEvent(GHOST_kEventWindowSize, window);
|
||||
}
|
||||
event = processWindowSizeEvent(window);
|
||||
break;
|
||||
case WM_CAPTURECHANGED:
|
||||
window->lostMouseCapture();
|
||||
@@ -1650,6 +1948,24 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE);
|
||||
}
|
||||
break;
|
||||
case WM_DISPLAYCHANGE: {
|
||||
GHOST_Wintab *wt = window->getWintab();
|
||||
if (wt) {
|
||||
for (GHOST_IWindow *iter_win : system->getWindowManager()->getWindows()) {
|
||||
GHOST_WindowWin32 *iter_win32win = (GHOST_WindowWin32 *)iter_win;
|
||||
wt->remapCoordinates();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case WM_KILLFOCUS:
|
||||
/* The WM_KILLFOCUS message is sent to a window immediately before it loses the keyboard
|
||||
* focus. We want to prevent this if a window is still active and it loses focus to
|
||||
* nowhere. */
|
||||
if (!wParam && hwnd == ::GetActiveWindow()) {
|
||||
::SetFocus(hwnd);
|
||||
}
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Window events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1686,12 +2002,6 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* object associated with the window.
|
||||
*/
|
||||
break;
|
||||
case WM_KILLFOCUS:
|
||||
/* The WM_KILLFOCUS message is sent to a window immediately before it loses the
|
||||
* keyboard focus. We want to prevent this if a window is still active and it loses
|
||||
* focus to nowhere. */
|
||||
if (!wParam && hwnd == ::GetActiveWindow())
|
||||
::SetFocus(hwnd);
|
||||
case WM_SHOWWINDOW:
|
||||
/* The WM_SHOWWINDOW message is sent to a window when the window is
|
||||
* about to be hidden or shown. */
|
||||
|
@@ -265,6 +265,16 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
int mouseY,
|
||||
void *data);
|
||||
|
||||
/***************************************************************************************
|
||||
** Modify tablet API
|
||||
***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Set which tablet API to use.
|
||||
* \param api: Enum indicating which API to use.
|
||||
*/
|
||||
void setTabletAPI(GHOST_TTabletAPI api) override;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Initializes the system.
|
||||
@@ -308,6 +318,12 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
GHOST_WindowWin32 *window,
|
||||
GHOST_TButtonMask mask);
|
||||
|
||||
/**
|
||||
* Creates tablet events from Wintab events.
|
||||
* \param window: The window receiving the event (the active window).
|
||||
*/
|
||||
static void processWintabEvent(GHOST_WindowWin32 *window);
|
||||
|
||||
/**
|
||||
* Creates tablet events from pointer events.
|
||||
* \param type: The type of pointer event.
|
||||
@@ -351,6 +367,13 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
*/
|
||||
GHOST_TKey processSpecialKey(short vKey, short scanCode) const;
|
||||
|
||||
/**
|
||||
* Creates a window size event.
|
||||
* \param window: The window receiving the event (the active window).
|
||||
* \return The event created.
|
||||
*/
|
||||
static GHOST_Event *processWindowSizeEvent(GHOST_WindowWin32 *window);
|
||||
|
||||
/**
|
||||
* Creates a window event.
|
||||
* \param type: The type of event to create.
|
||||
|
@@ -2563,7 +2563,7 @@ static bool is_filler_char(char c)
|
||||
return isspace(c) || c == '_' || c == '-' || c == ';' || c == ':';
|
||||
}
|
||||
|
||||
/* These C functions are copied from Wine 3.12's wintab.c */
|
||||
/* These C functions are copied from Wine 3.12's `wintab.c` */
|
||||
static bool match_token(const char *haystack, const char *needle)
|
||||
{
|
||||
const char *h, *n;
|
||||
|
@@ -556,7 +556,7 @@ static SDL_Cursor *sdl_ghost_CreateCursor(
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/* TODO, this is currently never freed but it wont leak either. */
|
||||
/* TODO, this is currently never freed but it won't leak either. */
|
||||
static SDL_Cursor *getStandardCursorShape(GHOST_TStandardCursor shape)
|
||||
{
|
||||
if (sdl_std_cursor_array[0] == NULL) {
|
||||
|
@@ -21,8 +21,6 @@
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "GHOST_WindowWin32.h"
|
||||
#include "GHOST_ContextD3D.h"
|
||||
#include "GHOST_ContextNone.h"
|
||||
@@ -72,7 +70,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
bool is_debug,
|
||||
bool dialog)
|
||||
: GHOST_Window(width, height, state, wantStereoVisual, false),
|
||||
m_tabletInRange(false),
|
||||
m_mousePresent(false),
|
||||
m_inLiveResize(false),
|
||||
m_system(system),
|
||||
m_hDC(0),
|
||||
@@ -82,6 +80,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
m_nPressedButtons(0),
|
||||
m_customCursor(0),
|
||||
m_wantAlphaBackground(alphaBackground),
|
||||
m_wintab(NULL),
|
||||
m_lastPointerTabletData(GHOST_TABLET_DATA_NONE),
|
||||
m_normal_state(GHOST_kWindowStateNormal),
|
||||
m_user32(NULL),
|
||||
m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : HWND_DESKTOP),
|
||||
@@ -90,10 +90,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
wchar_t *title_16 = alloc_utf16_from_8((char *)title, 0);
|
||||
RECT win_rect = {left, top, (long)(left + width), (long)(top + height)};
|
||||
|
||||
// Initialize tablet variables
|
||||
memset(&m_wintab, 0, sizeof(m_wintab));
|
||||
m_tabletData = GHOST_TABLET_DATA_NONE;
|
||||
|
||||
DWORD style = parentwindow ?
|
||||
WS_POPUPWINDOW | WS_CAPTION | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SIZEBOX :
|
||||
WS_OVERLAPPEDWINDOW;
|
||||
@@ -218,65 +214,10 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
}
|
||||
|
||||
// Initialize Wintab
|
||||
m_wintab.handle = ::LoadLibrary("Wintab32.dll");
|
||||
if (m_wintab.handle && m_system->getTabletAPI() != GHOST_kTabletNative) {
|
||||
// Get API functions
|
||||
m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA");
|
||||
m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA");
|
||||
m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose");
|
||||
m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket");
|
||||
m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable");
|
||||
m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap");
|
||||
|
||||
// Let's see if we can initialize tablet here.
|
||||
// Check if WinTab available by getting system context info.
|
||||
LOGCONTEXT lc = {0};
|
||||
lc.lcOptions |= CXO_SYSTEM;
|
||||
if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
|
||||
// Now init the tablet
|
||||
/* The maximum tablet size, pressure and orientation (tilt) */
|
||||
AXIS TabletX, TabletY, Pressure, Orientation[3];
|
||||
|
||||
// Open a Wintab context
|
||||
|
||||
// Open the context
|
||||
lc.lcPktData = PACKETDATA;
|
||||
lc.lcPktMode = PACKETMODE;
|
||||
lc.lcOptions |= CXO_MESSAGES;
|
||||
lc.lcMoveMask = PACKETDATA;
|
||||
|
||||
/* Set the entire tablet as active */
|
||||
m_wintab.info(WTI_DEVICES, DVC_X, &TabletX);
|
||||
m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY);
|
||||
|
||||
/* get the max pressure, to divide into a float */
|
||||
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
if (pressureSupport)
|
||||
m_wintab.maxPressure = Pressure.axMax;
|
||||
else
|
||||
m_wintab.maxPressure = 0;
|
||||
|
||||
/* get the max tilt axes, to divide into floats */
|
||||
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
|
||||
if (tiltSupport) {
|
||||
/* does the tablet support azimuth ([0]) and altitude ([1]) */
|
||||
if (Orientation[0].axResolution && Orientation[1].axResolution) {
|
||||
/* all this assumes the minimum is 0 */
|
||||
m_wintab.maxAzimuth = Orientation[0].axMax;
|
||||
m_wintab.maxAltitude = Orientation[1].axMax;
|
||||
}
|
||||
else { /* No so don't do tilt stuff. */
|
||||
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// The Wintab spec says we must open the context disabled if we are using cursor masks.
|
||||
m_wintab.tablet = m_wintab.open(m_hWnd, &lc, FALSE);
|
||||
if (m_wintab.enable && m_wintab.tablet) {
|
||||
m_wintab.enable(m_wintab.tablet, TRUE);
|
||||
}
|
||||
}
|
||||
if (system->getTabletAPI() != GHOST_kTabletWinPointer) {
|
||||
loadWintab(GHOST_kWindowStateMinimized != state);
|
||||
}
|
||||
|
||||
CoCreateInstance(
|
||||
CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar);
|
||||
}
|
||||
@@ -289,14 +230,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
m_Bar = NULL;
|
||||
}
|
||||
|
||||
if (m_wintab.handle) {
|
||||
if (m_wintab.close && m_wintab.tablet) {
|
||||
m_wintab.close(m_wintab.tablet);
|
||||
}
|
||||
|
||||
FreeLibrary(m_wintab.handle);
|
||||
memset(&m_wintab, 0, sizeof(m_wintab));
|
||||
}
|
||||
closeWintab();
|
||||
|
||||
if (m_user32) {
|
||||
FreeLibrary(m_user32);
|
||||
@@ -913,20 +847,16 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha
|
||||
GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
|
||||
std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletNative)) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TInt32 pointerId = GET_POINTERID_WPARAM(wParam);
|
||||
GHOST_TInt32 isPrimary = IS_POINTER_PRIMARY_WPARAM(wParam);
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
|
||||
GHOST_TUns32 outCount;
|
||||
GHOST_TUns32 outCount = 0;
|
||||
|
||||
if (!(GetPointerInfoHistory(pointerId, &outCount, NULL))) {
|
||||
if (!(GetPointerPenInfoHistory(pointerId, &outCount, NULL))) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
auto pointerPenInfo = std::vector<POINTER_PEN_INFO>(outCount);
|
||||
std::vector<POINTER_PEN_INFO> pointerPenInfo(outCount);
|
||||
outPointerInfo.resize(outCount);
|
||||
|
||||
if (!(GetPointerPenInfoHistory(pointerId, &outCount, pointerPenInfo.data()))) {
|
||||
@@ -988,148 +918,79 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
|
||||
}
|
||||
}
|
||||
|
||||
if (!outPointerInfo.empty()) {
|
||||
m_lastPointerTabletData = outPointerInfo.back().tabletData;
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state)
|
||||
void GHOST_WindowWin32::resetPointerPenInfo()
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return;
|
||||
}
|
||||
m_lastPointerTabletData = GHOST_TABLET_DATA_NONE;
|
||||
}
|
||||
|
||||
if (m_wintab.enable && m_wintab.tablet) {
|
||||
m_wintab.enable(m_wintab.tablet, state);
|
||||
GHOST_Wintab *GHOST_WindowWin32::getWintab() const
|
||||
{
|
||||
return m_wintab;
|
||||
}
|
||||
|
||||
if (m_wintab.overlap && state) {
|
||||
m_wintab.overlap(m_wintab.tablet, TRUE);
|
||||
void GHOST_WindowWin32::loadWintab(bool enable)
|
||||
{
|
||||
if (!m_wintab) {
|
||||
WINTAB_PRINTF("Loading Wintab for window %p\n", m_hWnd);
|
||||
if (m_wintab = GHOST_Wintab::loadWintab(m_hWnd)) {
|
||||
if (enable) {
|
||||
m_wintab->enable();
|
||||
|
||||
/* Focus Wintab if cursor is inside this window. This ensures Wintab is enabled when the
|
||||
* tablet is used to change the Tablet API. */
|
||||
GHOST_TInt32 x, y;
|
||||
if (m_system->getCursorPosition(x, y)) {
|
||||
GHOST_Rect rect;
|
||||
getClientBounds(rect);
|
||||
|
||||
if (rect.isInside(x, y)) {
|
||||
m_wintab->gainFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
|
||||
void GHOST_WindowWin32::closeWintab()
|
||||
{
|
||||
WINTAB_PRINTF("Closing Wintab for window %p\n", m_hWnd);
|
||||
delete m_wintab;
|
||||
m_wintab = NULL;
|
||||
}
|
||||
|
||||
bool GHOST_WindowWin32::usingTabletAPI(GHOST_TTabletAPI api) const
|
||||
{
|
||||
if (m_system->getTabletAPI() == api) {
|
||||
return true;
|
||||
}
|
||||
else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) {
|
||||
if (m_wintab.tablet)
|
||||
if (m_wintab && m_wintab->devicesPresent()) {
|
||||
return api == GHOST_kTabletWintab;
|
||||
else
|
||||
return api == GHOST_kTabletNative;
|
||||
}
|
||||
else {
|
||||
return api == GHOST_kTabletWinPointer;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWin32TabletInitEvent()
|
||||
GHOST_TabletData GHOST_WindowWin32::getTabletData()
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return;
|
||||
if (usingTabletAPI(GHOST_kTabletWintab)) {
|
||||
return m_wintab ? m_wintab->getLastTabletData() : GHOST_TABLET_DATA_NONE;
|
||||
}
|
||||
|
||||
// Let's see if we can initialize tablet here
|
||||
if (m_wintab.info && m_wintab.tablet) {
|
||||
AXIS Pressure, Orientation[3]; /* The maximum tablet size */
|
||||
|
||||
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
if (pressureSupport)
|
||||
m_wintab.maxPressure = Pressure.axMax;
|
||||
else
|
||||
m_wintab.maxPressure = 0;
|
||||
|
||||
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
|
||||
if (tiltSupport) {
|
||||
/* does the tablet support azimuth ([0]) and altitude ([1]) */
|
||||
if (Orientation[0].axResolution && Orientation[1].axResolution) {
|
||||
m_wintab.maxAzimuth = Orientation[0].axMax;
|
||||
m_wintab.maxAltitude = Orientation[1].axMax;
|
||||
}
|
||||
else { /* No so don't do tilt stuff. */
|
||||
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_tabletData.Active = GHOST_kTabletModeNone;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_wintab.packet && m_wintab.tablet) {
|
||||
PACKET pkt;
|
||||
if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) {
|
||||
switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
|
||||
case 0:
|
||||
m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
|
||||
break;
|
||||
case 1:
|
||||
m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
|
||||
break;
|
||||
case 2:
|
||||
m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_wintab.maxPressure > 0) {
|
||||
m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
|
||||
}
|
||||
else {
|
||||
m_tabletData.Pressure = 1.0f;
|
||||
}
|
||||
|
||||
if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
|
||||
ORIENTATION ort = pkt.pkOrientation;
|
||||
float vecLen;
|
||||
float altRad, azmRad; /* in radians */
|
||||
|
||||
/*
|
||||
* from the wintab spec:
|
||||
* orAzimuth Specifies the clockwise rotation of the
|
||||
* cursor about the z axis through a full circular range.
|
||||
*
|
||||
* orAltitude Specifies the angle with the x-y plane
|
||||
* through a signed, semicircular range. Positive values
|
||||
* specify an angle upward toward the positive z axis;
|
||||
* negative values specify an angle downward toward the negative z axis.
|
||||
*
|
||||
* wintab.h defines .orAltitude as a UINT but documents .orAltitude
|
||||
* as positive for upward angles and negative for downward angles.
|
||||
* WACOM uses negative altitude values to show that the pen is inverted;
|
||||
* therefore we cast .orAltitude as an (int) and then use the absolute value.
|
||||
*/
|
||||
|
||||
/* convert raw fixed point data to radians */
|
||||
altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0);
|
||||
azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0);
|
||||
|
||||
/* find length of the stylus' projected vector on the XY plane */
|
||||
vecLen = cos(altRad);
|
||||
|
||||
/* from there calculate X and Y components based on azimuth */
|
||||
m_tabletData.Xtilt = sin(azmRad) * vecLen;
|
||||
m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
|
||||
}
|
||||
else {
|
||||
m_tabletData.Xtilt = 0.0f;
|
||||
m_tabletData.Ytilt = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::bringTabletContextToFront()
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_wintab.overlap && m_wintab.tablet) {
|
||||
m_wintab.overlap(m_wintab.tablet, TRUE);
|
||||
else {
|
||||
return m_lastPointerTabletData;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -30,34 +30,18 @@
|
||||
|
||||
#include "GHOST_TaskbarWin32.h"
|
||||
#include "GHOST_Window.h"
|
||||
#include "GHOST_Wintab.h"
|
||||
#ifdef WITH_INPUT_IME
|
||||
# include "GHOST_ImeWin32.h"
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <wintab.h>
|
||||
// PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first
|
||||
#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR)
|
||||
#define PACKETMODE PK_BUTTONS
|
||||
#include <pktdef.h>
|
||||
|
||||
class GHOST_SystemWin32;
|
||||
class GHOST_DropTargetWin32;
|
||||
|
||||
// typedefs for WinTab functions to allow dynamic loading
|
||||
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
|
||||
typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
|
||||
typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
|
||||
typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID);
|
||||
typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
|
||||
typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
|
||||
|
||||
// typedefs for user32 functions to allow dynamic loading of Windows 10 DPI scaling functions
|
||||
typedef UINT(API *GHOST_WIN32_GetDpiForWindow)(HWND);
|
||||
#ifndef USER_DEFAULT_SCREEN_DPI
|
||||
# define USER_DEFAULT_SCREEN_DPI 96
|
||||
#endif // USER_DEFAULT_SCREEN_DPI
|
||||
|
||||
struct GHOST_PointerInfoWin32 {
|
||||
GHOST_TInt32 pointerId;
|
||||
@@ -65,7 +49,6 @@ struct GHOST_PointerInfoWin32 {
|
||||
GHOST_TButtonMask buttonMask;
|
||||
POINT pixelLocation;
|
||||
GHOST_TUns64 time;
|
||||
|
||||
GHOST_TabletData tabletData;
|
||||
};
|
||||
|
||||
@@ -259,16 +242,11 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
|
||||
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
|
||||
|
||||
const GHOST_TabletData &getTabletData()
|
||||
{
|
||||
return m_tabletData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query whether given tablet API should be used.
|
||||
* \param api: Tablet API to test.
|
||||
*/
|
||||
bool useTabletAPI(GHOST_TTabletAPI api) const;
|
||||
bool usingTabletAPI(GHOST_TTabletAPI api) const;
|
||||
|
||||
/**
|
||||
* Translate WM_POINTER events into GHOST_PointerInfoWin32 structs.
|
||||
@@ -281,10 +259,34 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
void processWin32TabletActivateEvent(WORD state);
|
||||
void processWin32TabletInitEvent();
|
||||
void processWin32TabletEvent(WPARAM wParam, LPARAM lParam);
|
||||
void bringTabletContextToFront();
|
||||
/**
|
||||
* Resets pointer pen tablet state.
|
||||
*/
|
||||
void resetPointerPenInfo();
|
||||
|
||||
/**
|
||||
* Retrieves pointer to Wintab if Wintab is the set Tablet API.
|
||||
* \return Pointer to Wintab member.
|
||||
*/
|
||||
GHOST_Wintab *getWintab() const;
|
||||
|
||||
/**
|
||||
* Loads Wintab context for the window.
|
||||
* \param enable: True if Wintab should be enabled after loading. Wintab should not be enabled if
|
||||
* the window is minimized.
|
||||
*/
|
||||
void loadWintab(bool enable);
|
||||
|
||||
/**
|
||||
* Closes Wintab for the window.
|
||||
*/
|
||||
void closeWintab();
|
||||
|
||||
/**
|
||||
* Get the most recent Windows Pointer tablet data.
|
||||
* \return Most recent pointer tablet data.
|
||||
*/
|
||||
GHOST_TabletData getTabletData();
|
||||
|
||||
GHOST_TSuccess beginFullScreen() const
|
||||
{
|
||||
@@ -298,10 +300,10 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
|
||||
GHOST_TUns16 getDPIHint() override;
|
||||
|
||||
/** Whether a tablet stylus is being tracked. */
|
||||
bool m_tabletInRange;
|
||||
/** True if the mouse is either over or captured by the window. */
|
||||
bool m_mousePresent;
|
||||
|
||||
/** if the window currently resizing */
|
||||
/** True if the window currently resizing. */
|
||||
bool m_inLiveResize;
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
@@ -385,27 +387,11 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
static const wchar_t *s_windowClassName;
|
||||
static const int s_maxTitleLength;
|
||||
|
||||
/** Tablet data for GHOST */
|
||||
GHOST_TabletData m_tabletData;
|
||||
/** Pointer to Wintab manager if Wintab is loaded. */
|
||||
GHOST_Wintab *m_wintab;
|
||||
|
||||
/* Wintab API */
|
||||
struct {
|
||||
/** `WinTab.dll` handle. */
|
||||
HMODULE handle = NULL;
|
||||
|
||||
/** API functions */
|
||||
GHOST_WIN32_WTInfo info;
|
||||
GHOST_WIN32_WTOpen open;
|
||||
GHOST_WIN32_WTClose close;
|
||||
GHOST_WIN32_WTPacket packet;
|
||||
GHOST_WIN32_WTEnable enable;
|
||||
GHOST_WIN32_WTOverlap overlap;
|
||||
|
||||
/** Stores the Tablet context if detected Tablet features using `WinTab.dll` */
|
||||
HCTX tablet;
|
||||
LONG maxPressure;
|
||||
LONG maxAzimuth, maxAltitude;
|
||||
} m_wintab;
|
||||
/** Most recent tablet data. */
|
||||
GHOST_TabletData m_lastPointerTabletData;
|
||||
|
||||
GHOST_TWindowState m_normal_state;
|
||||
|
||||
|
646
intern/ghost/intern/GHOST_Wintab.cpp
Normal file
646
intern/ghost/intern/GHOST_Wintab.cpp
Normal file
@@ -0,0 +1,646 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
*/
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
#include "GHOST_Wintab.h"
|
||||
#include "GHOST_Debug.h"
|
||||
|
||||
GHOST_Wintab *GHOST_Wintab::loadWintab(HWND hwnd)
|
||||
{
|
||||
/* Load Wintab library if available. */
|
||||
|
||||
auto handle = unique_hmodule(::LoadLibrary("Wintab32.dll"), &::FreeLibrary);
|
||||
if (!handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Get Wintab functions. */
|
||||
|
||||
auto info = (GHOST_WIN32_WTInfo)::GetProcAddress(handle.get(), "WTInfoA");
|
||||
if (!info) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto open = (GHOST_WIN32_WTOpen)::GetProcAddress(handle.get(), "WTOpenA");
|
||||
if (!open) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto get = (GHOST_WIN32_WTGet)::GetProcAddress(handle.get(), "WTGetA");
|
||||
if (!get) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto set = (GHOST_WIN32_WTSet)::GetProcAddress(handle.get(), "WTSetA");
|
||||
if (!set) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto close = (GHOST_WIN32_WTClose)::GetProcAddress(handle.get(), "WTClose");
|
||||
if (!close) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto packetsGet = (GHOST_WIN32_WTPacketsGet)::GetProcAddress(handle.get(), "WTPacketsGet");
|
||||
if (!packetsGet) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto queueSizeGet = (GHOST_WIN32_WTQueueSizeGet)::GetProcAddress(handle.get(), "WTQueueSizeGet");
|
||||
if (!queueSizeGet) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto queueSizeSet = (GHOST_WIN32_WTQueueSizeSet)::GetProcAddress(handle.get(), "WTQueueSizeSet");
|
||||
if (!queueSizeSet) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto enable = (GHOST_WIN32_WTEnable)::GetProcAddress(handle.get(), "WTEnable");
|
||||
if (!enable) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(handle.get(), "WTOverlap");
|
||||
if (!overlap) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Build Wintab context. */
|
||||
|
||||
LOGCONTEXT lc = {0};
|
||||
if (!info(WTI_DEFSYSCTX, 0, &lc)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Coord tablet, system;
|
||||
extractCoordinates(lc, tablet, system);
|
||||
modifyContext(lc);
|
||||
|
||||
/* The Wintab spec says we must open the context disabled if we are using cursor masks. */
|
||||
auto hctx = unique_hctx(open(hwnd, &lc, FALSE), close);
|
||||
if (!hctx) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Wintab provides no way to determine the maximum queue size aside from checking if attempts
|
||||
* to change the queue size are successful. */
|
||||
const int maxQueue = 500;
|
||||
int queueSize = queueSizeGet(hctx.get());
|
||||
|
||||
while (queueSize < maxQueue) {
|
||||
int testSize = min(queueSize + 16, maxQueue);
|
||||
if (queueSizeSet(hctx.get(), testSize)) {
|
||||
queueSize = testSize;
|
||||
}
|
||||
else {
|
||||
/* From Windows Wintab Documentation for WTQueueSizeSet:
|
||||
* "If the return value is zero, the context has no queue because the function deletes the
|
||||
* original queue before attempting to create a new one. The application must continue
|
||||
* calling the function with a smaller queue size until the function returns a non - zero
|
||||
* value."
|
||||
*
|
||||
* In our case we start with a known valid queue size and in the event of failure roll
|
||||
* back to the last valid queue size. The Wintab spec dates back to 16 bit Windows, thus
|
||||
* assumes memory recently deallocated may not be available, which is no longer a practical
|
||||
* concern. */
|
||||
if (!queueSizeSet(hctx.get(), queueSize)) {
|
||||
/* If a previously valid queue size is no longer valid, there is likely something wrong in
|
||||
* the Wintab implementation and we should not use it. */
|
||||
return nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int sanityQueueSize = queueSizeGet(hctx.get());
|
||||
WINTAB_PRINTF("initializeWintab queueSize: %d, queueSizeGet: %d\n", queueSize, sanityQueueSize);
|
||||
|
||||
WINTAB_PRINTF("Loaded Wintab context %p\n", hctx.get());
|
||||
|
||||
return new GHOST_Wintab(hwnd,
|
||||
std::move(handle),
|
||||
info,
|
||||
get,
|
||||
set,
|
||||
packetsGet,
|
||||
enable,
|
||||
overlap,
|
||||
std::move(hctx),
|
||||
tablet,
|
||||
system,
|
||||
queueSize);
|
||||
}
|
||||
|
||||
void GHOST_Wintab::modifyContext(LOGCONTEXT &lc)
|
||||
{
|
||||
lc.lcPktData = PACKETDATA;
|
||||
lc.lcPktMode = PACKETMODE;
|
||||
lc.lcMoveMask = PACKETDATA;
|
||||
lc.lcOptions |= CXO_CSRMESSAGES | CXO_MESSAGES;
|
||||
|
||||
/* Tablet scaling is handled manually because some drivers don't handle HIDPI or multi-display
|
||||
* correctly; reset tablet scale factors to un-scaled tablet coordinates. */
|
||||
lc.lcOutOrgX = lc.lcInOrgX;
|
||||
lc.lcOutOrgY = lc.lcInOrgY;
|
||||
lc.lcOutExtX = lc.lcInExtX;
|
||||
lc.lcOutExtY = lc.lcInExtY;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::extractCoordinates(LOGCONTEXT &lc, Coord &tablet, Coord &system)
|
||||
{
|
||||
tablet.x.org = lc.lcInOrgX;
|
||||
tablet.x.ext = lc.lcInExtX;
|
||||
tablet.y.org = lc.lcInOrgY;
|
||||
tablet.y.ext = lc.lcInExtY;
|
||||
|
||||
system.x.org = lc.lcSysOrgX;
|
||||
system.x.ext = lc.lcSysExtX;
|
||||
system.y.org = lc.lcSysOrgY;
|
||||
/* Wintab maps y origin to the tablet's bottom; invert y to match Windows y origin mapping to the
|
||||
* screen top. */
|
||||
system.y.ext = -lc.lcSysExtY;
|
||||
}
|
||||
|
||||
GHOST_Wintab::GHOST_Wintab(HWND hwnd,
|
||||
unique_hmodule handle,
|
||||
GHOST_WIN32_WTInfo info,
|
||||
GHOST_WIN32_WTGet get,
|
||||
GHOST_WIN32_WTSet set,
|
||||
GHOST_WIN32_WTPacketsGet packetsGet,
|
||||
GHOST_WIN32_WTEnable enable,
|
||||
GHOST_WIN32_WTOverlap overlap,
|
||||
unique_hctx hctx,
|
||||
Coord tablet,
|
||||
Coord system,
|
||||
int queueSize)
|
||||
: m_handle{std::move(handle)},
|
||||
m_fpInfo{info},
|
||||
m_fpGet{get},
|
||||
m_fpSet{set},
|
||||
m_fpPacketsGet{packetsGet},
|
||||
m_fpEnable{enable},
|
||||
m_fpOverlap{overlap},
|
||||
m_context{std::move(hctx)},
|
||||
m_tabletCoord{tablet},
|
||||
m_systemCoord{system},
|
||||
m_pkts{queueSize}
|
||||
{
|
||||
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
|
||||
updateCursorInfo();
|
||||
|
||||
/* Debug info. */
|
||||
|
||||
WINTAB_PRINTF("initializeWintab numDevices: %d\n", m_numDevices);
|
||||
|
||||
UINT maxcontexts, opencontexts;
|
||||
m_fpInfo(WTI_INTERFACE, IFC_NCONTEXTS, &maxcontexts);
|
||||
m_fpInfo(WTI_STATUS, STA_CONTEXTS, &opencontexts);
|
||||
WINTAB_PRINTF("%u max contexts, %u open contexts\n", maxcontexts, opencontexts);
|
||||
|
||||
/* Print button maps. */
|
||||
BYTE logicalButtons[32] = {0};
|
||||
BYTE systemButtons[32] = {0};
|
||||
for (int i = 0; i < 3; i++) {
|
||||
WINTAB_PRINTF("initializeWintab cursor %d buttons\n", i);
|
||||
UINT lbut = m_fpInfo(WTI_CURSORS + i, CSR_BUTTONMAP, &logicalButtons);
|
||||
if (lbut) {
|
||||
WINTAB_PRINTF("%d", logicalButtons[0]);
|
||||
for (int j = 1; j < lbut; j++) {
|
||||
WINTAB_PRINTF(", %d", logicalButtons[j]);
|
||||
}
|
||||
WINTAB_PRINTF("\n");
|
||||
}
|
||||
else {
|
||||
WINTAB_PRINTF("logical button error\n");
|
||||
}
|
||||
UINT sbut = m_fpInfo(WTI_CURSORS + i, CSR_SYSBTNMAP, &systemButtons);
|
||||
if (sbut) {
|
||||
WINTAB_PRINTF("%d", systemButtons[0]);
|
||||
for (int j = 1; j < sbut; j++) {
|
||||
WINTAB_PRINTF(", %d", systemButtons[j]);
|
||||
}
|
||||
WINTAB_PRINTF("\n");
|
||||
}
|
||||
else {
|
||||
WINTAB_PRINTF("system button error\n");
|
||||
}
|
||||
}
|
||||
|
||||
printContextInfo();
|
||||
}
|
||||
|
||||
GHOST_Wintab::~GHOST_Wintab()
|
||||
{
|
||||
WINTAB_PRINTF("Closing Wintab context %p\n", m_context.get());
|
||||
}
|
||||
|
||||
void GHOST_Wintab::enable()
|
||||
{
|
||||
m_fpEnable(m_context.get(), true);
|
||||
m_enabled = true;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::disable()
|
||||
{
|
||||
if (m_focused) {
|
||||
loseFocus();
|
||||
}
|
||||
m_fpEnable(m_context.get(), false);
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::gainFocus()
|
||||
{
|
||||
m_fpOverlap(m_context.get(), true);
|
||||
m_focused = true;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::loseFocus()
|
||||
{
|
||||
if (m_lastTabletData.Active != GHOST_kTabletModeNone) {
|
||||
leaveRange();
|
||||
}
|
||||
|
||||
/* Mouse mode of tablet or display layout may change when Wintab or Window is inactive. Don't
|
||||
* trust for mouse movement until re-verified. */
|
||||
m_coordTrusted = false;
|
||||
|
||||
m_fpOverlap(m_context.get(), false);
|
||||
m_focused = false;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::leaveRange()
|
||||
{
|
||||
/* Button state can't be tracked while out of range, reset it. */
|
||||
m_buttons = 0;
|
||||
/* Set to none to indicate tablet is inactive. */
|
||||
m_lastTabletData = GHOST_TABLET_DATA_NONE;
|
||||
/* Clear the packet queue. */
|
||||
m_fpPacketsGet(m_context.get(), m_pkts.size(), m_pkts.data());
|
||||
}
|
||||
|
||||
void GHOST_Wintab::remapCoordinates()
|
||||
{
|
||||
LOGCONTEXT lc = {0};
|
||||
|
||||
if (m_fpInfo(WTI_DEFSYSCTX, 0, &lc)) {
|
||||
extractCoordinates(lc, m_tabletCoord, m_systemCoord);
|
||||
modifyContext(lc);
|
||||
|
||||
m_fpSet(m_context.get(), &lc);
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_Wintab::updateCursorInfo()
|
||||
{
|
||||
AXIS Pressure, Orientation[3];
|
||||
|
||||
BOOL pressureSupport = m_fpInfo(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
m_maxPressure = pressureSupport ? Pressure.axMax : 0;
|
||||
WINTAB_PRINTF("cursorInfo maxPressure: %d\n", m_maxPressure);
|
||||
|
||||
BOOL tiltSupport = m_fpInfo(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
|
||||
/* Check if tablet supports azimuth [0] and altitude [1], encoded in axResolution. */
|
||||
if (tiltSupport && Orientation[0].axResolution && Orientation[1].axResolution) {
|
||||
m_maxAzimuth = Orientation[0].axMax;
|
||||
m_maxAltitude = Orientation[1].axMax;
|
||||
}
|
||||
else {
|
||||
m_maxAzimuth = m_maxAltitude = 0;
|
||||
}
|
||||
WINTAB_PRINTF("cursorInfo maxAzimuth: %d, maxAltitude: %d\n", m_maxAzimuth, m_maxAltitude);
|
||||
}
|
||||
|
||||
void GHOST_Wintab::processInfoChange(LPARAM lParam)
|
||||
{
|
||||
/* Update number of connected Wintab digitizers. */
|
||||
if (LOWORD(lParam) == WTI_INTERFACE && HIWORD(lParam) == IFC_NDEVICES) {
|
||||
WINTAB_PRINTF("%p processWintabInfoChangeEvent numDevices: %d\n", m_numDevices);
|
||||
m_fpInfo(WTI_INTERFACE, IFC_NDEVICES, &m_numDevices);
|
||||
}
|
||||
}
|
||||
|
||||
bool GHOST_Wintab::devicesPresent()
|
||||
{
|
||||
return m_numDevices > 0;
|
||||
}
|
||||
|
||||
GHOST_TabletData GHOST_Wintab::getLastTabletData()
|
||||
{
|
||||
return m_lastTabletData;
|
||||
}
|
||||
|
||||
void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
|
||||
{
|
||||
const int numPackets = m_fpPacketsGet(m_context.get(), m_pkts.size(), m_pkts.data());
|
||||
outWintabInfo.resize(numPackets);
|
||||
size_t outExtent = 0;
|
||||
|
||||
for (int i = 0; i < numPackets; i++) {
|
||||
PACKET pkt = m_pkts[i];
|
||||
GHOST_WintabInfoWin32 &out = outWintabInfo[i + outExtent];
|
||||
|
||||
out.tabletData = GHOST_TABLET_DATA_NONE;
|
||||
/* % 3 for multiple devices ("DualTrack"). */
|
||||
switch (pkt.pkCursor % 3) {
|
||||
case 0:
|
||||
/* Puck - processed as mouse. */
|
||||
out.tabletData.Active = GHOST_kTabletModeNone;
|
||||
break;
|
||||
case 1:
|
||||
out.tabletData.Active = GHOST_kTabletModeStylus;
|
||||
break;
|
||||
case 2:
|
||||
out.tabletData.Active = GHOST_kTabletModeEraser;
|
||||
break;
|
||||
}
|
||||
|
||||
out.x = pkt.pkX;
|
||||
out.y = pkt.pkY;
|
||||
|
||||
if (m_maxPressure > 0) {
|
||||
out.tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_maxPressure;
|
||||
}
|
||||
|
||||
if ((m_maxAzimuth > 0) && (m_maxAltitude > 0)) {
|
||||
ORIENTATION ort = pkt.pkOrientation;
|
||||
float vecLen;
|
||||
float altRad, azmRad; /* In radians. */
|
||||
|
||||
/*
|
||||
* From the wintab spec:
|
||||
* orAzimuth: Specifies the clockwise rotation of the cursor about the z axis through a
|
||||
* full circular range.
|
||||
* orAltitude: Specifies the angle with the x-y plane through a signed, semicircular range.
|
||||
* Positive values specify an angle upward toward the positive z axis; negative values
|
||||
* specify an angle downward toward the negative z axis.
|
||||
*
|
||||
* wintab.h defines orAltitude as a UINT but documents orAltitude as positive for upward
|
||||
* angles and negative for downward angles. WACOM uses negative altitude values to show that
|
||||
* the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
|
||||
* value.
|
||||
*/
|
||||
|
||||
/* Convert raw fixed point data to radians. */
|
||||
altRad = (float)((fabs((float)ort.orAltitude) / (float)m_maxAltitude) * M_PI / 2.0);
|
||||
azmRad = (float)(((float)ort.orAzimuth / (float)m_maxAzimuth) * M_PI * 2.0);
|
||||
|
||||
/* Find length of the stylus' projected vector on the XY plane. */
|
||||
vecLen = cos(altRad);
|
||||
|
||||
/* From there calculate X and Y components based on azimuth. */
|
||||
out.tabletData.Xtilt = sin(azmRad) * vecLen;
|
||||
out.tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
|
||||
}
|
||||
|
||||
out.time = pkt.pkTime;
|
||||
|
||||
/* Some Wintab libraries don't handle relative button input, so we track button presses
|
||||
* manually. */
|
||||
out.button = GHOST_kButtonMaskNone;
|
||||
out.type = GHOST_kEventCursorMove;
|
||||
|
||||
DWORD buttonsChanged = m_buttons ^ pkt.pkButtons;
|
||||
WORD buttonIndex = 0;
|
||||
GHOST_WintabInfoWin32 buttonRef = out;
|
||||
int buttons = 0;
|
||||
|
||||
while (buttonsChanged) {
|
||||
if (buttonsChanged & 1) {
|
||||
/* Find the index for the changed button from the button map. */
|
||||
GHOST_TButtonMask button = mapWintabToGhostButton(pkt.pkCursor, buttonIndex);
|
||||
|
||||
if (button != GHOST_kButtonMaskNone) {
|
||||
/* Extend output if multiple buttons are pressed. We don't extend input until we confirm
|
||||
* a Wintab buttons maps to a system button. */
|
||||
if (buttons > 0) {
|
||||
outWintabInfo.resize(outWintabInfo.size() + 1);
|
||||
outExtent++;
|
||||
GHOST_WintabInfoWin32 &out = outWintabInfo[i + outExtent];
|
||||
out = buttonRef;
|
||||
}
|
||||
buttons++;
|
||||
|
||||
out.button = button;
|
||||
if (buttonsChanged & pkt.pkButtons) {
|
||||
out.type = GHOST_kEventButtonDown;
|
||||
}
|
||||
else {
|
||||
out.type = GHOST_kEventButtonUp;
|
||||
}
|
||||
}
|
||||
|
||||
m_buttons ^= 1 << buttonIndex;
|
||||
}
|
||||
|
||||
buttonsChanged >>= 1;
|
||||
buttonIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!outWintabInfo.empty()) {
|
||||
m_lastTabletData = outWintabInfo.back().tabletData;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TButtonMask GHOST_Wintab::mapWintabToGhostButton(UINT cursor, WORD physicalButton)
|
||||
{
|
||||
const WORD numButtons = 32;
|
||||
BYTE logicalButtons[numButtons] = {0};
|
||||
BYTE systemButtons[numButtons] = {0};
|
||||
|
||||
if (!m_fpInfo(WTI_CURSORS + cursor, CSR_BUTTONMAP, &logicalButtons) ||
|
||||
!m_fpInfo(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons)) {
|
||||
return GHOST_kButtonMaskNone;
|
||||
}
|
||||
|
||||
if (physicalButton >= numButtons) {
|
||||
return GHOST_kButtonMaskNone;
|
||||
}
|
||||
|
||||
BYTE lb = logicalButtons[physicalButton];
|
||||
|
||||
if (lb >= numButtons) {
|
||||
return GHOST_kButtonMaskNone;
|
||||
}
|
||||
|
||||
switch (systemButtons[lb]) {
|
||||
case SBN_LCLICK:
|
||||
return GHOST_kButtonMaskLeft;
|
||||
case SBN_RCLICK:
|
||||
return GHOST_kButtonMaskRight;
|
||||
case SBN_MCLICK:
|
||||
return GHOST_kButtonMaskMiddle;
|
||||
default:
|
||||
return GHOST_kButtonMaskNone;
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_Wintab::mapWintabToSysCoordinates(int x_in, int y_in, int &x_out, int &y_out)
|
||||
{
|
||||
/* Maps from range [in.org, in.org + abs(in.ext)] to [out.org, out.org + abs(out.ext)], in
|
||||
* reverse if in.ext and out.ext have differing sign. */
|
||||
auto remap = [](int inPoint, Range in, Range out) -> int {
|
||||
int absInExt = abs(in.ext);
|
||||
int absOutExt = abs(out.ext);
|
||||
|
||||
/* Translate input from range [in.org, in.org + absInExt] to [0, absInExt] */
|
||||
int inMagnitude = inPoint - in.org;
|
||||
|
||||
/* If signs of extents differ, reverse input over range. */
|
||||
if ((in.ext < 0) != (out.ext < 0)) {
|
||||
inMagnitude = absInExt - inMagnitude;
|
||||
}
|
||||
|
||||
/* Scale from [0, absInExt] to [0, absOutExt]. */
|
||||
int outMagnitude = inMagnitude * absOutExt / absInExt;
|
||||
|
||||
/* Translate from range [0, absOutExt] to [out.org, out.org + absOutExt]. */
|
||||
int outPoint = outMagnitude + out.org;
|
||||
|
||||
return outPoint;
|
||||
};
|
||||
|
||||
x_out = remap(x_in, m_tabletCoord.x, m_systemCoord.x);
|
||||
y_out = remap(y_in, m_tabletCoord.y, m_systemCoord.y);
|
||||
}
|
||||
|
||||
bool GHOST_Wintab::trustCoordinates()
|
||||
{
|
||||
return m_coordTrusted;
|
||||
}
|
||||
|
||||
bool GHOST_Wintab::testCoordinates(int sysX, int sysY, int wtX, int wtY)
|
||||
{
|
||||
mapWintabToSysCoordinates(wtX, wtY, wtX, wtY);
|
||||
|
||||
/* Allow off by one pixel tolerance in case of rounding error. */
|
||||
if (abs(sysX - wtX) <= 1 && abs(sysY - wtY) <= 1) {
|
||||
m_coordTrusted = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
m_coordTrusted = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_Wintab::printContextInfo()
|
||||
{
|
||||
LOGCONTEXT debuglc;
|
||||
m_fpInfo(WTI_DEFSYSCTX, 0, &debuglc);
|
||||
|
||||
/* Print system context. */
|
||||
WINTAB_PRINTF("lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n",
|
||||
debuglc.lcOutOrgX,
|
||||
debuglc.lcOutOrgY,
|
||||
debuglc.lcOutExtX,
|
||||
debuglc.lcOutExtY);
|
||||
WINTAB_PRINTF("lcInOrgX: %d, lcInOrgY: %d, lcInExtX: %d, lcInExtY: %d\n",
|
||||
debuglc.lcInOrgX,
|
||||
debuglc.lcInOrgY,
|
||||
debuglc.lcInExtX,
|
||||
debuglc.lcInExtY);
|
||||
WINTAB_PRINTF("lcSysOrgX: %d, lcSysOrgY: %d, lcSysExtX: %d, lcSysExtY: %d\n",
|
||||
debuglc.lcSysOrgX,
|
||||
debuglc.lcSysOrgY,
|
||||
debuglc.lcSysExtX,
|
||||
debuglc.lcSysExtY);
|
||||
WINTAB_PRINTF("left: %d, top: %d, width: %d, height: %d\n",
|
||||
::GetSystemMetrics(SM_XVIRTUALSCREEN),
|
||||
::GetSystemMetrics(SM_YVIRTUALSCREEN),
|
||||
::GetSystemMetrics(SM_CXVIRTUALSCREEN),
|
||||
::GetSystemMetrics(SM_CYVIRTUALSCREEN));
|
||||
|
||||
/* Print system context, manually populated. */
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTORGX, &debuglc.lcOutOrgX);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTORGY, &debuglc.lcOutOrgY);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTEXTX, &debuglc.lcOutExtX);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_OUTEXTY, &debuglc.lcOutExtY);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSORGX, &debuglc.lcSysOrgX);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSORGY, &debuglc.lcSysOrgY);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSEXTX, &debuglc.lcSysExtX);
|
||||
m_fpInfo(WTI_DEFSYSCTX, CTX_SYSEXTY, &debuglc.lcSysExtY);
|
||||
WINTAB_PRINTF("index def lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n",
|
||||
debuglc.lcOutOrgX,
|
||||
debuglc.lcOutOrgY,
|
||||
debuglc.lcOutExtX,
|
||||
debuglc.lcOutExtY);
|
||||
WINTAB_PRINTF("index def lcSysOrgX: %d, lcSysOrgY: %d, lcSysExtX: %d, lcSysExtY: %d\n",
|
||||
debuglc.lcSysOrgX,
|
||||
debuglc.lcSysOrgY,
|
||||
debuglc.lcSysExtX,
|
||||
debuglc.lcSysExtY);
|
||||
|
||||
for (unsigned int i = 0; i < m_numDevices; i++) {
|
||||
/* Print individual device system context. */
|
||||
m_fpInfo(WTI_DSCTXS + i, 0, &debuglc);
|
||||
WINTAB_PRINTF("dev %d lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n",
|
||||
i,
|
||||
debuglc.lcOutOrgX,
|
||||
debuglc.lcOutOrgY,
|
||||
debuglc.lcOutExtX,
|
||||
debuglc.lcOutExtY);
|
||||
WINTAB_PRINTF("dev %d lcSysOrgX: %d, lcSysOrgY: %d, lcSysExtX: %d, lcSysExtY: %d\n",
|
||||
i,
|
||||
debuglc.lcSysOrgX,
|
||||
debuglc.lcSysOrgY,
|
||||
debuglc.lcSysExtX,
|
||||
debuglc.lcSysExtY);
|
||||
|
||||
/* Print individual device system context, manually populated. */
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_OUTORGX, &debuglc.lcOutOrgX);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_OUTORGY, &debuglc.lcOutOrgY);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_OUTEXTX, &debuglc.lcOutExtX);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_OUTEXTY, &debuglc.lcOutExtY);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_SYSORGX, &debuglc.lcSysOrgX);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_SYSORGY, &debuglc.lcSysOrgY);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_SYSEXTX, &debuglc.lcSysExtX);
|
||||
m_fpInfo(WTI_DSCTXS + i, CTX_SYSEXTY, &debuglc.lcSysExtY);
|
||||
WINTAB_PRINTF("index def dev %d lcOutOrgX: %d, lcOutOrgY: %d, lcOutExtX: %d, lcOutExtY: %d\n",
|
||||
i,
|
||||
debuglc.lcOutOrgX,
|
||||
debuglc.lcOutOrgY,
|
||||
debuglc.lcOutExtX,
|
||||
debuglc.lcOutExtY);
|
||||
WINTAB_PRINTF("index def dev %d lcSysOrgX: %d, lcSysOrgY: %d, lcSysExtX: %d, lcSysExtY: %d\n",
|
||||
i,
|
||||
debuglc.lcSysOrgX,
|
||||
debuglc.lcSysOrgY,
|
||||
debuglc.lcSysExtX,
|
||||
debuglc.lcSysExtY);
|
||||
|
||||
/* Print device axis. */
|
||||
AXIS axis_x, axis_y;
|
||||
m_fpInfo(WTI_DEVICES + i, DVC_X, &axis_x);
|
||||
m_fpInfo(WTI_DEVICES + i, DVC_Y, &axis_y);
|
||||
WINTAB_PRINTF("dev %d axis_x org: %d, axis_y org: %d axis_x ext: %d, axis_y ext: %d\n",
|
||||
i,
|
||||
axis_x.axMin,
|
||||
axis_y.axMin,
|
||||
axis_x.axMax - axis_x.axMin + 1,
|
||||
axis_y.axMax - axis_y.axMin + 1);
|
||||
|
||||
/* Other stuff while we have a logcontext. */
|
||||
WINTAB_PRINTF("sysmode %d\n", debuglc.lcSysMode);
|
||||
}
|
||||
}
|
254
intern/ghost/intern/GHOST_Wintab.h
Normal file
254
intern/ghost/intern/GHOST_Wintab.h
Normal file
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \ingroup GHOST
|
||||
* Declaration of GHOST_WintabWin32 class.
|
||||
*/
|
||||
|
||||
/* Wacom's Wintab documentation is periodically offline, moved, and increasingly hidden away. You
|
||||
* can find a (painstakingly) archived copy of the documentation at
|
||||
* https://web.archive.org/web/20201122230125/https://developer-docs-legacy.wacom.com/display/DevDocs/Windows+Wintab+Documentation
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <wtypes.h>
|
||||
|
||||
#include "GHOST_Types.h"
|
||||
|
||||
#include <wintab.h>
|
||||
/* PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first. */
|
||||
#define PACKETDATA \
|
||||
(PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME)
|
||||
#define PACKETMODE 0
|
||||
#include <pktdef.h>
|
||||
|
||||
/* Typedefs for Wintab functions to allow dynamic loading. */
|
||||
typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID);
|
||||
typedef BOOL(API *GHOST_WIN32_WTGet)(HCTX, LPLOGCONTEXTA);
|
||||
typedef BOOL(API *GHOST_WIN32_WTSet)(HCTX, LPLOGCONTEXTA);
|
||||
typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL);
|
||||
typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX);
|
||||
typedef int(API *GHOST_WIN32_WTPacketsGet)(HCTX, int, LPVOID);
|
||||
typedef int(API *GHOST_WIN32_WTQueueSizeGet)(HCTX);
|
||||
typedef BOOL(API *GHOST_WIN32_WTQueueSizeSet)(HCTX, int);
|
||||
typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL);
|
||||
typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL);
|
||||
|
||||
/* Typedefs for Wintab and Windows resource management. */
|
||||
typedef std::unique_ptr<std::remove_pointer_t<HMODULE>, decltype(&::FreeLibrary)> unique_hmodule;
|
||||
typedef std::unique_ptr<std::remove_pointer_t<HCTX>, GHOST_WIN32_WTClose> unique_hctx;
|
||||
|
||||
struct GHOST_WintabInfoWin32 {
|
||||
GHOST_TInt32 x, y;
|
||||
GHOST_TEventType type;
|
||||
GHOST_TButtonMask button;
|
||||
GHOST_TUns64 time;
|
||||
GHOST_TabletData tabletData;
|
||||
};
|
||||
|
||||
class GHOST_Wintab {
|
||||
public:
|
||||
/**
|
||||
* Loads Wintab if available.
|
||||
* \param hwnd: Window to attach Wintab context to.
|
||||
*/
|
||||
static GHOST_Wintab *loadWintab(HWND hwnd);
|
||||
|
||||
/**
|
||||
* Enables Wintab context.
|
||||
*/
|
||||
void enable();
|
||||
|
||||
/**
|
||||
* Disables the Wintab context and unwinds Wintab state.
|
||||
*/
|
||||
void disable();
|
||||
|
||||
/**
|
||||
* Brings Wintab context to the top of the overlap order.
|
||||
*/
|
||||
void gainFocus();
|
||||
|
||||
/**
|
||||
* Puts Wintab context at bottom of overlap order and unwinds Wintab state.
|
||||
*/
|
||||
void loseFocus();
|
||||
|
||||
/**
|
||||
* Clean up when Wintab leaves tracking range.
|
||||
*/
|
||||
void leaveRange();
|
||||
|
||||
/**
|
||||
* Handle Wintab coordinate changes when DisplayChange events occur.
|
||||
*/
|
||||
void remapCoordinates();
|
||||
|
||||
/**
|
||||
* Maps Wintab to Win32 display coordinates.
|
||||
* \param x_in: The tablet x coordinate.
|
||||
* \param y_in: The tablet y coordinate.
|
||||
* \param x_out: Output for the Win32 mapped x coordinate.
|
||||
* \param y_out: Output for the Win32 mapped y coordinate.
|
||||
*/
|
||||
void mapWintabToSysCoordinates(int x_in, int y_in, int &x_out, int &y_out);
|
||||
|
||||
/**
|
||||
* Updates cached Wintab properties for current cursor.
|
||||
*/
|
||||
void updateCursorInfo();
|
||||
|
||||
/**
|
||||
* Handle Wintab info changes such as change in number of connected tablets.
|
||||
* \param lParam: LPARAM of the event.
|
||||
*/
|
||||
void processInfoChange(LPARAM lParam);
|
||||
|
||||
/**
|
||||
* Whether Wintab devices are present.
|
||||
* \return True if Wintab devices are present.
|
||||
*/
|
||||
bool devicesPresent();
|
||||
|
||||
/**
|
||||
* Translate Wintab packets into GHOST_WintabInfoWin32 structs.
|
||||
* \param outWintabInfo: Storage to return resulting GHOST_WintabInfoWin32 data.
|
||||
*/
|
||||
void getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
|
||||
|
||||
/**
|
||||
* Whether Wintab coordinates should be trusted.
|
||||
* \return True if Wintab coordinates should be trusted.
|
||||
*/
|
||||
bool trustCoordinates();
|
||||
|
||||
/**
|
||||
* Tests whether Wintab coordinates can be trusted by comparing Win32 and Wintab reported cursor
|
||||
* position.
|
||||
* \param sysX: System cursor x position.
|
||||
* \param sysY: System cursor y position.
|
||||
* \param wtX: Wintab cursor x position.
|
||||
* \param wtY: Wintab cursor y position.
|
||||
* \return True if Win32 and Wintab cursor positions match within tolerance.
|
||||
*
|
||||
* Note: Only test coordinates on button press, not release. This prevents issues when async
|
||||
* mismatch causes mouse movement to replay and snap back, which is only an issue while drawing.
|
||||
*/
|
||||
bool testCoordinates(int sysX, int sysY, int wtX, int wtY);
|
||||
|
||||
/**
|
||||
* Retrieve the most recent tablet data, or none if pen is not in range.
|
||||
* \return Most recent tablet data, or none if pen is not in range.
|
||||
*/
|
||||
GHOST_TabletData getLastTabletData();
|
||||
|
||||
~GHOST_Wintab();
|
||||
|
||||
private:
|
||||
/** Wintab DLL handle. */
|
||||
unique_hmodule m_handle;
|
||||
/** Wintab API functions. */
|
||||
GHOST_WIN32_WTInfo m_fpInfo = nullptr;
|
||||
GHOST_WIN32_WTGet m_fpGet = nullptr;
|
||||
GHOST_WIN32_WTSet m_fpSet = nullptr;
|
||||
GHOST_WIN32_WTPacketsGet m_fpPacketsGet = nullptr;
|
||||
GHOST_WIN32_WTEnable m_fpEnable = nullptr;
|
||||
GHOST_WIN32_WTOverlap m_fpOverlap = nullptr;
|
||||
|
||||
/** Stores the Wintab tablet context. */
|
||||
unique_hctx m_context;
|
||||
/** Whether the context is enabled. */
|
||||
bool m_enabled = false;
|
||||
/** Whether the context has focus and is at the top of overlap order. */
|
||||
bool m_focused = false;
|
||||
|
||||
/** Pressed button map. */
|
||||
GHOST_TUns8 m_buttons = 0;
|
||||
|
||||
/** Range of a coordinate space. */
|
||||
struct Range {
|
||||
/** Origin of range. */
|
||||
int org = 0;
|
||||
/** Extent of range. */
|
||||
int ext = 1;
|
||||
};
|
||||
|
||||
/** 2D Coordinate space. */
|
||||
struct Coord {
|
||||
/** Range of x. */
|
||||
Range x = {};
|
||||
/** Range of y. */
|
||||
Range y = {};
|
||||
};
|
||||
/** Whether Wintab coordinates are trusted. */
|
||||
bool m_coordTrusted = false;
|
||||
/** Tablet input range. */
|
||||
Coord m_tabletCoord = {};
|
||||
/** System output range. */
|
||||
Coord m_systemCoord = {};
|
||||
|
||||
int m_maxPressure = 0;
|
||||
int m_maxAzimuth = 0;
|
||||
int m_maxAltitude = 0;
|
||||
|
||||
/** Number of connected Wintab devices. */
|
||||
UINT m_numDevices = 0;
|
||||
/** Reusable buffer to read in Wintab packets. */
|
||||
std::vector<PACKET> m_pkts;
|
||||
/** Most recently received tablet data, or none if pen is not in range. */
|
||||
GHOST_TabletData m_lastTabletData = GHOST_TABLET_DATA_NONE;
|
||||
|
||||
GHOST_Wintab(HWND hwnd,
|
||||
unique_hmodule handle,
|
||||
GHOST_WIN32_WTInfo info,
|
||||
GHOST_WIN32_WTGet get,
|
||||
GHOST_WIN32_WTSet set,
|
||||
GHOST_WIN32_WTPacketsGet packetsGet,
|
||||
GHOST_WIN32_WTEnable enable,
|
||||
GHOST_WIN32_WTOverlap overlap,
|
||||
unique_hctx hctx,
|
||||
Coord tablet,
|
||||
Coord system,
|
||||
int queueSize);
|
||||
|
||||
/**
|
||||
* Convert Wintab system mapped (mouse) buttons into Ghost button mask.
|
||||
* \param cursor: The Wintab cursor associated to the button.
|
||||
* \param physicalButton: The physical button ID to inspect.
|
||||
* \return The system mapped button.
|
||||
*/
|
||||
GHOST_TButtonMask mapWintabToGhostButton(UINT cursor, WORD physicalButton);
|
||||
|
||||
/**
|
||||
* Applies common modifications to Wintab context.
|
||||
* \param lc: Wintab context to modify.
|
||||
*/
|
||||
static void modifyContext(LOGCONTEXT &lc);
|
||||
|
||||
/**
|
||||
* Extracts tablet and system coordinates from Wintab context.
|
||||
* \param lc: Wintab context to extract coordinates from.
|
||||
* \param tablet: Tablet coordinates.
|
||||
* \param system: System coordinates.
|
||||
*/
|
||||
static void extractCoordinates(LOGCONTEXT &lc, Coord &tablet, Coord &system);
|
||||
|
||||
void printContextInfo();
|
||||
};
|
@@ -420,6 +420,11 @@ void GHOST_XrContext::getExtensionsToEnable(
|
||||
r_ext_names.push_back(gpu_binding);
|
||||
}
|
||||
|
||||
#if defined(WITH_GL_EGL)
|
||||
assert(openxr_extension_is_available(m_oxr->extensions, XR_MNDX_EGL_ENABLE_EXTENSION_NAME));
|
||||
r_ext_names.push_back(XR_MNDX_EGL_ENABLE_EXTENSION_NAME);
|
||||
#endif
|
||||
|
||||
for (const std::string_view &ext : try_ext) {
|
||||
if (openxr_extension_is_available(m_oxr->extensions, ext)) {
|
||||
r_ext_names.push_back(ext.data());
|
||||
|
@@ -22,7 +22,9 @@
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
#if defined(WITH_GHOST_X11)
|
||||
#if defined(WITH_GL_EGL)
|
||||
# include "GHOST_ContextEGL.h"
|
||||
#elif defined(WITH_GHOST_X11)
|
||||
# include "GHOST_ContextGLX.h"
|
||||
#elif defined(WIN32)
|
||||
# include "GHOST_ContextD3D.h"
|
||||
@@ -66,7 +68,9 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
XrSystemId system_id,
|
||||
std::string *r_requirement_info) const override
|
||||
{
|
||||
#if defined(WITH_GHOST_X11)
|
||||
#if defined(WITH_GL_EGL)
|
||||
GHOST_ContextEGL &ctx_gl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
|
||||
#elif defined(WITH_GHOST_X11)
|
||||
GHOST_ContextGLX &ctx_gl = static_cast<GHOST_ContextGLX &>(ghost_ctx);
|
||||
#else
|
||||
GHOST_ContextWGL &ctx_gl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
|
||||
@@ -106,6 +110,15 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
void initFromGhostContext(GHOST_Context &ghost_ctx) override
|
||||
{
|
||||
#if defined(WITH_GHOST_X11)
|
||||
# if defined(WITH_GL_EGL)
|
||||
GHOST_ContextEGL &ctx_egl = static_cast<GHOST_ContextEGL &>(ghost_ctx);
|
||||
|
||||
oxr_binding.egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
|
||||
oxr_binding.egl.getProcAddress = eglGetProcAddress;
|
||||
oxr_binding.egl.display = ctx_egl.getDisplay();
|
||||
oxr_binding.egl.config = ctx_egl.getConfig();
|
||||
oxr_binding.egl.context = ctx_egl.getContext();
|
||||
# else
|
||||
GHOST_ContextGLX &ctx_glx = static_cast<GHOST_ContextGLX &>(ghost_ctx);
|
||||
XVisualInfo *visual_info = glXGetVisualFromFBConfig(ctx_glx.m_display, ctx_glx.m_fbconfig);
|
||||
|
||||
@@ -117,6 +130,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding {
|
||||
oxr_binding.glx.visualid = visual_info->visualid;
|
||||
|
||||
XFree(visual_info);
|
||||
# endif
|
||||
#elif defined(WIN32)
|
||||
GHOST_ContextWGL &ctx_wgl = static_cast<GHOST_ContextWGL &>(ghost_ctx);
|
||||
|
||||
|
@@ -42,7 +42,13 @@
|
||||
# include <d3d12.h>
|
||||
#endif
|
||||
#ifdef WITH_GHOST_X11
|
||||
# include <GL/glxew.h>
|
||||
# ifdef WITH_GL_EGL
|
||||
/* TODO: Why do we have to create this typedef manually? */
|
||||
typedef void (*(*PFNEGLGETPROCADDRESSPROC)(const char *procname))(void);
|
||||
# include <GL/eglew.h>
|
||||
# else
|
||||
# include <GL/glxew.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <openxr/openxr.h>
|
||||
|
@@ -89,7 +89,7 @@ bool IK_QJacobianSolver::Setup(IK_QSegment *root, std::list<IK_QTask *> &tasks)
|
||||
if (num_dof == 0)
|
||||
return false;
|
||||
|
||||
// compute task id's and assing weights to task
|
||||
// compute task ids and assign weights to task
|
||||
int primary_size = 0, primary = 0;
|
||||
int secondary_size = 0, secondary = 0;
|
||||
double primary_weight = 0.0, secondary_weight = 0.0;
|
||||
@@ -237,7 +237,7 @@ void IK_QJacobianSolver::ConstrainPoleVector(IK_QSegment *root, std::list<IK_QTa
|
||||
|
||||
bool IK_QJacobianSolver::UpdateAngles(double &norm)
|
||||
{
|
||||
// assing each segment a unique id for the jacobian
|
||||
// assign each segment a unique id for the jacobian
|
||||
std::vector<IK_QSegment *>::iterator seg;
|
||||
IK_QSegment *qseg, *minseg = NULL;
|
||||
double minabsdelta = 1e10, absdelta;
|
||||
|
@@ -77,7 +77,7 @@ class scoped_array {
|
||||
|
||||
void reset(T* new_array) {
|
||||
if (sizeof(T)) {
|
||||
delete array_;
|
||||
delete[] array_;
|
||||
}
|
||||
array_ = new_array;
|
||||
}
|
||||
|
@@ -112,7 +112,7 @@ void MeshTopology::getEdgeVertexIndices(int edge_index, int *v1, int *v2) const
|
||||
|
||||
if (edge_index >= edges_.size()) {
|
||||
*v1 = -1;
|
||||
*v1 = -1;
|
||||
*v2 = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -31,9 +31,13 @@ typedef struct plConvexHull__ {
|
||||
plConvexHull plConvexHullCompute(float (*coords)[3], int count);
|
||||
void plConvexHullDelete(plConvexHull hull);
|
||||
int plConvexHullNumVertices(plConvexHull hull);
|
||||
int plConvexHullNumLoops(plConvexHull hull);
|
||||
int plConvexHullNumFaces(plConvexHull hull);
|
||||
void plConvexHullGetVertex(plConvexHull hull, int n, float coords[3], int *original_index);
|
||||
void plConvexHullGetLoop(plConvexHull hull, int n, int *v_from, int *v_to);
|
||||
int plConvexHullGetReversedLoopIndex(plConvexHull hull, int n);
|
||||
int plConvexHullGetFaceSize(plConvexHull hull, int n);
|
||||
void plConvexHullGetFaceLoops(plConvexHull hull, int n, int *loops);
|
||||
void plConvexHullGetFaceVertices(plConvexHull hull, int n, int *vertices);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -39,6 +39,12 @@ int plConvexHullNumVertices(plConvexHull hull)
|
||||
return computer->vertices.size();
|
||||
}
|
||||
|
||||
int plConvexHullNumLoops(plConvexHull hull)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
return computer->edges.size();
|
||||
}
|
||||
|
||||
int plConvexHullNumFaces(plConvexHull hull)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
@@ -55,6 +61,19 @@ void plConvexHullGetVertex(plConvexHull hull, int n, float coords[3], int *origi
|
||||
(*original_index) = computer->original_vertex_index[n];
|
||||
}
|
||||
|
||||
void plConvexHullGetLoop(plConvexHull hull, int n, int *v_from, int *v_to)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
(*v_from) = computer->edges[n].getSourceVertex();
|
||||
(*v_to) = computer->edges[n].getTargetVertex();
|
||||
}
|
||||
|
||||
int plConvexHullGetReversedLoopIndex(plConvexHull hull, int n)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
return computer->edges[n].getReverseEdge() - &computer->edges[0];
|
||||
}
|
||||
|
||||
int plConvexHullGetFaceSize(plConvexHull hull, int n)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
@@ -69,6 +88,19 @@ int plConvexHullGetFaceSize(plConvexHull hull, int n)
|
||||
return count;
|
||||
}
|
||||
|
||||
void plConvexHullGetFaceLoops(plConvexHull hull, int n, int *loops)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
const btConvexHullComputer::Edge *e_orig, *e;
|
||||
int count;
|
||||
|
||||
for (e_orig = &computer->edges[computer->faces[n]], e = e_orig, count = 0;
|
||||
count == 0 || e != e_orig;
|
||||
e = e->getNextEdgeOfFace(), count++) {
|
||||
loops[count] = e - &computer->edges[0];
|
||||
}
|
||||
}
|
||||
|
||||
void plConvexHullGetFaceVertices(plConvexHull hull, int n, int *vertices)
|
||||
{
|
||||
btConvexHullComputer *computer(reinterpret_cast<btConvexHullComputer *>(hull));
|
||||
|
Submodule release/datafiles/locale updated: 2cef4877ed...ab283053ab
Submodule release/scripts/addons updated: 27fe7f3a4f...ec07ed4c2e
@@ -49,16 +49,16 @@ def _initialize():
|
||||
|
||||
def paths():
|
||||
# RELEASE SCRIPTS: official scripts distributed in Blender releases
|
||||
addon_paths = _bpy.utils.script_paths("addons")
|
||||
addon_paths = _bpy.utils.script_paths(subdir="addons")
|
||||
|
||||
# CONTRIB SCRIPTS: good for testing but not official scripts yet
|
||||
# if folder addons_contrib/ exists, scripts in there will be loaded too
|
||||
addon_paths += _bpy.utils.script_paths("addons_contrib")
|
||||
addon_paths += _bpy.utils.script_paths(subdir="addons_contrib")
|
||||
|
||||
return addon_paths
|
||||
|
||||
|
||||
def modules_refresh(module_cache=addons_fake_modules):
|
||||
def modules_refresh(*, module_cache=addons_fake_modules):
|
||||
global error_encoding
|
||||
import os
|
||||
|
||||
@@ -203,9 +203,9 @@ def modules_refresh(module_cache=addons_fake_modules):
|
||||
del modules_stale
|
||||
|
||||
|
||||
def modules(module_cache=addons_fake_modules, *, refresh=True):
|
||||
def modules(*, module_cache=addons_fake_modules, refresh=True):
|
||||
if refresh or ((module_cache is addons_fake_modules) and modules._is_first):
|
||||
modules_refresh(module_cache)
|
||||
modules_refresh(module_cache=module_cache)
|
||||
modules._is_first = False
|
||||
|
||||
mod_list = list(module_cache.values())
|
||||
@@ -358,7 +358,8 @@ def enable(module_name, *, default_set=False, persistent=False, handle_error=Non
|
||||
except Exception as ex:
|
||||
# if the addon doesn't exist, don't print full traceback
|
||||
if type(ex) is ImportError and ex.name == module_name:
|
||||
print("addon not found:", repr(module_name))
|
||||
print("addon not loaded:", repr(module_name))
|
||||
print("cause:", str(ex))
|
||||
else:
|
||||
handle_error(ex)
|
||||
|
||||
@@ -512,7 +513,7 @@ def _blender_manual_url_prefix():
|
||||
return "https://docs.blender.org/manual/en/" + manual_version
|
||||
|
||||
|
||||
def module_bl_info(mod, info_basis=None):
|
||||
def module_bl_info(mod, *, info_basis=None):
|
||||
if info_basis is None:
|
||||
info_basis = {
|
||||
"name": "",
|
||||
|
@@ -134,7 +134,7 @@ def _disable(template_id, *, handle_error=None):
|
||||
print("\tapp_template_utils.disable", template_id)
|
||||
|
||||
|
||||
def import_from_path(path, ignore_not_found=False):
|
||||
def import_from_path(path, *, ignore_not_found=False):
|
||||
import os
|
||||
from importlib import import_module
|
||||
base_module, template_id = path.rsplit(os.sep, 2)[-2:]
|
||||
@@ -148,9 +148,9 @@ def import_from_path(path, ignore_not_found=False):
|
||||
raise ex
|
||||
|
||||
|
||||
def import_from_id(template_id, ignore_not_found=False):
|
||||
def import_from_id(template_id, *, ignore_not_found=False):
|
||||
import os
|
||||
path = next(iter(_bpy.utils.app_template_paths(template_id)), None)
|
||||
path = next(iter(_bpy.utils.app_template_paths(path=template_id)), None)
|
||||
if path is None:
|
||||
if ignore_not_found:
|
||||
return None
|
||||
@@ -163,7 +163,7 @@ def import_from_id(template_id, ignore_not_found=False):
|
||||
return import_from_path(path, ignore_not_found=ignore_not_found)
|
||||
|
||||
|
||||
def activate(template_id=None):
|
||||
def activate(*, template_id=None):
|
||||
template_id_prev = _app_template["id"]
|
||||
|
||||
# not needed but may as well avoids redundant
|
||||
@@ -190,4 +190,4 @@ def reset(*, reload_scripts=False):
|
||||
|
||||
# TODO reload_scripts
|
||||
|
||||
activate(template_id)
|
||||
activate(template_id=template_id)
|
||||
|
@@ -1572,7 +1572,7 @@ class I18n:
|
||||
if not os.path.isfile(dst):
|
||||
print("WARNING: trying to write as python code into {}, which is not a file! Aborting.".format(dst))
|
||||
return
|
||||
prev, txt, nxt, has_trans = self._parser_check_file(dst)
|
||||
prev, txt, nxt, _has_trans = self._parser_check_file(dst)
|
||||
if prev is None and nxt is None:
|
||||
print("WARNING: Looks like given python file {} has no auto-generated translations yet, will be added "
|
||||
"at the end of the file, you can move that section later if needed...".format(dst))
|
||||
|
@@ -71,7 +71,7 @@ def rtl_process_po(args, settings):
|
||||
po.write(kind="PO", dest=args.dst)
|
||||
|
||||
|
||||
def language_menu(args, settings):
|
||||
def language_menu(_args, settings):
|
||||
# 'DEFAULT' and en_US are always valid, fully-translated "languages"!
|
||||
stats = {"DEFAULT": 1.0, "en_US": 1.0}
|
||||
|
||||
|
@@ -84,10 +84,10 @@ def protect_format_seq(msg):
|
||||
# LRM = "\u200E"
|
||||
# RLM = "\u200F"
|
||||
LRE = "\u202A"
|
||||
RLE = "\u202B"
|
||||
# RLE = "\u202B"
|
||||
PDF = "\u202C"
|
||||
LRO = "\u202D"
|
||||
RLO = "\u202E"
|
||||
# RLO = "\u202E"
|
||||
# uctrl = {LRE, RLE, PDF, LRO, RLO}
|
||||
# Most likely incomplete, but seems to cover current needs.
|
||||
format_codes = set("tslfd")
|
||||
|
@@ -26,7 +26,7 @@ __all__ = (
|
||||
)
|
||||
|
||||
|
||||
def generate(context, space_type, use_fallback_keys=True, use_reset=True):
|
||||
def generate(context, space_type, *, use_fallback_keys=True, use_reset=True):
|
||||
"""
|
||||
Keymap for popup toolbar, currently generated each time.
|
||||
"""
|
||||
|
@@ -17,7 +17,7 @@
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
|
||||
def keyconfig_data_oskey_from_ctrl(keyconfig_data_src, filter_fn=None):
|
||||
def keyconfig_data_oskey_from_ctrl(keyconfig_data_src, *, filter_fn=None):
|
||||
keyconfig_data_dst = []
|
||||
for km_name, km_parms, km_items_data_src in keyconfig_data_src:
|
||||
km_items_data_dst = km_items_data_src.copy()
|
||||
@@ -61,4 +61,4 @@ def keyconfig_data_oskey_from_ctrl_for_macos(keyconfig_data_src):
|
||||
return False
|
||||
return True
|
||||
|
||||
return keyconfig_data_oskey_from_ctrl(keyconfig_data_src, filter_fn)
|
||||
return keyconfig_data_oskey_from_ctrl(keyconfig_data_src, filter_fn=filter_fn)
|
||||
|
@@ -19,7 +19,7 @@
|
||||
# <pep8-80 compliant>
|
||||
|
||||
|
||||
def url_prefill_from_blender(addon_info=None):
|
||||
def url_prefill_from_blender(*, addon_info=None):
|
||||
import bpy
|
||||
import gpu
|
||||
import struct
|
||||
|
@@ -56,7 +56,7 @@ def _getattr_bytes(var, attr):
|
||||
return var.path_resolve(attr, False).as_bytes()
|
||||
|
||||
|
||||
def abspath(path, start=None, library=None):
|
||||
def abspath(path, *, start=None, library=None):
|
||||
"""
|
||||
Returns the absolute path relative to the current blend file
|
||||
using the "//" prefix.
|
||||
@@ -92,7 +92,7 @@ def abspath(path, start=None, library=None):
|
||||
return path
|
||||
|
||||
|
||||
def relpath(path, start=None):
|
||||
def relpath(path, *, start=None):
|
||||
"""
|
||||
Returns the path relative to the current blend file using the "//" prefix.
|
||||
|
||||
@@ -134,7 +134,7 @@ def is_subdir(path, directory):
|
||||
return False
|
||||
|
||||
|
||||
def clean_name(name, replace="_"):
|
||||
def clean_name(name, *, replace="_"):
|
||||
"""
|
||||
Returns a name with characters replaced that
|
||||
may cause problems under various circumstances,
|
||||
@@ -311,7 +311,7 @@ def resolve_ncase(path):
|
||||
return ncase_path if found else path
|
||||
|
||||
|
||||
def ensure_ext(filepath, ext, case_sensitive=False):
|
||||
def ensure_ext(filepath, ext, *, case_sensitive=False):
|
||||
"""
|
||||
Return the path with the extension added if it is not already set.
|
||||
|
||||
@@ -332,7 +332,7 @@ def ensure_ext(filepath, ext, case_sensitive=False):
|
||||
return filepath + ext
|
||||
|
||||
|
||||
def module_names(path, recursive=False):
|
||||
def module_names(path, *, recursive=False):
|
||||
"""
|
||||
Return a list of modules which can be imported from *path*.
|
||||
|
||||
@@ -361,7 +361,7 @@ def module_names(path, recursive=False):
|
||||
if isfile(fullpath):
|
||||
modules.append((filename, fullpath))
|
||||
if recursive:
|
||||
for mod_name, mod_path in module_names(directory, True):
|
||||
for mod_name, mod_path in module_names(directory, recursive=True):
|
||||
modules.append(("%s.%s" % (filename, mod_name),
|
||||
mod_path,
|
||||
))
|
||||
|
@@ -81,7 +81,7 @@ _script_module_dirs = "startup", "modules"
|
||||
_is_factory_startup = _bpy.app.factory_startup
|
||||
|
||||
|
||||
def execfile(filepath, mod=None):
|
||||
def execfile(filepath, *, mod=None):
|
||||
"""
|
||||
Execute a file path as a Python script.
|
||||
|
||||
@@ -193,7 +193,7 @@ _global_loaded_modules = [] # store loaded module names for reloading.
|
||||
import bpy_types as _bpy_types # keep for comparisons, never ever reload this.
|
||||
|
||||
|
||||
def load_scripts(reload_scripts=False, refresh_scripts=False):
|
||||
def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
||||
"""
|
||||
Load scripts and run each modules register function.
|
||||
|
||||
@@ -357,7 +357,7 @@ def script_path_pref():
|
||||
return _os.path.normpath(path) if path else None
|
||||
|
||||
|
||||
def script_paths(subdir=None, user_pref=True, check_all=False, use_user=True):
|
||||
def script_paths(*, subdir=None, user_pref=True, check_all=False, use_user=True):
|
||||
"""
|
||||
Returns a list of valid script paths.
|
||||
|
||||
@@ -446,16 +446,16 @@ def refresh_script_paths():
|
||||
_sys_path_ensure_append(path)
|
||||
|
||||
|
||||
def app_template_paths(subdir=None):
|
||||
def app_template_paths(*, path=None):
|
||||
"""
|
||||
Returns valid application template paths.
|
||||
|
||||
:arg subdir: Optional subdir.
|
||||
:type subdir: string
|
||||
:arg path: Optional subdir.
|
||||
:type path: string
|
||||
:return: app template paths.
|
||||
:rtype: generator
|
||||
"""
|
||||
subdir_args = (subdir,) if subdir is not None else ()
|
||||
subdir_args = (path,) if path is not None else ()
|
||||
# Note: keep in sync with: Blender's 'BKE_appdir_app_template_any'.
|
||||
# Uses 'BLENDER_USER_SCRIPTS', 'BLENDER_SYSTEM_SCRIPTS'
|
||||
# ... in this case 'system' accounts for 'local' too.
|
||||
@@ -463,9 +463,9 @@ def app_template_paths(subdir=None):
|
||||
(_user_resource, "bl_app_templates_user"),
|
||||
(system_resource, "bl_app_templates_system"),
|
||||
):
|
||||
path = resource_fn('SCRIPTS', _os.path.join("startup", module_name, *subdir_args))
|
||||
if path and _os.path.isdir(path):
|
||||
yield path
|
||||
path_test = resource_fn('SCRIPTS', path=_os.path.join("startup", module_name, *subdir_args))
|
||||
if path_test and _os.path.isdir(path_test):
|
||||
yield path_test
|
||||
|
||||
|
||||
def preset_paths(subdir):
|
||||
@@ -478,7 +478,7 @@ def preset_paths(subdir):
|
||||
:rtype: list
|
||||
"""
|
||||
dirs = []
|
||||
for path in script_paths("presets", check_all=True):
|
||||
for path in script_paths(subdir="presets", check_all=True):
|
||||
directory = _os.path.join(path, subdir)
|
||||
if not directory.startswith(path):
|
||||
raise Exception("invalid subdir given %r" % subdir)
|
||||
@@ -532,7 +532,7 @@ def is_path_builtin(path):
|
||||
return False
|
||||
|
||||
|
||||
def smpte_from_seconds(time, fps=None, fps_base=None):
|
||||
def smpte_from_seconds(time, *, fps=None, fps_base=None):
|
||||
"""
|
||||
Returns an SMPTE formatted string from the *time*:
|
||||
``HH:MM:SS:FF``.
|
||||
@@ -552,7 +552,7 @@ def smpte_from_seconds(time, fps=None, fps_base=None):
|
||||
)
|
||||
|
||||
|
||||
def smpte_from_frame(frame, fps=None, fps_base=None):
|
||||
def smpte_from_frame(frame, *, fps=None, fps_base=None):
|
||||
"""
|
||||
Returns an SMPTE formatted string from the *frame*:
|
||||
``HH:MM:SS:FF``.
|
||||
@@ -585,7 +585,7 @@ def smpte_from_frame(frame, fps=None, fps_base=None):
|
||||
))
|
||||
|
||||
|
||||
def time_from_frame(frame, fps=None, fps_base=None):
|
||||
def time_from_frame(frame, *, fps=None, fps_base=None):
|
||||
"""
|
||||
Returns the time from a frame number .
|
||||
|
||||
@@ -610,7 +610,7 @@ def time_from_frame(frame, fps=None, fps_base=None):
|
||||
return timedelta(0, frame / fps)
|
||||
|
||||
|
||||
def time_to_frame(time, fps=None, fps_base=None):
|
||||
def time_to_frame(time, *, fps=None, fps_base=None):
|
||||
"""
|
||||
Returns a float frame number from a time given in seconds or
|
||||
as a datetime.timedelta object.
|
||||
@@ -639,7 +639,7 @@ def time_to_frame(time, fps=None, fps_base=None):
|
||||
return time * fps
|
||||
|
||||
|
||||
def preset_find(name, preset_path, display_name=False, ext=".py"):
|
||||
def preset_find(name, preset_path, *, display_name=False, ext=".py"):
|
||||
if not name:
|
||||
return None
|
||||
|
||||
@@ -676,7 +676,7 @@ def keyconfig_init():
|
||||
keyconfig_set(filepath)
|
||||
|
||||
|
||||
def keyconfig_set(filepath, report=None):
|
||||
def keyconfig_set(filepath, *, report=None):
|
||||
from os.path import basename, splitext
|
||||
|
||||
if _bpy.app.debug_python:
|
||||
@@ -712,14 +712,14 @@ def keyconfig_set(filepath, report=None):
|
||||
return True
|
||||
|
||||
|
||||
def user_resource(resource_type, path="", create=False):
|
||||
def user_resource(resource_type, *, path="", create=False):
|
||||
"""
|
||||
Return a user resource path (normally from the users home directory).
|
||||
|
||||
:arg type: Resource type in ['DATAFILES', 'CONFIG', 'SCRIPTS', 'AUTOSAVE'].
|
||||
:type type: string
|
||||
:arg subdir: Optional subdirectory.
|
||||
:type subdir: string
|
||||
:arg path: Optional subdirectory.
|
||||
:type path: string
|
||||
:arg create: Treat the path as a directory and create
|
||||
it if its not existing.
|
||||
:type create: boolean
|
||||
@@ -727,7 +727,7 @@ def user_resource(resource_type, path="", create=False):
|
||||
:rtype: string
|
||||
"""
|
||||
|
||||
target_path = _user_resource(resource_type, path)
|
||||
target_path = _user_resource(resource_type, path=path)
|
||||
|
||||
if create:
|
||||
# should always be true.
|
||||
|
@@ -447,7 +447,7 @@ def path_reference(
|
||||
"""
|
||||
import os
|
||||
is_relative = filepath.startswith("//")
|
||||
filepath_abs = bpy.path.abspath(filepath, base_src, library)
|
||||
filepath_abs = bpy.path.abspath(filepath, start=base_src, library=library)
|
||||
filepath_abs = os.path.normpath(filepath_abs)
|
||||
|
||||
if mode in {'ABSOLUTE', 'RELATIVE', 'STRIP'}:
|
||||
|
@@ -64,7 +64,7 @@ def region_2d_to_vector_3d(region, rv3d, coord):
|
||||
return view_vector
|
||||
|
||||
|
||||
def region_2d_to_origin_3d(region, rv3d, coord, clamp=None):
|
||||
def region_2d_to_origin_3d(region, rv3d, coord, *, clamp=None):
|
||||
"""
|
||||
Return the 3d view origin from the region relative 2d coords.
|
||||
|
||||
@@ -167,7 +167,7 @@ def region_2d_to_location_3d(region, rv3d, coord, depth_location):
|
||||
)[0]
|
||||
|
||||
|
||||
def location_3d_to_region_2d(region, rv3d, coord, default=None):
|
||||
def location_3d_to_region_2d(region, rv3d, coord, *, default=None):
|
||||
"""
|
||||
Return the *region* relative 2d location of a 3d position.
|
||||
|
||||
|
@@ -150,7 +150,11 @@ class Object(bpy_types.ID):
|
||||
class WindowManager(bpy_types.ID):
|
||||
__slots__ = ()
|
||||
|
||||
def popup_menu(self, draw_func, title="", icon='NONE'):
|
||||
def popup_menu(
|
||||
self, draw_func, *,
|
||||
title="",
|
||||
icon='NONE',
|
||||
):
|
||||
import bpy
|
||||
popup = self.popmenu_begin__internal(title, icon=icon)
|
||||
|
||||
@@ -176,7 +180,11 @@ class WindowManager(bpy_types.ID):
|
||||
finally:
|
||||
self.popover_end__internal(popup, keymap=keymap)
|
||||
|
||||
def popup_menu_pie(self, event, draw_func, title="", icon='NONE'):
|
||||
def popup_menu_pie(
|
||||
self, event, draw_func, *,
|
||||
title="",
|
||||
icon='NONE',
|
||||
):
|
||||
import bpy
|
||||
pie = self.piemenu_begin__internal(title, icon=icon, event=event)
|
||||
|
||||
@@ -392,7 +400,7 @@ class EditBone(StructRNA, _GenericBone, metaclass=StructMetaPropGroup):
|
||||
self.tail = self.head + vec
|
||||
self.roll = other.roll
|
||||
|
||||
def transform(self, matrix, scale=True, roll=True):
|
||||
def transform(self, matrix, *, scale=True, roll=True):
|
||||
"""
|
||||
Transform the the bones head, tail, roll and envelope
|
||||
(when the matrix has a scale component).
|
||||
@@ -739,7 +747,7 @@ class Operator(StructRNA, metaclass=RNAMeta):
|
||||
return delattr(properties, attr)
|
||||
return super().__delattr__(attr)
|
||||
|
||||
def as_keywords(self, ignore=()):
|
||||
def as_keywords(self, *, ignore=()):
|
||||
"""Return a copy of the properties as a dictionary"""
|
||||
ignore = ignore + ("rna_type",)
|
||||
return {attr: getattr(self, attr)
|
||||
|
@@ -86,7 +86,7 @@ def get_doc(obj):
|
||||
return result and RE_EMPTY_LINE.sub('', result.rstrip()) or ''
|
||||
|
||||
|
||||
def get_argspec(func, strip_self=True, doc=None, source=None):
|
||||
def get_argspec(func, *, strip_self=True, doc=None, source=None):
|
||||
"""Get argument specifications.
|
||||
|
||||
:param strip_self: strip `self` from argspec
|
||||
|
@@ -143,7 +143,7 @@ def complete(line):
|
||||
"""
|
||||
import inspect
|
||||
|
||||
def try_import(mod, only_modules=False):
|
||||
def try_import(mod, *, only_modules=False):
|
||||
|
||||
def is_importable(module, attr):
|
||||
if only_modules:
|
||||
@@ -184,7 +184,7 @@ def complete(line):
|
||||
mod = words[1].split('.')
|
||||
if len(mod) < 2:
|
||||
return filter_prefix(get_root_modules(), words[-1])
|
||||
completion_list = try_import('.'.join(mod[:-1]), True)
|
||||
completion_list = try_import('.'.join(mod[:-1]), only_modules=True)
|
||||
completion_list = ['.'.join(mod[:-1] + [el]) for el in completion_list]
|
||||
return filter_prefix(completion_list, words[-1])
|
||||
if len(words) >= 3 and words[0] == 'from':
|
||||
|
@@ -62,7 +62,7 @@ def complete_names(word, namespace):
|
||||
return sorted(set(completer.matches))
|
||||
|
||||
|
||||
def complete_indices(word, namespace, obj=None, base=None):
|
||||
def complete_indices(word, namespace, *, obj=None, base=None):
|
||||
"""Complete a list or dictionary with its indices:
|
||||
|
||||
* integer numbers for list
|
||||
@@ -117,7 +117,7 @@ def complete_indices(word, namespace, obj=None, base=None):
|
||||
return matches
|
||||
|
||||
|
||||
def complete(word, namespace, private=True):
|
||||
def complete(word, namespace, *, private=True):
|
||||
"""Complete word within a namespace with the standard rlcompleter
|
||||
module. Also supports index or key access [].
|
||||
|
||||
@@ -191,7 +191,7 @@ def complete(word, namespace, private=True):
|
||||
# an extra char '[', '(' or '.' will be added
|
||||
if hasattr(obj, '__getitem__') and not is_struct_seq(obj):
|
||||
# list or dictionary
|
||||
matches = complete_indices(word, namespace, obj)
|
||||
matches = complete_indices(word, namespace, obj=obj)
|
||||
elif hasattr(obj, '__call__'):
|
||||
# callables
|
||||
matches = [word + '(']
|
||||
|
@@ -87,7 +87,7 @@ def complete(line, cursor, namespace, private):
|
||||
matches.sort()
|
||||
else:
|
||||
from . import complete_namespace
|
||||
matches = complete_namespace.complete(word, namespace, private)
|
||||
matches = complete_namespace.complete(word, namespace, private=private)
|
||||
else:
|
||||
# for now we don't have completers for strings
|
||||
# TODO: add file auto completer for strings
|
||||
@@ -96,7 +96,7 @@ def complete(line, cursor, namespace, private):
|
||||
return matches, word
|
||||
|
||||
|
||||
def expand(line, cursor, namespace, private=True):
|
||||
def expand(line, cursor, namespace, *, private=True):
|
||||
"""This method is invoked when the user asks autocompletion,
|
||||
e.g. when Ctrl+Space is clicked.
|
||||
|
||||
@@ -150,5 +150,5 @@ def expand(line, cursor, namespace, private=True):
|
||||
line = line[:cursor] + prefix + line[cursor:]
|
||||
cursor += len(prefix.encode('utf-8'))
|
||||
if no_calltip and prefix.endswith('('):
|
||||
return expand(line, cursor, namespace, private)
|
||||
return expand(line, cursor, namespace, private=private)
|
||||
return line, cursor, scrollback
|
||||
|
@@ -21,7 +21,7 @@ __all__ = (
|
||||
)
|
||||
|
||||
|
||||
def batch_for_shader(shader, type, content, indices=None):
|
||||
def batch_for_shader(shader, type, content, *, indices=None):
|
||||
"""
|
||||
Return a batch already configured and compatible with the shader.
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
|
||||
def draw_circle_2d(position, color, radius, segments=32):
|
||||
def draw_circle_2d(position, color, radius, *, segments=32):
|
||||
"""
|
||||
Draw a circle.
|
||||
|
||||
|
@@ -240,7 +240,7 @@ def RKS_GEN_custom_props(_ksi, _context, ks, data):
|
||||
prop_path = '["%s"]' % bpy.utils.escape_identifier(cprop_name)
|
||||
try:
|
||||
rna_property = data.path_resolve(prop_path, False)
|
||||
except ValueError as ex:
|
||||
except ValueError:
|
||||
# This happens when a custom property is set to None. In that case it cannot
|
||||
# be converted to an FCurve-compatible value, so we can't keyframe it anyway.
|
||||
continue
|
||||
|
@@ -25,7 +25,7 @@ class NodeCategory:
|
||||
def poll(cls, _context):
|
||||
return True
|
||||
|
||||
def __init__(self, identifier, name, description="", items=None):
|
||||
def __init__(self, identifier, name, *, description="", items=None):
|
||||
self.identifier = identifier
|
||||
self.name = name
|
||||
self.description = description
|
||||
@@ -43,7 +43,7 @@ class NodeCategory:
|
||||
|
||||
|
||||
class NodeItem:
|
||||
def __init__(self, nodetype, label=None, settings=None, poll=None):
|
||||
def __init__(self, nodetype, *, label=None, settings=None, poll=None):
|
||||
|
||||
if settings is None:
|
||||
settings = {}
|
||||
@@ -92,7 +92,7 @@ class NodeItem:
|
||||
|
||||
|
||||
class NodeItemCustom:
|
||||
def __init__(self, poll=None, draw=None):
|
||||
def __init__(self, *, poll=None, draw=None):
|
||||
self.poll = poll
|
||||
self.draw = draw
|
||||
|
||||
|
@@ -271,7 +271,7 @@ def draw_filtered(display_keymaps, filter_type, filter_text, layout):
|
||||
# keymap items must match against all.
|
||||
kmi_test_type = []
|
||||
|
||||
# initialize? - so if a if a kmi has a MOD assigned it wont show up.
|
||||
# initialize? - so if a kmi has a MOD assigned it won't show up.
|
||||
# for kv in key_mod.values():
|
||||
# kmi_test_dict[kv] = {False}
|
||||
|
||||
|
@@ -15,16 +15,21 @@ if language == 'DEFAULT':
|
||||
language = os.getenv('LANG', '').split('.')[0]
|
||||
|
||||
LANG = {
|
||||
"ar_EG": "ar",
|
||||
"de_DE": "de",
|
||||
"ru_RU": "ru",
|
||||
"uk_UA": "uk",
|
||||
"es": "es",
|
||||
"fi_FI": "fi",
|
||||
"fr_FR": "fr",
|
||||
"id_ID": "id",
|
||||
"it_IT": "it",
|
||||
"ja_JP": "ja",
|
||||
"ko_KR": "ko",
|
||||
"pt_PT": "pt",
|
||||
"pt_BR": "pt",
|
||||
"ru_RU": "ru",
|
||||
"sk_SK": "sk",
|
||||
"sr_RS": "sr",
|
||||
"uk_UA": "uk",
|
||||
"vi_VN": "vi",
|
||||
"zh_CN": "zh-hans",
|
||||
"zh_TW": "zh-hant",
|
||||
@@ -58,6 +63,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.sndparticle_combined_export*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-combined-export"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_bottom*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-bottom"),
|
||||
("bpy.types.fluiddomainsettings.vector_scale_with_magnitude*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-scale-with-magnitude"),
|
||||
("bpy.types.movietrackingstabilization.use_2d_stabilization*", "movie_clip/tracking/clip/sidebar/stabilization/panel.html#bpy-types-movietrackingstabilization-use-2d-stabilization"),
|
||||
("bpy.types.spacespreadsheet.display_context_path_collapsed*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-display-context-path-collapsed"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_front*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-front"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_right*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-right"),
|
||||
@@ -169,6 +175,7 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylethicknessmodifier_calligraphy*", "render/freestyle/parameter_editor/line_style/modifiers/thickness/calligraphy.html#bpy-types-linestylethicknessmodifier-calligraphy"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"),
|
||||
("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"),
|
||||
("bpy.types.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"),
|
||||
("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_camera*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-camera"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_others*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-others"),
|
||||
@@ -180,6 +187,7 @@ url_manual_mapping = (
|
||||
("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"),
|
||||
("bpy.ops.outliner.collection_indirect_only_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-indirect-only-clear"),
|
||||
("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"),
|
||||
("bpy.types.editbone.bbone_handle_use_scale_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-start"),
|
||||
("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"),
|
||||
("bpy.types.fluiddomainsettings.cache_frame_start*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-start"),
|
||||
("bpy.types.fluiddomainsettings.cache_mesh_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-mesh-format"),
|
||||
@@ -200,6 +208,7 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.use_fill_holdout*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-use-fill-holdout"),
|
||||
("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"),
|
||||
("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"),
|
||||
("bpy.types.spaceclipeditor.use_grayscale_preview*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-grayscale-preview"),
|
||||
("bpy.types.spaceoutliner.use_filter_lib_override*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-lib-override"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_empty*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-empty"),
|
||||
("bpy.types.spaceoutliner.use_filter_object_light*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-light"),
|
||||
@@ -213,11 +222,13 @@ url_manual_mapping = (
|
||||
("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"),
|
||||
("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"),
|
||||
("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"),
|
||||
("bpy.types.editbone.bbone_handle_use_ease_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-start"),
|
||||
("bpy.types.fluiddomainsettings.color_ramp_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field"),
|
||||
("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"),
|
||||
("bpy.types.fluideffectorsettings.use_plane_init*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-use-plane-init"),
|
||||
("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"),
|
||||
("bpy.types.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"),
|
||||
("bpy.types.movieclipuser.use_render_undistorted*", "editors/clip/display/clip_display.html#bpy-types-movieclipuser-use-render-undistorted"),
|
||||
("bpy.types.movietrackingcamera.distortion_model*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-distortion-model"),
|
||||
("bpy.types.rendersettings.resolution_percentage*", "render/output/properties/dimensions.html#bpy-types-rendersettings-resolution-percentage"),
|
||||
("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"),
|
||||
@@ -236,6 +247,7 @@ url_manual_mapping = (
|
||||
("bpy.types.brushgpencilsettings.fill_threshold*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-threshold"),
|
||||
("bpy.types.clothsettings.vertex_group_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-pressure"),
|
||||
("bpy.types.cyclesmaterialsettings.displacement*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-displacement"),
|
||||
("bpy.types.editbone.bbone_handle_use_scale_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-end"),
|
||||
("bpy.types.fluiddomainsettings.adapt_threshold*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-threshold"),
|
||||
("bpy.types.fluiddomainsettings.cache_directory*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-directory"),
|
||||
("bpy.types.fluiddomainsettings.cache_frame_end*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-end"),
|
||||
@@ -272,6 +284,8 @@ url_manual_mapping = (
|
||||
("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"),
|
||||
("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"),
|
||||
("bpy.types.cyclesrendersettings.texture_limit*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-texture-limit"),
|
||||
("bpy.types.editbone.bbone_custom_handle_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-start"),
|
||||
("bpy.types.editbone.bbone_handle_use_ease_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-end"),
|
||||
("bpy.types.fluiddomainsettings.additional_res*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-additional-res"),
|
||||
("bpy.types.fluiddomainsettings.dissolve_speed*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-dissolve-speed"),
|
||||
("bpy.types.fluiddomainsettings.effector_group*", "physics/fluid/type/domain/collections.html#bpy-types-fluiddomainsettings-effector-group"),
|
||||
@@ -294,6 +308,7 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylegeometrymodifier_sampling*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/sampling.html#bpy-types-linestylegeometrymodifier-sampling"),
|
||||
("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"),
|
||||
("bpy.types.rendersettings.use_persistent_data*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-persistent-data"),
|
||||
("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"),
|
||||
("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"),
|
||||
("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"),
|
||||
("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"),
|
||||
@@ -314,6 +329,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluidflowsettings.velocity_factor*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-factor"),
|
||||
("bpy.types.fluidflowsettings.velocity_normal*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-normal"),
|
||||
("bpy.types.geometrynodealignrotationtovector*", "modeling/geometry_nodes/point/align_rotation_to_vector.html#bpy-types-geometrynodealignrotationtovector"),
|
||||
("bpy.types.geometrynodeattributevectorrotate*", "modeling/geometry_nodes/attribute/attribute_vector_rotate.html#bpy-types-geometrynodeattributevectorrotate"),
|
||||
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
|
||||
("bpy.types.materialgpencilstyle.stroke_style*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-stroke-style"),
|
||||
("bpy.types.objectlineart.use_crease_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-crease-override"),
|
||||
@@ -322,6 +338,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.use_file_extension*", "render/output/properties/output.html#bpy-types-rendersettings-use-file-extension"),
|
||||
("bpy.types.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"),
|
||||
("bpy.types.spaceclipeditor.annotation_source*", "movie_clip/tracking/clip/sidebar/annotation.html#bpy-types-spaceclipeditor-annotation-source"),
|
||||
("bpy.types.spaceclipeditor.show_blue_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-blue-channel"),
|
||||
("bpy.types.spaceoutliner.use_filter_children*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-children"),
|
||||
("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"),
|
||||
("bpy.types.spacesequenceeditor.show_metadata*", "video_editing/preview/introduction.html#bpy-types-spacesequenceeditor-show-metadata"),
|
||||
@@ -340,6 +357,8 @@ url_manual_mapping = (
|
||||
("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"),
|
||||
("bpy.types.cyclesobjectsettings.dicing_rate*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-dicing-rate"),
|
||||
("bpy.types.cyclesrendersettings.use_fast_gi*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-use-fast-gi"),
|
||||
("bpy.types.editbone.bbone_custom_handle_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-end"),
|
||||
("bpy.types.editbone.bbone_handle_type_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-start"),
|
||||
("bpy.types.fluiddomainsettings.adapt_margin*", "physics/fluid/type/domain/gas/adaptive_domain.html#bpy-types-fluiddomainsettings-adapt-margin"),
|
||||
("bpy.types.fluiddomainsettings.burning_rate*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-burning-rate"),
|
||||
("bpy.types.fluiddomainsettings.guide_parent*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-parent"),
|
||||
@@ -360,6 +379,8 @@ url_manual_mapping = (
|
||||
("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"),
|
||||
("bpy.types.rendersettings.use_bake_multires*", "render/cycles/baking.html#bpy-types-rendersettings-use-bake-multires"),
|
||||
("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"),
|
||||
("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"),
|
||||
("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"),
|
||||
("bpy.types.spacesequenceeditor.overlay_type*", "video_editing/preview/sidebar.html#bpy-types-spacesequenceeditor-overlay-type"),
|
||||
("bpy.types.spacesequenceeditor.show_fcurves*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-fcurves"),
|
||||
("bpy.types.spaceuveditor.sticky_select_mode*", "editors/uv/selecting.html#bpy-types-spaceuveditor-sticky-select-mode"),
|
||||
@@ -436,6 +457,8 @@ url_manual_mapping = (
|
||||
("bpy.types.colormanagedviewsettings.gamma*", "render/color_management.html#bpy-types-colormanagedviewsettings-gamma"),
|
||||
("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"),
|
||||
("bpy.types.curve.bevel_factor_mapping_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-end"),
|
||||
("bpy.types.editbone.bbone_handle_type_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-end"),
|
||||
("bpy.types.editbone.use_endroll_as_inroll*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-endroll-as-inroll"),
|
||||
("bpy.types.fluiddomainsettings.cache_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-type"),
|
||||
("bpy.types.fluiddomainsettings.flip_ratio*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-flip-ratio"),
|
||||
("bpy.types.fluiddomainsettings.guide_beta*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-beta"),
|
||||
@@ -448,6 +471,7 @@ url_manual_mapping = (
|
||||
("bpy.types.geometrynodeattributecolorramp*", "modeling/geometry_nodes/attribute/attribute_color_ramp.html#bpy-types-geometrynodeattributecolorramp"),
|
||||
("bpy.types.geometrynodeattributeproximity*", "modeling/geometry_nodes/attribute/attribute_proximity.html#bpy-types-geometrynodeattributeproximity"),
|
||||
("bpy.types.geometrynodeattributerandomize*", "modeling/geometry_nodes/attribute/attribute_randomize.html#bpy-types-geometrynodeattributerandomize"),
|
||||
("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"),
|
||||
("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"),
|
||||
("bpy.types.imageformatsettings.color_mode*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-mode"),
|
||||
("bpy.types.linestyle*modifier_alongstroke*", "render/freestyle/parameter_editor/line_style/modifiers/color/along_stroke.html#bpy-types-linestyle-modifier-alongstroke"),
|
||||
@@ -466,6 +490,7 @@ url_manual_mapping = (
|
||||
("bpy.types.rendersettings.use_compositing*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-compositing"),
|
||||
("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"),
|
||||
("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"),
|
||||
("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-lock-selection"),
|
||||
("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"),
|
||||
("bpy.types.spaceoutliner.show_mode_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-mode-column"),
|
||||
("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"),
|
||||
@@ -491,6 +516,7 @@ url_manual_mapping = (
|
||||
("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"),
|
||||
("bpy.types.compositornodecolorcorrection*", "compositing/types/color/color_correction.html#bpy-types-compositornodecolorcorrection"),
|
||||
("bpy.types.compositornodemoviedistortion*", "compositing/types/distort/movie_distortion.html#bpy-types-compositornodemoviedistortion"),
|
||||
("bpy.types.editbone.use_inherit_rotation*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-inherit-rotation"),
|
||||
("bpy.types.fluiddomainsettings.use_guide*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-use-guide"),
|
||||
("bpy.types.fluiddomainsettings.use_noise*", "physics/fluid/type/domain/gas/noise.html#bpy-types-fluiddomainsettings-use-noise"),
|
||||
("bpy.types.fluiddomainsettings.use_slice*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-use-slice"),
|
||||
@@ -501,7 +527,9 @@ url_manual_mapping = (
|
||||
("bpy.types.fluidflowsettings.temperature*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-temperature"),
|
||||
("bpy.types.fluidflowsettings.use_texture*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-texture"),
|
||||
("bpy.types.fmodifierenvelopecontrolpoint*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifierenvelopecontrolpoint"),
|
||||
("bpy.types.geometrynodeattributecurvemap*", "modeling/geometry_nodes/attribute/attribute_curve_map.html#bpy-types-geometrynodeattributecurvemap"),
|
||||
("bpy.types.geometrynodeattributemaprange*", "modeling/geometry_nodes/attribute/attribute_map_range.html#bpy-types-geometrynodeattributemaprange"),
|
||||
("bpy.types.geometrynodeattributetransfer*", "modeling/geometry_nodes/attribute/attribute_transfer.html#bpy-types-geometrynodeattributetransfer"),
|
||||
("bpy.types.layercollection.hide_viewport*", "editors/outliner/interface.html#bpy-types-layercollection-hide-viewport"),
|
||||
("bpy.types.layercollection.indirect_only*", "editors/outliner/interface.html#bpy-types-layercollection-indirect-only"),
|
||||
("bpy.types.material.use_sss_translucency*", "render/eevee/materials/settings.html#bpy-types-material-use-sss-translucency"),
|
||||
@@ -546,6 +574,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.use_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-mesh"),
|
||||
("bpy.types.geometrynodeattributecompare*", "modeling/geometry_nodes/attribute/attribute_compare.html#bpy-types-geometrynodeattributecompare"),
|
||||
("bpy.types.geometrynodeattributeconvert*", "modeling/geometry_nodes/attribute/attribute_convert.html#bpy-types-geometrynodeattributeconvert"),
|
||||
("bpy.types.geometrynodeselectbymaterial*", "modeling/geometry_nodes/material/select_by_material.html#bpy-types-geometrynodeselectbymaterial"),
|
||||
("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"),
|
||||
("bpy.types.materialgpencilstyle.pattern*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-pattern"),
|
||||
("bpy.types.materialgpencilstyle.texture*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-texture"),
|
||||
@@ -595,10 +624,12 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodedistancematte*", "compositing/types/matte/distance_key.html#bpy-types-compositornodedistancematte"),
|
||||
("bpy.types.compositornodesetalpha.mode*", "compositing/types/converter/set_alpha.html#bpy-types-compositornodesetalpha-mode"),
|
||||
("bpy.types.dopesheet.use_filter_invert*", "editors/graph_editor/channels.html#bpy-types-dopesheet-use-filter-invert"),
|
||||
("bpy.types.editbone.use_local_location*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-local-location"),
|
||||
("bpy.types.fluiddomainsettings.gravity*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-gravity"),
|
||||
("bpy.types.fluidflowsettings.flow_type*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-flow-type"),
|
||||
("bpy.types.fluidflowsettings.subframes*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-subframes"),
|
||||
("bpy.types.geometrynodeattributeremove*", "modeling/geometry_nodes/attribute/attribute_remove.html#bpy-types-geometrynodeattributeremove"),
|
||||
("bpy.types.geometrynodematerialreplace*", "modeling/geometry_nodes/material/replace.html#bpy-types-geometrynodematerialreplace"),
|
||||
("bpy.types.geometrynodepointdistribute*", "modeling/geometry_nodes/point/point_distribute.html#bpy-types-geometrynodepointdistribute"),
|
||||
("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"),
|
||||
("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"),
|
||||
@@ -621,6 +652,7 @@ url_manual_mapping = (
|
||||
("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/sidebar.html#bpy-types-sequenceeditor-show-overlay"),
|
||||
("bpy.types.sequenceeditor.use_prefetch*", "video_editing/preview/sidebar.html#bpy-types-sequenceeditor-use-prefetch"),
|
||||
("bpy.types.soundsequence.show_waveform*", "video_editing/sequencer/sidebar/strip.html#bpy-types-soundsequence-show-waveform"),
|
||||
("bpy.types.spaceclipeditor.show_stable*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-stable"),
|
||||
("bpy.types.spaceoutliner.filter_invert*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-invert"),
|
||||
("bpy.types.spacetexteditor.show_margin*", "editors/text_editor.html#bpy-types-spacetexteditor-show-margin"),
|
||||
("bpy.types.spline.radius_interpolation*", "modeling/curves/properties/active_spline.html#bpy-types-spline-radius-interpolation"),
|
||||
@@ -647,6 +679,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.view3d.localview_remove_from*", "editors/3dview/navigate/local_view.html#bpy-ops-view3d-localview-remove-from"),
|
||||
("bpy.types.animdata.action_blend_type*", "editors/nla/sidebar.html#bpy-types-animdata-action-blend-type"),
|
||||
("bpy.types.bakesettings.use_pass_emit*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-emit"),
|
||||
("bpy.types.bone.use_envelope_multiply*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-envelope-multiply"),
|
||||
("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"),
|
||||
("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"),
|
||||
("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"),
|
||||
@@ -662,6 +695,9 @@ url_manual_mapping = (
|
||||
("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifierfunctiongenerator"),
|
||||
("bpy.types.geometrynodeattributeclamp*", "modeling/geometry_nodes/attribute/attribute_clamp.html#bpy-types-geometrynodeattributeclamp"),
|
||||
("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/collection_info.html#bpy-types-geometrynodecollectioninfo"),
|
||||
("bpy.types.geometrynodecurvesubdivide*", "modeling/geometry_nodes/curve/curve_subdivide.html#bpy-types-geometrynodecurvesubdivide"),
|
||||
("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"),
|
||||
("bpy.types.geometrynodematerialassign*", "modeling/geometry_nodes/material/assign.html#bpy-types-geometrynodematerialassign"),
|
||||
("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/volume/points_to_volume.html#bpy-types-geometrynodepointstovolume"),
|
||||
("bpy.types.geometrynodepointtranslate*", "modeling/geometry_nodes/point/point_translate.html#bpy-types-geometrynodepointtranslate"),
|
||||
("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"),
|
||||
@@ -721,13 +757,17 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodesplitviewer*", "compositing/types/output/split_viewer.html#bpy-types-compositornodesplitviewer"),
|
||||
("bpy.types.curve.render_resolution_u*", "modeling/curves/properties/shape.html#bpy-types-curve-render-resolution-u"),
|
||||
("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"),
|
||||
("bpy.types.editbone.use_scale_easing*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-use-scale-easing"),
|
||||
("bpy.types.fluiddomainsettings.alpha*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-alpha"),
|
||||
("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"),
|
||||
("bpy.types.geometrynodeattributefill*", "modeling/geometry_nodes/attribute/attribute_fill.html#bpy-types-geometrynodeattributefill"),
|
||||
("bpy.types.geometrynodeattributemath*", "modeling/geometry_nodes/attribute/attribute_math.html#bpy-types-geometrynodeattributemath"),
|
||||
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
||||
("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"),
|
||||
("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"),
|
||||
("bpy.types.geometrynodepointinstance*", "modeling/geometry_nodes/point/point_instance.html#bpy-types-geometrynodepointinstance"),
|
||||
("bpy.types.geometrynodepointseparate*", "modeling/geometry_nodes/point/point_separate.html#bpy-types-geometrynodepointseparate"),
|
||||
("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"),
|
||||
("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"),
|
||||
("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-flip"),
|
||||
("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/properties.html#bpy-types-materialgpencilstyle-mode"),
|
||||
@@ -746,6 +786,7 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodebsdftranslucent*", "render/shader_nodes/shader/translucent.html#bpy-types-shadernodebsdftranslucent"),
|
||||
("bpy.types.shadernodebsdftransparent*", "render/shader_nodes/shader/transparent.html#bpy-types-shadernodebsdftransparent"),
|
||||
("bpy.types.shadernodevectortransform*", "render/shader_nodes/vector/transform.html#bpy-types-shadernodevectortransform"),
|
||||
("bpy.types.spaceclipeditor.show_grid*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-grid"),
|
||||
("bpy.types.spaceoutliner.filter_text*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-text"),
|
||||
("bpy.types.spacetexteditor.find_text*", "editors/text_editor.html#bpy-types-spacetexteditor-find-text"),
|
||||
("bpy.types.spacetexteditor.font_size*", "editors/text_editor.html#bpy-types-spacetexteditor-font-size"),
|
||||
@@ -775,11 +816,12 @@ url_manual_mapping = (
|
||||
("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"),
|
||||
("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"),
|
||||
("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"),
|
||||
("bpy.ops.sequencer.crossfade_sounds*", "video_editing/sequencer/strips/transitions/cross.html#bpy-ops-sequencer-crossfade-sounds"),
|
||||
("bpy.ops.sequencer.crossfade_sounds*", "video_editing/sequencer/strips/transitions/sound_crossfade.html#bpy-ops-sequencer-crossfade-sounds"),
|
||||
("bpy.ops.sequencer.export_subtitles*", "video_editing/preview/introduction.html#bpy-ops-sequencer-export-subtitles"),
|
||||
("bpy.ops.transform.edge_bevelweight*", "modeling/meshes/editing/edge/edge_data.html#bpy-ops-transform-edge-bevelweight"),
|
||||
("bpy.ops.wm.previews_batch_generate*", "files/blend/previews.html#bpy-ops-wm-previews-batch-generate"),
|
||||
("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"),
|
||||
("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"),
|
||||
("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"),
|
||||
("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"),
|
||||
("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"),
|
||||
@@ -801,6 +843,7 @@ url_manual_mapping = (
|
||||
("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"),
|
||||
("bpy.types.functionnodefloatcompare*", "modeling/geometry_nodes/utilities/float_compare.html#bpy-types-functionnodefloatcompare"),
|
||||
("bpy.types.geometrynodeattributemix*", "modeling/geometry_nodes/attribute/attribute_mix.html#bpy-types-geometrynodeattributemix"),
|
||||
("bpy.types.geometrynodecurvereverse*", "modeling/geometry_nodes/curve/curve_reverse.html#bpy-types-geometrynodecurvereverse"),
|
||||
("bpy.types.geometrynodejoingeometry*", "modeling/geometry_nodes/geometry/join_geometry.html#bpy-types-geometrynodejoingeometry"),
|
||||
("bpy.types.geometrynodemeshcylinder*", "modeling/geometry_nodes/mesh_primitives/cylinder.html#bpy-types-geometrynodemeshcylinder"),
|
||||
("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh_primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"),
|
||||
@@ -810,6 +853,7 @@ url_manual_mapping = (
|
||||
("bpy.types.linestyle*modifier_noise*", "render/freestyle/parameter_editor/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"),
|
||||
("bpy.types.maintainvolumeconstraint*", "animation/constraints/transform/maintain_volume.html#bpy-types-maintainvolumeconstraint"),
|
||||
("bpy.types.mesh.use_mirror_topology*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-topology"),
|
||||
("bpy.types.movieclip.display_aspect*", "editors/clip/display/clip_display.html#bpy-types-movieclip-display-aspect"),
|
||||
("bpy.types.nodesocketinterface.name*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-name"),
|
||||
("bpy.types.particleinstancemodifier*", "modeling/modifiers/physics/particle_instance.html#bpy-types-particleinstancemodifier"),
|
||||
("bpy.types.sequencetransform.offset*", "video_editing/sequencer/sidebar/strip.html#bpy-types-sequencetransform-offset"),
|
||||
@@ -834,6 +878,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.curve.match_texture_space*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-ops-curve-match-texture-space"),
|
||||
("bpy.ops.font.text_paste_from_file*", "modeling/texts/editing.html#bpy-ops-font-text-paste-from-file"),
|
||||
("bpy.ops.gpencil.frame_clean_loose*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-frame-clean-loose"),
|
||||
("bpy.ops.mask.primitive_circle_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-circle-add"),
|
||||
("bpy.ops.mask.primitive_square_add*", "movie_clip/masking/scurve.html#bpy-ops-mask-primitive-square-add"),
|
||||
("bpy.ops.mesh.primitive_circle_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-circle-add"),
|
||||
("bpy.ops.mesh.primitive_monkey_add*", "modeling/meshes/primitives.html#bpy-ops-mesh-primitive-monkey-add"),
|
||||
("bpy.ops.mesh.select_face_by_sides*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-face-by-sides"),
|
||||
@@ -845,8 +891,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.render.play-rendered-anim*", "render/output/animation_player.html#bpy-ops-render-play-rendered-anim"),
|
||||
("bpy.ops.scene.blenderkit_download*", "addons/3d_view/blenderkit.html#bpy-ops-scene-blenderkit-download"),
|
||||
("bpy.ops.sculpt.set_pivot_position*", "sculpt_paint/sculpting/editing/sculpt.html#bpy-ops-sculpt-set-pivot-position"),
|
||||
("bpy.ops.sequencer.image_strip_add*", "video_editing/sequencer/strips/movie_image.html#bpy-ops-sequencer-image-strip-add"),
|
||||
("bpy.ops.sequencer.movie_strip_add*", "video_editing/sequencer/strips/movie_image.html#bpy-ops-sequencer-movie-strip-add"),
|
||||
("bpy.ops.sequencer.image_strip_add*", "video_editing/sequencer/strips/image.html#bpy-ops-sequencer-image-strip-add"),
|
||||
("bpy.ops.sequencer.movie_strip_add*", "video_editing/sequencer/strips/movie.html#bpy-ops-sequencer-movie-strip-add"),
|
||||
("bpy.ops.sequencer.reassign_inputs*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reassign-inputs"),
|
||||
("bpy.ops.sequencer.sound_strip_add*", "video_editing/sequencer/strips/sound.html#bpy-ops-sequencer-sound-strip-add"),
|
||||
("bpy.ops.ui.remove_override_button*", "files/linked_libraries/library_overrides.html#bpy-ops-ui-remove-override-button"),
|
||||
@@ -870,11 +916,18 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodetranslate*", "compositing/types/distort/translate.html#bpy-types-compositornodetranslate"),
|
||||
("bpy.types.constraint.target_space*", "animation/constraints/interface/common.html#bpy-types-constraint-target-space"),
|
||||
("bpy.types.curve.use_deform_bounds*", "modeling/curves/properties/shape.html#bpy-types-curve-use-deform-bounds"),
|
||||
("bpy.types.editbone.bbone_curveinx*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinx"),
|
||||
("bpy.types.editbone.bbone_curveinz*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-curveinz"),
|
||||
("bpy.types.editbone.bbone_scaleout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scaleout"),
|
||||
("bpy.types.editbone.bbone_segments*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-segments"),
|
||||
("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"),
|
||||
("bpy.types.functionnodebooleanmath*", "modeling/geometry_nodes/utilities/boolean_math.html#bpy-types-functionnodebooleanmath"),
|
||||
("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/string.html#bpy-types-functionnodeinputstring"),
|
||||
("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/vector.html#bpy-types-functionnodeinputvector"),
|
||||
("bpy.types.functionnoderandomfloat*", "modeling/geometry_nodes/input/random_float.html#bpy-types-functionnoderandomfloat"),
|
||||
("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/curve_length.html#bpy-types-geometrynodecurvelength"),
|
||||
("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"),
|
||||
("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/curve/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"),
|
||||
("bpy.types.geometrynodepointrotate*", "modeling/geometry_nodes/point/point_rotate.html#bpy-types-geometrynodepointrotate"),
|
||||
("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"),
|
||||
("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"),
|
||||
@@ -938,6 +991,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.view3d.blenderkit_search*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-search"),
|
||||
("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"),
|
||||
("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"),
|
||||
("bpy.types.bone.envelope_distance*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-distance"),
|
||||
("bpy.types.brightcontrastmodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-brightcontrastmodifier"),
|
||||
("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"),
|
||||
("bpy.types.brush.pose_deform_type*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-deform-type"),
|
||||
@@ -965,6 +1019,11 @@ url_manual_mapping = (
|
||||
("bpy.types.curve.bevel_resolution*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-resolution"),
|
||||
("bpy.types.cyclesmaterialsettings*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings"),
|
||||
("bpy.types.dopesheet.show_summary*", "editors/dope_sheet/introduction.html#bpy-types-dopesheet-show-summary"),
|
||||
("bpy.types.editbone.bbone_easeout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easeout"),
|
||||
("bpy.types.editbone.bbone_rollout*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollout"),
|
||||
("bpy.types.editbone.bbone_scalein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-scalein"),
|
||||
("bpy.types.editbone.inherit_scale*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-inherit-scale"),
|
||||
("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"),
|
||||
("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"),
|
||||
("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/circle.html#bpy-types-geometrynodemeshcircle"),
|
||||
("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"),
|
||||
@@ -1064,6 +1123,8 @@ url_manual_mapping = (
|
||||
("bpy.types.dampedtrackconstraint*", "animation/constraints/tracking/damped_track.html#bpy-types-dampedtrackconstraint"),
|
||||
("bpy.types.distortednoisetexture*", "render/materials/legacy_textures/types/distorted_noise.html#bpy-types-distortednoisetexture"),
|
||||
("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"),
|
||||
("bpy.types.editbone.bbone_easein*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-easein"),
|
||||
("bpy.types.editbone.bbone_rollin*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-rollin"),
|
||||
("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"),
|
||||
("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"),
|
||||
("bpy.types.geometrynodeedgesplit*", "modeling/geometry_nodes/mesh/edge_split.html#bpy-types-geometrynodeedgesplit"),
|
||||
@@ -1121,6 +1182,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.spreadsheet.toggle_pin*", "editors/spreadsheet.html#bpy-ops-spreadsheet-toggle-pin"),
|
||||
("bpy.ops.uv.follow_active_quads*", "modeling/meshes/editing/uv.html#bpy-ops-uv-follow-active-quads"),
|
||||
("bpy.types.arraygpencilmodifier*", "grease_pencil/modifiers/generate/array.html#bpy-types-arraygpencilmodifier"),
|
||||
("bpy.types.bone.envelope_weight*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-weight"),
|
||||
("bpy.types.brush.use_persistent*", "sculpt_paint/sculpting/tools/layer.html#bpy-types-brush-use-persistent"),
|
||||
("bpy.types.buildgpencilmodifier*", "grease_pencil/modifiers/generate/build.html#bpy-types-buildgpencilmodifier"),
|
||||
("bpy.types.colorbalancemodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-colorbalancemodifier"),
|
||||
@@ -1139,6 +1201,7 @@ url_manual_mapping = (
|
||||
("bpy.types.curve.use_path_clamp*", "modeling/curves/properties/path_animation.html#bpy-types-curve-use-path-clamp"),
|
||||
("bpy.types.datatransfermodifier*", "modeling/modifiers/modify/data_transfer.html#bpy-types-datatransfermodifier"),
|
||||
("bpy.types.dynamicpaintmodifier*", "physics/dynamic_paint/index.html#bpy-types-dynamicpaintmodifier"),
|
||||
("bpy.types.editbone.use_connect*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-connect"),
|
||||
("bpy.types.ffmpegsettings.audio*", "render/output/properties/output.html#bpy-types-ffmpegsettings-audio"),
|
||||
("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"),
|
||||
("bpy.types.gaussianblursequence*", "video_editing/sequencer/strips/effects/blur.html#bpy-types-gaussianblursequence"),
|
||||
@@ -1173,6 +1236,7 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodewavelength*", "render/shader_nodes/converter/wavelength.html#bpy-types-shadernodewavelength"),
|
||||
("bpy.types.shrinkwrapconstraint*", "animation/constraints/relationship/shrinkwrap.html#bpy-types-shrinkwrapconstraint"),
|
||||
("bpy.types.simpledeformmodifier*", "modeling/modifiers/deform/simple_deform.html#bpy-types-simpledeformmodifier"),
|
||||
("bpy.types.spaceclipeditor.show*", "editors/clip/display/index.html#bpy-types-spaceclipeditor-show"),
|
||||
("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"),
|
||||
("bpy.types.speedcontrolsequence*", "video_editing/sequencer/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"),
|
||||
("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"),
|
||||
@@ -1251,6 +1315,7 @@ url_manual_mapping = (
|
||||
("bpy.types.cyclesworldsettings*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings"),
|
||||
("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"),
|
||||
("bpy.types.geometrynodeboolean*", "modeling/geometry_nodes/mesh/boolean.html#bpy-types-geometrynodeboolean"),
|
||||
("bpy.types.geometrynoderaycast*", "modeling/geometry_nodes/geometry/raycast.html#bpy-types-geometrynoderaycast"),
|
||||
("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"),
|
||||
("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"),
|
||||
("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"),
|
||||
@@ -1259,6 +1324,7 @@ url_manual_mapping = (
|
||||
("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"),
|
||||
("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"),
|
||||
("bpy.types.particledupliweight*", "physics/particles/emitter/vertex_groups.html#bpy-types-particledupliweight"),
|
||||
("bpy.types.posebone.bone_group*", "animation/armatures/bones/properties/relations.html#bpy-types-posebone-bone-group"),
|
||||
("bpy.types.poseboneconstraints*", "animation/armatures/posing/bone_constraints/index.html#bpy-types-poseboneconstraints"),
|
||||
("bpy.types.rigidbodyconstraint*", "physics/rigid_body/constraints/index.html#bpy-types-rigidbodyconstraint"),
|
||||
("bpy.types.rigifyarmaturelayer*", "addons/rigging/rigify/metarigs.html#bpy-types-rigifyarmaturelayer"),
|
||||
@@ -1356,7 +1422,8 @@ url_manual_mapping = (
|
||||
("bpy.types.curvepaintsettings*", "modeling/curves/tools/draw.html#bpy-types-curvepaintsettings"),
|
||||
("bpy.types.fmodifiergenerator*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifiergenerator"),
|
||||
("bpy.types.freestylelinestyle*", "render/freestyle/parameter_editor/line_style/index.html#bpy-types-freestylelinestyle"),
|
||||
("bpy.types.gammacrosssequence*", "video_editing/sequencer/strips/transitions/cross.html#bpy-types-gammacrosssequence"),
|
||||
("bpy.types.gammacrosssequence*", "video_editing/sequencer/strips/transitions/gamma_cross.html#bpy-types-gammacrosssequence"),
|
||||
("bpy.types.geometrynodeswitch*", "modeling/geometry_nodes/utilities/switch.html#bpy-types-geometrynodeswitch"),
|
||||
("bpy.types.gpencilsculptguide*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide"),
|
||||
("bpy.types.huecorrectmodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-huecorrectmodifier"),
|
||||
("bpy.types.imagepaint.stencil*", "sculpt_paint/texture_paint/tool_settings/mask.html#bpy-types-imagepaint-stencil"),
|
||||
@@ -1378,7 +1445,7 @@ url_manual_mapping = (
|
||||
("bpy.types.shadernodegeometry*", "render/shader_nodes/input/geometry.html#bpy-types-shadernodegeometry"),
|
||||
("bpy.types.shadernodehairinfo*", "render/shader_nodes/input/hair_info.html#bpy-types-shadernodehairinfo"),
|
||||
("bpy.types.shadernodemaprange*", "render/shader_nodes/converter/map_range.html#bpy-types-shadernodemaprange"),
|
||||
("bpy.types.shadernodergbcurve*", "render/shader_nodes/color/rgb_curves.html#bpy-types-shadernodergbcurve"),
|
||||
("bpy.types.shadernodergbcurve*", "modeling/geometry_nodes/color/rgb_curves.html#bpy-types-shadernodergbcurve"),
|
||||
("bpy.types.shadernodeseparate*", "render/shader_nodes/converter/combine_separate.html#bpy-types-shadernodeseparate"),
|
||||
("bpy.types.shadernodetexbrick*", "render/shader_nodes/textures/brick.html#bpy-types-shadernodetexbrick"),
|
||||
("bpy.types.shadernodetexcoord*", "render/shader_nodes/input/texture_coordinate.html#bpy-types-shadernodetexcoord"),
|
||||
@@ -1477,7 +1544,7 @@ url_manual_mapping = (
|
||||
("bpy.types.mesh.use_mirror_y*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-y"),
|
||||
("bpy.types.mesh.use_mirror_z*", "modeling/meshes/tools/tool_settings.html#bpy-types-mesh-use-mirror-z"),
|
||||
("bpy.types.meshcachemodifier*", "modeling/modifiers/modify/mesh_cache.html#bpy-types-meshcachemodifier"),
|
||||
("bpy.types.movieclipsequence*", "video_editing/sequencer/strips/clip_mask.html#bpy-types-movieclipsequence"),
|
||||
("bpy.types.movieclipsequence*", "video_editing/sequencer/strips/clip.html#bpy-types-movieclipsequence"),
|
||||
("bpy.types.object.dimensions*", "scene_layout/object/properties/transforms.html#bpy-types-object-dimensions"),
|
||||
("bpy.types.object.pass_index*", "scene_layout/object/properties/relations.html#bpy-types-object-pass-index"),
|
||||
("bpy.types.object.track_axis*", "scene_layout/object/properties/relations.html#bpy-types-object-track-axis"),
|
||||
@@ -1515,6 +1582,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.curve.make_segment*", "modeling/curves/editing/control_points.html#bpy-ops-curve-make-segment"),
|
||||
("bpy.ops.graph.euler_filter*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-euler-filter"),
|
||||
("bpy.ops.marker.camera_bind*", "animation/markers.html#bpy-ops-marker-camera-bind"),
|
||||
("bpy.ops.mask.select_circle*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-circle"),
|
||||
("bpy.ops.mask.select_linked*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-linked"),
|
||||
("bpy.ops.mesh.beautify_fill*", "modeling/meshes/editing/face/beautify_faces.html#bpy-ops-mesh-beautify-fill"),
|
||||
("bpy.ops.mesh.colors_rotate*", "modeling/meshes/editing/face/face_data.html#bpy-ops-mesh-colors-rotate"),
|
||||
("bpy.ops.mesh.edge_collapse*", "modeling/meshes/editing/mesh/delete.html#bpy-ops-mesh-edge-collapse"),
|
||||
@@ -1550,6 +1619,8 @@ url_manual_mapping = (
|
||||
("bpy.types.addonpreferences*", "editors/preferences/addons.html#bpy-types-addonpreferences"),
|
||||
("bpy.types.arealight.spread*", "render/lights/light_object.html#bpy-types-arealight-spread"),
|
||||
("bpy.types.armaturemodifier*", "modeling/modifiers/deform/armature.html#bpy-types-armaturemodifier"),
|
||||
("bpy.types.bone.head_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-head-radius"),
|
||||
("bpy.types.bone.tail_radius*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-tail-radius"),
|
||||
("bpy.types.brush.cloth_mass*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-mass"),
|
||||
("bpy.types.brushtextureslot*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot"),
|
||||
("bpy.types.colormixsequence*", "video_editing/sequencer/strips/effects/color_mix.html#bpy-types-colormixsequence"),
|
||||
@@ -1560,8 +1631,11 @@ url_manual_mapping = (
|
||||
("bpy.types.decimatemodifier*", "modeling/modifiers/generate/decimate.html#bpy-types-decimatemodifier"),
|
||||
("bpy.types.displacemodifier*", "modeling/modifiers/deform/displace.html#bpy-types-displacemodifier"),
|
||||
("bpy.types.displaysafeareas*", "render/cameras.html#bpy-types-displaysafeareas"),
|
||||
("bpy.types.editbone.bbone_x*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-x"),
|
||||
("bpy.types.editbone.bbone_z*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-z"),
|
||||
("bpy.types.fmodifierstepped*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifierstepped"),
|
||||
("bpy.types.freestylelineset*", "render/freestyle/parameter_editor/line_set.html#bpy-types-freestylelineset"),
|
||||
("bpy.types.mask.frame_start*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-start"),
|
||||
("bpy.types.mesh.*customdata*", "modeling/meshes/properties/custom_data.html#bpy-types-mesh-customdata"),
|
||||
("bpy.types.multicamsequence*", "video_editing/sequencer/strips/effects/multicam.html#bpy-types-multicamsequence"),
|
||||
("bpy.types.multiplysequence*", "video_editing/sequencer/strips/effects/multiply.html#bpy-types-multiplysequence"),
|
||||
@@ -1612,6 +1686,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.gpencil.reproject*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-reproject"),
|
||||
("bpy.ops.graph.easing_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-easing-type"),
|
||||
("bpy.ops.graph.handle_type*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-handle-type"),
|
||||
("bpy.ops.mask.parent_clear*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-clear"),
|
||||
("bpy.ops.mesh.bevel.vertex*", "modeling/meshes/editing/vertex/bevel_vertices.html#bpy-ops-mesh-bevel-vertex"),
|
||||
("bpy.ops.mesh.delete_loose*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-delete-loose"),
|
||||
("bpy.ops.mesh.face_shading*", "modeling/meshes/editing/face/shading.html#bpy-ops-mesh-face-shading"),
|
||||
@@ -1640,11 +1715,14 @@ url_manual_mapping = (
|
||||
("bpy.ops.wm.previews_clear*", "files/blend/previews.html#bpy-ops-wm-previews-clear"),
|
||||
("bpy.types.armature.layers*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers"),
|
||||
("bpy.types.armature.rigify*", "addons/rigging/rigify/basics.html#bpy-types-armature-rigify"),
|
||||
("bpy.types.bone.use_deform*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-deform"),
|
||||
("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"),
|
||||
("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"),
|
||||
("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"),
|
||||
("bpy.types.curve.eval_time*", "modeling/curves/properties/path_animation.html#bpy-types-curve-eval-time"),
|
||||
("bpy.types.curve.fill_mode*", "modeling/curves/properties/shape.html#bpy-types-curve-fill-mode"),
|
||||
("bpy.types.editbone.layers*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-layers"),
|
||||
("bpy.types.editbone.parent*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-parent"),
|
||||
("bpy.types.explodemodifier*", "modeling/modifiers/physics/explode.html#bpy-types-explodemodifier"),
|
||||
("bpy.types.fcurvemodifiers*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fcurvemodifiers"),
|
||||
("bpy.types.floorconstraint*", "animation/constraints/relationship/floor.html#bpy-types-floorconstraint"),
|
||||
@@ -1685,6 +1763,8 @@ url_manual_mapping = (
|
||||
("bpy.ops.gpencil.dissolve*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-dissolve"),
|
||||
("bpy.ops.graph.frame_jump*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-frame-jump"),
|
||||
("bpy.ops.graph.sound_bake*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-sound-bake"),
|
||||
("bpy.ops.mask.select_less*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-less"),
|
||||
("bpy.ops.mask.select_more*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-more"),
|
||||
("bpy.ops.mesh.convex_hull*", "modeling/meshes/editing/mesh/convex_hull.html#bpy-ops-mesh-convex-hull"),
|
||||
("bpy.ops.mesh.edge_rotate*", "modeling/meshes/editing/edge/rotate_edge.html#bpy-ops-mesh-edge-rotate"),
|
||||
("bpy.ops.mesh.unsubdivide*", "modeling/meshes/editing/edge/unsubdivide.html#bpy-ops-mesh-unsubdivide"),
|
||||
@@ -1718,6 +1798,7 @@ url_manual_mapping = (
|
||||
("bpy.types.curvesmodifier*", "video_editing/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"),
|
||||
("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"),
|
||||
("bpy.types.fmodifiernoise*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifiernoise"),
|
||||
("bpy.types.mask.frame_end*", "movie_clip/masking/sidebar.html#bpy-types-mask-frame-end"),
|
||||
("bpy.types.material.paint*", "sculpt_paint/texture_paint/index.html#bpy-types-material-paint"),
|
||||
("bpy.types.mirrormodifier*", "modeling/modifiers/generate/mirror.html#bpy-types-mirrormodifier"),
|
||||
("bpy.types.movieclipproxy*", "editors/clip/sidebar.html#bpy-types-movieclipproxy"),
|
||||
@@ -1757,6 +1838,9 @@ url_manual_mapping = (
|
||||
("bpy.ops.fluid.free_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-ops-fluid-free-mesh"),
|
||||
("bpy.ops.font.select_all*", "modeling/texts/selecting.html#bpy-ops-font-select-all"),
|
||||
("bpy.ops.gpencil.convert*", "grease_pencil/modes/object/convert_to_geometry.html#bpy-ops-gpencil-convert"),
|
||||
("bpy.ops.mask.parent_set*", "movie_clip/masking/editing.html#bpy-ops-mask-parent-set"),
|
||||
("bpy.ops.mask.select_all*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-all"),
|
||||
("bpy.ops.mask.select_box*", "movie_clip/masking/selecting.html#bpy-ops-mask-select-box"),
|
||||
("bpy.ops.mesh.customdata*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata"),
|
||||
("bpy.ops.mesh.edge_split*", "modeling/meshes/editing/mesh/split.html#bpy-ops-mesh-edge-split"),
|
||||
("bpy.ops.mesh.fill_holes*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-fill-holes"),
|
||||
@@ -1800,11 +1884,15 @@ url_manual_mapping = (
|
||||
("bpy.types.crosssequence*", "video_editing/sequencer/strips/transitions/cross.html#bpy-types-crosssequence"),
|
||||
("bpy.types.curve.extrude*", "modeling/curves/properties/geometry.html#bpy-types-curve-extrude"),
|
||||
("bpy.types.curvemodifier*", "modeling/modifiers/deform/curve.html#bpy-types-curvemodifier"),
|
||||
("bpy.types.editbone.head*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-head"),
|
||||
("bpy.types.editbone.lock*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-lock"),
|
||||
("bpy.types.editbone.roll*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-roll"),
|
||||
("bpy.types.editbone.tail*", "animation/armatures/bones/properties/transform.html#bpy-types-editbone-tail"),
|
||||
("bpy.types.fieldsettings*", "physics/forces/force_fields/index.html#bpy-types-fieldsettings"),
|
||||
("bpy.types.imagesequence*", "video_editing/sequencer/strips/movie_image.html#bpy-types-imagesequence"),
|
||||
("bpy.types.imagesequence*", "video_editing/sequencer/strips/image.html#bpy-types-imagesequence"),
|
||||
("bpy.types.marbletexture*", "render/materials/legacy_textures/types/marble.html#bpy-types-marbletexture"),
|
||||
("bpy.types.modifier.show*", "modeling/modifiers/introduction.html#bpy-types-modifier-show"),
|
||||
("bpy.types.moviesequence*", "video_editing/sequencer/strips/movie_image.html#bpy-types-moviesequence"),
|
||||
("bpy.types.moviesequence*", "video_editing/sequencer/strips/movie.html#bpy-types-moviesequence"),
|
||||
("bpy.types.movietracking*", "movie_clip/tracking/index.html#bpy-types-movietracking"),
|
||||
("bpy.types.nlastrip.mute*", "editors/nla/sidebar.html#bpy-types-nlastrip-mute"),
|
||||
("bpy.types.nlastrip.name*", "editors/nla/sidebar.html#bpy-types-nlastrip-name"),
|
||||
@@ -1880,7 +1968,7 @@ url_manual_mapping = (
|
||||
("bpy.types.latticepoint*", "animation/lattice.html#bpy-types-latticepoint"),
|
||||
("bpy.types.magictexture*", "render/materials/legacy_textures/types/magic.html#bpy-types-magictexture"),
|
||||
("bpy.types.maskmodifier*", "modeling/modifiers/generate/mask.html#bpy-types-maskmodifier"),
|
||||
("bpy.types.masksequence*", "video_editing/sequencer/strips/clip_mask.html#bpy-types-masksequence"),
|
||||
("bpy.types.masksequence*", "video_editing/sequencer/strips/mask.html#bpy-types-masksequence"),
|
||||
("bpy.types.materialslot*", "render/materials/assignment.html#bpy-types-materialslot"),
|
||||
("bpy.types.metasequence*", "video_editing/sequencer/meta.html#bpy-types-metasequence"),
|
||||
("bpy.types.object.color*", "scene_layout/object/properties/display.html#bpy-types-object-color"),
|
||||
@@ -1982,6 +2070,8 @@ url_manual_mapping = (
|
||||
("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"),
|
||||
("bpy.types.imagepaint*", "sculpt_paint/texture_paint/index.html#bpy-types-imagepaint"),
|
||||
("bpy.types.lightprobe*", "render/eevee/light_probes/index.html#bpy-types-lightprobe"),
|
||||
("bpy.types.maskparent*", "movie_clip/masking/sidebar.html#bpy-types-maskparent"),
|
||||
("bpy.types.maskspline*", "movie_clip/masking/sidebar.html#bpy-types-maskspline"),
|
||||
("bpy.types.node.color*", "interface/controls/nodes/sidebar.html#bpy-types-node-color"),
|
||||
("bpy.types.node.label*", "interface/controls/nodes/sidebar.html#bpy-types-node-label"),
|
||||
("bpy.types.nodesocket*", "interface/controls/nodes/parts.html#bpy-types-nodesocket"),
|
||||
@@ -2017,6 +2107,7 @@ url_manual_mapping = (
|
||||
("bpy.types.dopesheet*", "editors/dope_sheet/index.html#bpy-types-dopesheet"),
|
||||
("bpy.types.fmodifier*", "editors/graph_editor/fcurves/sidebar/modifiers.html#bpy-types-fmodifier"),
|
||||
("bpy.types.freestyle*", "render/freestyle/index.html#bpy-types-freestyle"),
|
||||
("bpy.types.masklayer*", "movie_clip/masking/sidebar.html#bpy-types-masklayer"),
|
||||
("bpy.types.movieclip*", "movie_clip/index.html#bpy-types-movieclip"),
|
||||
("bpy.types.node.name*", "interface/controls/nodes/sidebar.html#bpy-types-node-name"),
|
||||
("bpy.types.nodeframe*", "interface/controls/nodes/frame.html#bpy-types-nodeframe"),
|
||||
|
@@ -30,7 +30,7 @@ ARRAY_TYPES = (list, tuple, IDPropertyArray, Vector)
|
||||
MAX_DISPLAY_ROWS = 4
|
||||
|
||||
|
||||
def rna_idprop_ui_get(item, create=True):
|
||||
def rna_idprop_ui_get(item, *, create=True):
|
||||
try:
|
||||
return item['_RNA_UI']
|
||||
except:
|
||||
@@ -59,9 +59,9 @@ def rna_idprop_ui_prop_update(item, prop):
|
||||
prop_rna.update()
|
||||
|
||||
|
||||
def rna_idprop_ui_prop_get(item, prop, create=True):
|
||||
def rna_idprop_ui_prop_get(item, prop, *, create=True):
|
||||
|
||||
rna_ui = rna_idprop_ui_get(item, create)
|
||||
rna_ui = rna_idprop_ui_get(item, create=create)
|
||||
|
||||
if rna_ui is None:
|
||||
return None
|
||||
@@ -73,8 +73,8 @@ def rna_idprop_ui_prop_get(item, prop, create=True):
|
||||
return rna_ui[prop]
|
||||
|
||||
|
||||
def rna_idprop_ui_prop_clear(item, prop, remove=True):
|
||||
rna_ui = rna_idprop_ui_get(item, False)
|
||||
def rna_idprop_ui_prop_clear(item, prop, *, remove=True):
|
||||
rna_ui = rna_idprop_ui_get(item, create=False)
|
||||
|
||||
if rna_ui is None:
|
||||
return
|
||||
@@ -143,7 +143,7 @@ def rna_idprop_ui_prop_default_set(item, prop, value):
|
||||
pass
|
||||
|
||||
if defvalue:
|
||||
rna_ui = rna_idprop_ui_prop_get(item, prop, True)
|
||||
rna_ui = rna_idprop_ui_prop_get(item, prop, create=True)
|
||||
rna_ui["default"] = defvalue
|
||||
else:
|
||||
rna_ui = rna_idprop_ui_prop_get(item, prop)
|
||||
@@ -181,7 +181,7 @@ def rna_idprop_ui_create(
|
||||
rna_idprop_ui_prop_update(item, prop)
|
||||
|
||||
# Clear the UI settings
|
||||
rna_ui_group = rna_idprop_ui_get(item, True)
|
||||
rna_ui_group = rna_idprop_ui_get(item, create=True)
|
||||
rna_ui_group[prop] = {}
|
||||
rna_ui = rna_ui_group[prop]
|
||||
|
||||
@@ -210,7 +210,7 @@ def rna_idprop_ui_create(
|
||||
return rna_ui
|
||||
|
||||
|
||||
def draw(layout, context, context_member, property_type, use_edit=True):
|
||||
def draw(layout, context, context_member, property_type, *, use_edit=True):
|
||||
|
||||
def assign_props(prop, val, key):
|
||||
prop.data_path = context_member
|
||||
|
@@ -245,9 +245,10 @@ def rna2xml(
|
||||
fw("%s</%s>\n" % (root_ident, root_node))
|
||||
|
||||
|
||||
def xml2rna(root_xml,
|
||||
root_rna=None, # must be set
|
||||
):
|
||||
def xml2rna(
|
||||
root_xml, *,
|
||||
root_rna=None, # must be set
|
||||
):
|
||||
|
||||
def rna2xml_node(xml_node, value):
|
||||
# print("evaluating:", xml_node.nodeName)
|
||||
@@ -394,7 +395,7 @@ def xml_file_run(context, filepath, rna_map):
|
||||
xml2rna(xml_node, root_rna=value)
|
||||
|
||||
|
||||
def xml_file_write(context, filepath, rna_map, skip_typemap=None):
|
||||
def xml_file_write(context, filepath, rna_map, *, skip_typemap=None):
|
||||
|
||||
file = open(filepath, "w", encoding="utf-8")
|
||||
fw = file.write
|
||||
|
@@ -3010,6 +3010,22 @@ def km_clip_dopesheet_editor(_params):
|
||||
|
||||
return keymap
|
||||
|
||||
def km_spreadsheet_generic(_params):
|
||||
items = []
|
||||
keymap = (
|
||||
"Spreadsheet Generic",
|
||||
{"space_type": 'SPREADSHEET', "region_type": 'WINDOW'},
|
||||
{"items": items},
|
||||
)
|
||||
|
||||
items.extend([
|
||||
*_template_space_region_type_toggle(
|
||||
sidebar_key={"type": 'N', "value": 'PRESS'},
|
||||
),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Animation
|
||||
@@ -4090,7 +4106,7 @@ def km_pose(params):
|
||||
("pose.bone_layers", {"type": 'M', "value": 'PRESS'}, None),
|
||||
("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, None),
|
||||
("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keyframe_delete", {"type": 'I', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),
|
||||
("poselib.browse_interactive", {"type": 'L', "value": 'PRESS', "alt": True}, None),
|
||||
("poselib.pose_add", {"type": 'L', "value": 'PRESS', "shift": True}, None),
|
||||
@@ -4162,7 +4178,7 @@ def km_object_mode(params):
|
||||
("wm.context_toggle", {"type": 'PERIOD', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("data_path", 'tool_settings.use_transform_data_origin')]}),
|
||||
("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keyframe_delete", {"type": 'I', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),
|
||||
("collection.create", {"type": 'G', "value": 'PRESS', "ctrl": True}, None),
|
||||
("collection.objects_remove", {"type": 'G', "value": 'PRESS', "ctrl": True, "alt": True}, None),
|
||||
@@ -7067,6 +7083,7 @@ def generate_keymaps(params=None):
|
||||
km_image(params),
|
||||
km_node_generic(params),
|
||||
km_node_editor(params),
|
||||
km_spreadsheet_generic(params),
|
||||
km_info(params),
|
||||
km_file_browser(params),
|
||||
km_file_browser_main(params),
|
||||
|
@@ -3000,7 +3000,7 @@ def km_pose(params):
|
||||
("anim.keyframe_insert_by_name", {"type": 'R', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("type", 'Scaling')]}),
|
||||
|
||||
("anim.keyframe_delete_v3d", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keying_set_active_set", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),
|
||||
*_template_items_context_menu("VIEW3D_MT_pose_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# Tools
|
||||
@@ -3071,7 +3071,7 @@ def km_object_mode(params):
|
||||
{"properties": [("type", 'Rotation')]}),
|
||||
("anim.keyframe_insert_by_name", {"type": 'R', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("type", 'Scaling')]}),
|
||||
("anim.keyframe_delete_v3d", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keyframe_delete", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("anim.keying_set_active_set", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),
|
||||
*_template_items_context_menu("VIEW3D_MT_object_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("object.move_to_collection", {"type": 'G', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
@@ -23,7 +23,7 @@ from bpy.app.handlers import persistent
|
||||
|
||||
|
||||
@persistent
|
||||
def load_handler(dummy):
|
||||
def load_handler(_):
|
||||
import bpy
|
||||
|
||||
# 2D Animation
|
||||
|
@@ -21,7 +21,7 @@ from bpy.app.handlers import persistent
|
||||
|
||||
|
||||
@persistent
|
||||
def load_handler(dummy):
|
||||
def load_handler(_):
|
||||
import bpy
|
||||
# Apply subdivision modifier on startup
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
@@ -21,7 +21,7 @@ from bpy.app.handlers import persistent
|
||||
|
||||
|
||||
@persistent
|
||||
def load_handler(dummy):
|
||||
def load_handler(_):
|
||||
from bpy import context
|
||||
screen = context.screen
|
||||
for area in screen.areas:
|
||||
|
@@ -219,7 +219,7 @@ class MeshSelectNext(Operator):
|
||||
|
||||
if find_adjacent.select_next(bm, self.report):
|
||||
bm.select_flush_mode()
|
||||
bmesh.update_edit_mesh(me, False)
|
||||
bmesh.update_edit_mesh(me, loop_triangles=False)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -244,7 +244,7 @@ class MeshSelectPrev(Operator):
|
||||
|
||||
if find_adjacent.select_prev(bm, self.report):
|
||||
bm.select_flush_mode()
|
||||
bmesh.update_edit_mesh(me, False)
|
||||
bmesh.update_edit_mesh(me, loop_triangles=False)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@@ -331,14 +331,15 @@ class NODE_OT_active_preview_toggle(Operator):
|
||||
active_node = ntree.nodes.active
|
||||
|
||||
if active_node.active_preview:
|
||||
self.disable_preview(context, ntree, active_node)
|
||||
self._disable_preview(context, active_node)
|
||||
else:
|
||||
self.enable_preview(context, node_editor, ntree, active_node)
|
||||
self._enable_preview(context, node_editor, ntree, active_node)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
def enable_preview(self, context, node_editor, ntree, active_node):
|
||||
spreadsheets = self.find_unpinned_spreadsheets(context)
|
||||
@classmethod
|
||||
def _enable_preview(cls, context, node_editor, ntree, active_node):
|
||||
spreadsheets = cls._find_unpinned_spreadsheets(context)
|
||||
|
||||
for spreadsheet in spreadsheets:
|
||||
spreadsheet.set_geometry_node_context(node_editor, active_node)
|
||||
@@ -347,14 +348,16 @@ class NODE_OT_active_preview_toggle(Operator):
|
||||
node.active_preview = False
|
||||
active_node.active_preview = True
|
||||
|
||||
def disable_preview(self, context, ntree, active_node):
|
||||
spreadsheets = self.find_unpinned_spreadsheets(context)
|
||||
@classmethod
|
||||
def _disable_preview(cls, context, active_node):
|
||||
spreadsheets = cls._find_unpinned_spreadsheets(context)
|
||||
for spreadsheet in spreadsheets:
|
||||
spreadsheet.context_path.clear()
|
||||
|
||||
active_node.active_preview = False
|
||||
|
||||
def find_unpinned_spreadsheets(self, context):
|
||||
@staticmethod
|
||||
def _find_unpinned_spreadsheets(context):
|
||||
spreadsheets = []
|
||||
for window in context.window_manager.windows:
|
||||
for area in window.screen.areas:
|
||||
|
@@ -114,9 +114,7 @@ class AddPresetBase:
|
||||
filename = self.as_filename(name)
|
||||
|
||||
target_path = os.path.join("presets", self.preset_subdir)
|
||||
target_path = bpy.utils.user_resource('SCRIPTS',
|
||||
target_path,
|
||||
create=True)
|
||||
target_path = bpy.utils.user_resource('SCRIPTS', path=target_path, create=True)
|
||||
|
||||
if not target_path:
|
||||
self.report({'WARNING'}, "Failed to create presets path")
|
||||
|
@@ -90,7 +90,7 @@ class PREFERENCES_OT_copy_prev(Operator):
|
||||
|
||||
@classmethod
|
||||
def _old_version_path(cls, version):
|
||||
return bpy.utils.resource_path('USER', version[0], version[1])
|
||||
return bpy.utils.resource_path('USER', major=version[0], minor=version[1])
|
||||
|
||||
@classmethod
|
||||
def previous_version(cls):
|
||||
@@ -226,7 +226,11 @@ class PREFERENCES_OT_keyconfig_import(Operator):
|
||||
|
||||
config_name = basename(self.filepath)
|
||||
|
||||
path = bpy.utils.user_resource('SCRIPTS', os.path.join("presets", "keyconfig"), create=True)
|
||||
path = bpy.utils.user_resource(
|
||||
'SCRIPTS',
|
||||
path=os.path.join("presets", "keyconfig"),
|
||||
create=True,
|
||||
)
|
||||
path = os.path.join(path, config_name)
|
||||
|
||||
try:
|
||||
@@ -529,7 +533,11 @@ class PREFERENCES_OT_theme_install(Operator):
|
||||
|
||||
xmlfile = self.filepath
|
||||
|
||||
path_themes = bpy.utils.user_resource('SCRIPTS', "presets/interface_theme", create=True)
|
||||
path_themes = bpy.utils.user_resource(
|
||||
'SCRIPTS',
|
||||
path=os.path.join("presets", "interface_theme"),
|
||||
create=True,
|
||||
)
|
||||
|
||||
if not path_themes:
|
||||
self.report({'ERROR'}, "Failed to get themes path")
|
||||
@@ -622,8 +630,8 @@ class PREFERENCES_OT_addon_install(Operator):
|
||||
pyfile = self.filepath
|
||||
|
||||
if self.target == 'DEFAULT':
|
||||
# don't use bpy.utils.script_paths("addons") because we may not be able to write to it.
|
||||
path_addons = bpy.utils.user_resource('SCRIPTS', "addons", create=True)
|
||||
# Don't use `bpy.utils.script_paths(path="addons")` because we may not be able to write to it.
|
||||
path_addons = bpy.utils.user_resource('SCRIPTS', path="addons", create=True)
|
||||
else:
|
||||
path_addons = context.preferences.filepaths.script_directory
|
||||
if path_addons:
|
||||
@@ -882,7 +890,8 @@ class PREFERENCES_OT_app_template_install(Operator):
|
||||
filepath = self.filepath
|
||||
|
||||
path_app_templates = bpy.utils.user_resource(
|
||||
'SCRIPTS', os.path.join("startup", "bl_app_templates_user"),
|
||||
'SCRIPTS',
|
||||
path=os.path.join("startup", "bl_app_templates_user"),
|
||||
create=True,
|
||||
)
|
||||
|
||||
@@ -988,7 +997,7 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
||||
prefs = context.preferences
|
||||
|
||||
path_studiolights = os.path.join("studiolights", self.type.lower())
|
||||
path_studiolights = bpy.utils.user_resource('DATAFILES', path_studiolights, create=True)
|
||||
path_studiolights = bpy.utils.user_resource('DATAFILES', path=path_studiolights, create=True)
|
||||
if not path_studiolights:
|
||||
self.report({'ERROR'}, "Failed to create Studio Light path")
|
||||
return {'CANCELLED'}
|
||||
@@ -1034,7 +1043,11 @@ class PREFERENCES_OT_studiolight_new(Operator):
|
||||
wm = context.window_manager
|
||||
filename = bpy.path.ensure_ext(self.filename, ".sl")
|
||||
|
||||
path_studiolights = bpy.utils.user_resource('DATAFILES', os.path.join("studiolights", "studio"), create=True)
|
||||
path_studiolights = bpy.utils.user_resource(
|
||||
'DATAFILES',
|
||||
path=os.path.join("studiolights", "studio"),
|
||||
create=True,
|
||||
)
|
||||
if not path_studiolights:
|
||||
self.report({'ERROR'}, "Failed to get Studio Light path")
|
||||
return {'CANCELLED'}
|
||||
|
@@ -223,7 +223,7 @@ def extend(obj, EXTEND_MODE):
|
||||
for f_triple in walk_face(f_act):
|
||||
apply_uv(*f_triple)
|
||||
|
||||
bmesh.update_edit_mesh(me, False)
|
||||
bmesh.update_edit_mesh(me, loop_triangles=False)
|
||||
return STATUS_OK
|
||||
|
||||
|
||||
|
@@ -1100,7 +1100,7 @@ class WM_OT_path_open(Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
def _wm_doc_get_id(doc_id, do_url=True, url_prefix="", report=None):
|
||||
def _wm_doc_get_id(doc_id, *, do_url=True, url_prefix="", report=None):
|
||||
|
||||
def operator_exists_pair(a, b):
|
||||
# Not fast, this is only for docs.
|
||||
@@ -1190,7 +1190,7 @@ class WM_OT_doc_view_manual(Operator):
|
||||
doc_id: doc_id
|
||||
|
||||
@staticmethod
|
||||
def _find_reference(rna_id, url_mapping, verbose=True):
|
||||
def _find_reference(rna_id, url_mapping, *, verbose=True):
|
||||
if verbose:
|
||||
print("online manual check for: '%s'... " % rna_id)
|
||||
from fnmatch import fnmatchcase
|
||||
@@ -1526,7 +1526,7 @@ class WM_OT_properties_edit(Operator):
|
||||
self.default = ""
|
||||
|
||||
# setup defaults
|
||||
prop_ui = rna_idprop_ui_prop_get(item, prop, False) # don't create
|
||||
prop_ui = rna_idprop_ui_prop_get(item, prop, create=False)
|
||||
if prop_ui:
|
||||
self.min = prop_ui.get("min", -1000000000)
|
||||
self.max = prop_ui.get("max", 1000000000)
|
||||
@@ -1910,7 +1910,7 @@ class WM_OT_toolbar(Operator):
|
||||
return context.space_data is not None
|
||||
|
||||
@staticmethod
|
||||
def keymap_from_toolbar(context, space_type, use_fallback_keys=True, use_reset=True):
|
||||
def keymap_from_toolbar(context, space_type, *, use_fallback_keys=True, use_reset=True):
|
||||
from bl_ui.space_toolsystem_common import ToolSelectPanelHelper
|
||||
from bl_keymap_utils import keymap_from_toolbar
|
||||
|
||||
@@ -2211,7 +2211,7 @@ class WM_OT_batch_rename(Operator):
|
||||
actions: CollectionProperty(type=BatchRenameAction)
|
||||
|
||||
@staticmethod
|
||||
def _data_from_context(context, data_type, only_selected, check_context=False):
|
||||
def _data_from_context(context, data_type, only_selected, *, check_context=False):
|
||||
|
||||
mode = context.mode
|
||||
scene = context.scene
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user