Compare commits
85 Commits
temp-point
...
soc-2020-t
Author | SHA1 | Date | |
---|---|---|---|
2d0c84cf76 | |||
167eace0e7 | |||
f066bf923c | |||
6e60b3cf59 | |||
098be40b53 | |||
30021b0416 | |||
1e41a9a86b | |||
5b7c621787 | |||
77cde6f1a1 | |||
191ab5990b | |||
6196b6df92 | |||
14efcadcb2 | |||
fcf7337748 | |||
07e11b54ab | |||
685609c5ea | |||
81f16d2f80 | |||
95d3aac846 | |||
d63e7a997d | |||
d2a70fbd43 | |||
c2134cd13c | |||
501c0bfccb | |||
9231bc646c | |||
0db26fd828 | |||
a09ae63e2b | |||
39da831001 | |||
500bf1f2bb | |||
eb5fd291cf | |||
7c1656d0e6 | |||
1c6302a7e5 | |||
4a5165d945 | |||
4d2d536747 | |||
c2918d8525 | |||
e6abea5ce6 | |||
5dda36d875 | |||
e3e81f60a8 | |||
f7d2ed66a6 | |||
6490eeabd5 | |||
92fdbcc283 | |||
f91a54a86d | |||
94781b3453 | |||
1942c8293e | |||
41b536e116 | |||
28a0ffcfc8 | |||
739788e75d | |||
0b6586ed0e | |||
cad0c94745 | |||
5da0776a76 | |||
a79e7e51c4 | |||
34fce0c470 | |||
fa1ad74f6f | |||
e86e217e74 | |||
571212afcf | |||
8f0b9e8186 | |||
1ecde4370e | |||
ee4742c0b7 | |||
d1debd9602 | |||
7583dc6cc3 | |||
d83e7b7987 | |||
6d6dc32279 | |||
b4038986c1 | |||
c7cdca0e33 | |||
04049a2080 | |||
75c1016853 | |||
2db15f52c1 | |||
23614570b4 | |||
d758139af4 | |||
3c0a407511 | |||
b94856d804 | |||
f534e9928d | |||
9236fb2725 | |||
d21ad2cc39 | |||
911a2b1d78 | |||
16d58a509a | |||
49f00b597e | |||
a7d2ca5064 | |||
f447d2748b | |||
59c817bf8a | |||
235cd70da8 | |||
84446e055d | |||
b4d2cbafb7 | |||
ce46e80b87 | |||
eef4792627 | |||
ea00f1b416 | |||
0ee4f5cb0b | |||
2e5576237d |
@@ -610,11 +610,6 @@ if(WIN32)
|
||||
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
# See WITH_WINDOWS_SCCACHE for Windows.
|
||||
option(WITH_COMPILER_CCACHE "Use ccache to improve rebuild times (Works with Ninja, Makefiles and Xcode)" OFF)
|
||||
endif()
|
||||
|
||||
# The following only works with the Ninja generator in CMake >= 3.0.
|
||||
if("${CMAKE_GENERATOR}" MATCHES "Ninja")
|
||||
option(WITH_NINJA_POOL_JOBS
|
||||
@@ -1773,10 +1768,6 @@ elseif(WITH_CYCLES_STANDALONE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Testing
|
||||
add_subdirectory(tests)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Blender Application
|
||||
if(WITH_BLENDER)
|
||||
@@ -1784,6 +1775,11 @@ if(WITH_BLENDER)
|
||||
endif()
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Testing
|
||||
add_subdirectory(tests)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define 'heavy' submodules (for Ninja builder when using pools).
|
||||
setup_heavy_lib_pool()
|
||||
|
@@ -41,7 +41,6 @@ Convenience Targets
|
||||
* developer: Enable faster builds, error checking and tests, recommended for developers.
|
||||
* config: Run cmake configuration tool to set build options.
|
||||
* ninja: Use ninja build tool for faster builds.
|
||||
* ccache: Use ccache for faster rebuilds.
|
||||
|
||||
Note: passing the argument 'BUILD_DIR=path' when calling make will override the default build dir.
|
||||
Note: passing the argument 'BUILD_CMAKE_ARGS=args' lets you add cmake arguments.
|
||||
@@ -242,10 +241,6 @@ ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
|
||||
ifneq "$(findstring ccache, $(MAKECMDGOALS))" ""
|
||||
CMAKE_CONFIG_ARGS:=-DWITH_COMPILER_CCACHE=YES $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# build tool
|
||||
|
||||
@@ -345,7 +340,6 @@ headless: all
|
||||
bpy: all
|
||||
developer: all
|
||||
ninja: all
|
||||
ccache: all
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Build dependencies
|
||||
|
@@ -2086,7 +2086,7 @@ compile_OIIO() {
|
||||
cmake_d="$cmake_d -D USE_OPENCV=OFF"
|
||||
cmake_d="$cmake_d -D BUILD_TESTING=OFF"
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF"
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=ON"
|
||||
cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF"
|
||||
cmake_d="$cmake_d -D TXT2MAN="
|
||||
#cmake_d="$cmake_d -D CMAKE_EXPORT_COMPILE_COMMANDS=ON"
|
||||
#cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON"
|
||||
@@ -4072,7 +4072,7 @@ install_DEB() {
|
||||
else
|
||||
check_package_version_ge_lt_DEB libopenimageio-dev $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
if [ $? -eq 0 -a "$_with_built_openexr" = false ]; then
|
||||
install_packages_DEB libopenimageio-dev openimageio-tools
|
||||
install_packages_DEB libopenimageio-dev
|
||||
clean_OIIO
|
||||
else
|
||||
compile_OIIO
|
||||
@@ -4714,13 +4714,13 @@ install_RPM() {
|
||||
INFO "Forced OpenImageIO building, as requested..."
|
||||
compile_OIIO
|
||||
else
|
||||
check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
if [ $? -eq 0 -a $_with_built_openexr == false ]; then
|
||||
install_packages_RPM OpenImageIO-devel OpenImageIO-utils
|
||||
clean_OIIO
|
||||
else
|
||||
#check_package_version_ge_lt_RPM OpenImageIO-devel $OIIO_VERSION_MIN $OIIO_VERSION_MAX
|
||||
#if [ $? -eq 0 -a $_with_built_openexr == false ]; then
|
||||
# install_packages_RPM OpenImageIO-devel
|
||||
# clean_OIIO
|
||||
#else
|
||||
compile_OIIO
|
||||
fi
|
||||
#fi
|
||||
fi
|
||||
|
||||
|
||||
|
@@ -42,7 +42,7 @@ def get_cmake_options(builder):
|
||||
elif builder.platform == 'linux':
|
||||
config_file = "build_files/buildbot/config/blender_linux.cmake"
|
||||
|
||||
optix_sdk_dir = os.path.join(builder.blender_dir, '..', '..', 'NVIDIA-Optix-SDK-7.1')
|
||||
optix_sdk_dir = os.path.join(builder.blender_dir, '..', '..', 'NVIDIA-Optix-SDK')
|
||||
options.append('-DOPTIX_ROOT_DIR:PATH=' + optix_sdk_dir)
|
||||
|
||||
# Workaround to build sm_30 kernels with CUDA 10, since CUDA 11 no longer supports that architecture
|
||||
|
@@ -330,9 +330,6 @@ function(gtest_add_tests)
|
||||
set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*")
|
||||
set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)")
|
||||
|
||||
# This will get a filter for each test suite.
|
||||
set(test_filters "")
|
||||
|
||||
foreach(source IN LISTS ARGS_SOURCES)
|
||||
if(NOT ARGS_SKIP_DEPENDENCY)
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${source})
|
||||
@@ -379,32 +376,175 @@ function(gtest_add_tests)
|
||||
list(APPEND testList ${ctest_test_name})
|
||||
endif()
|
||||
else()
|
||||
# BLENDER: collect tests named "suite.testcase" as list of "suite.*" filters.
|
||||
string(REGEX REPLACE "\\..*$" "" gtest_suite_name ${gtest_test_name})
|
||||
list(APPEND test_filters "${gtest_suite_name}.*")
|
||||
set(ctest_test_name ${ARGS_TEST_PREFIX}${gtest_test_name}${ARGS_TEST_SUFFIX})
|
||||
add_test(NAME ${ctest_test_name}
|
||||
${workDir}
|
||||
COMMAND ${ARGS_TARGET}
|
||||
--gtest_filter=${gtest_test_name}
|
||||
${ARGS_EXTRA_ARGS}
|
||||
)
|
||||
list(APPEND testList ${ctest_test_name})
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
# Join all found GTest suite names into one big filter.
|
||||
list(REMOVE_DUPLICATES test_filters)
|
||||
list(JOIN test_filters ":" gtest_filter)
|
||||
add_test(NAME ${ARGS_TEST_PREFIX}
|
||||
${workDir}
|
||||
COMMAND ${ARGS_TARGET}
|
||||
--gtest_filter=${gtest_filter}
|
||||
${ARGS_EXTRA_ARGS}
|
||||
)
|
||||
list(APPEND testList ${ARGS_TEST_PREFIX})
|
||||
|
||||
if(ARGS_TEST_LIST)
|
||||
set(${ARGS_TEST_LIST} ${testList} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
# BLENDER: remove the discovery function gtest_discover_tests(). It's not used,
|
||||
# as it generates too many test invocations.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
function(gtest_discover_tests TARGET)
|
||||
cmake_parse_arguments(
|
||||
""
|
||||
"NO_PRETTY_TYPES;NO_PRETTY_VALUES"
|
||||
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;DISCOVERY_TIMEOUT;XML_OUTPUT_DIR;DISCOVERY_MODE"
|
||||
"EXTRA_ARGS;PROPERTIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
if(NOT _WORKING_DIRECTORY)
|
||||
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
if(NOT _TEST_LIST)
|
||||
set(_TEST_LIST ${TARGET}_TESTS)
|
||||
endif()
|
||||
if(NOT _DISCOVERY_TIMEOUT)
|
||||
set(_DISCOVERY_TIMEOUT 5)
|
||||
endif()
|
||||
if(NOT _DISCOVERY_MODE)
|
||||
if(NOT CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE)
|
||||
set(CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE "POST_BUILD")
|
||||
endif()
|
||||
set(_DISCOVERY_MODE ${CMAKE_GTEST_DISCOVER_TESTS_DISCOVERY_MODE})
|
||||
endif()
|
||||
|
||||
get_property(
|
||||
has_counter
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
SET
|
||||
)
|
||||
if(has_counter)
|
||||
get_property(
|
||||
counter
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
)
|
||||
math(EXPR counter "${counter} + 1")
|
||||
else()
|
||||
set(counter 1)
|
||||
endif()
|
||||
set_property(
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CTEST_DISCOVERED_TEST_COUNTER
|
||||
${counter}
|
||||
)
|
||||
|
||||
# Define rule to generate test list for aforementioned test executable
|
||||
# Blender: use _ instead of [] to avoid problems with zsh regex.
|
||||
set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_${counter}_")
|
||||
set(ctest_include_file "${ctest_file_base}_include.cmake")
|
||||
set(ctest_tests_file "${ctest_file_base}_tests.cmake")
|
||||
get_property(crosscompiling_emulator
|
||||
TARGET ${TARGET}
|
||||
PROPERTY CROSSCOMPILING_EMULATOR
|
||||
)
|
||||
|
||||
if(_DISCOVERY_MODE STREQUAL "POST_BUILD")
|
||||
add_custom_command(
|
||||
TARGET ${TARGET} POST_BUILD
|
||||
BYPRODUCTS "${ctest_tests_file}"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "TEST_TARGET=${TARGET}"
|
||||
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
|
||||
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
|
||||
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
|
||||
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
|
||||
-D "TEST_PROPERTIES=${_PROPERTIES}"
|
||||
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||
-D "NO_PRETTY_TYPES=${_NO_PRETTY_TYPES}"
|
||||
-D "NO_PRETTY_VALUES=${_NO_PRETTY_VALUES}"
|
||||
-D "TEST_LIST=${_TEST_LIST}"
|
||||
-D "CTEST_FILE=${ctest_tests_file}"
|
||||
-D "TEST_DISCOVERY_TIMEOUT=${_DISCOVERY_TIMEOUT}"
|
||||
-D "TEST_XML_OUTPUT_DIR=${_XML_OUTPUT_DIR}"
|
||||
-P "${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
file(WRITE "${ctest_include_file}"
|
||||
"if(EXISTS \"${ctest_tests_file}\")\n"
|
||||
" include(\"${ctest_tests_file}\")\n"
|
||||
"else()\n"
|
||||
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
|
||||
"endif()\n"
|
||||
)
|
||||
elseif(_DISCOVERY_MODE STREQUAL "PRE_TEST")
|
||||
|
||||
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL
|
||||
PROPERTY GENERATOR_IS_MULTI_CONFIG
|
||||
)
|
||||
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
set(ctest_tests_file "${ctest_file_base}_tests-$<CONFIG>.cmake")
|
||||
endif()
|
||||
|
||||
string(CONCAT ctest_include_content
|
||||
"if(EXISTS \"$<TARGET_FILE:${TARGET}>\")" "\n"
|
||||
" if(\"$<TARGET_FILE:${TARGET}>\" IS_NEWER_THAN \"${ctest_tests_file}\")" "\n"
|
||||
" include(\"${_GOOGLETEST_DISCOVER_TESTS_SCRIPT}\")" "\n"
|
||||
" gtest_discover_tests_impl(" "\n"
|
||||
" TEST_EXECUTABLE" " [==[" "$<TARGET_FILE:${TARGET}>" "]==]" "\n"
|
||||
" TEST_EXECUTOR" " [==[" "${crosscompiling_emulator}" "]==]" "\n"
|
||||
" TEST_WORKING_DIR" " [==[" "${_WORKING_DIRECTORY}" "]==]" "\n"
|
||||
" TEST_EXTRA_ARGS" " [==[" "${_EXTRA_ARGS}" "]==]" "\n"
|
||||
" TEST_PROPERTIES" " [==[" "${_PROPERTIES}" "]==]" "\n"
|
||||
" TEST_PREFIX" " [==[" "${_TEST_PREFIX}" "]==]" "\n"
|
||||
" TEST_SUFFIX" " [==[" "${_TEST_SUFFIX}" "]==]" "\n"
|
||||
" NO_PRETTY_TYPES" " [==[" "${_NO_PRETTY_TYPES}" "]==]" "\n"
|
||||
" NO_PRETTY_VALUES" " [==[" "${_NO_PRETTY_VALUES}" "]==]" "\n"
|
||||
" TEST_LIST" " [==[" "${_TEST_LIST}" "]==]" "\n"
|
||||
" CTEST_FILE" " [==[" "${ctest_tests_file}" "]==]" "\n"
|
||||
" TEST_DISCOVERY_TIMEOUT" " [==[" "${_DISCOVERY_TIMEOUT}" "]==]" "\n"
|
||||
" TEST_XML_OUTPUT_DIR" " [==[" "${_XML_OUTPUT_DIR}" "]==]" "\n"
|
||||
" )" "\n"
|
||||
" endif()" "\n"
|
||||
" include(\"${ctest_tests_file}\")" "\n"
|
||||
"else()" "\n"
|
||||
" add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)" "\n"
|
||||
"endif()" "\n"
|
||||
)
|
||||
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
foreach(_config ${CMAKE_CONFIGURATION_TYPES})
|
||||
file(GENERATE OUTPUT "${ctest_file_base}_include-${_config}.cmake" CONTENT "${ctest_include_content}" CONDITION $<CONFIG:${_config}>)
|
||||
endforeach()
|
||||
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include-\${CTEST_CONFIGURATION_TYPE}.cmake\")")
|
||||
else()
|
||||
file(GENERATE OUTPUT "${ctest_file_base}_include.cmake" CONTENT "${ctest_include_content}")
|
||||
file(WRITE "${ctest_include_file}" "include(\"${ctest_file_base}_include.cmake\")")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(FATAL_ERROR "Unknown DISCOVERY_MODE: ${_DISCOVERY_MODE}")
|
||||
endif()
|
||||
|
||||
# Add discovered tests to directory TEST_INCLUDE_FILES
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
|
||||
)
|
||||
|
||||
endfunction()
|
||||
|
||||
###############################################################################
|
||||
|
||||
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
|
||||
${CMAKE_CURRENT_LIST_DIR}/GTestAddTests.cmake
|
||||
)
|
||||
|
||||
# Restore project's policies
|
||||
cmake_policy(POP)
|
||||
|
194
build_files/cmake/Modules/GTestAddTests.cmake
Normal file
194
build_files/cmake/Modules/GTestAddTests.cmake
Normal file
@@ -0,0 +1,194 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License,
|
||||
# see accompanying file BSD-3-Clause-license.txt for details.
|
||||
|
||||
# Changes made to this script have been marked with "BLENDER".
|
||||
|
||||
|
||||
# BLENDER: disable ASAN leak detection when trying to discover tests.
|
||||
set(ENV{ASAN_OPTIONS} "detect_leaks=0")
|
||||
|
||||
cmake_minimum_required(VERSION ${CMAKE_VERSION})
|
||||
|
||||
# Overwrite possibly existing ${_CTEST_FILE} with empty file
|
||||
set(flush_tests_MODE WRITE)
|
||||
|
||||
# Flushes script to ${_CTEST_FILE}
|
||||
macro(flush_script)
|
||||
file(${flush_tests_MODE} "${_CTEST_FILE}" "${script}")
|
||||
set(flush_tests_MODE APPEND)
|
||||
|
||||
set(script "")
|
||||
endmacro()
|
||||
|
||||
# Flushes tests_buffer to tests
|
||||
macro(flush_tests_buffer)
|
||||
list(APPEND tests "${tests_buffer}")
|
||||
set(tests_buffer "")
|
||||
endmacro()
|
||||
|
||||
macro(add_command NAME)
|
||||
set(_args "")
|
||||
foreach(_arg ${ARGN})
|
||||
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||
string(APPEND _args " [==[${_arg}]==]")
|
||||
else()
|
||||
string(APPEND _args " ${_arg}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(APPEND script "${NAME}(${_args})\n")
|
||||
string(LENGTH "${script}" _script_len)
|
||||
if(${_script_len} GREATER "50000")
|
||||
flush_script()
|
||||
endif()
|
||||
# Unsets macro local variables to prevent leakage outside of this macro.
|
||||
unset(_args)
|
||||
unset(_script_len)
|
||||
endmacro()
|
||||
|
||||
function(gtest_discover_tests_impl)
|
||||
|
||||
cmake_parse_arguments(
|
||||
""
|
||||
""
|
||||
"NO_PRETTY_TYPES;NO_PRETTY_VALUES;TEST_EXECUTABLE;TEST_EXECUTOR;TEST_WORKING_DIR;TEST_PREFIX;TEST_SUFFIX;TEST_LIST;CTEST_FILE;TEST_DISCOVERY_TIMEOUT;TEST_XML_OUTPUT_DIR"
|
||||
"TEST_EXTRA_ARGS;TEST_PROPERTIES"
|
||||
${ARGN}
|
||||
)
|
||||
|
||||
set(prefix "${_TEST_PREFIX}")
|
||||
set(suffix "${_TEST_SUFFIX}")
|
||||
set(extra_args ${_TEST_EXTRA_ARGS})
|
||||
set(properties ${_TEST_PROPERTIES})
|
||||
set(script)
|
||||
set(suite)
|
||||
set(tests)
|
||||
set(tests_buffer)
|
||||
|
||||
# Run test executable to get list of available tests
|
||||
if(NOT EXISTS "${_TEST_EXECUTABLE}")
|
||||
message(FATAL_ERROR
|
||||
"Specified test executable does not exist.\n"
|
||||
" Path: '${_TEST_EXECUTABLE}'"
|
||||
)
|
||||
endif()
|
||||
execute_process(
|
||||
COMMAND ${_TEST_EXECUTOR} "${_TEST_EXECUTABLE}" --gtest_list_tests
|
||||
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
|
||||
TIMEOUT ${_TEST_DISCOVERY_TIMEOUT}
|
||||
OUTPUT_VARIABLE output
|
||||
RESULT_VARIABLE result
|
||||
)
|
||||
if(NOT ${result} EQUAL 0)
|
||||
string(REPLACE "\n" "\n " output "${output}")
|
||||
message(FATAL_ERROR
|
||||
"Error running test executable.\n"
|
||||
" Path: '${_TEST_EXECUTABLE}'\n"
|
||||
" Result: ${result}\n"
|
||||
" Output:\n"
|
||||
" ${output}\n"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Preserve semicolon in test-parameters
|
||||
string(REPLACE [[;]] [[\;]] output "${output}")
|
||||
string(REPLACE "\n" ";" output "${output}")
|
||||
|
||||
# Parse output
|
||||
foreach(line ${output})
|
||||
# Skip header
|
||||
if(NOT line MATCHES "gtest_main\\.cc")
|
||||
# Do we have a module name or a test name?
|
||||
if(NOT line MATCHES "^ ")
|
||||
# Module; remove trailing '.' to get just the name...
|
||||
string(REGEX REPLACE "\\.( *#.*)?" "" suite "${line}")
|
||||
if(line MATCHES "#" AND NOT _NO_PRETTY_TYPES)
|
||||
string(REGEX REPLACE "/[0-9]\\.+ +#.*= +" "/" pretty_suite "${line}")
|
||||
else()
|
||||
set(pretty_suite "${suite}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^DISABLED_" "" pretty_suite "${pretty_suite}")
|
||||
else()
|
||||
# Test name; strip spaces and comments to get just the name...
|
||||
string(REGEX REPLACE " +" "" test "${line}")
|
||||
if(test MATCHES "#" AND NOT _NO_PRETTY_VALUES)
|
||||
string(REGEX REPLACE "/[0-9]+#GetParam..=" "/" pretty_test "${test}")
|
||||
else()
|
||||
string(REGEX REPLACE "#.*" "" pretty_test "${test}")
|
||||
endif()
|
||||
string(REGEX REPLACE "^DISABLED_" "" pretty_test "${pretty_test}")
|
||||
string(REGEX REPLACE "#.*" "" test "${test}")
|
||||
if(NOT "${_TEST_XML_OUTPUT_DIR}" STREQUAL "")
|
||||
set(TEST_XML_OUTPUT_PARAM "--gtest_output=xml:${_TEST_XML_OUTPUT_DIR}/${prefix}${suite}.${test}${suffix}.xml")
|
||||
else()
|
||||
unset(TEST_XML_OUTPUT_PARAM)
|
||||
endif()
|
||||
|
||||
# sanitize test name for further processing downstream
|
||||
set(testname "${prefix}${pretty_suite}.${pretty_test}${suffix}")
|
||||
# escape \
|
||||
string(REPLACE [[\]] [[\\]] testname "${testname}")
|
||||
# escape ;
|
||||
string(REPLACE [[;]] [[\;]] testname "${testname}")
|
||||
# escape $
|
||||
string(REPLACE [[$]] [[\$]] testname "${testname}")
|
||||
|
||||
# ...and add to script
|
||||
add_command(add_test
|
||||
"${testname}"
|
||||
${_TEST_EXECUTOR}
|
||||
"${_TEST_EXECUTABLE}"
|
||||
"--gtest_filter=${suite}.${test}"
|
||||
"--gtest_also_run_disabled_tests"
|
||||
${TEST_XML_OUTPUT_PARAM}
|
||||
${extra_args}
|
||||
)
|
||||
if(suite MATCHES "^DISABLED" OR test MATCHES "^DISABLED")
|
||||
add_command(set_tests_properties
|
||||
"${testname}"
|
||||
PROPERTIES DISABLED TRUE
|
||||
)
|
||||
endif()
|
||||
add_command(set_tests_properties
|
||||
"${testname}"
|
||||
PROPERTIES
|
||||
WORKING_DIRECTORY "${_TEST_WORKING_DIR}"
|
||||
SKIP_REGULAR_EXPRESSION "\\\\[ SKIPPED \\\\]"
|
||||
${properties}
|
||||
)
|
||||
list(APPEND tests_buffer "${testname}")
|
||||
list(LENGTH tests_buffer tests_buffer_length)
|
||||
if(${tests_buffer_length} GREATER "250")
|
||||
flush_tests_buffer()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
# Create a list of all discovered tests, which users may use to e.g. set
|
||||
# properties on the tests
|
||||
flush_tests_buffer()
|
||||
add_command(set ${_TEST_LIST} ${tests})
|
||||
|
||||
# Write CTest script
|
||||
flush_script()
|
||||
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
gtest_discover_tests_impl(
|
||||
NO_PRETTY_TYPES ${NO_PRETTY_TYPES}
|
||||
NO_PRETTY_VALUES ${NO_PRETTY_VALUES}
|
||||
TEST_EXECUTABLE ${TEST_EXECUTABLE}
|
||||
TEST_EXECUTOR ${TEST_EXECUTOR}
|
||||
TEST_WORKING_DIR ${TEST_WORKING_DIR}
|
||||
TEST_PREFIX ${TEST_PREFIX}
|
||||
TEST_SUFFIX ${TEST_SUFFIX}
|
||||
TEST_LIST ${TEST_LIST}
|
||||
CTEST_FILE ${CTEST_FILE}
|
||||
TEST_DISCOVERY_TIMEOUT ${TEST_DISCOVERY_TIMEOUT}
|
||||
TEST_XML_OUTPUT_DIR ${TEST_XML_OUTPUT_DIR}
|
||||
TEST_EXTRA_ARGS ${TEST_EXTRA_ARGS}
|
||||
TEST_PROPERTIES ${TEST_PROPERTIES}
|
||||
)
|
||||
endif()
|
@@ -8,17 +8,6 @@
|
||||
#
|
||||
#=============================================================================
|
||||
|
||||
function(GET_BLENDER_TEST_INSTALL_DIR VARIABLE_NAME)
|
||||
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
endif()
|
||||
set(${VARIABLE_NAME} "${TEST_INSTALL_DIR}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
macro(BLENDER_SRC_GTEST_EX)
|
||||
if(WITH_GTESTS)
|
||||
set(options SKIP_ADD_TEST)
|
||||
@@ -86,7 +75,13 @@ macro(BLENDER_SRC_GTEST_EX)
|
||||
target_link_libraries(${TARGET_NAME} ${GMP_LIBRARIES})
|
||||
endif()
|
||||
|
||||
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
|
||||
get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(GENERATOR_IS_MULTI_CONFIG)
|
||||
string(REPLACE "\${BUILD_TYPE}" "$<CONFIG>" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
string(REPLACE "\${BUILD_TYPE}" "" TEST_INSTALL_DIR ${CMAKE_INSTALL_PREFIX})
|
||||
endif()
|
||||
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${TESTS_OUTPUT_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE "${TESTS_OUTPUT_DIR}"
|
||||
|
@@ -13,7 +13,7 @@ Invocation:
|
||||
export CLANG_BIND_DIR="/dsk/src/llvm/tools/clang/bindings/python"
|
||||
export CLANG_LIB_DIR="/opt/llvm/lib"
|
||||
|
||||
python clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
|
||||
python2 clang_array_check.py somefile.c -DSOME_DEFINE -I/some/include
|
||||
|
||||
... defines and includes are optional
|
||||
|
||||
@@ -76,32 +76,6 @@ defs_precalc = {
|
||||
"glNormal3bv": {0: 3},
|
||||
"glNormal3iv": {0: 3},
|
||||
"glNormal3sv": {0: 3},
|
||||
|
||||
# GPU immediate mode.
|
||||
"immVertex2iv": {1: 2},
|
||||
|
||||
"immVertex2fv": {1: 2},
|
||||
"immVertex3fv": {1: 3},
|
||||
|
||||
"immAttr2fv": {1: 2},
|
||||
"immAttr3fv": {1: 3},
|
||||
"immAttr4fv": {1: 4},
|
||||
|
||||
"immAttr3ubv": {1: 3},
|
||||
"immAttr4ubv": {1: 4},
|
||||
|
||||
"immUniform2fv": {1: 2},
|
||||
"immUniform3fv": {1: 3},
|
||||
"immUniform4fv": {1: 4},
|
||||
|
||||
"immUniformColor3fv": {0: 3},
|
||||
"immUniformColor4fv": {0: 4},
|
||||
|
||||
"immUniformColor3ubv": {1: 3},
|
||||
"immUniformColor4ubv": {1: 4},
|
||||
|
||||
"immUniformColor3fvAlpha": {0: 3},
|
||||
"immUniformColor4fvAlpha": {0: 4},
|
||||
}
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -126,8 +100,7 @@ else:
|
||||
if CLANG_LIB_DIR is None:
|
||||
print("$CLANG_LIB_DIR clang lib dir not set")
|
||||
|
||||
if CLANG_BIND_DIR:
|
||||
sys.path.append(CLANG_BIND_DIR)
|
||||
sys.path.append(CLANG_BIND_DIR)
|
||||
|
||||
import clang
|
||||
import clang.cindex
|
||||
@@ -135,8 +108,7 @@ from clang.cindex import (CursorKind,
|
||||
TypeKind,
|
||||
TokenKind)
|
||||
|
||||
if CLANG_LIB_DIR:
|
||||
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
|
||||
clang.cindex.Config.set_library_path(CLANG_LIB_DIR)
|
||||
|
||||
index = clang.cindex.Index.create()
|
||||
|
||||
|
@@ -32,7 +32,7 @@ CHECKER_IGNORE_PREFIX = [
|
||||
"intern/moto",
|
||||
]
|
||||
|
||||
CHECKER_BIN = "python3"
|
||||
CHECKER_BIN = "python2"
|
||||
|
||||
CHECKER_ARGS = [
|
||||
os.path.join(os.path.dirname(__file__), "clang_array_check.py"),
|
||||
|
@@ -388,43 +388,6 @@ function(blender_add_lib
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_LINK_LIBS ${name})
|
||||
endfunction()
|
||||
|
||||
function(blender_add_test_suite)
|
||||
if (ARGC LESS 1)
|
||||
message(FATAL_ERROR "No arguments supplied to blender_add_test_suite()")
|
||||
endif()
|
||||
|
||||
# Parse the arguments
|
||||
set(oneValueArgs TARGET SUITE_NAME)
|
||||
set(multiValueArgs SOURCES)
|
||||
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
# Figure out the release dir, as some tests need files from there.
|
||||
GET_BLENDER_TEST_INSTALL_DIR(TEST_INSTALL_DIR)
|
||||
if(APPLE)
|
||||
set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION})
|
||||
else()
|
||||
if(WIN32 OR WITH_INSTALL_PORTABLE)
|
||||
set(_test_release_dir ${TEST_INSTALL_DIR}/${BLENDER_VERSION})
|
||||
else()
|
||||
set(_test_release_dir ${TEST_INSTALL_DIR}/share/blender/${BLENDER_VERSION})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Define a test case with our custom gtest_add_tests() command.
|
||||
include(GTest)
|
||||
gtest_add_tests(
|
||||
TARGET ${ARGS_TARGET}
|
||||
SOURCES "${ARGS_SOURCES}"
|
||||
TEST_PREFIX ${ARGS_SUITE_NAME}
|
||||
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
|
||||
EXTRA_ARGS
|
||||
--test-assets-dir "${CMAKE_SOURCE_DIR}/../lib/tests"
|
||||
--test-release-dir "${_test_release_dir}"
|
||||
)
|
||||
|
||||
unset(_test_release_dir)
|
||||
endfunction()
|
||||
|
||||
# Add tests for a Blender library, to be called in tandem with blender_add_lib().
|
||||
# The tests will be part of the blender_test executable (see tests/gtests/runner).
|
||||
function(blender_add_test_lib
|
||||
@@ -458,12 +421,6 @@ function(blender_add_test_lib
|
||||
blender_add_lib__impl(${name} "${sources}" "${includes}" "${includes_sys}" "${library_deps}")
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY BLENDER_TEST_LIBS ${name})
|
||||
|
||||
blender_add_test_suite(
|
||||
TARGET blender_test
|
||||
SUITE_NAME ${name}
|
||||
SOURCES "${sources}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -497,10 +454,14 @@ function(blender_add_test_executable
|
||||
SKIP_ADD_TEST
|
||||
)
|
||||
|
||||
blender_add_test_suite(
|
||||
TARGET ${name}_test
|
||||
SUITE_NAME ${name}
|
||||
SOURCES "${sources}"
|
||||
include(GTest)
|
||||
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
|
||||
${CMAKE_SOURCE_DIR}/build_files/cmake/Modules/GTestAddTests.cmake
|
||||
)
|
||||
|
||||
gtest_discover_tests(${name}_test
|
||||
DISCOVERY_MODE PRE_TEST
|
||||
WORKING_DIRECTORY "${TEST_INSTALL_DIR}"
|
||||
)
|
||||
endfunction()
|
||||
|
||||
|
@@ -470,17 +470,3 @@ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
||||
|
||||
if(WITH_COMPILER_CCACHE)
|
||||
if(NOT CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
# Makefiles and ninja
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
|
||||
else()
|
||||
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
|
||||
set(WITH_COMPILER_CCACHE OFF)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -154,32 +154,3 @@ if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode")
|
||||
string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}")
|
||||
endif()
|
||||
|
||||
if(WITH_COMPILER_CCACHE)
|
||||
if(CMAKE_GENERATOR STREQUAL "Xcode")
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
get_filename_component(ccompiler "${CMAKE_C_COMPILER}" NAME)
|
||||
get_filename_component(cxxcompiler "${CMAKE_CXX_COMPILER}" NAME)
|
||||
# Ccache can figure out which compiler to use if it's invoked from
|
||||
# a symlink with the name of the compiler.
|
||||
# https://ccache.dev/manual/4.1.html#_run_modes
|
||||
set(_fake_compiler_dir "${CMAKE_BINARY_DIR}/ccache")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory ${_fake_compiler_dir})
|
||||
set(_fake_C_COMPILER "${_fake_compiler_dir}/${ccompiler}")
|
||||
set(_fake_CXX_COMPILER "${_fake_compiler_dir}/${cxxcompiler}")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_C_COMPILER})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CCACHE_PROGRAM}" ${_fake_CXX_COMPILER})
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC ${_fake_C_COMPILER} CACHE STRING "" FORCE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD ${_fake_C_COMPILER} CACHE STRING "" FORCE)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS ${_fake_CXX_COMPILER} CACHE STRING "" FORCE)
|
||||
unset(_fake_compiler_dir)
|
||||
unset(_fake_C_COMPILER)
|
||||
unset(_fake_CXX_COMPILER)
|
||||
else()
|
||||
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
|
||||
set(WITH_COMPILER_CCACHE OFF)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -684,15 +684,3 @@ set(PLATFORM_LINKFLAGS
|
||||
if(WITH_INSTALL_PORTABLE)
|
||||
string(APPEND CMAKE_EXE_LINKER_FLAGS " -no-pie")
|
||||
endif()
|
||||
|
||||
if(WITH_COMPILER_CCACHE)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
# Makefiles and ninja
|
||||
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "" FORCE)
|
||||
else()
|
||||
message(WARNING "Ccache NOT found, disabling WITH_COMPILER_CCACHE")
|
||||
set(WITH_COMPILER_CCACHE OFF)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -163,13 +163,13 @@ Now in the button's context menu select *Copy Data Path*, then paste the result
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subdivision"].levels
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels
|
||||
|
||||
Press :kbd:`Return` and you'll get the current value of 1. Now try changing the value to 2:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.active_object.modifiers["Subdivision"].levels = 2
|
||||
bpy.context.active_object.modifiers["Subsurf"].levels = 2
|
||||
|
||||
You can see the value update in the Subdivision Surface modifier's UI as well as the cube.
|
||||
|
||||
@@ -185,31 +185,43 @@ For example, if you want to access the texture of a brush via Python to adjust i
|
||||
#. Start in the default scene and enable Sculpt Mode from the 3D Viewport header.
|
||||
#. From the Sidebar expand the Brush Settings panel's *Texture* subpanel and add a new texture.
|
||||
*Notice the texture data-block menu itself doesn't have very useful links (you can check the tooltips).*
|
||||
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the
|
||||
:ref:`Properties Editor <blender_manual:bpy.types.Texture.contrast`
|
||||
#. The contrast setting isn't exposed in the Sidebar, so view the texture in the properties editor:
|
||||
|
||||
- In the properties editor select the Texture tab.
|
||||
- Select brush texture.
|
||||
- Expand the *Colors* panel to locate the *Contrast* number field.
|
||||
#. Open the context menu of the contrast field and select *Online Python Reference*.
|
||||
This takes you to ``bpy.types.Texture.contrast``. Now you can see that ``contrast`` is a property of texture.
|
||||
#. To find out how to access the texture from the brush check on the references at the bottom of the page.
|
||||
Sometimes there are many references, and it may take some guesswork to find the right one,
|
||||
but in this case it's ``tool_settings.sculpt.brush.texture``.
|
||||
but in this case it's ``Brush.texture``.
|
||||
|
||||
#. Now you know that the texture can be accessed from ``bpy.data.brushes["BrushName"].texture``
|
||||
but normally you *won't* want to access the brush by name, instead you want to access the active brush.
|
||||
So the next step is to check on where brushes are accessed from via the references.
|
||||
In this case there it is simply ``bpy.context.brush``.
|
||||
|
||||
Now you can use the Python console to form the nested properties needed to access brush textures contrast:
|
||||
:menuselection:`Context --> Tool Settings --> Sculpt --> Brush --> Texture --> Contrast`.
|
||||
*Context -> Brush -> Texture -> Contrast*.
|
||||
|
||||
Since the attribute for each is given along the way you can compose the data path in the Python console:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.tool_settings.sculpt.brush.texture.contrast
|
||||
bpy.context.brush.texture.contrast
|
||||
|
||||
There can be multiple ways to access the same data, which you choose often depends on the task.
|
||||
An alternate path to access the same setting is:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.context.sculpt.brush.texture.contrast
|
||||
|
||||
Or access the brush directly:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
bpy.data.textures["Texture"].contrast
|
||||
bpy.data.brushes["BrushName"].texture.contrast
|
||||
|
||||
|
||||
If you are writing a user tool normally you want to use the :mod:`bpy.context` since the user normally expects
|
||||
|
@@ -35,13 +35,12 @@ but not to fully cover each topic.
|
||||
|
||||
A quick list of helpful things to know before starting:
|
||||
|
||||
- Enable :ref:`Developer Extra <blender_manual:prefs-interface-dev-extras`
|
||||
and :ref:`Python Tooltips <blender_manual:prefs-interface-tooltips-python>`.
|
||||
- The :ref:`Python Console <blender_manual:bpy.types.SpaceConsole>`
|
||||
is great for testing one-liners; it has autocompletion so you can inspect the API quickly.
|
||||
- Button tooltips show Python attributes and operator names (when enabled see above).
|
||||
- The context menu of buttons directly links to this API documentation (when enabled see above).
|
||||
- Many python examples can be found in the text editor's template menu.
|
||||
- Blender uses Python 3.x; some online documentation still assumes version 2.x.
|
||||
- The interactive console is great for testing one-liners.
|
||||
It also has autocompletion so you can inspect the API quickly.
|
||||
- Button tooltips show Python attributes and operator names.
|
||||
- The context menu of buttons directly links to this API documentation.
|
||||
- More operator examples can be found in the text editor's template menu.
|
||||
- To examine further scripts distributed with Blender, see:
|
||||
|
||||
- ``scripts/startup/bl_ui`` for the user interface.
|
||||
@@ -238,7 +237,7 @@ Examples:
|
||||
{'FINISHED'}
|
||||
>>> bpy.ops.mesh.hide(unselected=False)
|
||||
{'FINISHED'}
|
||||
>>> bpy.ops.object.transform_apply()
|
||||
>>> bpy.ops.object.scale_apply()
|
||||
{'FINISHED'}
|
||||
|
||||
.. tip::
|
||||
|
@@ -24,9 +24,10 @@ The three main use cases for the terminal are:
|
||||
- If the script runs for too long or you accidentally enter an infinite loop,
|
||||
:kbd:`Ctrl-C` in the terminal (:kbd:`Ctrl-Break` on Windows) will quit the script early.
|
||||
|
||||
.. seealso::
|
||||
.. note::
|
||||
|
||||
:ref:`blender_manual:command_line-launch-index`.
|
||||
For Linux and macOS users this means starting the terminal first, then running Blender from within it.
|
||||
On Windows the terminal can be enabled from the Help menu.
|
||||
|
||||
|
||||
Interface Tricks
|
||||
|
@@ -1,5 +1,7 @@
|
||||
/* T76453: Prevent Long enum lists */
|
||||
.field-list li {
|
||||
/* Prevent Long enum lists */
|
||||
.field-body {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-height: 245px;
|
||||
overflow-y: auto !important;
|
||||
}
|
||||
|
@@ -72,9 +72,6 @@ protected:
|
||||
/// The channel mapper reader in between.
|
||||
std::shared_ptr<ChannelMapperReader> m_mapper;
|
||||
|
||||
/// Whether the source is being read for the first time.
|
||||
bool m_first_reading;
|
||||
|
||||
/// Whether to keep the source if end of it is reached.
|
||||
bool m_keep;
|
||||
|
||||
|
19
extern/audaspace/src/devices/SoftwareDevice.cpp
vendored
19
extern/audaspace/src/devices/SoftwareDevice.cpp
vendored
@@ -78,7 +78,7 @@ bool SoftwareDevice::SoftwareHandle::pause(bool keep)
|
||||
}
|
||||
|
||||
SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep) :
|
||||
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_first_reading(true), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
|
||||
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(0.0f), m_old_volume(0.0f), m_loopcount(0),
|
||||
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
|
||||
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
|
||||
m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
|
||||
@@ -106,14 +106,6 @@ void SoftwareDevice::SoftwareHandle::update()
|
||||
if(m_pitch->getSpecs().channels != CHANNELS_MONO)
|
||||
{
|
||||
m_volume = m_user_volume;
|
||||
|
||||
// we don't know a previous volume if this source has never been read before
|
||||
if(m_first_reading)
|
||||
{
|
||||
m_old_volume = m_volume;
|
||||
m_first_reading = false;
|
||||
}
|
||||
|
||||
m_pitch->setPitch(m_user_pitch);
|
||||
return;
|
||||
}
|
||||
@@ -222,13 +214,6 @@ void SoftwareDevice::SoftwareHandle::update()
|
||||
m_volume *= m_user_volume;
|
||||
}
|
||||
|
||||
// we don't know a previous volume if this source has never been read before
|
||||
if(m_first_reading)
|
||||
{
|
||||
m_old_volume = m_volume;
|
||||
m_first_reading = false;
|
||||
}
|
||||
|
||||
// 3D Cue
|
||||
|
||||
Quaternion orientation;
|
||||
@@ -769,8 +754,6 @@ void SoftwareDevice::mix(data_t* buffer, int length)
|
||||
{
|
||||
m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
|
||||
|
||||
sound->m_old_volume = sound->m_volume;
|
||||
|
||||
pos += len;
|
||||
|
||||
if(sound->m_loopcount > 0)
|
||||
|
@@ -22,7 +22,6 @@
|
||||
#include <mutex>
|
||||
|
||||
#define KEEP_TIME 10
|
||||
#define POSITION_EPSILON (1.0 / static_cast<double>(RATE_48000))
|
||||
|
||||
AUD_NAMESPACE_BEGIN
|
||||
|
||||
@@ -65,7 +64,7 @@ bool SequenceHandle::updatePosition(double position)
|
||||
if(m_handle.get())
|
||||
{
|
||||
// we currently have a handle, let's check where we are
|
||||
if(position - POSITION_EPSILON >= m_entry->m_end)
|
||||
if(position >= m_entry->m_end)
|
||||
{
|
||||
if(position >= m_entry->m_end + KEEP_TIME)
|
||||
// far end, stopping
|
||||
@@ -77,7 +76,7 @@ bool SequenceHandle::updatePosition(double position)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if(position + POSITION_EPSILON >= m_entry->m_begin)
|
||||
else if(position >= m_entry->m_begin)
|
||||
{
|
||||
// inside, resuming
|
||||
m_handle->resume();
|
||||
@@ -99,7 +98,7 @@ bool SequenceHandle::updatePosition(double position)
|
||||
else
|
||||
{
|
||||
// we don't have a handle, let's start if we should be playing
|
||||
if(position + POSITION_EPSILON >= m_entry->m_begin && position - POSITION_EPSILON <= m_entry->m_end)
|
||||
if(position >= m_entry->m_begin && position <= m_entry->m_end)
|
||||
{
|
||||
start();
|
||||
return m_valid;
|
||||
|
1
extern/mantaflow/CMakeLists.txt
vendored
1
extern/mantaflow/CMakeLists.txt
vendored
@@ -200,7 +200,6 @@ set(SRC
|
||||
${MANTA_PP}/plugin/ptsplugins.cpp
|
||||
${MANTA_PP}/plugin/secondaryparticles.cpp
|
||||
${MANTA_PP}/plugin/surfaceturbulence.cpp
|
||||
${MANTA_PP}/plugin/viscosity.cpp
|
||||
${MANTA_PP}/plugin/vortexplugins.cpp
|
||||
${MANTA_PP}/plugin/waveletturbulence.cpp
|
||||
${MANTA_PP}/plugin/waves.cpp
|
||||
|
2
extern/mantaflow/helper/util/rcmatrix.h
vendored
2
extern/mantaflow/helper/util/rcmatrix.h
vendored
@@ -1035,7 +1035,7 @@ template<class N, class T> struct RCFixedMatrix {
|
||||
typedef RCMatrix<int, Real> Matrix;
|
||||
typedef RCFixedMatrix<int, Real> FixedMatrix;
|
||||
|
||||
}
|
||||
} // namespace Manta
|
||||
|
||||
#undef parallel_for
|
||||
#undef parallel_end
|
||||
|
94
extern/mantaflow/preprocessed/conjugategrad.cpp
vendored
94
extern/mantaflow/preprocessed/conjugategrad.cpp
vendored
@@ -397,7 +397,7 @@ struct UpdateSearchVec : public KernelBase {
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
// CG class
|
||||
// CG class
|
||||
|
||||
template<class APPLYMAT>
|
||||
GridCg<APPLYMAT>::GridCg(Grid<Real> &dst,
|
||||
@@ -406,8 +406,10 @@ GridCg<APPLYMAT>::GridCg(Grid<Real> &dst,
|
||||
Grid<Real> &search,
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &tmp,
|
||||
std::vector<Grid<Real> *> matrixAVec,
|
||||
std::vector<Grid<Real> *> rhsVec)
|
||||
Grid<Real> *pA0,
|
||||
Grid<Real> *pAi,
|
||||
Grid<Real> *pAj,
|
||||
Grid<Real> *pAk)
|
||||
: GridCgInterface(),
|
||||
mInited(false),
|
||||
mIterations(0),
|
||||
@@ -417,8 +419,10 @@ GridCg<APPLYMAT>::GridCg(Grid<Real> &dst,
|
||||
mSearch(search),
|
||||
mFlags(flags),
|
||||
mTmp(tmp),
|
||||
mMatrixA(matrixAVec),
|
||||
mVecRhs(rhsVec),
|
||||
mpA0(pA0),
|
||||
mpAi(pAi),
|
||||
mpAj(pAj),
|
||||
mpAk(pAk),
|
||||
mPcMethod(PC_None),
|
||||
mpPCA0(nullptr),
|
||||
mpPCAi(nullptr),
|
||||
@@ -441,37 +445,19 @@ template<class APPLYMAT> void GridCg<APPLYMAT>::doInit()
|
||||
|
||||
if (mPcMethod == PC_ICP) {
|
||||
assertMsg(mDst.is3D(), "ICP only supports 3D grids so far");
|
||||
InitPreconditionIncompCholesky(mFlags,
|
||||
*mpPCA0,
|
||||
*mpPCAi,
|
||||
*mpPCAj,
|
||||
*mpPCAk,
|
||||
*mMatrixA[0],
|
||||
*mMatrixA[1],
|
||||
*mMatrixA[2],
|
||||
*mMatrixA[3]);
|
||||
ApplyPreconditionIncompCholesky(mTmp,
|
||||
mResidual,
|
||||
mFlags,
|
||||
*mpPCA0,
|
||||
*mpPCAi,
|
||||
*mpPCAj,
|
||||
*mpPCAk,
|
||||
*mMatrixA[0],
|
||||
*mMatrixA[1],
|
||||
*mMatrixA[2],
|
||||
*mMatrixA[3]);
|
||||
InitPreconditionIncompCholesky(
|
||||
mFlags, *mpPCA0, *mpPCAi, *mpPCAj, *mpPCAk, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
ApplyPreconditionIncompCholesky(
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mpPCAi, *mpPCAj, *mpPCAk, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
}
|
||||
else if (mPcMethod == PC_mICP) {
|
||||
assertMsg(mDst.is3D(), "mICP only supports 3D grids so far");
|
||||
InitPreconditionModifiedIncompCholesky2(
|
||||
mFlags, *mpPCA0, *mMatrixA[0], *mMatrixA[1], *mMatrixA[2], *mMatrixA[3]);
|
||||
InitPreconditionModifiedIncompCholesky2(mFlags, *mpPCA0, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
ApplyPreconditionModifiedIncompCholesky2(
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mMatrixA[0], *mMatrixA[1], *mMatrixA[2], *mMatrixA[3]);
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
}
|
||||
else if (mPcMethod == PC_MGP) {
|
||||
InitPreconditionMultigrid(
|
||||
mMG, *mMatrixA[0], *mMatrixA[1], *mMatrixA[2], *mMatrixA[3], mAccuracy);
|
||||
InitPreconditionMultigrid(mMG, *mpA0, *mpAi, *mpAj, *mpAk, mAccuracy);
|
||||
ApplyPreconditionMultigrid(mMG, mTmp, mResidual);
|
||||
}
|
||||
else {
|
||||
@@ -479,6 +465,7 @@ template<class APPLYMAT> void GridCg<APPLYMAT>::doInit()
|
||||
}
|
||||
|
||||
mSearch.copyFrom(mTmp);
|
||||
|
||||
mSigma = GridDotProduct(mTmp, mResidual);
|
||||
}
|
||||
|
||||
@@ -493,7 +480,7 @@ template<class APPLYMAT> bool GridCg<APPLYMAT>::iterate()
|
||||
// this could reinterpret the mpA pointers (not so clean right now)
|
||||
// tmp = applyMat(search)
|
||||
|
||||
APPLYMAT(mFlags, mTmp, mSearch, mMatrixA, mVecRhs);
|
||||
APPLYMAT(mFlags, mTmp, mSearch, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
|
||||
// alpha = sigma/dot(tmp, search)
|
||||
Real dp = GridDotProduct(mTmp, mSearch);
|
||||
@@ -505,20 +492,11 @@ template<class APPLYMAT> bool GridCg<APPLYMAT>::iterate()
|
||||
gridScaledAdd<Real, Real>(mResidual, mTmp, -alpha); // residual += tmp * -alpha
|
||||
|
||||
if (mPcMethod == PC_ICP)
|
||||
ApplyPreconditionIncompCholesky(mTmp,
|
||||
mResidual,
|
||||
mFlags,
|
||||
*mpPCA0,
|
||||
*mpPCAi,
|
||||
*mpPCAj,
|
||||
*mpPCAk,
|
||||
*mMatrixA[0],
|
||||
*mMatrixA[1],
|
||||
*mMatrixA[2],
|
||||
*mMatrixA[3]);
|
||||
ApplyPreconditionIncompCholesky(
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mpPCAi, *mpPCAj, *mpPCAk, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
else if (mPcMethod == PC_mICP)
|
||||
ApplyPreconditionModifiedIncompCholesky2(
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mMatrixA[0], *mMatrixA[1], *mMatrixA[2], *mMatrixA[3]);
|
||||
mTmp, mResidual, mFlags, *mpPCA0, *mpA0, *mpAi, *mpAj, *mpAk);
|
||||
else if (mPcMethod == PC_MGP)
|
||||
ApplyPreconditionMultigrid(mMG, mTmp, mResidual);
|
||||
else
|
||||
@@ -606,15 +584,13 @@ void GridCg<APPLYMAT>::setMGPreconditioner(PreconditionType method, GridMg *MG)
|
||||
assertMsg(method == PC_MGP, "GridCg<APPLYMAT>::setMGPreconditioner: Invalid method specified.");
|
||||
|
||||
mPcMethod = method;
|
||||
|
||||
mMG = MG;
|
||||
}
|
||||
|
||||
// explicit instantiation
|
||||
template class GridCg<ApplyMatrix>;
|
||||
template class GridCg<ApplyMatrix2D>;
|
||||
template class GridCg<ApplyMatrixViscosityU>;
|
||||
template class GridCg<ApplyMatrixViscosityV>;
|
||||
template class GridCg<ApplyMatrixViscosityW>;
|
||||
|
||||
//*****************************************************************************
|
||||
// diffusion for real and vec grids, e.g. for viscosity
|
||||
@@ -662,15 +638,10 @@ void cgSolveDiffusion(const FlagGrid &flags,
|
||||
if (grid.getType() & GridBase::TypeReal) {
|
||||
Grid<Real> &u = ((Grid<Real> &)grid);
|
||||
rhs.copyFrom(u);
|
||||
vector<Grid<Real> *> matA{&A0, &Ai, &Aj};
|
||||
|
||||
if (flags.is3D()) {
|
||||
matA.push_back(&Ak);
|
||||
gcg = new GridCg<ApplyMatrix>(u, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
else {
|
||||
gcg = new GridCg<ApplyMatrix2D>(u, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
if (flags.is3D())
|
||||
gcg = new GridCg<ApplyMatrix>(u, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
else
|
||||
gcg = new GridCg<ApplyMatrix2D>(u, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
|
||||
gcg->setAccuracy(cgAccuracy);
|
||||
gcg->solve(maxIter);
|
||||
@@ -682,17 +653,12 @@ void cgSolveDiffusion(const FlagGrid &flags,
|
||||
else if ((grid.getType() & GridBase::TypeVec3) || (grid.getType() & GridBase::TypeMAC)) {
|
||||
Grid<Vec3> &vec = ((Grid<Vec3> &)grid);
|
||||
Grid<Real> u(parent);
|
||||
vector<Grid<Real> *> matA{&A0, &Ai, &Aj};
|
||||
|
||||
// core solve is same as for a regular real grid
|
||||
if (flags.is3D()) {
|
||||
matA.push_back(&Ak);
|
||||
gcg = new GridCg<ApplyMatrix>(u, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
else {
|
||||
gcg = new GridCg<ApplyMatrix2D>(u, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
|
||||
if (flags.is3D())
|
||||
gcg = new GridCg<ApplyMatrix>(u, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
else
|
||||
gcg = new GridCg<ApplyMatrix2D>(u, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
gcg->setAccuracy(cgAccuracy);
|
||||
|
||||
// diffuse every component separately
|
||||
|
468
extern/mantaflow/preprocessed/conjugategrad.h
vendored
468
extern/mantaflow/preprocessed/conjugategrad.h
vendored
@@ -78,9 +78,13 @@ template<class APPLYMAT> class GridCg : public GridCgInterface {
|
||||
Grid<Real> &search,
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &tmp,
|
||||
std::vector<Grid<Real> *> matrixAVec,
|
||||
std::vector<Grid<Real> *> rhsVec = {});
|
||||
~GridCg(){};
|
||||
Grid<Real> *A0,
|
||||
Grid<Real> *pAi,
|
||||
Grid<Real> *pAj,
|
||||
Grid<Real> *pAk);
|
||||
~GridCg()
|
||||
{
|
||||
}
|
||||
|
||||
void doInit();
|
||||
bool iterate();
|
||||
@@ -129,10 +133,7 @@ template<class APPLYMAT> class GridCg : public GridCgInterface {
|
||||
const FlagGrid &mFlags;
|
||||
Grid<Real> &mTmp;
|
||||
|
||||
//! shape of A matrix defined here (e.g. diagonal, positive neighbor cells, etc)
|
||||
std::vector<Grid<Real> *> mMatrixA;
|
||||
//! shape of rhs vector defined here (e.g. 1 rhs for regular fluids solve, 3 rhs for viscosity)
|
||||
std::vector<Grid<Real> *> mVecRhs;
|
||||
Grid<Real> *mpA0, *mpAi, *mpAj, *mpAk;
|
||||
|
||||
PreconditionType mPcMethod;
|
||||
//! preconditioning grids
|
||||
@@ -153,9 +154,11 @@ struct ApplyMatrix : public KernelBase {
|
||||
ApplyMatrix(const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs)
|
||||
: KernelBase(&flags, 0), flags(flags), dst(dst), src(src), matrixA(matrixA), vecRhs(vecRhs)
|
||||
Grid<Real> &A0,
|
||||
Grid<Real> &Ai,
|
||||
Grid<Real> &Aj,
|
||||
Grid<Real> &Ak)
|
||||
: KernelBase(&flags, 0), flags(flags), dst(dst), src(src), A0(A0), Ai(Ai), Aj(Aj), Ak(Ak)
|
||||
{
|
||||
runMessage();
|
||||
run();
|
||||
@@ -164,18 +167,11 @@ struct ApplyMatrix : public KernelBase {
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs) const
|
||||
Grid<Real> &A0,
|
||||
Grid<Real> &Ai,
|
||||
Grid<Real> &Aj,
|
||||
Grid<Real> &Ak) const
|
||||
{
|
||||
unusedParameter(vecRhs); // Not needed in this matrix application
|
||||
|
||||
if (matrixA.size() != 4)
|
||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
||||
Grid<Real> &A0 = *matrixA[0];
|
||||
Grid<Real> &Ai = *matrixA[1];
|
||||
Grid<Real> &Aj = *matrixA[2];
|
||||
Grid<Real> &Ak = *matrixA[3];
|
||||
|
||||
if (!flags.isFluid(idx)) {
|
||||
dst[idx] = src[idx];
|
||||
return;
|
||||
@@ -200,16 +196,26 @@ struct ApplyMatrix : public KernelBase {
|
||||
return src;
|
||||
}
|
||||
typedef Grid<Real> type2;
|
||||
inline const std::vector<Grid<Real> *> &getArg3()
|
||||
inline Grid<Real> &getArg3()
|
||||
{
|
||||
return matrixA;
|
||||
return A0;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type3;
|
||||
inline const std::vector<Grid<Real> *> &getArg4()
|
||||
typedef Grid<Real> type3;
|
||||
inline Grid<Real> &getArg4()
|
||||
{
|
||||
return vecRhs;
|
||||
return Ai;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type4;
|
||||
typedef Grid<Real> type4;
|
||||
inline Grid<Real> &getArg5()
|
||||
{
|
||||
return Aj;
|
||||
}
|
||||
typedef Grid<Real> type5;
|
||||
inline Grid<Real> &getArg6()
|
||||
{
|
||||
return Ak;
|
||||
}
|
||||
typedef Grid<Real> type6;
|
||||
void runMessage()
|
||||
{
|
||||
debMsg("Executing kernel ApplyMatrix ", 3);
|
||||
@@ -220,7 +226,7 @@ struct ApplyMatrix : public KernelBase {
|
||||
void operator()(const tbb::blocked_range<IndexInt> &__r) const
|
||||
{
|
||||
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
|
||||
op(idx, flags, dst, src, matrixA, vecRhs);
|
||||
op(idx, flags, dst, src, A0, Ai, Aj, Ak);
|
||||
}
|
||||
void run()
|
||||
{
|
||||
@@ -229,8 +235,10 @@ struct ApplyMatrix : public KernelBase {
|
||||
const FlagGrid &flags;
|
||||
Grid<Real> &dst;
|
||||
const Grid<Real> &src;
|
||||
const std::vector<Grid<Real> *> matrixA;
|
||||
const std::vector<Grid<Real> *> vecRhs;
|
||||
Grid<Real> &A0;
|
||||
Grid<Real> &Ai;
|
||||
Grid<Real> &Aj;
|
||||
Grid<Real> &Ak;
|
||||
};
|
||||
|
||||
//! Kernel: Apply symmetric stored Matrix. 2D version
|
||||
@@ -239,9 +247,11 @@ struct ApplyMatrix2D : public KernelBase {
|
||||
ApplyMatrix2D(const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs)
|
||||
: KernelBase(&flags, 0), flags(flags), dst(dst), src(src), matrixA(matrixA), vecRhs(vecRhs)
|
||||
Grid<Real> &A0,
|
||||
Grid<Real> &Ai,
|
||||
Grid<Real> &Aj,
|
||||
Grid<Real> &Ak)
|
||||
: KernelBase(&flags, 0), flags(flags), dst(dst), src(src), A0(A0), Ai(Ai), Aj(Aj), Ak(Ak)
|
||||
{
|
||||
runMessage();
|
||||
run();
|
||||
@@ -250,16 +260,12 @@ struct ApplyMatrix2D : public KernelBase {
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs) const
|
||||
Grid<Real> &A0,
|
||||
Grid<Real> &Ai,
|
||||
Grid<Real> &Aj,
|
||||
Grid<Real> &Ak) const
|
||||
{
|
||||
unusedParameter(vecRhs); // Not needed in this matrix application
|
||||
|
||||
if (matrixA.size() != 3)
|
||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
||||
Grid<Real> &A0 = *matrixA[0];
|
||||
Grid<Real> &Ai = *matrixA[1];
|
||||
Grid<Real> &Aj = *matrixA[2];
|
||||
unusedParameter(Ak); // only there for parameter compatibility with ApplyMatrix
|
||||
|
||||
if (!flags.isFluid(idx)) {
|
||||
dst[idx] = src[idx];
|
||||
@@ -284,16 +290,26 @@ struct ApplyMatrix2D : public KernelBase {
|
||||
return src;
|
||||
}
|
||||
typedef Grid<Real> type2;
|
||||
inline const std::vector<Grid<Real> *> &getArg3()
|
||||
inline Grid<Real> &getArg3()
|
||||
{
|
||||
return matrixA;
|
||||
return A0;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type3;
|
||||
inline const std::vector<Grid<Real> *> &getArg4()
|
||||
typedef Grid<Real> type3;
|
||||
inline Grid<Real> &getArg4()
|
||||
{
|
||||
return vecRhs;
|
||||
return Ai;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type4;
|
||||
typedef Grid<Real> type4;
|
||||
inline Grid<Real> &getArg5()
|
||||
{
|
||||
return Aj;
|
||||
}
|
||||
typedef Grid<Real> type5;
|
||||
inline Grid<Real> &getArg6()
|
||||
{
|
||||
return Ak;
|
||||
}
|
||||
typedef Grid<Real> type6;
|
||||
void runMessage()
|
||||
{
|
||||
debMsg("Executing kernel ApplyMatrix2D ", 3);
|
||||
@@ -304,7 +320,7 @@ struct ApplyMatrix2D : public KernelBase {
|
||||
void operator()(const tbb::blocked_range<IndexInt> &__r) const
|
||||
{
|
||||
for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++)
|
||||
op(idx, flags, dst, src, matrixA, vecRhs);
|
||||
op(idx, flags, dst, src, A0, Ai, Aj, Ak);
|
||||
}
|
||||
void run()
|
||||
{
|
||||
@@ -313,358 +329,12 @@ struct ApplyMatrix2D : public KernelBase {
|
||||
const FlagGrid &flags;
|
||||
Grid<Real> &dst;
|
||||
const Grid<Real> &src;
|
||||
const std::vector<Grid<Real> *> matrixA;
|
||||
const std::vector<Grid<Real> *> vecRhs;
|
||||
Grid<Real> &A0;
|
||||
Grid<Real> &Ai;
|
||||
Grid<Real> &Aj;
|
||||
Grid<Real> &Ak;
|
||||
};
|
||||
|
||||
struct ApplyMatrixViscosityU : public KernelBase {
|
||||
ApplyMatrixViscosityU(const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs)
|
||||
: KernelBase(&flags, 1), flags(flags), dst(dst), src(src), matrixA(matrixA), vecRhs(vecRhs)
|
||||
{
|
||||
runMessage();
|
||||
run();
|
||||
}
|
||||
inline void op(int i,
|
||||
int j,
|
||||
int k,
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs) const
|
||||
{
|
||||
if (matrixA.size() != 15)
|
||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
||||
Grid<Real> &A0 = *matrixA[0];
|
||||
Grid<Real> &Aplusi = *matrixA[1];
|
||||
Grid<Real> &Aplusj = *matrixA[2];
|
||||
Grid<Real> &Aplusk = *matrixA[3];
|
||||
Grid<Real> &Aminusi = *matrixA[4];
|
||||
Grid<Real> &Aminusj = *matrixA[5];
|
||||
Grid<Real> &Aminusk = *matrixA[6];
|
||||
|
||||
if (vecRhs.size() != 2)
|
||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
||||
Grid<Real> &srcV = *vecRhs[0];
|
||||
Grid<Real> &srcW = *vecRhs[1];
|
||||
|
||||
dst(i, j, k) = src(i, j, k) * A0(i, j, k) + src(i + 1, j, k) * Aplusi(i, j, k) +
|
||||
src(i, j + 1, k) * Aplusj(i, j, k) + src(i, j, k + 1) * Aplusk(i, j, k) +
|
||||
src(i - 1, j, k) * Aminusi(i, j, k) + src(i, j - 1, k) * Aminusj(i, j, k) +
|
||||
src(i, j, k - 1) * Aminusk(i, j, k);
|
||||
|
||||
dst(i, j, k) += srcV(i, j + 1, k) * (*matrixA[7])(i, j, k) +
|
||||
srcV(i - 1, j + 1, k) * (*matrixA[8])(i, j, k) +
|
||||
srcV(i, j, k) * (*matrixA[9])(i, j, k) +
|
||||
srcV(i - 1, j, k) * (*matrixA[10])(i, j, k) +
|
||||
srcW(i, j, k + 1) * (*matrixA[11])(i, j, k) +
|
||||
srcW(i - 1, j, k + 1) * (*matrixA[12])(i, j, k) +
|
||||
srcW(i, j, k) * (*matrixA[13])(i, j, k) +
|
||||
srcW(i - 1, j, k) * (*matrixA[14])(i, j, k);
|
||||
}
|
||||
inline const FlagGrid &getArg0()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
typedef FlagGrid type0;
|
||||
inline Grid<Real> &getArg1()
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
typedef Grid<Real> type1;
|
||||
inline const Grid<Real> &getArg2()
|
||||
{
|
||||
return src;
|
||||
}
|
||||
typedef Grid<Real> type2;
|
||||
inline const std::vector<Grid<Real> *> &getArg3()
|
||||
{
|
||||
return matrixA;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type3;
|
||||
inline const std::vector<Grid<Real> *> &getArg4()
|
||||
{
|
||||
return vecRhs;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type4;
|
||||
void runMessage()
|
||||
{
|
||||
debMsg("Executing kernel ApplyMatrixViscosityU ", 3);
|
||||
debMsg("Kernel range"
|
||||
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
|
||||
4);
|
||||
};
|
||||
void operator()(const tbb::blocked_range<IndexInt> &__r) const
|
||||
{
|
||||
const int _maxX = maxX;
|
||||
const int _maxY = maxY;
|
||||
if (maxZ > 1) {
|
||||
for (int k = __r.begin(); k != (int)__r.end(); k++)
|
||||
for (int j = 1; j < _maxY; j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
else {
|
||||
const int k = 0;
|
||||
for (int j = __r.begin(); j != (int)__r.end(); j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
}
|
||||
void run()
|
||||
{
|
||||
if (maxZ > 1)
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
|
||||
else
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
|
||||
}
|
||||
const FlagGrid &flags;
|
||||
Grid<Real> &dst;
|
||||
const Grid<Real> &src;
|
||||
const std::vector<Grid<Real> *> matrixA;
|
||||
const std::vector<Grid<Real> *> vecRhs;
|
||||
};
|
||||
|
||||
struct ApplyMatrixViscosityV : public KernelBase {
|
||||
ApplyMatrixViscosityV(const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs)
|
||||
: KernelBase(&flags, 1), flags(flags), dst(dst), src(src), matrixA(matrixA), vecRhs(vecRhs)
|
||||
{
|
||||
runMessage();
|
||||
run();
|
||||
}
|
||||
inline void op(int i,
|
||||
int j,
|
||||
int k,
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs) const
|
||||
{
|
||||
if (matrixA.size() != 15)
|
||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
||||
Grid<Real> &A0 = *matrixA[0];
|
||||
Grid<Real> &Aplusi = *matrixA[1];
|
||||
Grid<Real> &Aplusj = *matrixA[2];
|
||||
Grid<Real> &Aplusk = *matrixA[3];
|
||||
Grid<Real> &Aminusi = *matrixA[4];
|
||||
Grid<Real> &Aminusj = *matrixA[5];
|
||||
Grid<Real> &Aminusk = *matrixA[6];
|
||||
|
||||
if (vecRhs.size() != 2)
|
||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
||||
Grid<Real> &srcU = *vecRhs[0];
|
||||
Grid<Real> &srcW = *vecRhs[1];
|
||||
|
||||
dst(i, j, k) = src(i, j, k) * A0(i, j, k) + src(i + 1, j, k) * Aplusi(i, j, k) +
|
||||
src(i, j + 1, k) * Aplusj(i, j, k) + src(i, j, k + 1) * Aplusk(i, j, k) +
|
||||
src(i - 1, j, k) * Aminusi(i, j, k) + src(i, j - 1, k) * Aminusj(i, j, k) +
|
||||
src(i, j, k - 1) * Aminusk(i, j, k);
|
||||
|
||||
dst(i, j, k) += srcU(i + 1, j, k) * (*matrixA[7])(i, j, k) +
|
||||
srcU(i + 1, j - 1, k) * (*matrixA[8])(i, j, k) +
|
||||
srcU(i, j, k) * (*matrixA[9])(i, j, k) +
|
||||
srcU(i, j - 1, k) * (*matrixA[10])(i, j, k) +
|
||||
srcW(i, j, k + 1) * (*matrixA[11])(i, j, k) +
|
||||
srcW(i, j - 1, k + 1) * (*matrixA[12])(i, j, k) +
|
||||
srcW(i, j, k) * (*matrixA[13])(i, j, k) +
|
||||
srcW(i, j - 1, k) * (*matrixA[14])(i, j, k);
|
||||
}
|
||||
inline const FlagGrid &getArg0()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
typedef FlagGrid type0;
|
||||
inline Grid<Real> &getArg1()
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
typedef Grid<Real> type1;
|
||||
inline const Grid<Real> &getArg2()
|
||||
{
|
||||
return src;
|
||||
}
|
||||
typedef Grid<Real> type2;
|
||||
inline const std::vector<Grid<Real> *> &getArg3()
|
||||
{
|
||||
return matrixA;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type3;
|
||||
inline const std::vector<Grid<Real> *> &getArg4()
|
||||
{
|
||||
return vecRhs;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type4;
|
||||
void runMessage()
|
||||
{
|
||||
debMsg("Executing kernel ApplyMatrixViscosityV ", 3);
|
||||
debMsg("Kernel range"
|
||||
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
|
||||
4);
|
||||
};
|
||||
void operator()(const tbb::blocked_range<IndexInt> &__r) const
|
||||
{
|
||||
const int _maxX = maxX;
|
||||
const int _maxY = maxY;
|
||||
if (maxZ > 1) {
|
||||
for (int k = __r.begin(); k != (int)__r.end(); k++)
|
||||
for (int j = 1; j < _maxY; j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
else {
|
||||
const int k = 0;
|
||||
for (int j = __r.begin(); j != (int)__r.end(); j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
}
|
||||
void run()
|
||||
{
|
||||
if (maxZ > 1)
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
|
||||
else
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
|
||||
}
|
||||
const FlagGrid &flags;
|
||||
Grid<Real> &dst;
|
||||
const Grid<Real> &src;
|
||||
const std::vector<Grid<Real> *> matrixA;
|
||||
const std::vector<Grid<Real> *> vecRhs;
|
||||
};
|
||||
|
||||
struct ApplyMatrixViscosityW : public KernelBase {
|
||||
ApplyMatrixViscosityW(const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs)
|
||||
: KernelBase(&flags, 1), flags(flags), dst(dst), src(src), matrixA(matrixA), vecRhs(vecRhs)
|
||||
{
|
||||
runMessage();
|
||||
run();
|
||||
}
|
||||
inline void op(int i,
|
||||
int j,
|
||||
int k,
|
||||
const FlagGrid &flags,
|
||||
Grid<Real> &dst,
|
||||
const Grid<Real> &src,
|
||||
const std::vector<Grid<Real> *> matrixA,
|
||||
const std::vector<Grid<Real> *> vecRhs) const
|
||||
{
|
||||
if (matrixA.size() != 15)
|
||||
errMsg("ConjugatedGrad: Invalid A matrix in apply matrix step");
|
||||
Grid<Real> &A0 = *matrixA[0];
|
||||
Grid<Real> &Aplusi = *matrixA[1];
|
||||
Grid<Real> &Aplusj = *matrixA[2];
|
||||
Grid<Real> &Aplusk = *matrixA[3];
|
||||
Grid<Real> &Aminusi = *matrixA[4];
|
||||
Grid<Real> &Aminusj = *matrixA[5];
|
||||
Grid<Real> &Aminusk = *matrixA[6];
|
||||
|
||||
if (vecRhs.size() != 2)
|
||||
errMsg("ConjugatedGrad: Invalid rhs vector in apply matrix step");
|
||||
Grid<Real> &srcU = *vecRhs[0];
|
||||
Grid<Real> &srcV = *vecRhs[1];
|
||||
|
||||
dst(i, j, k) = src(i, j, k) * A0(i, j, k) + src(i + 1, j, k) * Aplusi(i, j, k) +
|
||||
src(i, j + 1, k) * Aplusj(i, j, k) + src(i, j, k + 1) * Aplusk(i, j, k) +
|
||||
src(i - 1, j, k) * Aminusi(i, j, k) + src(i, j - 1, k) * Aminusj(i, j, k) +
|
||||
src(i, j, k - 1) * Aminusk(i, j, k);
|
||||
|
||||
dst(i, j, k) += srcU(i + 1, j, k) * (*matrixA[7])(i, j, k) +
|
||||
srcU(i + 1, j, k - 1) * (*matrixA[8])(i, j, k) +
|
||||
srcU(i, j, k) * (*matrixA[9])(i, j, k) +
|
||||
srcU(i, j, k - 1) * (*matrixA[10])(i, j, k) +
|
||||
srcV(i, j + 1, k) * (*matrixA[11])(i, j, k) +
|
||||
srcV(i, j + 1, k - 1) * (*matrixA[12])(i, j, k) +
|
||||
srcV(i, j, k) * (*matrixA[13])(i, j, k) +
|
||||
srcV(i, j, k - 1) * (*matrixA[14])(i, j, k);
|
||||
}
|
||||
inline const FlagGrid &getArg0()
|
||||
{
|
||||
return flags;
|
||||
}
|
||||
typedef FlagGrid type0;
|
||||
inline Grid<Real> &getArg1()
|
||||
{
|
||||
return dst;
|
||||
}
|
||||
typedef Grid<Real> type1;
|
||||
inline const Grid<Real> &getArg2()
|
||||
{
|
||||
return src;
|
||||
}
|
||||
typedef Grid<Real> type2;
|
||||
inline const std::vector<Grid<Real> *> &getArg3()
|
||||
{
|
||||
return matrixA;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type3;
|
||||
inline const std::vector<Grid<Real> *> &getArg4()
|
||||
{
|
||||
return vecRhs;
|
||||
}
|
||||
typedef std::vector<Grid<Real> *> type4;
|
||||
void runMessage()
|
||||
{
|
||||
debMsg("Executing kernel ApplyMatrixViscosityW ", 3);
|
||||
debMsg("Kernel range"
|
||||
<< " x " << maxX << " y " << maxY << " z " << minZ << " - " << maxZ << " ",
|
||||
4);
|
||||
};
|
||||
void operator()(const tbb::blocked_range<IndexInt> &__r) const
|
||||
{
|
||||
const int _maxX = maxX;
|
||||
const int _maxY = maxY;
|
||||
if (maxZ > 1) {
|
||||
for (int k = __r.begin(); k != (int)__r.end(); k++)
|
||||
for (int j = 1; j < _maxY; j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
else {
|
||||
const int k = 0;
|
||||
for (int j = __r.begin(); j != (int)__r.end(); j++)
|
||||
for (int i = 1; i < _maxX; i++)
|
||||
op(i, j, k, flags, dst, src, matrixA, vecRhs);
|
||||
}
|
||||
}
|
||||
void run()
|
||||
{
|
||||
if (maxZ > 1)
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(minZ, maxZ), *this);
|
||||
else
|
||||
tbb::parallel_for(tbb::blocked_range<IndexInt>(1, maxY), *this);
|
||||
}
|
||||
const FlagGrid &flags;
|
||||
Grid<Real> &dst;
|
||||
const Grid<Real> &src;
|
||||
const std::vector<Grid<Real> *> matrixA;
|
||||
const std::vector<Grid<Real> *> vecRhs;
|
||||
};
|
||||
|
||||
/* NOTE: Use this template for new matrix application kernels
|
||||
|
||||
//! Template for matrix application kernels
|
||||
KERNEL()
|
||||
void ApplyMatrixTemplate (const FlagGrid& flags, Grid<Real>& dst, const Grid<Real>& src,
|
||||
const std::vector<Grid<Real> *> matrixA, const std::vector<Grid<Real> *> vecRhs)
|
||||
{
|
||||
// The kernel must define how to use the grids from the matrixA and vecRhs lists
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//! Kernel: Construct the matrix for the poisson equation
|
||||
|
||||
struct MakeLaplaceMatrix : public KernelBase {
|
||||
|
19
extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
19
extern/mantaflow/preprocessed/fileio/iovdb.cpp
vendored
@@ -423,14 +423,13 @@ int writeObjectsVDB(const string &filename,
|
||||
|
||||
if (GridBase *mantaGrid = dynamic_cast<GridBase *>(*iter)) {
|
||||
|
||||
if (clipGrid) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size");
|
||||
}
|
||||
if (mantaGrid->getType() & GridBase::TypeInt) {
|
||||
debMsg("Writing int grid '" << mantaGrid->getName() << "' to vdb file " << filename, 1);
|
||||
Grid<int> *mantaIntGrid = (Grid<int> *)mantaGrid;
|
||||
if (clipGrid && mantaIntGrid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<int, openvdb::Int32Grid>(mantaIntGrid, clip, vdbClipGrid);
|
||||
gridsVDB.push_back(vdbGrid);
|
||||
}
|
||||
@@ -441,11 +440,6 @@ int writeObjectsVDB(const string &filename,
|
||||
Grid<Real> *mantaRealGrid = (Grid<Real> *)mantaGrid;
|
||||
// Only supply clip grid if real grid is not equal to the clip grid
|
||||
openvdb::FloatGrid::Ptr tmpClipGrid = (mantaRealGrid == clipGrid) ? nullptr : vdbClipGrid;
|
||||
if (clipGrid && mantaRealGrid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<Real, openvdb::FloatGrid>(mantaRealGrid, clip, tmpClipGrid);
|
||||
gridsVDB.push_back(vdbGrid);
|
||||
}
|
||||
@@ -454,11 +448,6 @@ int writeObjectsVDB(const string &filename,
|
||||
gClass = (mantaGrid->getType() & GridBase::TypeMAC) ? openvdb::GRID_STAGGERED :
|
||||
openvdb::GRID_UNKNOWN;
|
||||
Grid<Vec3> *mantaVec3Grid = (Grid<Vec3> *)mantaGrid;
|
||||
if (clipGrid && mantaVec3Grid->saveSparse()) {
|
||||
assertMsg(clipGrid->getSize() == mantaGrid->getSize(),
|
||||
"writeObjectsVDB: Clip grid and exported grid must have the same size "
|
||||
<< clipGrid->getSize() << " vs " << mantaGrid->getSize());
|
||||
}
|
||||
vdbGrid = exportVDB<Vec3, openvdb::Vec3SGrid>(mantaVec3Grid, clip, vdbClipGrid);
|
||||
gridsVDB.push_back(vdbGrid);
|
||||
}
|
||||
|
35
extern/mantaflow/preprocessed/general.h
vendored
35
extern/mantaflow/preprocessed/general.h
vendored
@@ -42,7 +42,7 @@ inline void updateQtGui(bool full, int frame, float time, const std::string &cur
|
||||
# ifdef _DEBUG
|
||||
# define DEBUG 1
|
||||
# endif // _DEBUG
|
||||
#endif // DEBUG
|
||||
#endif // DEBUG
|
||||
|
||||
// Standard exception
|
||||
class Error : public std::exception {
|
||||
@@ -242,39 +242,6 @@ inline bool c_isnan(float c)
|
||||
return d != d;
|
||||
}
|
||||
|
||||
//! Swap so that a<b
|
||||
template<class T> inline void sort(T &a, T &b)
|
||||
{
|
||||
if (a > b)
|
||||
std::swap(a, b);
|
||||
}
|
||||
|
||||
//! Swap so that a<b<c
|
||||
template<class T> inline void sort(T &a, T &b, T &c)
|
||||
{
|
||||
if (a > b)
|
||||
std::swap(a, b);
|
||||
if (a > c)
|
||||
std::swap(a, c);
|
||||
if (b > c)
|
||||
std::swap(b, c);
|
||||
}
|
||||
|
||||
//! Swap so that a<b<c<d
|
||||
template<class T> inline void sort(T &a, T &b, T &c, T &d)
|
||||
{
|
||||
if (a > b)
|
||||
std::swap(a, b);
|
||||
if (c > d)
|
||||
std::swap(c, d);
|
||||
if (a > c)
|
||||
std::swap(a, c);
|
||||
if (b > d)
|
||||
std::swap(b, d);
|
||||
if (b > c)
|
||||
std::swap(b, c);
|
||||
}
|
||||
|
||||
} // namespace Manta
|
||||
|
||||
#endif
|
||||
|
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
2
extern/mantaflow/preprocessed/gitinfo.h
vendored
@@ -1,3 +1,3 @@
|
||||
|
||||
|
||||
#define MANTA_GIT_VERSION "commit e2285cb9bc492987f728123be6cfc1fe11fe73d6"
|
||||
#define MANTA_GIT_VERSION "commit 327917cd59b03bef3a953b5f58fc1637b3a83e01"
|
||||
|
@@ -1135,27 +1135,26 @@ struct KnAddForceIfLower : public KernelBase {
|
||||
if (!curFluid && !curEmpty)
|
||||
return;
|
||||
|
||||
Real minVal, maxVal, sum;
|
||||
if (flags.isFluid(i - 1, j, k) || (curFluid && flags.isEmpty(i - 1, j, k))) {
|
||||
Real forceMACX = 0.5 * (force(i - 1, j, k).x + force(i, j, k).x);
|
||||
minVal = min(vel(i, j, k).x, forceMACX);
|
||||
maxVal = max(vel(i, j, k).x, forceMACX);
|
||||
sum = vel(i, j, k).x + forceMACX;
|
||||
vel(i, j, k).x = (forceMACX > 0) ? min(sum, maxVal) : max(sum, minVal);
|
||||
Real min = std::min(vel(i, j, k).x, forceMACX);
|
||||
Real max = std::max(vel(i, j, k).x, forceMACX);
|
||||
Real sum = vel(i, j, k).x + forceMACX;
|
||||
vel(i, j, k).x = (forceMACX > 0) ? std::min(sum, max) : std::max(sum, min);
|
||||
}
|
||||
if (flags.isFluid(i, j - 1, k) || (curFluid && flags.isEmpty(i, j - 1, k))) {
|
||||
Real forceMACY = 0.5 * (force(i, j - 1, k).y + force(i, j, k).y);
|
||||
minVal = min(vel(i, j, k).y, forceMACY);
|
||||
maxVal = max(vel(i, j, k).y, forceMACY);
|
||||
sum = vel(i, j, k).y + forceMACY;
|
||||
vel(i, j, k).y = (forceMACY > 0) ? min(sum, maxVal) : max(sum, minVal);
|
||||
Real min = std::min(vel(i, j, k).y, forceMACY);
|
||||
Real max = std::max(vel(i, j, k).y, forceMACY);
|
||||
Real sum = vel(i, j, k).y + forceMACY;
|
||||
vel(i, j, k).y = (forceMACY > 0) ? std::min(sum, max) : std::max(sum, min);
|
||||
}
|
||||
if (vel.is3D() && (flags.isFluid(i, j, k - 1) || (curFluid && flags.isEmpty(i, j, k - 1)))) {
|
||||
Real forceMACZ = 0.5 * (force(i, j, k - 1).z + force(i, j, k).z);
|
||||
minVal = min(vel(i, j, k).z, forceMACZ);
|
||||
maxVal = max(vel(i, j, k).z, forceMACZ);
|
||||
sum = vel(i, j, k).z + forceMACZ;
|
||||
vel(i, j, k).z = (forceMACZ > 0) ? min(sum, maxVal) : max(sum, minVal);
|
||||
Real min = std::min(vel(i, j, k).z, forceMACZ);
|
||||
Real max = std::max(vel(i, j, k).z, forceMACZ);
|
||||
Real sum = vel(i, j, k).z + forceMACZ;
|
||||
vel(i, j, k).z = (forceMACZ > 0) ? std::min(sum, max) : std::max(sum, min);
|
||||
}
|
||||
}
|
||||
inline const FlagGrid &getArg0()
|
||||
|
@@ -1138,15 +1138,11 @@ void solvePressureSystem(Grid<Real> &rhs,
|
||||
// note: the last factor increases the max iterations for 2d, which right now can't use a
|
||||
// preconditioner
|
||||
GridCgInterface *gcg;
|
||||
vector<Grid<Real> *> matA{&A0, &Ai, &Aj};
|
||||
|
||||
if (vel.is3D()) {
|
||||
matA.push_back(&Ak);
|
||||
gcg = new GridCg<ApplyMatrix>(pressure, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
else {
|
||||
gcg = new GridCg<ApplyMatrix2D>(pressure, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
if (vel.is3D())
|
||||
gcg = new GridCg<ApplyMatrix>(pressure, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
else
|
||||
gcg = new GridCg<ApplyMatrix2D>(
|
||||
pressure, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
|
||||
gcg->setAccuracy(cgAccuracy);
|
||||
gcg->setUseL2Norm(useL2Norm);
|
||||
|
1430
extern/mantaflow/preprocessed/plugin/viscosity.cpp
vendored
1430
extern/mantaflow/preprocessed/plugin/viscosity.cpp
vendored
File diff suppressed because it is too large
Load Diff
@@ -576,10 +576,8 @@ void VICintegration(VortexSheetMesh &mesh,
|
||||
|
||||
// prepare CG solver
|
||||
const int maxIter = (int)(cgMaxIterFac * vel.getSize().max());
|
||||
vector<Grid<Real> *> matA{&A0, &Ai, &Aj, &Ak};
|
||||
|
||||
GridCgInterface *gcg = new GridCg<ApplyMatrix>(
|
||||
solution, rhs, residual, search, flags, temp1, matA);
|
||||
solution, rhs, residual, search, flags, temp1, &A0, &Ai, &Aj, &Ak);
|
||||
gcg->setAccuracy(cgAccuracy);
|
||||
gcg->setUseL2Norm(true);
|
||||
gcg->setICPreconditioner(
|
||||
|
13
extern/mantaflow/preprocessed/plugin/waves.cpp
vendored
13
extern/mantaflow/preprocessed/plugin/waves.cpp
vendored
@@ -423,15 +423,10 @@ void cgSolveWE(const FlagGrid &flags,
|
||||
|
||||
const int maxIter = (int)(cgMaxIterFac * flags.getSize().max()) * (flags.is3D() ? 1 : 4);
|
||||
GridCgInterface *gcg;
|
||||
vector<Grid<Real> *> matA{&A0, &Ai, &Aj};
|
||||
|
||||
if (flags.is3D()) {
|
||||
matA.push_back(&Ak);
|
||||
gcg = new GridCg<ApplyMatrix>(out, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
else {
|
||||
gcg = new GridCg<ApplyMatrix2D>(out, rhs, residual, search, flags, tmp, matA);
|
||||
}
|
||||
if (flags.is3D())
|
||||
gcg = new GridCg<ApplyMatrix>(out, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
else
|
||||
gcg = new GridCg<ApplyMatrix2D>(out, rhs, residual, search, flags, tmp, &A0, &Ai, &Aj, &Ak);
|
||||
|
||||
gcg->setAccuracy(cgAccuracy);
|
||||
|
||||
|
@@ -145,7 +145,6 @@ extern void PbRegister_flipComputeSurfaceNormals();
|
||||
extern void PbRegister_flipUpdateNeighborRatio();
|
||||
extern void PbRegister_particleSurfaceTurbulence();
|
||||
extern void PbRegister_debugCheckParts();
|
||||
extern void PbRegister_applyViscosity();
|
||||
extern void PbRegister_markAsFixed();
|
||||
extern void PbRegister_texcoordInflow();
|
||||
extern void PbRegister_meshSmokeInflow();
|
||||
@@ -343,7 +342,6 @@ void MantaEnsureRegistration()
|
||||
PbRegister_flipUpdateNeighborRatio();
|
||||
PbRegister_particleSurfaceTurbulence();
|
||||
PbRegister_debugCheckParts();
|
||||
PbRegister_applyViscosity();
|
||||
PbRegister_markAsFixed();
|
||||
PbRegister_texcoordInflow();
|
||||
PbRegister_meshSmokeInflow();
|
||||
|
@@ -282,7 +282,7 @@ def list_render_passes(scene, srl):
|
||||
yield ("CryptoAsset" + '{:02d}'.format(i), "RGBA", 'COLOR')
|
||||
|
||||
# Denoising passes.
|
||||
if (scene.cycles.use_denoising and crl.use_denoising) or crl.denoising_store_passes:
|
||||
if crl.use_denoising or crl.denoising_store_passes:
|
||||
yield ("Noisy Image", "RGBA", 'COLOR')
|
||||
if crl.denoising_store_passes:
|
||||
yield ("Denoising Normal", "XYZ", 'VECTOR')
|
||||
|
@@ -1148,7 +1148,7 @@ class CYCLES_PT_context_material(CyclesButtonsPanel, Panel):
|
||||
split = layout.split(factor=0.65)
|
||||
|
||||
if ob:
|
||||
split.template_ID(ob, "active_material", new="material.new", duplicate="material.duplicate")
|
||||
split.template_ID(ob, "active_material", new="material.new")
|
||||
row = split.row()
|
||||
|
||||
if slot:
|
||||
@@ -1443,7 +1443,6 @@ class CYCLES_LIGHT_PT_nodes(CyclesButtonsPanel, Panel):
|
||||
|
||||
class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
|
||||
bl_label = "Spot Shape"
|
||||
bl_parent_id = "CYCLES_LIGHT_PT_light"
|
||||
bl_context = "data"
|
||||
|
||||
@classmethod
|
||||
@@ -1455,6 +1454,7 @@ class CYCLES_LIGHT_PT_spot(CyclesButtonsPanel, Panel):
|
||||
layout = self.layout
|
||||
light = context.light
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
col = layout.column()
|
||||
col.prop(light, "spot_size", text="Size")
|
||||
@@ -1969,11 +1969,9 @@ class CYCLES_RENDER_PT_bake_output(CyclesButtonsPanel, Panel):
|
||||
if rd.bake_type == 'DISPLACEMENT':
|
||||
layout.prop(rd, "use_bake_lores_mesh")
|
||||
else:
|
||||
layout.prop(cbk, "target")
|
||||
|
||||
if cbk.target == 'IMAGE_TEXTURES':
|
||||
layout.prop(cbk, "margin")
|
||||
layout.prop(cbk, "use_clear", text="Clear Image")
|
||||
layout.prop(cbk, "margin")
|
||||
layout.prop(cbk, "use_clear", text="Clear Image")
|
||||
|
||||
|
||||
class CYCLES_RENDER_PT_debug(CyclesButtonsPanel, Panel):
|
||||
|
@@ -43,41 +43,42 @@ int blender_device_threads(BL::Scene &b_scene)
|
||||
|
||||
DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background)
|
||||
{
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
/* Find cycles preferences. */
|
||||
PointerRNA cpreferences;
|
||||
BL::Preferences::addons_iterator b_addon_iter;
|
||||
for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
|
||||
++b_addon_iter) {
|
||||
if (b_addon_iter->module() == "cycles") {
|
||||
cpreferences = b_addon_iter->preferences().ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Default to CPU device. */
|
||||
DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
|
||||
|
||||
if (BlenderSession::device_override != DEVICE_MASK_ALL) {
|
||||
vector<DeviceInfo> devices = Device::available_devices(BlenderSession::device_override);
|
||||
|
||||
if (devices.empty()) {
|
||||
device = Device::dummy_device("Found no Cycles device of the specified type");
|
||||
}
|
||||
else {
|
||||
int threads = blender_device_threads(b_scene);
|
||||
device = Device::get_multi_device(devices, threads, background);
|
||||
return Device::dummy_device("Found no Cycles device of the specified type");
|
||||
}
|
||||
|
||||
int threads = blender_device_threads(b_scene);
|
||||
return Device::get_multi_device(devices, threads, background);
|
||||
}
|
||||
else if (get_enum(cscene, "device") == 2) {
|
||||
|
||||
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
|
||||
|
||||
/* Default to CPU device. */
|
||||
DeviceInfo device = Device::available_devices(DEVICE_MASK_CPU).front();
|
||||
|
||||
if (get_enum(cscene, "device") == 2) {
|
||||
/* Find network device. */
|
||||
vector<DeviceInfo> devices = Device::available_devices(DEVICE_MASK_NETWORK);
|
||||
if (!devices.empty()) {
|
||||
device = devices.front();
|
||||
return devices.front();
|
||||
}
|
||||
}
|
||||
else if (get_enum(cscene, "device") == 1) {
|
||||
/* Find cycles preferences. */
|
||||
PointerRNA cpreferences;
|
||||
|
||||
BL::Preferences::addons_iterator b_addon_iter;
|
||||
for (b_preferences.addons.begin(b_addon_iter); b_addon_iter != b_preferences.addons.end();
|
||||
++b_addon_iter) {
|
||||
if (b_addon_iter->module() == "cycles") {
|
||||
cpreferences = b_addon_iter->preferences().ptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test if we are using GPU devices. */
|
||||
ComputeDevice compute_device = (ComputeDevice)get_enum(
|
||||
cpreferences, "compute_device_type", COMPUTE_DEVICE_NUM, COMPUTE_DEVICE_CPU);
|
||||
@@ -116,11 +117,11 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen
|
||||
device = Device::get_multi_device(used_devices, threads, background);
|
||||
}
|
||||
/* Else keep using the CPU device that was set before. */
|
||||
}
|
||||
}
|
||||
|
||||
if (!get_boolean(cpreferences, "peer_memory")) {
|
||||
device.has_peer_memory = false;
|
||||
if (!get_boolean(cpreferences, "peer_memory")) {
|
||||
device.has_peer_memory = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return device;
|
||||
|
@@ -351,10 +351,6 @@ static bool lookup_property(BL::ID b_id, const string &name, float4 *r_value)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (prop == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PropertyType type = RNA_property_type(prop);
|
||||
int arraylen = RNA_property_array_length(&ptr, prop);
|
||||
|
||||
|
@@ -682,7 +682,6 @@ void BVHEmbree::refit(Progress &progress)
|
||||
if (mesh->num_triangles() > 0) {
|
||||
RTCGeometry geom = rtcGetGeometry(scene, geom_id);
|
||||
set_tri_vertex_buffer(geom, mesh, true);
|
||||
rtcSetGeometryUserData(geom, (void *)mesh->optix_prim_offset);
|
||||
rtcCommitGeometry(geom);
|
||||
}
|
||||
}
|
||||
@@ -691,7 +690,6 @@ void BVHEmbree::refit(Progress &progress)
|
||||
if (hair->num_curves() > 0) {
|
||||
RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1);
|
||||
set_curve_vertex_buffer(geom, hair, true);
|
||||
rtcSetGeometryUserData(geom, (void *)hair->optix_prim_offset);
|
||||
rtcCommitGeometry(geom);
|
||||
}
|
||||
}
|
||||
|
@@ -1929,19 +1929,18 @@ void CUDADevice::render(DeviceTask &task, RenderTile &rtile, device_vector<WorkT
|
||||
}
|
||||
|
||||
uint step_samples = divide_up(min_blocks * num_threads_per_block, wtile->w * wtile->h);
|
||||
if (task.adaptive_sampling.use) {
|
||||
step_samples = task.adaptive_sampling.align_static_samples(step_samples);
|
||||
}
|
||||
|
||||
/* Render all samples. */
|
||||
int start_sample = rtile.start_sample;
|
||||
int end_sample = rtile.start_sample + rtile.num_samples;
|
||||
|
||||
for (int sample = start_sample; sample < end_sample;) {
|
||||
for (int sample = start_sample; sample < end_sample; sample += step_samples) {
|
||||
/* Setup and copy work tile to device. */
|
||||
wtile->start_sample = sample;
|
||||
wtile->num_samples = step_samples;
|
||||
if (task.adaptive_sampling.use) {
|
||||
wtile->num_samples = task.adaptive_sampling.align_samples(sample, step_samples);
|
||||
}
|
||||
wtile->num_samples = min(wtile->num_samples, end_sample - sample);
|
||||
wtile->num_samples = min(step_samples, end_sample - sample);
|
||||
work_tiles.copy_to_device();
|
||||
|
||||
CUdeviceptr d_work_tiles = (CUdeviceptr)work_tiles.device_pointer;
|
||||
@@ -1963,8 +1962,7 @@ void CUDADevice::render(DeviceTask &task, RenderTile &rtile, device_vector<WorkT
|
||||
cuda_assert(cuCtxSynchronize());
|
||||
|
||||
/* Update progress. */
|
||||
sample += wtile->num_samples;
|
||||
rtile.sample = sample;
|
||||
rtile.sample = sample + wtile->num_samples;
|
||||
task.update_progress(&rtile, rtile.w * rtile.h * wtile->num_samples);
|
||||
|
||||
if (task.get_cancel()) {
|
||||
|
@@ -920,7 +920,8 @@ class CPUDevice : public Device {
|
||||
ccl_global float *buffer = render_buffer + index * kernel_data.film.pass_stride;
|
||||
if (buffer[kernel_data.film.pass_sample_count] < 0.0f) {
|
||||
buffer[kernel_data.film.pass_sample_count] = -buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = tile.sample / buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = tile.sample / max((float)tile.start_sample + 1.0f,
|
||||
buffer[kernel_data.film.pass_sample_count]);
|
||||
if (sample_multiplier != 1.0f) {
|
||||
kernel_adaptive_post_adjust(kg, buffer, sample_multiplier);
|
||||
}
|
||||
@@ -996,7 +997,7 @@ class CPUDevice : public Device {
|
||||
coverage.finalize();
|
||||
}
|
||||
|
||||
if (task.adaptive_sampling.use && (tile.stealing_state != RenderTile::WAS_STOLEN)) {
|
||||
if (task.adaptive_sampling.use) {
|
||||
adaptive_sampling_post(tile, kg);
|
||||
}
|
||||
}
|
||||
|
@@ -248,14 +248,11 @@ class MultiDevice : public Device {
|
||||
void build_bvh(BVH *bvh, Progress &progress, bool refit) override
|
||||
{
|
||||
/* Try to build and share a single acceleration structure, if possible */
|
||||
if (bvh->params.bvh_layout == BVH_LAYOUT_BVH2 || bvh->params.bvh_layout == BVH_LAYOUT_EMBREE) {
|
||||
if (bvh->params.bvh_layout == BVH_LAYOUT_BVH2) {
|
||||
devices.back().device->build_bvh(bvh, progress, refit);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
|
||||
bvh->params.bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE);
|
||||
|
||||
BVHMulti *const bvh_multi = static_cast<BVHMulti *>(bvh);
|
||||
bvh_multi->sub_bvhs.resize(devices.size());
|
||||
|
||||
|
@@ -314,14 +314,6 @@ class OptiXDevice : public CUDADevice {
|
||||
common_cflags += string_printf(" -I\"%s/include\"", optix_sdk_path);
|
||||
}
|
||||
|
||||
// Specialization for shader raytracing
|
||||
if (requested_features.use_shader_raytrace) {
|
||||
common_cflags += " --keep-device-functions";
|
||||
}
|
||||
else {
|
||||
common_cflags += " -D __NO_SHADER_RAYTRACE__";
|
||||
}
|
||||
|
||||
return common_cflags;
|
||||
}
|
||||
|
||||
@@ -760,6 +752,9 @@ class OptiXDevice : public CUDADevice {
|
||||
const int end_sample = rtile.start_sample + rtile.num_samples;
|
||||
// Keep this number reasonable to avoid running into TDRs
|
||||
int step_samples = (info.display_device ? 8 : 32);
|
||||
if (task.adaptive_sampling.use) {
|
||||
step_samples = task.adaptive_sampling.align_static_samples(step_samples);
|
||||
}
|
||||
|
||||
// Offset into launch params buffer so that streams use separate data
|
||||
device_ptr launch_params_ptr = launch_params.device_pointer +
|
||||
@@ -767,14 +762,10 @@ class OptiXDevice : public CUDADevice {
|
||||
|
||||
const CUDAContextScope scope(cuContext);
|
||||
|
||||
for (int sample = rtile.start_sample; sample < end_sample;) {
|
||||
for (int sample = rtile.start_sample; sample < end_sample; sample += step_samples) {
|
||||
// Copy work tile information to device
|
||||
wtile.num_samples = min(step_samples, end_sample - sample);
|
||||
wtile.start_sample = sample;
|
||||
wtile.num_samples = step_samples;
|
||||
if (task.adaptive_sampling.use) {
|
||||
wtile.num_samples = task.adaptive_sampling.align_samples(sample, step_samples);
|
||||
}
|
||||
wtile.num_samples = min(wtile.num_samples, end_sample - sample);
|
||||
device_ptr d_wtile_ptr = launch_params_ptr + offsetof(KernelParams, tile);
|
||||
check_result_cuda(
|
||||
cuMemcpyHtoDAsync(d_wtile_ptr, &wtile, sizeof(wtile), cuda_stream[thread_index]));
|
||||
@@ -816,8 +807,7 @@ class OptiXDevice : public CUDADevice {
|
||||
check_result_cuda(cuStreamSynchronize(cuda_stream[thread_index]));
|
||||
|
||||
// Update current sample, so it is displayed correctly
|
||||
sample += wtile.num_samples;
|
||||
rtile.sample = sample;
|
||||
rtile.sample = wtile.start_sample + wtile.num_samples;
|
||||
// Update task progress after the kernel completed rendering
|
||||
task.update_progress(&rtile, wtile.w * wtile.h * wtile.num_samples);
|
||||
|
||||
@@ -1250,12 +1240,6 @@ class OptiXDevice : public CUDADevice {
|
||||
|
||||
void build_bvh(BVH *bvh, Progress &progress, bool refit) override
|
||||
{
|
||||
if (bvh->params.bvh_layout == BVH_LAYOUT_BVH2) {
|
||||
/* For baking CUDA is used, build appropriate BVH for that. */
|
||||
Device::build_bvh(bvh, progress, refit);
|
||||
return;
|
||||
}
|
||||
|
||||
BVHOptiX *const bvh_optix = static_cast<BVHOptiX *>(bvh);
|
||||
|
||||
progress.set_substatus("Building OptiX acceleration structure");
|
||||
@@ -1516,24 +1500,11 @@ class OptiXDevice : public CUDADevice {
|
||||
}
|
||||
else {
|
||||
unsigned int num_instances = 0;
|
||||
unsigned int max_num_instances = 0xFFFFFFFF;
|
||||
|
||||
bvh_optix->as_data.free();
|
||||
bvh_optix->traversable_handle = 0;
|
||||
bvh_optix->motion_transform_data.free();
|
||||
|
||||
optixDeviceContextGetProperty(context,
|
||||
OPTIX_DEVICE_PROPERTY_LIMIT_MAX_INSTANCE_ID,
|
||||
&max_num_instances,
|
||||
sizeof(max_num_instances));
|
||||
// Do not count first bit, which is used to distinguish instanced and non-instanced objects
|
||||
max_num_instances >>= 1;
|
||||
if (bvh->objects.size() > max_num_instances) {
|
||||
progress.set_error(
|
||||
"Failed to build OptiX acceleration structure because there are too many instances");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fill instance descriptions
|
||||
# if OPTIX_ABI_VERSION < 41
|
||||
device_vector<OptixAabb> aabbs(this, "optix tlas aabbs", MEM_READ_ONLY);
|
||||
@@ -1587,8 +1558,8 @@ class OptiXDevice : public CUDADevice {
|
||||
instance.transform[5] = 1.0f;
|
||||
instance.transform[10] = 1.0f;
|
||||
|
||||
// Set user instance ID to object index (but leave low bit blank)
|
||||
instance.instanceId = ob->get_device_index() << 1;
|
||||
// Set user instance ID to object index
|
||||
instance.instanceId = ob->get_device_index();
|
||||
|
||||
// Have to have at least one bit in the mask, or else instance would always be culled
|
||||
instance.visibilityMask = 1;
|
||||
@@ -1694,9 +1665,9 @@ class OptiXDevice : public CUDADevice {
|
||||
else {
|
||||
// Disable instance transform if geometry already has it applied to vertex data
|
||||
instance.flags = OPTIX_INSTANCE_FLAG_DISABLE_TRANSFORM;
|
||||
// Non-instanced objects read ID from 'prim_object', so distinguish
|
||||
// them from instanced objects with the low bit set
|
||||
instance.instanceId |= 1;
|
||||
// Non-instanced objects read ID from prim_object, so
|
||||
// distinguish them from instanced objects with high bit set
|
||||
instance.instanceId |= 0x800000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -223,8 +223,8 @@ bool DeviceSplitKernel::path_trace(DeviceTask &task,
|
||||
subtile.num_samples = samples_per_second;
|
||||
|
||||
if (task.adaptive_sampling.use) {
|
||||
subtile.num_samples = task.adaptive_sampling.align_samples(subtile.start_sample,
|
||||
subtile.num_samples);
|
||||
subtile.num_samples = task.adaptive_sampling.align_dynamic_samples(subtile.start_sample,
|
||||
subtile.num_samples);
|
||||
}
|
||||
|
||||
/* Don't go beyond requested number of samples. */
|
||||
|
@@ -144,20 +144,41 @@ AdaptiveSampling::AdaptiveSampling() : use(true), adaptive_step(0), min_samples(
|
||||
}
|
||||
|
||||
/* Render samples in steps that align with the adaptive filtering. */
|
||||
int AdaptiveSampling::align_samples(int sample, int num_samples) const
|
||||
int AdaptiveSampling::align_static_samples(int samples) const
|
||||
{
|
||||
int end_sample = sample + num_samples;
|
||||
|
||||
/* Round down end sample to the nearest sample that needs filtering. */
|
||||
end_sample &= ~(adaptive_step - 1);
|
||||
|
||||
if (end_sample <= sample) {
|
||||
/* In order to reach the next sample that needs filtering, we'd need
|
||||
* to increase num_samples. We don't do that in this function, so
|
||||
* just keep it as is and don't filter this time around. */
|
||||
return num_samples;
|
||||
if (samples > adaptive_step) {
|
||||
/* Make multiple of adaptive_step. */
|
||||
while (samples % adaptive_step != 0) {
|
||||
samples--;
|
||||
}
|
||||
}
|
||||
return end_sample - sample;
|
||||
else if (samples < adaptive_step) {
|
||||
/* Make divisor of adaptive_step. */
|
||||
while (adaptive_step % samples != 0) {
|
||||
samples--;
|
||||
}
|
||||
}
|
||||
|
||||
return max(samples, 1);
|
||||
}
|
||||
|
||||
/* Render samples in steps that align with the adaptive filtering, with the
|
||||
* suggested number of samples dynamically changing. */
|
||||
int AdaptiveSampling::align_dynamic_samples(int offset, int samples) const
|
||||
{
|
||||
/* Round so that we end up on multiples of adaptive_samples. */
|
||||
samples += offset;
|
||||
|
||||
if (samples > adaptive_step) {
|
||||
/* Make multiple of adaptive_step. */
|
||||
while (samples % adaptive_step != 0) {
|
||||
samples--;
|
||||
}
|
||||
}
|
||||
|
||||
samples -= offset;
|
||||
|
||||
return max(samples, 1);
|
||||
}
|
||||
|
||||
bool AdaptiveSampling::need_filter(int sample) const
|
||||
|
@@ -117,7 +117,8 @@ class AdaptiveSampling {
|
||||
public:
|
||||
AdaptiveSampling();
|
||||
|
||||
int align_samples(int sample, int num_samples) const;
|
||||
int align_static_samples(int samples) const;
|
||||
int align_dynamic_samples(int offset, int samples) const;
|
||||
bool need_filter(int sample) const;
|
||||
|
||||
bool use;
|
||||
|
@@ -214,6 +214,13 @@ ccl_device_inline float3 object_location(KernelGlobals *kg, const ShaderData *sd
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Total surface area of object */
|
||||
|
||||
ccl_device_inline float object_surface_area(KernelGlobals *kg, int object)
|
||||
{
|
||||
return kernel_tex_fetch(__objects, object).surface_area;
|
||||
}
|
||||
|
||||
/* Color of the object */
|
||||
|
||||
ccl_device_inline float3 object_color(KernelGlobals *kg, int object)
|
||||
@@ -321,7 +328,7 @@ ccl_device_inline float object_volume_density(KernelGlobals *kg, int object)
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
return kernel_tex_fetch(__objects, object).volume_density;
|
||||
return kernel_tex_fetch(__objects, object).surface_area;
|
||||
}
|
||||
|
||||
ccl_device_inline float object_volume_step_size(KernelGlobals *kg, int object)
|
||||
|
@@ -1461,7 +1461,7 @@ typedef struct KernelObject {
|
||||
Transform tfm;
|
||||
Transform itfm;
|
||||
|
||||
float volume_density;
|
||||
float surface_area;
|
||||
float pass_id;
|
||||
float random_number;
|
||||
float color[3];
|
||||
|
@@ -139,7 +139,7 @@ kernel_cuda_adaptive_scale_samples(WorkTile *tile, int start_sample, int sample,
|
||||
ccl_global float *buffer = tile->buffer + index * kernel_data.film.pass_stride;
|
||||
if(buffer[kernel_data.film.pass_sample_count] < 0.0f) {
|
||||
buffer[kernel_data.film.pass_sample_count] = -buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = sample / buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = sample / max((float)start_sample + 1.0f, buffer[kernel_data.film.pass_sample_count]);
|
||||
if(sample_multiplier != 1.0f) {
|
||||
kernel_adaptive_post_adjust(&kg, buffer, sample_multiplier);
|
||||
}
|
||||
|
@@ -45,12 +45,13 @@ template<bool always = false> ccl_device_forceinline uint get_object_id()
|
||||
uint object = optixGetInstanceId();
|
||||
#endif
|
||||
// Choose between always returning object ID or only for instances
|
||||
if (always || (object & 1) == 0)
|
||||
// Can just remove the low bit since instance always contains object ID
|
||||
return object >> 1;
|
||||
else
|
||||
// Set to OBJECT_NONE if this is not an instanced object
|
||||
return OBJECT_NONE;
|
||||
if (always)
|
||||
// Can just remove the high bit since instance always contains object ID
|
||||
return object & 0x7FFFFF;
|
||||
// Set to OBJECT_NONE if this is not an instanced object
|
||||
else if (object & 0x800000)
|
||||
object = OBJECT_NONE;
|
||||
return object;
|
||||
}
|
||||
|
||||
extern "C" __global__ void __raygen__kernel_optix_path_trace()
|
||||
|
@@ -109,7 +109,7 @@ static void shaderdata_to_shaderglobals(
|
||||
globals->dvdy = sd->dv.dy;
|
||||
globals->dPdu = TO_VEC3(sd->dPdu);
|
||||
globals->dPdv = TO_VEC3(sd->dPdv);
|
||||
globals->surfacearea = 1.0f;
|
||||
globals->surfacearea = (sd->object == OBJECT_NONE) ? 1.0f : object_surface_area(kg, sd->object);
|
||||
globals->time = sd->time;
|
||||
|
||||
/* booleans */
|
||||
|
@@ -29,7 +29,8 @@ ccl_device void kernel_adaptive_adjust_samples(KernelGlobals *kg)
|
||||
int sample = kernel_split_params.tile.start_sample + kernel_split_params.tile.num_samples;
|
||||
if (buffer[kernel_data.film.pass_sample_count] < 0.0f) {
|
||||
buffer[kernel_data.film.pass_sample_count] = -buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = sample / buffer[kernel_data.film.pass_sample_count];
|
||||
float sample_multiplier = sample / max((float)kernel_split_params.tile.start_sample + 1.0f,
|
||||
buffer[kernel_data.film.pass_sample_count]);
|
||||
if (sample_multiplier != 1.0f) {
|
||||
kernel_adaptive_post_adjust(kg, buffer, sample_multiplier);
|
||||
}
|
||||
|
@@ -280,15 +280,6 @@ void Geometry::tag_update(Scene *scene, bool rebuild)
|
||||
scene->object_manager->need_update = true;
|
||||
}
|
||||
|
||||
void Geometry::tag_bvh_update(bool rebuild)
|
||||
{
|
||||
tag_modified();
|
||||
|
||||
if (rebuild) {
|
||||
need_update_rebuild = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Geometry Manager */
|
||||
|
||||
GeometryManager::GeometryManager()
|
||||
@@ -924,7 +915,7 @@ void GeometryManager::device_update_attributes(Device *device,
|
||||
scene->object_manager->device_update_mesh_offsets(device, dscene, scene);
|
||||
}
|
||||
|
||||
void GeometryManager::mesh_calc_offset(Scene *scene, BVHLayout bvh_layout)
|
||||
void GeometryManager::mesh_calc_offset(Scene *scene)
|
||||
{
|
||||
size_t vert_size = 0;
|
||||
size_t tri_size = 0;
|
||||
@@ -939,14 +930,6 @@ void GeometryManager::mesh_calc_offset(Scene *scene, BVHLayout bvh_layout)
|
||||
size_t optix_prim_size = 0;
|
||||
|
||||
foreach (Geometry *geom, scene->geometry) {
|
||||
if (geom->optix_prim_offset != optix_prim_size) {
|
||||
/* Need to rebuild BVH in OptiX, since refit only allows modified mesh data there */
|
||||
const bool has_optix_bvh = bvh_layout == BVH_LAYOUT_OPTIX ||
|
||||
bvh_layout == BVH_LAYOUT_MULTI_OPTIX ||
|
||||
bvh_layout == BVH_LAYOUT_MULTI_OPTIX_EMBREE;
|
||||
geom->tag_bvh_update(has_optix_bvh);
|
||||
}
|
||||
|
||||
if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) {
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
|
||||
@@ -1543,9 +1526,7 @@ void GeometryManager::device_update(Device *device,
|
||||
/* Device update. */
|
||||
device_free(device, dscene);
|
||||
|
||||
const BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
|
||||
device->get_bvh_layout_mask());
|
||||
mesh_calc_offset(scene, bvh_layout);
|
||||
mesh_calc_offset(scene);
|
||||
if (true_displacement_used) {
|
||||
scoped_callback_timer timer([scene](double time) {
|
||||
if (scene->update_stats) {
|
||||
@@ -1572,6 +1553,8 @@ void GeometryManager::device_update(Device *device,
|
||||
}
|
||||
|
||||
/* Update displacement. */
|
||||
BVHLayout bvh_layout = BVHParams::best_bvh_layout(scene->params.bvh_layout,
|
||||
device->get_bvh_layout_mask());
|
||||
bool displacement_done = false;
|
||||
size_t num_bvh = 0;
|
||||
|
||||
|
@@ -157,8 +157,6 @@ class Geometry : public Node {
|
||||
|
||||
/* Updates */
|
||||
void tag_update(Scene *scene, bool rebuild);
|
||||
|
||||
void tag_bvh_update(bool rebuild);
|
||||
};
|
||||
|
||||
/* Geometry Manager */
|
||||
@@ -200,7 +198,7 @@ class GeometryManager {
|
||||
vector<AttributeRequestSet> &object_attributes);
|
||||
|
||||
/* Compute verts/triangles/curves offsets in global arrays. */
|
||||
void mesh_calc_offset(Scene *scene, BVHLayout bvh_layout);
|
||||
void mesh_calc_offset(Scene *scene);
|
||||
|
||||
void device_update_object(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
|
||||
|
||||
|
@@ -55,6 +55,12 @@ struct UpdateObjectTransformState {
|
||||
*/
|
||||
map<ParticleSystem *, int> particle_offset;
|
||||
|
||||
/* Mesh area.
|
||||
* Used to avoid calculation of mesh area multiple times. Used for both
|
||||
* read and write. Acquire surface_area_lock to keep it all thread safe.
|
||||
*/
|
||||
map<Mesh *, float> surface_area_map;
|
||||
|
||||
/* Motion offsets for each object. */
|
||||
array<uint> motion_offset;
|
||||
|
||||
@@ -70,8 +76,12 @@ struct UpdateObjectTransformState {
|
||||
bool have_curves;
|
||||
|
||||
/* ** Scheduling queue. ** */
|
||||
|
||||
Scene *scene;
|
||||
|
||||
/* Some locks to keep everything thread-safe. */
|
||||
thread_spin_lock surface_area_lock;
|
||||
|
||||
/* First unused object index in the queue. */
|
||||
int queue_start_object;
|
||||
};
|
||||
@@ -369,17 +379,80 @@ ObjectManager::~ObjectManager()
|
||||
{
|
||||
}
|
||||
|
||||
static float object_volume_density(const Transform &tfm, Geometry *geom)
|
||||
static float object_surface_area(UpdateObjectTransformState *state,
|
||||
const Transform &tfm,
|
||||
Geometry *geom)
|
||||
{
|
||||
if (geom->geometry_type == Geometry::VOLUME) {
|
||||
if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
Mesh *mesh = static_cast<Mesh *>(geom);
|
||||
if (mesh->has_volume || geom->geometry_type == Geometry::VOLUME) {
|
||||
/* Volume density automatically adjust to object scale. */
|
||||
if (static_cast<Volume *>(geom)->get_object_space()) {
|
||||
if (geom->geometry_type == Geometry::VOLUME &&
|
||||
static_cast<Volume *>(geom)->get_object_space()) {
|
||||
const float3 unit = normalize(make_float3(1.0f, 1.0f, 1.0f));
|
||||
return 1.0f / len(transform_direction(&tfm, unit));
|
||||
}
|
||||
else {
|
||||
return 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0f;
|
||||
/* Compute surface area. for uniform scale we can do avoid the many
|
||||
* transform calls and share computation for instances.
|
||||
*
|
||||
* TODO(brecht): Correct for displacement, and move to a better place.
|
||||
*/
|
||||
float surface_area = 0.0f;
|
||||
float uniform_scale;
|
||||
if (transform_uniform_scale(tfm, uniform_scale)) {
|
||||
map<Mesh *, float>::iterator it;
|
||||
|
||||
/* NOTE: This isn't fully optimal and could in theory lead to multiple
|
||||
* threads calculating area of the same mesh in parallel. However, this
|
||||
* also prevents suspending all the threads when some mesh's area is
|
||||
* not yet known.
|
||||
*/
|
||||
state->surface_area_lock.lock();
|
||||
it = state->surface_area_map.find(mesh);
|
||||
state->surface_area_lock.unlock();
|
||||
|
||||
if (it == state->surface_area_map.end()) {
|
||||
size_t num_triangles = mesh->num_triangles();
|
||||
for (size_t j = 0; j < num_triangles; j++) {
|
||||
Mesh::Triangle t = mesh->get_triangle(j);
|
||||
float3 p1 = mesh->get_verts()[t.v[0]];
|
||||
float3 p2 = mesh->get_verts()[t.v[1]];
|
||||
float3 p3 = mesh->get_verts()[t.v[2]];
|
||||
|
||||
surface_area += triangle_area(p1, p2, p3);
|
||||
}
|
||||
|
||||
state->surface_area_lock.lock();
|
||||
state->surface_area_map[mesh] = surface_area;
|
||||
state->surface_area_lock.unlock();
|
||||
}
|
||||
else {
|
||||
surface_area = it->second;
|
||||
}
|
||||
|
||||
surface_area *= uniform_scale;
|
||||
}
|
||||
else {
|
||||
size_t num_triangles = mesh->num_triangles();
|
||||
for (size_t j = 0; j < num_triangles; j++) {
|
||||
Mesh::Triangle t = mesh->get_triangle(j);
|
||||
float3 p1 = transform_point(&tfm, mesh->get_verts()[t.v[0]]);
|
||||
float3 p2 = transform_point(&tfm, mesh->get_verts()[t.v[1]]);
|
||||
float3 p3 = transform_point(&tfm, mesh->get_verts()[t.v[2]]);
|
||||
|
||||
surface_area += triangle_area(p1, p2, p3);
|
||||
}
|
||||
}
|
||||
|
||||
return surface_area;
|
||||
}
|
||||
|
||||
void ObjectManager::device_update_object_transform(UpdateObjectTransformState *state, Object *ob)
|
||||
@@ -403,7 +476,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s
|
||||
|
||||
kobject.tfm = tfm;
|
||||
kobject.itfm = itfm;
|
||||
kobject.volume_density = object_volume_density(tfm, geom);
|
||||
kobject.surface_area = object_surface_area(state, tfm, geom);
|
||||
kobject.color[0] = color.x;
|
||||
kobject.color[1] = color.y;
|
||||
kobject.color[2] = color.z;
|
||||
|
@@ -459,17 +459,13 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
|
||||
int device_num = device->device_number(tile_device);
|
||||
|
||||
while (!tile_manager.next_tile(tile, device_num, tile_types)) {
|
||||
if (steal_tile(rtile, tile_device, tile_lock)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Wait for denoising tiles to become available */
|
||||
if ((tile_types & RenderTile::DENOISE) && !progress.get_cancel() && tile_manager.has_tiles()) {
|
||||
denoising_cond.wait(tile_lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
return steal_tile(rtile, tile_device, tile_lock);
|
||||
}
|
||||
|
||||
/* fill render tile */
|
||||
@@ -481,7 +477,6 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ
|
||||
rtile.num_samples = tile_manager.state.num_samples;
|
||||
rtile.resolution = tile_manager.state.resolution_divider;
|
||||
rtile.tile_index = tile->index;
|
||||
rtile.stealing_state = RenderTile::NO_STEALING;
|
||||
|
||||
if (tile->state == Tile::DENOISE) {
|
||||
rtile.task = RenderTile::DENOISE;
|
||||
|
@@ -548,23 +548,22 @@ void SVMCompiler::generated_shared_closure_nodes(ShaderNode *root_node,
|
||||
}
|
||||
}
|
||||
|
||||
void SVMCompiler::find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes,
|
||||
ShaderGraph *graph,
|
||||
CompilerState *state)
|
||||
void SVMCompiler::generate_aov_node(ShaderNode *node, CompilerState *state)
|
||||
{
|
||||
foreach (ShaderNode *node, graph->nodes) {
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
||||
OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node);
|
||||
if (aov_node->slot >= 0) {
|
||||
aov_nodes.insert(aov_node);
|
||||
foreach (ShaderInput *in, node->inputs) {
|
||||
if (in->link != NULL) {
|
||||
find_dependencies(aov_nodes, state->nodes_done, in);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* execute dependencies for node */
|
||||
foreach (ShaderInput *in, node->inputs) {
|
||||
if (in->link != NULL) {
|
||||
ShaderNodeSet dependencies;
|
||||
find_dependencies(dependencies, state->nodes_done, in);
|
||||
generate_svm_nodes(dependencies, state);
|
||||
}
|
||||
}
|
||||
|
||||
/* compile node itself */
|
||||
generate_node(node, state->nodes_done);
|
||||
|
||||
state->nodes_done.insert(node);
|
||||
state->nodes_done_flag[node->id] = true;
|
||||
}
|
||||
|
||||
void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
||||
@@ -632,25 +631,6 @@ void SVMCompiler::generate_multi_closure(ShaderNode *root_node,
|
||||
}
|
||||
}
|
||||
|
||||
/* For dependencies AOV nodes, prevent them from being categorized
|
||||
* as exclusive deps of one or the other closure, since the need to
|
||||
* execute them for AOV writing is not dependent on the closure
|
||||
* weights. */
|
||||
if (state->aov_nodes.size()) {
|
||||
set_intersection(state->aov_nodes.begin(),
|
||||
state->aov_nodes.end(),
|
||||
cl1deps.begin(),
|
||||
cl1deps.end(),
|
||||
std::inserter(shareddeps, shareddeps.begin()),
|
||||
node_id_comp);
|
||||
set_intersection(state->aov_nodes.begin(),
|
||||
state->aov_nodes.end(),
|
||||
cl2deps.begin(),
|
||||
cl2deps.end(),
|
||||
std::inserter(shareddeps, shareddeps.begin()),
|
||||
node_id_comp);
|
||||
}
|
||||
|
||||
if (!shareddeps.empty()) {
|
||||
if (cl1in->link) {
|
||||
generated_shared_closure_nodes(root_node, cl1in->link->parent, state, shareddeps);
|
||||
@@ -802,9 +782,6 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
|
||||
}
|
||||
|
||||
if (generate) {
|
||||
if (type == SHADER_TYPE_SURFACE) {
|
||||
find_aov_nodes_and_dependencies(state.aov_nodes, graph, &state);
|
||||
}
|
||||
generate_multi_closure(clin->link->parent, clin->link->parent, &state);
|
||||
}
|
||||
}
|
||||
@@ -812,15 +789,28 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
|
||||
/* compile output node */
|
||||
output->compile(*this);
|
||||
|
||||
if (!state.aov_nodes.empty()) {
|
||||
/* AOV passes are only written if the object is directly visible, so
|
||||
* there is no point in evaluating all the nodes generated only for the
|
||||
* AOV outputs if that's not the case. Therefore, we insert
|
||||
* NODE_AOV_START into the shader before the AOV-only nodes are
|
||||
* generated which tells the kernel that it can stop evaluation
|
||||
* early if AOVs will not be written. */
|
||||
add_node(NODE_AOV_START, 0, 0, 0);
|
||||
generate_svm_nodes(state.aov_nodes, &state);
|
||||
if (type == SHADER_TYPE_SURFACE) {
|
||||
vector<OutputAOVNode *> aov_outputs;
|
||||
foreach (ShaderNode *node, graph->nodes) {
|
||||
if (node->special_type == SHADER_SPECIAL_TYPE_OUTPUT_AOV) {
|
||||
OutputAOVNode *aov_node = static_cast<OutputAOVNode *>(node);
|
||||
if (aov_node->slot >= 0) {
|
||||
aov_outputs.push_back(aov_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aov_outputs.size() > 0) {
|
||||
/* AOV passes are only written if the object is directly visible, so
|
||||
* there is no point in evaluating all the nodes generated only for the
|
||||
* AOV outputs if that's not the case. Therefore, we insert
|
||||
* NODE_AOV_START into the shader before the AOV-only nodes are
|
||||
* generated which tells the kernel that it can stop evaluation
|
||||
* early if AOVs will not be written. */
|
||||
add_node(NODE_AOV_START, 0, 0, 0);
|
||||
foreach (OutputAOVNode *node, aov_outputs) {
|
||||
generate_aov_node(node, &state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -176,9 +176,6 @@ class SVMCompiler {
|
||||
/* Set of closures which were already compiled. */
|
||||
ShaderNodeSet closure_done;
|
||||
|
||||
/* Set of nodes used for writing AOVs. */
|
||||
ShaderNodeSet aov_nodes;
|
||||
|
||||
/* ** SVM nodes generation state ** */
|
||||
|
||||
/* Flag whether the node with corresponding ID was already compiled or
|
||||
@@ -200,9 +197,6 @@ class SVMCompiler {
|
||||
const ShaderNodeSet &done,
|
||||
ShaderInput *input,
|
||||
ShaderNode *skip_node = NULL);
|
||||
void find_aov_nodes_and_dependencies(ShaderNodeSet &aov_nodes,
|
||||
ShaderGraph *graph,
|
||||
CompilerState *state);
|
||||
void generate_node(ShaderNode *node, ShaderNodeSet &done);
|
||||
void generate_aov_node(ShaderNode *node, CompilerState *state);
|
||||
void generate_closure_node(ShaderNode *node, CompilerState *state);
|
||||
|
@@ -225,9 +225,6 @@ GHOST_SystemWin32::GHOST_SystemWin32()
|
||||
#ifdef WITH_INPUT_NDOF
|
||||
m_ndofManager = new GHOST_NDOFManagerWin32(*this);
|
||||
#endif
|
||||
|
||||
getCursorPosition(m_mousePosX, m_mousePosY);
|
||||
m_mouseTimestamp = ::GetTickCount();
|
||||
}
|
||||
|
||||
GHOST_SystemWin32::~GHOST_SystemWin32()
|
||||
@@ -536,20 +533,7 @@ GHOST_TSuccess GHOST_SystemWin32::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
||||
{
|
||||
if (!::GetActiveWindow())
|
||||
return GHOST_kFailure;
|
||||
|
||||
INPUT input;
|
||||
input.type = INPUT_MOUSE;
|
||||
input.mi.mouseData = 0;
|
||||
input.mi.time = ::GetTickCount();
|
||||
/* Map from virtual screen to 0-65536. */
|
||||
input.mi.dx = (x - GetSystemMetrics(SM_XVIRTUALSCREEN)) * 65536 /
|
||||
GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||
input.mi.dy = (y - GetSystemMetrics(SM_YVIRTUALSCREEN)) * 65536 /
|
||||
GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||
input.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_VIRTUALDESK;
|
||||
SendInput(1, &input, sizeof(input));
|
||||
|
||||
return GHOST_kSuccess;
|
||||
return ::SetCursorPos(x, y) == TRUE ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
@@ -585,13 +569,13 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
|
||||
*/
|
||||
bool swapped = ::GetSystemMetrics(SM_SWAPBUTTON) == TRUE;
|
||||
|
||||
bool down = HIBYTE(::GetAsyncKeyState(VK_LBUTTON)) != 0;
|
||||
bool down = HIBYTE(::GetKeyState(VK_LBUTTON)) != 0;
|
||||
buttons.set(swapped ? GHOST_kButtonMaskRight : GHOST_kButtonMaskLeft, down);
|
||||
|
||||
down = HIBYTE(::GetAsyncKeyState(VK_MBUTTON)) != 0;
|
||||
down = HIBYTE(::GetKeyState(VK_MBUTTON)) != 0;
|
||||
buttons.set(GHOST_kButtonMaskMiddle, down);
|
||||
|
||||
down = HIBYTE(::GetAsyncKeyState(VK_RBUTTON)) != 0;
|
||||
down = HIBYTE(::GetKeyState(VK_RBUTTON)) != 0;
|
||||
buttons.set(swapped ? GHOST_kButtonMaskLeft : GHOST_kButtonMaskRight, down);
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
@@ -955,113 +939,148 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type,
|
||||
{
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
GHOST_TabletData td = window->m_tabletInRange ? window->getLastTabletData() :
|
||||
GHOST_TABLET_DATA_NONE;
|
||||
|
||||
/* Move mouse to button event position. */
|
||||
if (!window->m_tabletInRange) {
|
||||
processCursorEvent(window);
|
||||
if (type == GHOST_kEventButtonDown) {
|
||||
window->updateMouseCapture(MousePressed);
|
||||
}
|
||||
else {
|
||||
/* Tablet should be hadling inbetween 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));
|
||||
else if (type == GHOST_kEventButtonUp) {
|
||||
window->updateMouseCapture(MouseReleased);
|
||||
}
|
||||
|
||||
window->updateMouseCapture(type == GHOST_kEventButtonDown ? MousePressed : MouseReleased);
|
||||
return new GHOST_EventButton(system->getMilliSeconds(), type, window, mask, td);
|
||||
/* Check for active Wintab mouse emulation in addition to a tablet in range because a proximity
|
||||
* leave event might have fired before the Windows mouse up event, thus there are still tablet
|
||||
* events to grab. The described behavior was observed in a Wacom Bamboo CTE-450. */
|
||||
if (window->useTabletAPI(GHOST_kTabletWintab) &&
|
||||
(window->m_tabletInRange || window->wintabSysButPressed()) &&
|
||||
processWintabEvent(type, window, mask, window->getMousePressed())) {
|
||||
/* Wintab processing only handles in-contact events. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new GHOST_EventButton(
|
||||
system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processWintabEvent(GHOST_WindowWin32 *window)
|
||||
GHOST_TSuccess GHOST_SystemWin32::processWintabEvent(GHOST_TEventType type,
|
||||
GHOST_WindowWin32 *window,
|
||||
GHOST_TButtonMask mask,
|
||||
bool mousePressed)
|
||||
{
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
std::vector<GHOST_WintabInfoWin32> wintabInfo;
|
||||
if (!window->getWintabInfo(wintabInfo)) {
|
||||
return;
|
||||
/* Only process Wintab packets if we can correlate them to a Window's mouse button event. When a
|
||||
* button event associated to a mouse button by Wintab occurs outside of WM_*BUTTON events,
|
||||
* there's no way to tell if other simultaneously pressed non-mouse mapped buttons are associated
|
||||
* to a modifier key (shift, alt, ctrl) or a system event (scroll, etc.) and thus it is not
|
||||
* possible to determine if a mouse click event should occur. */
|
||||
if (!mousePressed && !window->wintabSysButPressed()) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
for (auto info : wintabInfo) {
|
||||
std::vector<GHOST_WintabInfoWin32> wintabInfo;
|
||||
if (!window->getWintabInfo(wintabInfo)) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
auto wtiIter = wintabInfo.begin();
|
||||
|
||||
/* We only process events that correlate to a mouse button events, so there may exist Wintab
|
||||
* button down events that were instead mapped to e.g. scroll still in the queue. We need to
|
||||
* skip those and find the last button down mapped to mouse buttons. */
|
||||
if (!window->wintabSysButPressed()) {
|
||||
/* Assume there may be no button down event currently in the queue. */
|
||||
wtiIter = wintabInfo.end();
|
||||
|
||||
for (auto it = wintabInfo.begin(); it != wintabInfo.end(); it++) {
|
||||
if (it->type == GHOST_kEventButtonDown) {
|
||||
wtiIter = it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool unhandledButton = type != GHOST_kEventCursorMove;
|
||||
|
||||
for (; wtiIter != wintabInfo.end(); wtiIter++) {
|
||||
auto info = *wtiIter;
|
||||
|
||||
switch (info.type) {
|
||||
case GHOST_kEventCursorMove: {
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonDown: {
|
||||
/* While changing windows with a tablet, Window's mouse button events normally occur before
|
||||
* tablet proximity events, so a button up event can't be differentiated as occurring from
|
||||
* a Wintab tablet or a normal mouse and a Ghost button event will always be generated.
|
||||
*
|
||||
* If we were called during a button down event create a ghost button down event, otherwise
|
||||
* don't duplicate the prior button down as it interrupts drawing immediately after
|
||||
* changing a window. */
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
|
||||
WM_QUIT != msg.message) {
|
||||
window->updateMouseCapture(MousePressed);
|
||||
if (type == GHOST_kEventButtonDown && mask == info.button) {
|
||||
system->pushEvent(
|
||||
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
|
||||
unhandledButton = false;
|
||||
}
|
||||
window->updateWintabSysBut(MousePressed);
|
||||
break;
|
||||
}
|
||||
case GHOST_kEventButtonUp: {
|
||||
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;
|
||||
}
|
||||
|
||||
MSG msg;
|
||||
if (PeekMessage(&msg, window->getHWND(), message, message, PM_REMOVE | PM_NOYIELD) &&
|
||||
WM_QUIT != msg.message) {
|
||||
window->updateMouseCapture(MouseReleased);
|
||||
system->pushEvent(
|
||||
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
|
||||
}
|
||||
case GHOST_kEventCursorMove:
|
||||
system->pushEvent(new GHOST_EventCursor(
|
||||
info.time, GHOST_kEventCursorMove, window, info.x, info.y, info.tabletData));
|
||||
break;
|
||||
case GHOST_kEventButtonUp:
|
||||
system->pushEvent(
|
||||
new GHOST_EventButton(info.time, info.type, window, info.button, info.tabletData));
|
||||
if (type == GHOST_kEventButtonUp && mask == info.button) {
|
||||
unhandledButton = false;
|
||||
}
|
||||
window->updateWintabSysBut(MouseReleased);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Wintab button found correlating to the system button event, handle it too.
|
||||
*
|
||||
* Wintab button up events may be handled during WM_MOUSEMOVE, before their corresponding
|
||||
* WM_*BUTTONUP event has fired, which results in two GHOST Button up events for a single Wintab
|
||||
* associated button event. Alternatively this Windows button up event may have been generated
|
||||
* from a non-stylus device such as a button on the tablet pad and needs to be handled for some
|
||||
* workflows.
|
||||
*
|
||||
* The ambiguity introduced by Windows and Wintab buttons being asynchronous and having no
|
||||
* definitive way to associate each, and that the Wintab API does not provide enough information
|
||||
* to differentiate whether the stylus down is or is not modified by another button to a
|
||||
* non-mouse mapping, means that we must pessimistically generate mouse up events when we are
|
||||
* unsure of an association to prevent the mouse locking into a down state. */
|
||||
if (unhandledButton) {
|
||||
if (!window->wintabSysButPressed()) {
|
||||
GHOST_TInt32 x, y;
|
||||
system->getCursorPosition(x, y);
|
||||
system->pushEvent(new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x,
|
||||
y,
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
system->pushEvent(new GHOST_EventButton(
|
||||
system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE));
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processPointerEvent(
|
||||
UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventHandled)
|
||||
{
|
||||
std::vector<GHOST_PointerInfoWin32> pointerInfo;
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
/* 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)) {
|
||||
return;
|
||||
}
|
||||
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
std::vector<GHOST_PointerInfoWin32> pointerInfo;
|
||||
|
||||
if (window->getPointerInfo(pointerInfo, wParam, lParam) != GHOST_kSuccess) {
|
||||
return;
|
||||
}
|
||||
@@ -1127,106 +1146,70 @@ void GHOST_SystemWin32::processPointerEvent(
|
||||
system->setCursorPosition(pointerInfo[0].pixelLocation.x, pointerInfo[0].pixelLocation.y);
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
|
||||
GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *window)
|
||||
{
|
||||
/* Cursor moves handled by tablets while active. */
|
||||
if (window->m_tabletInRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
GHOST_TInt32 x_screen, y_screen;
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem();
|
||||
|
||||
DWORD msgPos = ::GetMessagePos();
|
||||
LONG msgTime = ::GetMessageTime();
|
||||
|
||||
/* GetMessagePointsEx processes points as 16 bit integers and can fail or return erroneous values
|
||||
* if negative input is not truncated. */
|
||||
int msgPosX = GET_X_LPARAM(msgPos) & 0x0000FFFF;
|
||||
int msgPosY = GET_Y_LPARAM(msgPos) & 0x0000FFFF;
|
||||
|
||||
const int maxPoints = 64;
|
||||
MOUSEMOVEPOINT currentPoint = {msgPosX, msgPosY, (DWORD)msgTime, 0};
|
||||
MOUSEMOVEPOINT points[maxPoints] = {0};
|
||||
/* GetMouseMovePointsEx returns the number of points returned that are less than or equal to the
|
||||
* requested point. If the requested point is the most recent, this returns up to 64 requested
|
||||
* points. */
|
||||
int numPoints = ::GetMouseMovePointsEx(
|
||||
sizeof(MOUSEMOVEPOINT), ¤tPoint, points, maxPoints, GMMP_USE_DISPLAY_POINTS);
|
||||
|
||||
if (numPoints == -1) {
|
||||
/* Points at edge of screen are often not in the queue, use the message's point instead. */
|
||||
numPoints = 1;
|
||||
points[0] = currentPoint;
|
||||
}
|
||||
|
||||
GHOST_TInt32 x_accum = 0, y_accum = 0;
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
|
||||
/* Points are in reverse chronological order. Find least recent, unprocessed mouse move. */
|
||||
int i;
|
||||
for (i = 0; i < numPoints; i++) {
|
||||
if (points[i].time < system->m_mouseTimestamp) {
|
||||
break;
|
||||
if (window->m_tabletInRange || window->wintabSysButPressed()) {
|
||||
if (window->useTabletAPI(GHOST_kTabletWintab) &&
|
||||
processWintabEvent(
|
||||
GHOST_kEventCursorMove, window, GHOST_kButtonMaskNone, window->getMousePressed())) {
|
||||
return NULL;
|
||||
}
|
||||
else 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;
|
||||
}
|
||||
|
||||
/* GetMouseMovePointsEx returns 16 bit number as 32 bit. If negative, we need to sign extend.
|
||||
*/
|
||||
points[i].x = points[i].x > 32767 ? points[i].x | 0xFFFF0000 : points[i].x;
|
||||
points[i].y = points[i].y > 32767 ? points[i].y | 0xFFFF0000 : points[i].y;
|
||||
|
||||
if (points[i].time == system->m_mouseTimestamp && points[i].x == system->m_mousePosX &&
|
||||
points[i].y == system->m_mousePosY) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (--i >= 0) {
|
||||
system->pushEvent(new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
points[i].x + x_accum,
|
||||
points[i].y + y_accum,
|
||||
GHOST_TABLET_DATA_NONE));
|
||||
/* If using Wintab but no button event is currently active,
|
||||
* fall through to default handling. */
|
||||
}
|
||||
|
||||
DWORD lastTimestamp = points[0].time;
|
||||
system->getCursorPosition(x_screen, y_screen);
|
||||
|
||||
/* Check if we need to wrap the cursor. */
|
||||
if (window->getCursorGrabModeIsWarp()) {
|
||||
/* Wrap based on current cursor position in case Win32 mouse move queue is out of order due to
|
||||
* prior wrap. */
|
||||
POINT point;
|
||||
::GetCursorPos(&point);
|
||||
GHOST_TInt32 x_current = point.x;
|
||||
GHOST_TInt32 y_current = point.y;
|
||||
GHOST_TInt32 x_wrap = point.x;
|
||||
GHOST_TInt32 y_wrap = point.y;
|
||||
if (window->getCursorGrabModeIsWarp() && !window->m_tabletInRange) {
|
||||
GHOST_TInt32 x_new = x_screen;
|
||||
GHOST_TInt32 y_new = y_screen;
|
||||
GHOST_TInt32 x_accum, y_accum;
|
||||
GHOST_Rect bounds;
|
||||
|
||||
/* Fallback to window bounds. */
|
||||
/* fallback to window bounds */
|
||||
if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) {
|
||||
window->getClientBounds(bounds);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
bounds.wrapPoint(x_wrap, y_wrap, 2, window->getCursorGrabAxis());
|
||||
bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis());
|
||||
|
||||
if (x_wrap != x_current || y_wrap != y_current) {
|
||||
system->setCursorPosition(x_wrap, y_wrap);
|
||||
window->setCursorGrabAccum(x_accum + (x_current - x_wrap), y_accum + (y_current - y_wrap));
|
||||
|
||||
/* First message after SendInput wrap is invalid for unknown reasons, skip events until one
|
||||
* tick after SendInput event time. */
|
||||
lastTimestamp = ::GetTickCount() + 1;
|
||||
window->getCursorGrabAccum(x_accum, y_accum);
|
||||
if (x_new != x_screen || y_new != y_screen) {
|
||||
/* when wrapping we don't need to add an event because the
|
||||
* setCursorPosition call will cause a new event after */
|
||||
system->setCursorPosition(x_new, y_new); /* wrap */
|
||||
window->setCursorGrabAccum(x_accum + (x_screen - x_new), y_accum + (y_screen - y_new));
|
||||
}
|
||||
else {
|
||||
return new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x_screen + x_accum,
|
||||
y_screen + y_accum,
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
system->m_mousePosX = points[0].x;
|
||||
system->m_mousePosY = points[0].y;
|
||||
/* Use latest time, checking for overflow. */
|
||||
if (lastTimestamp > system->m_mouseTimestamp || ::GetTickCount() < system->m_mouseTimestamp) {
|
||||
system->m_mouseTimestamp = lastTimestamp;
|
||||
else {
|
||||
return new GHOST_EventCursor(system->getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x_screen,
|
||||
y_screen,
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void GHOST_SystemWin32::processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam)
|
||||
@@ -1334,23 +1317,6 @@ 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)
|
||||
{
|
||||
@@ -1390,10 +1356,12 @@ void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api)
|
||||
GHOST_System::setTabletAPI(api);
|
||||
|
||||
GHOST_WindowManager *wm = getWindowManager();
|
||||
GHOST_WindowWin32 *activeWindow = (GHOST_WindowWin32 *)wm->getActiveWindow();
|
||||
|
||||
for (GHOST_IWindow *win : wm->getWindows()) {
|
||||
GHOST_WindowWin32 *windowWin32 = (GHOST_WindowWin32 *)win;
|
||||
windowWin32->setWintabEnabled(windowWin32->useTabletAPI(GHOST_kTabletWintab));
|
||||
GHOST_WindowWin32 *windowsWindow = (GHOST_WindowWin32 *)win;
|
||||
windowsWindow->updateWintab(windowsWindow == activeWindow,
|
||||
!::IsIconic(windowsWindow->getHWND()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1638,28 +1606,15 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
case WT_INFOCHANGE: {
|
||||
window->processWintabInfoChangeEvent(lParam);
|
||||
eventHandled = true;
|
||||
break;
|
||||
}
|
||||
case WT_CSRCHANGE:
|
||||
window->updateWintabCursorInfo();
|
||||
eventHandled = true;
|
||||
break;
|
||||
case WT_PROXIMITY: {
|
||||
if (window->useTabletAPI(GHOST_kTabletWintab)) {
|
||||
if (LOWORD(lParam)) {
|
||||
window->m_tabletInRange = true;
|
||||
}
|
||||
else {
|
||||
window->processWintabLeave();
|
||||
}
|
||||
}
|
||||
eventHandled = true;
|
||||
bool inRange = LOWORD(lParam);
|
||||
window->processWintabProximityEvent(inRange);
|
||||
break;
|
||||
}
|
||||
case WT_PACKET:
|
||||
processWintabEvent(window);
|
||||
eventHandled = true;
|
||||
window->updateWintabEventsSyncTime();
|
||||
break;
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Pointer events, processed
|
||||
@@ -1709,19 +1664,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
}
|
||||
break;
|
||||
case WM_MOUSEMOVE:
|
||||
if (!window->m_mousePresent) {
|
||||
TRACKMOUSEEVENT tme = {sizeof(tme)};
|
||||
tme.dwFlags = TME_LEAVE;
|
||||
tme.hwndTrack = hwnd;
|
||||
TrackMouseEvent(&tme);
|
||||
window->m_mousePresent = true;
|
||||
window->setWintabOverlap(true);
|
||||
}
|
||||
|
||||
if (!window->m_tabletInRange) {
|
||||
processCursorEvent(window);
|
||||
eventHandled = true;
|
||||
}
|
||||
event = processCursorEvent(window);
|
||||
break;
|
||||
case WM_MOUSEWHEEL: {
|
||||
/* The WM_MOUSEWHEEL message is sent to the focus window
|
||||
@@ -1763,13 +1706,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
window->loadCursor(true, GHOST_kStandardCursorDefault);
|
||||
}
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
window->m_mousePresent = false;
|
||||
window->setWintabOverlap(false);
|
||||
if (!window->m_tabletInRange) {
|
||||
processCursorEvent(window);
|
||||
}
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Mouse events, ignored
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1785,6 +1722,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
* is sent to the window that has captured the mouse.
|
||||
*/
|
||||
break;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Window events, processed
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -1817,6 +1755,8 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||
if (LOWORD(wParam) == WA_INACTIVE)
|
||||
window->lostMouseCapture();
|
||||
|
||||
window->updateWintab(LOWORD(wParam) != WA_INACTIVE, !::IsIconic(window->getHWND()));
|
||||
|
||||
lResult = ::DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
break;
|
||||
}
|
||||
@@ -1858,8 +1798,6 @@ 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
|
||||
@@ -1867,13 +1805,21 @@ 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.
|
||||
*/
|
||||
event = processWindowSizeEvent(window);
|
||||
|
||||
if (wParam == SIZE_MINIMIZED) {
|
||||
window->setWintabEnabled(false);
|
||||
/* 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 if (wParam == SIZE_MAXIMIZED || wParam == SIZE_RESTORED) {
|
||||
window->setWintabEnabled(true);
|
||||
else {
|
||||
event = processWindowEvent(GHOST_kEventWindowSize, window);
|
||||
}
|
||||
|
||||
/* Window might be minimized while inactive. When a window is inactive but not minimized,
|
||||
* Wintab is left enabled (to catch the case where a pen is used to activate a window).
|
||||
* When an inactive window is minimized, we need to disable Wintab. */
|
||||
if (msg == WM_SIZE && wParam == SIZE_MINIMIZED) {
|
||||
window->updateWintab(false, false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@@ -322,9 +322,16 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
|
||||
/**
|
||||
* Creates tablet events from Wintab events.
|
||||
* \param type: The type of pointer event.
|
||||
* \param window: The window receiving the event (the active window).
|
||||
* \param mask: The button mask of the calling event.
|
||||
* \param mousePressed: Whether the mouse is currently pressed.
|
||||
* \return True if the method handled the event.
|
||||
*/
|
||||
static void processWintabEvent(GHOST_WindowWin32 *window);
|
||||
static GHOST_TSuccess processWintabEvent(GHOST_TEventType type,
|
||||
GHOST_WindowWin32 *window,
|
||||
GHOST_TButtonMask mask,
|
||||
bool mousePressed);
|
||||
|
||||
/**
|
||||
* Creates tablet events from pointer events.
|
||||
@@ -340,8 +347,9 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
/**
|
||||
* Creates cursor event.
|
||||
* \param window: The window receiving the event (the active window).
|
||||
* \return The event created.
|
||||
*/
|
||||
static void processCursorEvent(GHOST_WindowWin32 *window);
|
||||
static GHOST_EventCursor *processCursorEvent(GHOST_WindowWin32 *window);
|
||||
|
||||
/**
|
||||
* Handles a mouse wheel event.
|
||||
@@ -368,13 +376,6 @@ 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.
|
||||
@@ -462,23 +463,16 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||
__int64 m_lfstart;
|
||||
/** AltGr on current keyboard layout. */
|
||||
bool m_hasAltGr;
|
||||
/** Language identifier. */
|
||||
/** language identifier. */
|
||||
WORD m_langId;
|
||||
/** Stores keyboard layout. */
|
||||
/** stores keyboard layout. */
|
||||
HKL m_keylayout;
|
||||
|
||||
/** Console status. */
|
||||
/** Console status */
|
||||
int m_consoleStatus;
|
||||
|
||||
/** Wheel delta accumulator. */
|
||||
/** Wheel delta accumulator */
|
||||
int m_wheelDeltaAccum;
|
||||
|
||||
/** Last mouse x position. */
|
||||
int m_mousePosX;
|
||||
/** Last mouse y position. */
|
||||
int m_mousePosY;
|
||||
/** Last mouse timestamp. */
|
||||
DWORD m_mouseTimestamp;
|
||||
};
|
||||
|
||||
inline void GHOST_SystemWin32::retrieveModifierKeys(GHOST_ModifierKeys &keys) const
|
||||
|
@@ -905,8 +905,8 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
|
||||
static void postNotification()
|
||||
{
|
||||
NSUserNotification *notification = [[NSUserNotification alloc] init];
|
||||
notification.title = @"Blender Progress Notification";
|
||||
notification.informativeText = @"Calculation is finished.";
|
||||
notification.title = @"Blender progress notification";
|
||||
notification.informativeText = @"Calculation is finished";
|
||||
notification.soundName = NSUserNotificationDefaultSoundName;
|
||||
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
|
||||
[notification release];
|
||||
|
@@ -72,7 +72,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
bool is_debug,
|
||||
bool dialog)
|
||||
: GHOST_Window(width, height, state, wantStereoVisual, false),
|
||||
m_mousePresent(false),
|
||||
m_tabletInRange(false),
|
||||
m_inLiveResize(false),
|
||||
m_system(system),
|
||||
@@ -310,7 +309,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
||||
(m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable")) &&
|
||||
(m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"))) {
|
||||
initializeWintab();
|
||||
setWintabEnabled(true);
|
||||
// Determine which tablet API to use and enable it.
|
||||
updateWintab(m_system->m_windowFocus, m_system->m_windowFocus);
|
||||
}
|
||||
|
||||
CoCreateInstance(
|
||||
@@ -326,12 +326,13 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
|
||||
}
|
||||
|
||||
if (m_wintab.handle) {
|
||||
setWintabEnabled(false);
|
||||
updateWintab(false, false);
|
||||
if (m_wintab.close && m_wintab.context) {
|
||||
m_wintab.close(m_wintab.context);
|
||||
}
|
||||
|
||||
FreeLibrary(m_wintab.handle);
|
||||
memset(&m_wintab, 0, sizeof(m_wintab));
|
||||
}
|
||||
|
||||
if (m_user32) {
|
||||
@@ -770,6 +771,32 @@ void GHOST_WindowWin32::updateMouseCapture(GHOST_MouseCaptureEventWin32 event)
|
||||
}
|
||||
}
|
||||
|
||||
bool GHOST_WindowWin32::getMousePressed() const
|
||||
{
|
||||
return m_nPressedButtons;
|
||||
}
|
||||
|
||||
bool GHOST_WindowWin32::wintabSysButPressed() const
|
||||
{
|
||||
return m_wintab.numSysButtons;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::updateWintabSysBut(GHOST_MouseCaptureEventWin32 event)
|
||||
{
|
||||
switch (event) {
|
||||
case MousePressed:
|
||||
m_wintab.numSysButtons++;
|
||||
break;
|
||||
case MouseReleased:
|
||||
if (m_wintab.numSysButtons)
|
||||
m_wintab.numSysButtons--;
|
||||
break;
|
||||
case OperatorGrab:
|
||||
case OperatorUngrab:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
HCURSOR GHOST_WindowWin32::getStandardCursor(GHOST_TStandardCursor shape) const
|
||||
{
|
||||
// Convert GHOST cursor to Windows OEM cursor
|
||||
@@ -973,6 +1000,28 @@ GHOST_TSuccess GHOST_WindowWin32::hasCursorShape(GHOST_TStandardCursor cursorSha
|
||||
return (getStandardCursor(cursorShape)) ? GHOST_kSuccess : GHOST_kFailure;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::updateWintab(bool active, bool visible)
|
||||
{
|
||||
if (m_wintab.enable && m_wintab.overlap && m_wintab.context) {
|
||||
bool enable = useTabletAPI(GHOST_kTabletWintab) && visible;
|
||||
bool overlap = enable && active;
|
||||
|
||||
/* Disabling context while the Window is not minimized can cause issues on receiving Wintab
|
||||
* input while changing a window for some drivers, so only disable if either Wintab had been
|
||||
* disabled or the window is minimized. */
|
||||
m_wintab.enable(m_wintab.context, enable);
|
||||
m_wintab.overlap(m_wintab.context, overlap);
|
||||
|
||||
if (!overlap) {
|
||||
/* WT_PROXIMITY event doesn't occur unless tablet's cursor leaves the proximity while the
|
||||
* window is active. */
|
||||
m_tabletInRange = false;
|
||||
m_wintab.numSysButtons = 0;
|
||||
m_wintab.sysButtonsPressed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::initializeWintab()
|
||||
{
|
||||
/* Return if wintab library handle doesn't exist or wintab is already initialized. */
|
||||
@@ -985,6 +1034,8 @@ void GHOST_WindowWin32::initializeWintab()
|
||||
if (m_wintab.open && m_wintab.info && m_wintab.queueSizeGet && m_wintab.queueSizeSet &&
|
||||
m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) {
|
||||
|
||||
/* The pressure and orientation (tilt) */
|
||||
AXIS Pressure, Orientation[3];
|
||||
lc.lcPktData = PACKETDATA;
|
||||
lc.lcPktMode = PACKETMODE;
|
||||
lc.lcMoveMask = PACKETDATA;
|
||||
@@ -995,7 +1046,19 @@ void GHOST_WindowWin32::initializeWintab()
|
||||
|
||||
m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
|
||||
|
||||
updateWintabCursorInfo();
|
||||
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0;
|
||||
|
||||
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
|
||||
/* Does the tablet support azimuth ([0]) and altitude ([1])? */
|
||||
if (tiltSupport && 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 dont 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.context = m_wintab.open(m_hWnd, &lc, FALSE);
|
||||
@@ -1108,68 +1171,9 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo(
|
||||
}
|
||||
}
|
||||
|
||||
if (!outPointerInfo.empty()) {
|
||||
lastTabletData = outPointerInfo.back().tabletData;
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::setWintabEnabled(bool enable)
|
||||
{
|
||||
if (m_wintab.enable && m_wintab.get && m_wintab.context) {
|
||||
LOGCONTEXT context = {0};
|
||||
|
||||
if (m_wintab.get(m_wintab.context, &context)) {
|
||||
if (enable && context.lcStatus & CXS_DISABLED && useTabletAPI(GHOST_kTabletWintab)) {
|
||||
m_wintab.enable(m_wintab.context, true);
|
||||
|
||||
POINT cursorPos;
|
||||
::GetCursorPos(&cursorPos);
|
||||
GHOST_Rect bounds;
|
||||
getClientBounds(bounds);
|
||||
if (bounds.isInside(cursorPos.x, cursorPos.y)) {
|
||||
setWintabOverlap(true);
|
||||
}
|
||||
}
|
||||
else if (!enable && !(context.lcStatus & CXS_DISABLED)) {
|
||||
setWintabOverlap(false);
|
||||
m_wintab.enable(m_wintab.context, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::setWintabOverlap(bool overlap)
|
||||
{
|
||||
if (m_wintab.overlap && m_wintab.get && m_wintab.packetsGet && m_wintab.context) {
|
||||
LOGCONTEXT context = {0};
|
||||
|
||||
if (m_wintab.get(m_wintab.context, &context)) {
|
||||
if (overlap && context.lcStatus & CXS_OBSCURED && useTabletAPI(GHOST_kTabletWintab)) {
|
||||
m_wintab.overlap(m_wintab.context, true);
|
||||
}
|
||||
else if (!overlap && context.lcStatus & CXS_ONTOP) {
|
||||
m_wintab.overlap(m_wintab.context, false);
|
||||
|
||||
/* If context is disabled, Windows Ink may be active and managing m_tabletInRange. Don't
|
||||
* modify it. */
|
||||
if (!(context.lcStatus & CXS_DISABLED)) {
|
||||
processWintabLeave();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWintabLeave()
|
||||
{
|
||||
m_tabletInRange = false;
|
||||
m_wintab.buttons = 0;
|
||||
/* Clear the packet queue. */
|
||||
m_wintab.packetsGet(m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWintabDisplayChangeEvent()
|
||||
{
|
||||
LOGCONTEXT lc_sys = {0}, lc_curr = {0};
|
||||
@@ -1203,38 +1207,48 @@ bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const
|
||||
}
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::updateWintabCursorInfo()
|
||||
void GHOST_WindowWin32::processWintabProximityEvent(bool inRange)
|
||||
{
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's see if we can initialize tablet here
|
||||
if (m_wintab.info && m_wintab.context) {
|
||||
AXIS Pressure, Orientation[3];
|
||||
AXIS Pressure, Orientation[3]; /* The maximum tablet size */
|
||||
|
||||
BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure);
|
||||
m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0;
|
||||
|
||||
BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation);
|
||||
/* Does the tablet support azimuth ([0]) and altitude ([1]). */
|
||||
/* does the tablet support azimuth ([0]) and altitude ([1]) */
|
||||
if (tiltSupport && Orientation[0].axResolution && Orientation[1].axResolution) {
|
||||
m_wintab.maxAzimuth = Orientation[0].axMax;
|
||||
m_wintab.maxAltitude = Orientation[1].axMax;
|
||||
}
|
||||
else {
|
||||
else { /* no so dont do tilt stuff */
|
||||
m_wintab.maxAzimuth = m_wintab.maxAltitude = 0;
|
||||
}
|
||||
}
|
||||
|
||||
m_tabletInRange = inRange;
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam)
|
||||
{
|
||||
/* Update number of connected Wintab digitizers */
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
|
||||
|
||||
// Update number of connected Wintab digitizers
|
||||
if (LOWORD(lParam) == WTI_INTERFACE && HIWORD(lParam) == IFC_NDEVICES) {
|
||||
m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices);
|
||||
if (useTabletAPI(GHOST_kTabletWintab)) {
|
||||
setWintabEnabled(true);
|
||||
}
|
||||
updateWintab((GHOST_WindowWin32 *)system->getWindowManager()->getActiveWindow() == this,
|
||||
!::IsIconic(m_hWnd));
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TButtonMask GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, WORD physicalButton)
|
||||
GHOST_TSuccess GHOST_WindowWin32::wintabMouseToGhost(UINT cursor,
|
||||
WORD physicalButton,
|
||||
GHOST_TButtonMask &ghostButton)
|
||||
{
|
||||
const WORD numButtons = 32;
|
||||
BYTE logicalButtons[numButtons] = {0};
|
||||
@@ -1244,135 +1258,198 @@ GHOST_TButtonMask GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, WORD physic
|
||||
m_wintab.info(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons);
|
||||
|
||||
if (physicalButton >= numButtons) {
|
||||
return GHOST_kButtonMaskNone;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
BYTE lb = logicalButtons[physicalButton];
|
||||
|
||||
if (lb >= numButtons) {
|
||||
return GHOST_kButtonMaskNone;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
switch (systemButtons[lb]) {
|
||||
case SBN_LCLICK:
|
||||
return GHOST_kButtonMaskLeft;
|
||||
ghostButton = GHOST_kButtonMaskLeft;
|
||||
return GHOST_kSuccess;
|
||||
case SBN_RCLICK:
|
||||
return GHOST_kButtonMaskRight;
|
||||
ghostButton = GHOST_kButtonMaskRight;
|
||||
return GHOST_kSuccess;
|
||||
case SBN_MCLICK:
|
||||
return GHOST_kButtonMaskMiddle;
|
||||
ghostButton = GHOST_kButtonMaskMiddle;
|
||||
return GHOST_kSuccess;
|
||||
default:
|
||||
return GHOST_kButtonMaskNone;
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
|
||||
{
|
||||
if (!(useTabletAPI(GHOST_kTabletWintab) && m_wintab.packetsGet && m_wintab.context)) {
|
||||
if (!useTabletAPI(GHOST_kTabletWintab)) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
if (!(m_wintab.packetsGet && m_wintab.context)) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem();
|
||||
|
||||
const int numPackets = m_wintab.packetsGet(
|
||||
m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
|
||||
outWintabInfo.resize(numPackets);
|
||||
updateWintabEvents();
|
||||
|
||||
for (int i = 0; i < numPackets; i++) {
|
||||
PACKET pkt = m_wintab.pkts[i];
|
||||
GHOST_WintabInfoWin32 &out = outWintabInfo[i];
|
||||
auto &pendingEvents = m_wintab.pendingEvents;
|
||||
size_t pendingEventSize = pendingEvents.size();
|
||||
outWintabInfo.resize(pendingEventSize);
|
||||
|
||||
out.tabletData = GHOST_TABLET_DATA_NONE;
|
||||
/* % 3 for multiple devices ("DualTrack"). */
|
||||
switch (pkt.pkCursor % 3) {
|
||||
for (int i = 0; i < pendingEventSize; i++) {
|
||||
PACKET pkt = pendingEvents.front();
|
||||
pendingEvents.pop();
|
||||
|
||||
GHOST_TabletData tabletData = GHOST_TABLET_DATA_NONE;
|
||||
switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */
|
||||
case 0:
|
||||
/* Puck - processed as mouse. */
|
||||
out.tabletData.Active = GHOST_kTabletModeNone;
|
||||
tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */
|
||||
break;
|
||||
case 1:
|
||||
out.tabletData.Active = GHOST_kTabletModeStylus;
|
||||
tabletData.Active = GHOST_kTabletModeStylus; /* stylus */
|
||||
break;
|
||||
case 2:
|
||||
out.tabletData.Active = GHOST_kTabletModeEraser;
|
||||
tabletData.Active = GHOST_kTabletModeEraser; /* eraser */
|
||||
break;
|
||||
}
|
||||
|
||||
out.x = pkt.pkX;
|
||||
out.y = pkt.pkY;
|
||||
|
||||
if (m_wintab.maxPressure > 0) {
|
||||
out.tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
|
||||
tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure;
|
||||
}
|
||||
|
||||
if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) {
|
||||
ORIENTATION ort = pkt.pkOrientation;
|
||||
float vecLen;
|
||||
float altRad, azmRad; /* In radians. */
|
||||
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.
|
||||
* from the wintab spec:
|
||||
* orAzimuth Specifies the clockwise rotation of the
|
||||
* cursor about the z axis through a full circular range.
|
||||
*
|
||||
* 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.
|
||||
* 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. */
|
||||
/* 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. */
|
||||
/* 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);
|
||||
/* from there calculate X and Y components based on azimuth */
|
||||
tabletData.Xtilt = sin(azmRad) * vecLen;
|
||||
tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen);
|
||||
}
|
||||
|
||||
/* Some Wintab libraries don't handle relative button input, so we track button presses
|
||||
* manually. */
|
||||
out.button = GHOST_kButtonMaskNone;
|
||||
out.type = GHOST_kEventCursorMove;
|
||||
outWintabInfo[i].x = pkt.pkX;
|
||||
outWintabInfo[i].y = pkt.pkY;
|
||||
|
||||
DWORD buttonsChanged = m_wintab.buttons ^ pkt.pkButtons;
|
||||
if (buttonsChanged) {
|
||||
/* Find the index for the changed button from the button map. */
|
||||
WORD physicalButton = 0;
|
||||
for (DWORD diff = (unsigned)buttonsChanged >> 1; diff > 0; diff = (unsigned)diff >> 1) {
|
||||
physicalButton++;
|
||||
}
|
||||
/* Some Wintab libraries don't handle relative button input correctly, so we track button
|
||||
* presses manually. Examples include Wacom's Bamboo modifying button events in the queue when
|
||||
* peeked, or missing events when entering the window when the context is not on top. */
|
||||
DWORD buttonsChanged = m_wintab.sysButtonsPressed ^ pkt.pkButtons;
|
||||
|
||||
out.button = wintabMouseToGhost(pkt.pkCursor, physicalButton);
|
||||
|
||||
if (out.button != GHOST_kButtonMaskNone) {
|
||||
if (buttonsChanged & pkt.pkButtons) {
|
||||
out.type = GHOST_kEventButtonDown;
|
||||
}
|
||||
else {
|
||||
out.type = GHOST_kEventButtonUp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only update handled button, in case multiple button events arrived simultaneously. */
|
||||
m_wintab.buttons ^= 1 << physicalButton;
|
||||
/* Find the index for the changed button from the button map. */
|
||||
WORD physicalButton = 0;
|
||||
for (DWORD diff = (unsigned)buttonsChanged >> 1; diff > 0; diff = (unsigned)diff >> 1) {
|
||||
physicalButton++;
|
||||
}
|
||||
|
||||
out.time = system->tickCountToMillis(pkt.pkTime);
|
||||
}
|
||||
if (buttonsChanged &&
|
||||
wintabMouseToGhost(pkt.pkCursor, physicalButton, outWintabInfo[i].button)) {
|
||||
if (buttonsChanged & pkt.pkButtons) {
|
||||
outWintabInfo[i].type = GHOST_kEventButtonDown;
|
||||
}
|
||||
else {
|
||||
outWintabInfo[i].type = GHOST_kEventButtonUp;
|
||||
}
|
||||
}
|
||||
else {
|
||||
outWintabInfo[i].type = GHOST_kEventCursorMove;
|
||||
}
|
||||
|
||||
if (!outWintabInfo.empty()) {
|
||||
lastTabletData = outWintabInfo.back().tabletData;
|
||||
m_wintab.sysButtonsPressed = pkt.pkButtons;
|
||||
|
||||
outWintabInfo[i].time = system->millisSinceStart(pkt.pkTime);
|
||||
outWintabInfo[i].tabletData = tabletData;
|
||||
}
|
||||
|
||||
return GHOST_kSuccess;
|
||||
}
|
||||
|
||||
GHOST_TabletData GHOST_WindowWin32::getLastTabletData()
|
||||
void GHOST_WindowWin32::updateWintabEvents()
|
||||
{
|
||||
return lastTabletData;
|
||||
readWintabEvents();
|
||||
// When a Wintab device is used to leave window focus, some of it's packets are periodically not
|
||||
// queued in time to be flushed. Reading packets needs to occur before expiring packets to clear
|
||||
// these from the queue.
|
||||
expireWintabEvents();
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::updateWintabEventsSyncTime()
|
||||
{
|
||||
readWintabEvents();
|
||||
|
||||
if (!m_wintab.pendingEvents.empty()) {
|
||||
auto lastEvent = m_wintab.pendingEvents.back();
|
||||
m_wintab.sysTimeOffset = ::GetTickCount() - lastEvent.pkTime;
|
||||
}
|
||||
|
||||
expireWintabEvents();
|
||||
}
|
||||
|
||||
void GHOST_WindowWin32::readWintabEvents()
|
||||
{
|
||||
if (!(m_wintab.packetsGet && m_wintab.context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto &pendingEvents = m_wintab.pendingEvents;
|
||||
|
||||
/* Get new packets. */
|
||||
const int numPackets = m_wintab.packetsGet(
|
||||
m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data());
|
||||
|
||||
for (int i = 0; i < numPackets; i++) {
|
||||
pendingEvents.push(m_wintab.pkts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Wintab (per documentation but may vary with implementation) does not update when its event
|
||||
* buffer is full. This is an issue because we need some synchronization point between Wintab
|
||||
* events and Win32 events, so we can't drain and process the queue immediately. We need to
|
||||
* associate Wintab mouse events to Win32 mouse events because Wintab buttons are modal (a button
|
||||
* associated to left click is not always a left click) and there's no way to reconstruct their
|
||||
* mode from the Wintab API alone. There is no guaranteed ordering between Wintab and Win32 mouse
|
||||
* events and no documented time stamp shared between the two, so we synchronize on mouse button
|
||||
* events. */
|
||||
void GHOST_WindowWin32::expireWintabEvents()
|
||||
{
|
||||
auto &pendingEvents = m_wintab.pendingEvents;
|
||||
|
||||
DWORD currTime = ::GetTickCount() - m_wintab.sysTimeOffset;
|
||||
DWORD millisTimeout = 300;
|
||||
while (!pendingEvents.empty()) {
|
||||
DWORD pkTime = pendingEvents.front().pkTime;
|
||||
|
||||
if (currTime > pkTime + millisTimeout) {
|
||||
pendingEvents.pop();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GHOST_TUns16 GHOST_WindowWin32::getDPIHint()
|
||||
|
@@ -437,6 +437,13 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const;
|
||||
void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const;
|
||||
|
||||
/**
|
||||
* Handle setup and switch between Wintab and Pointer APIs.
|
||||
* \param active: Whether the window is or will be in an active state.
|
||||
* \param visible: Whether the window is currently (or will be) visible).
|
||||
*/
|
||||
void updateWintab(bool active, bool visible);
|
||||
|
||||
/**
|
||||
* Query whether given tablet API should be used.
|
||||
* \param api: Tablet API to test.
|
||||
@@ -454,32 +461,16 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
WPARAM wParam,
|
||||
LPARAM lParam);
|
||||
|
||||
/**
|
||||
* Enables or disables Wintab context.
|
||||
* \param enable: Whether the context should be enabled.
|
||||
*/
|
||||
void setWintabEnabled(bool enable);
|
||||
|
||||
/**
|
||||
* Changes Wintab context overlap.
|
||||
* \param overlap: Whether context should be brought to top of overlap order.
|
||||
*/
|
||||
void setWintabOverlap(bool overlap);
|
||||
|
||||
/**
|
||||
* Resets Wintab state.
|
||||
*/
|
||||
void processWintabLeave();
|
||||
|
||||
/**
|
||||
* Handle Wintab coordinate changes when DisplayChange events occur.
|
||||
*/
|
||||
void processWintabDisplayChangeEvent();
|
||||
|
||||
/**
|
||||
* Updates cached Wintab properties for current cursor.
|
||||
* Set tablet details when a cursor enters range.
|
||||
* \param inRange: Whether the Wintab device is in tracking range.
|
||||
*/
|
||||
void updateWintabCursorInfo();
|
||||
void processWintabProximityEvent(bool inRange);
|
||||
|
||||
/**
|
||||
* Handle Wintab info changes such as change in number of connected tablets.
|
||||
@@ -495,10 +486,14 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo);
|
||||
|
||||
/**
|
||||
* Get the most recent tablet data.
|
||||
* \return Most recent tablet data.
|
||||
* Updates pending Wintab events and syncs Wintab time with OS time.
|
||||
*/
|
||||
GHOST_TabletData getLastTabletData();
|
||||
void updateWintabEventsSyncTime();
|
||||
|
||||
/**
|
||||
* Updates pending Wintab events.
|
||||
*/
|
||||
void updateWintabEvents();
|
||||
|
||||
GHOST_TSuccess beginFullScreen() const
|
||||
{
|
||||
@@ -512,8 +507,24 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
|
||||
GHOST_TUns16 getDPIHint() override;
|
||||
|
||||
/** Whether the mouse is either over or captured by the window. */
|
||||
bool m_mousePresent;
|
||||
/**
|
||||
* Get whether there are currently any mouse buttons pressed.
|
||||
* \return True if there are any currently pressed mouse buttons.
|
||||
*/
|
||||
bool getMousePressed() const;
|
||||
|
||||
/**
|
||||
* Get if there are currently pressed Wintab buttons associated to a Windows mouse button press.
|
||||
* \return True if there are currently any pressed Wintab buttons associated to a Windows
|
||||
* mouse button press.
|
||||
*/
|
||||
bool wintabSysButPressed() const;
|
||||
|
||||
/**
|
||||
* Register a Wintab button has been associated to a Windows mouse button press.
|
||||
* \param event: Whether the button was pressed or released.
|
||||
*/
|
||||
void updateWintabSysBut(GHOST_MouseCaptureEventWin32 event);
|
||||
|
||||
/** Whether a tablet stylus is being tracked. */
|
||||
bool m_tabletInRange;
|
||||
@@ -571,28 +582,28 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
int hotY,
|
||||
bool canInvertColor);
|
||||
|
||||
/** Pointer to system. */
|
||||
/** Pointer to system */
|
||||
GHOST_SystemWin32 *m_system;
|
||||
/** Pointer to COM IDropTarget implementor. */
|
||||
/** Pointer to COM IDropTarget implementor */
|
||||
GHOST_DropTargetWin32 *m_dropTarget;
|
||||
/** Window handle. */
|
||||
HWND m_hWnd;
|
||||
/** Device context handle. */
|
||||
HDC m_hDC;
|
||||
|
||||
/** Flag for if window has captured the mouse. */
|
||||
/** Flag for if window has captured the mouse */
|
||||
bool m_hasMouseCaptured;
|
||||
/** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab().
|
||||
* Multiple grabs must be released with a single ungrab. */
|
||||
/** Flag if an operator grabs the mouse with WM_cursor_grab_enable/ungrab()
|
||||
* Multiple grabs must be released with a single ungrab */
|
||||
bool m_hasGrabMouse;
|
||||
/** Count of number of pressed buttons. */
|
||||
/** Count of number of pressed buttons */
|
||||
int m_nPressedButtons;
|
||||
/** HCURSOR structure of the custom cursor. */
|
||||
/** HCURSOR structure of the custom cursor */
|
||||
HCURSOR m_customCursor;
|
||||
/** Request GL context aith alpha channel. */
|
||||
/** request GL context aith alpha channel */
|
||||
bool m_wantAlphaBackground;
|
||||
|
||||
/** ITaskbarList3 structure for progress bar. */
|
||||
/** ITaskbarList3 structure for progress bar*/
|
||||
ITaskbarList3 *m_Bar;
|
||||
|
||||
static const wchar_t *s_windowClassName;
|
||||
@@ -615,33 +626,42 @@ class GHOST_WindowWin32 : public GHOST_Window {
|
||||
GHOST_WIN32_WTEnable enable = NULL;
|
||||
GHOST_WIN32_WTOverlap overlap = NULL;
|
||||
|
||||
/** Stores the Tablet context if detected Tablet features using WinTab.dll. */
|
||||
/** Stores the Tablet context if detected Tablet features using WinTab.dll */
|
||||
HCTX context = NULL;
|
||||
/** Number of connected Wintab digitizers. */
|
||||
/** Number of connected Wintab digitizers */
|
||||
UINT numDevices = 0;
|
||||
/** Pressed button map. */
|
||||
GHOST_TUns8 buttons = 0;
|
||||
/** Number of cursors currently in contact mapped to system buttons */
|
||||
GHOST_TUns8 numSysButtons = 0;
|
||||
/** Cursors currently in contact mapped to system buttons */
|
||||
DWORD sysButtonsPressed = 0;
|
||||
DWORD sysTimeOffset = 0;
|
||||
LONG maxPressure = 0;
|
||||
LONG maxAzimuth = 0, maxAltitude = 0;
|
||||
/** Reusable buffer to read in Wintab Packets. */
|
||||
std::vector<PACKET> pkts;
|
||||
/** Queue of packets to process. */
|
||||
std::queue<PACKET> pendingEvents;
|
||||
} m_wintab;
|
||||
|
||||
/** Most recent tablet data. */
|
||||
GHOST_TabletData lastTabletData = GHOST_TABLET_DATA_NONE;
|
||||
|
||||
/**
|
||||
* Wintab setup.
|
||||
*/
|
||||
void initializeWintab();
|
||||
|
||||
void readWintabEvents();
|
||||
|
||||
void expireWintabEvents();
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* \param buttonMask: Return pointer for button found.
|
||||
* \return Whether an associated button was found.
|
||||
*/
|
||||
GHOST_TButtonMask wintabMouseToGhost(UINT cursor, WORD physicalButton);
|
||||
GHOST_TSuccess wintabMouseToGhost(UINT cursor,
|
||||
WORD physicalButton,
|
||||
GHOST_TButtonMask &buttonMask);
|
||||
|
||||
GHOST_TWindowState m_normal_state;
|
||||
|
||||
|
@@ -118,27 +118,27 @@ void MEM_lockfree_freeN(void *vmemh);
|
||||
void *MEM_lockfree_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
|
||||
void *MEM_lockfree_reallocN_id(void *vmemh,
|
||||
size_t len,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(2);
|
||||
void *MEM_lockfree_recallocN_id(void *vmemh,
|
||||
size_t len,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(2);
|
||||
void *MEM_lockfree_callocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
void *MEM_lockfree_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||
void *MEM_lockfree_calloc_arrayN(size_t len,
|
||||
size_t size,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
|
||||
void *MEM_lockfree_mallocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
void *MEM_lockfree_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||
void *MEM_lockfree_malloc_arrayN(size_t len,
|
||||
size_t size,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
|
||||
void *MEM_lockfree_mallocN_aligned(size_t len,
|
||||
size_t alignment,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
||||
void MEM_lockfree_printmemlist_pydict(void);
|
||||
void MEM_lockfree_printmemlist(void);
|
||||
@@ -161,27 +161,27 @@ void MEM_guarded_freeN(void *vmemh);
|
||||
void *MEM_guarded_dupallocN(const void *vmemh) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
|
||||
void *MEM_guarded_reallocN_id(void *vmemh,
|
||||
size_t len,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(2);
|
||||
void *MEM_guarded_recallocN_id(void *vmemh,
|
||||
size_t len,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(2);
|
||||
void *MEM_guarded_callocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
void *MEM_guarded_callocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||
void *MEM_guarded_calloc_arrayN(size_t len,
|
||||
size_t size,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
|
||||
void *MEM_guarded_mallocN(size_t len, const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
void *MEM_guarded_mallocN(size_t len, const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(2);
|
||||
void *MEM_guarded_malloc_arrayN(size_t len,
|
||||
size_t size,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1, 2) ATTR_NONNULL(3);
|
||||
void *MEM_guarded_mallocN_aligned(size_t len,
|
||||
size_t alignment,
|
||||
const char *str) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
const char *UNUSED(str)) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
|
||||
ATTR_ALLOC_SIZE(1) ATTR_NONNULL(3);
|
||||
void MEM_guarded_printmemlist_pydict(void);
|
||||
void MEM_guarded_printmemlist(void);
|
||||
|
@@ -72,7 +72,6 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
||||
mUsingFractions = (fds->flags & FLUID_DOMAIN_USE_FRACTIONS) && mUsingLiquid;
|
||||
mUsingMesh = (fds->flags & FLUID_DOMAIN_USE_MESH) && mUsingLiquid;
|
||||
mUsingDiffusion = (fds->flags & FLUID_DOMAIN_USE_DIFFUSION) && mUsingLiquid;
|
||||
mUsingViscosity = (fds->flags & FLUID_DOMAIN_USE_VISCOSITY) && mUsingLiquid;
|
||||
mUsingMVel = (fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS) && mUsingLiquid;
|
||||
mUsingGuiding = (fds->flags & FLUID_DOMAIN_USE_GUIDE);
|
||||
mUsingDrops = (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) && mUsingLiquid;
|
||||
@@ -222,10 +221,6 @@ MANTA::MANTA(int *res, FluidModifierData *fmd)
|
||||
initSuccess &= initLiquidMesh();
|
||||
}
|
||||
|
||||
if (mUsingViscosity) {
|
||||
initSuccess &= initLiquidViscosity();
|
||||
}
|
||||
|
||||
if (mUsingDiffusion) {
|
||||
initSuccess &= initCurvature();
|
||||
}
|
||||
@@ -445,17 +440,6 @@ bool MANTA::initLiquidMesh(FluidModifierData *fmd)
|
||||
return runPythonString(pythonCommands);
|
||||
}
|
||||
|
||||
bool MANTA::initLiquidViscosity(FluidModifierData *fmd)
|
||||
{
|
||||
vector<string> pythonCommands;
|
||||
string tmpString = fluid_variables_viscosity + fluid_solver_viscosity + liquid_alloc_viscosity;
|
||||
string finalString = parseScript(tmpString, fmd);
|
||||
pythonCommands.push_back(finalString);
|
||||
|
||||
mUsingViscosity = true;
|
||||
return runPythonString(pythonCommands);
|
||||
}
|
||||
|
||||
bool MANTA::initCurvature(FluidModifierData *fmd)
|
||||
{
|
||||
std::vector<std::string> pythonCommands;
|
||||
@@ -887,10 +871,8 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd)
|
||||
mRNAMap["CACHE_DIR"] = cacheDirectory;
|
||||
mRNAMap["COMPRESSION_OPENVDB"] = vdbCompressionMethod;
|
||||
mRNAMap["PRECISION_OPENVDB"] = vdbPrecisionHalf;
|
||||
mRNAMap["CLIP_OPENVDB"] = to_string(fds->clipping);
|
||||
mRNAMap["CLIP_OPENVDB"] = to_string(fds->clipping);
|
||||
mRNAMap["PP_PARTICLE_MAXIMUM"] = to_string(fds->sys_particle_maximum);
|
||||
mRNAMap["USING_VISCOSITY"] = getBooleanString(fds->flags & FLUID_DOMAIN_USE_VISCOSITY);
|
||||
mRNAMap["VISCOSITY_VALUE"] = to_string(fds->viscosity_value);
|
||||
|
||||
/* Fluid object names. */
|
||||
mRNAMap["NAME_FLAGS"] = FLUID_NAME_FLAGS;
|
||||
@@ -1394,14 +1376,15 @@ bool MANTA::readGuiding(FluidModifierData *fmd, int framenr, bool sourceDomain)
|
||||
if (with_debug)
|
||||
cout << "MANTA::readGuiding()" << endl;
|
||||
|
||||
FluidDomainSettings *fds = fmd->domain;
|
||||
|
||||
if (!mUsingGuiding)
|
||||
return false;
|
||||
if (!fmd)
|
||||
if (!fds)
|
||||
return false;
|
||||
|
||||
ostringstream ss;
|
||||
vector<string> pythonCommands;
|
||||
FluidDomainSettings *fds = fmd->domain;
|
||||
|
||||
string directory = (sourceDomain) ? getDirectory(fmd, FLUID_DOMAIN_DIR_DATA) :
|
||||
getDirectory(fmd, FLUID_DOMAIN_DIR_GUIDE);
|
||||
@@ -1745,7 +1728,6 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
||||
bool guiding = fds->active_fields & FLUID_DOMAIN_ACTIVE_GUIDE;
|
||||
bool invel = fds->active_fields & FLUID_DOMAIN_ACTIVE_INVEL;
|
||||
bool outflow = fds->active_fields & FLUID_DOMAIN_ACTIVE_OUTFLOW;
|
||||
bool viscosity = fds->flags & FLUID_DOMAIN_USE_VISCOSITY;
|
||||
|
||||
string manta_script;
|
||||
|
||||
@@ -1760,8 +1742,6 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
||||
manta_script += fluid_variables_particles + liquid_variables_particles;
|
||||
if (guiding)
|
||||
manta_script += fluid_variables_guiding;
|
||||
if (viscosity)
|
||||
manta_script += fluid_variables_viscosity;
|
||||
|
||||
/* Solvers. */
|
||||
manta_script += header_solvers + fluid_solver;
|
||||
@@ -1771,8 +1751,6 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
||||
manta_script += fluid_solver_particles;
|
||||
if (guiding)
|
||||
manta_script += fluid_solver_guiding;
|
||||
if (viscosity)
|
||||
manta_script += fluid_solver_viscosity;
|
||||
|
||||
/* Grids. */
|
||||
manta_script += header_grids + fluid_alloc + liquid_alloc;
|
||||
@@ -1790,8 +1768,6 @@ bool MANTA::exportLiquidScript(FluidModifierData *fmd)
|
||||
manta_script += fluid_alloc_invel;
|
||||
if (outflow)
|
||||
manta_script += fluid_alloc_outflow;
|
||||
if (viscosity)
|
||||
manta_script += liquid_alloc_viscosity;
|
||||
|
||||
/* Domain init. */
|
||||
manta_script += header_gridinit + liquid_init_phi;
|
||||
|
@@ -67,7 +67,6 @@ struct MANTA {
|
||||
bool initColorsHigh(struct FluidModifierData *fmd = nullptr);
|
||||
bool initLiquid(FluidModifierData *fmd = nullptr);
|
||||
bool initLiquidMesh(FluidModifierData *fmd = nullptr);
|
||||
bool initLiquidViscosity(FluidModifierData *fmd = nullptr);
|
||||
bool initObstacle(FluidModifierData *fmd = nullptr);
|
||||
bool initCurvature(FluidModifierData *fmd = nullptr);
|
||||
bool initGuiding(FluidModifierData *fmd = nullptr);
|
||||
@@ -758,7 +757,6 @@ struct MANTA {
|
||||
bool mUsingNoise;
|
||||
bool mUsingMesh;
|
||||
bool mUsingDiffusion;
|
||||
bool mUsingViscosity;
|
||||
bool mUsingMVel;
|
||||
bool mUsingLiquid;
|
||||
bool mUsingSmoke;
|
||||
|
@@ -79,11 +79,6 @@ const std::string fluid_solver_guiding =
|
||||
mantaMsg('Solver guiding')\n\
|
||||
sg$ID$ = Solver(name='solver_guiding$ID$', gridSize=gs_sg$ID$)\n";
|
||||
|
||||
const std::string fluid_solver_viscosity =
|
||||
"\n\
|
||||
mantaMsg('Solver viscosity')\n\
|
||||
sv$ID$ = Solver(name='solver_viscosity$ID$', gridSize=gs_sv$ID$, dim=dim_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// VARIABLES
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
@@ -138,7 +133,7 @@ end_frame_s$ID$ = $END_FRAME$\n\
|
||||
\n\
|
||||
# Fluid diffusion / viscosity\n\
|
||||
domainSize_s$ID$ = $FLUID_DOMAIN_SIZE$ # longest domain side in meters\n\
|
||||
kinViscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\
|
||||
viscosity_s$ID$ = $FLUID_VISCOSITY$ / (domainSize_s$ID$*domainSize_s$ID$) # kinematic viscosity in m^2/s\n\
|
||||
\n\
|
||||
# Factors to convert Blender units to Manta units\n\
|
||||
ratioMetersToRes_s$ID$ = float(domainSize_s$ID$) / float(res_s$ID$) # [meters / cells]\n\
|
||||
@@ -204,10 +199,6 @@ tau_sg$ID$ = 1.0\n\
|
||||
sigma_sg$ID$ = 0.99/tau_sg$ID$\n\
|
||||
theta_sg$ID$ = 1.0\n";
|
||||
|
||||
const std::string fluid_variables_viscosity =
|
||||
"\n\
|
||||
gs_sv$ID$ = vec3($RESX$*2, $RESY$*2, $RESZ$*2)\n";
|
||||
|
||||
const std::string fluid_with_obstacle =
|
||||
"\n\
|
||||
using_obstacle_s$ID$ = True\n";
|
||||
@@ -412,9 +403,7 @@ def fluid_post_step_$ID$():\n\
|
||||
mantaMsg('Fluid post step')\n\
|
||||
\n\
|
||||
# Copy vel grid to reals grids (which Blender internal will in turn use for vel access)\n\
|
||||
copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
copyVec3ToReal(source=guidevel_sg$ID$, targetX=x_guidevel_s$ID$, targetY=y_guidevel_s$ID$, targetZ=z_guidevel_s$ID$)\n";
|
||||
copyVec3ToReal(source=vel_s$ID$, targetX=x_vel_s$ID$, targetY=y_vel_s$ID$, targetZ=z_vel_s$ID$)\n";
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DESTRUCTION
|
||||
@@ -678,9 +667,7 @@ const std::string fluid_load_guiding =
|
||||
def fluid_load_guiding_$ID$(path, framenr, file_format):\n\
|
||||
mantaMsg('Fluid load guiding, frame ' + str(framenr))\n\
|
||||
guidevel_sg$ID$.setName('$NAME_VELOCITY_GUIDE$')\n\
|
||||
fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format, file_name=file_guiding_s$ID$)\n\
|
||||
\n\
|
||||
copyVec3ToReal(source=guidevel_sg$ID$, targetX=x_guidevel_s$ID$, targetY=y_guidevel_s$ID$, targetZ=z_guidevel_s$ID$)\n";
|
||||
fluid_file_import_s$ID$(dict=fluid_guiding_dict_s$ID$, path=path, framenr=framenr, file_format=file_format, file_name=file_guiding_s$ID$)\n";
|
||||
|
||||
const std::string fluid_load_vel =
|
||||
"\n\
|
||||
|
@@ -40,8 +40,6 @@ radiusFactor_s$ID$ = $PARTICLE_RADIUS$\n\
|
||||
using_mesh_s$ID$ = $USING_MESH$\n\
|
||||
using_final_mesh_s$ID$ = $USING_IMPROVED_MESH$\n\
|
||||
using_fractions_s$ID$ = $USING_FRACTIONS$\n\
|
||||
using_apic_s$ID$ = $USING_APIC$\n\
|
||||
using_viscosity_s$ID$ = $USING_VISCOSITY$\n\
|
||||
fracThreshold_s$ID$ = $FRACTIONS_THRESHOLD$\n\
|
||||
fracDistance_s$ID$ = $FRACTIONS_DISTANCE$\n\
|
||||
flipRatio_s$ID$ = $FLIP_RATIO$\n\
|
||||
@@ -53,7 +51,7 @@ smoothenNeg_s$ID$ = $MESH_SMOOTHEN_NEG$\n\
|
||||
randomness_s$ID$ = $PARTICLE_RANDOMNESS$\n\
|
||||
surfaceTension_s$ID$ = $LIQUID_SURFACE_TENSION$\n\
|
||||
maxSysParticles_s$ID$ = $PP_PARTICLE_MAXIMUM$\n\
|
||||
viscosityValue_s$ID$ = $VISCOSITY_VALUE$\n";
|
||||
using_apic_s$ID$ = $USING_APIC$\n";
|
||||
|
||||
const std::string liquid_variables_particles =
|
||||
"\n\
|
||||
@@ -137,13 +135,6 @@ liquid_mesh_dict_s$ID$ = { 'lMesh' : mesh_sm$ID$ }\n\
|
||||
if using_speedvectors_s$ID$:\n\
|
||||
liquid_meshvel_dict_s$ID$ = { 'lVelMesh' : mVel_mesh$ID$ }\n";
|
||||
|
||||
const std::string liquid_alloc_viscosity =
|
||||
"\n\
|
||||
# Viscosity grids\n\
|
||||
volumes_s$ID$ = sv$ID$.create(RealGrid)\n\
|
||||
viscosity_s$ID$ = s$ID$.create(RealGrid)\n\
|
||||
viscosity_s$ID$.setConst(viscosityValue_s$ID$)\n";
|
||||
|
||||
const std::string liquid_alloc_curvature =
|
||||
"\n\
|
||||
mantaMsg('Liquid alloc curvature')\n\
|
||||
@@ -315,7 +306,7 @@ def liquid_step_$ID$():\n\
|
||||
if using_diffusion_s$ID$:\n\
|
||||
mantaMsg('Viscosity')\n\
|
||||
# diffusion param for solve = const * dt / dx^2\n\
|
||||
alphaV = kinViscosity_s$ID$ * s$ID$.timestep * float(res_s$ID$*res_s$ID$)\n\
|
||||
alphaV = viscosity_s$ID$ * s$ID$.timestep * float(res_s$ID$*res_s$ID$)\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
cgSolveDiffusion(flags_s$ID$, vel_s$ID$, alphaV)\n\
|
||||
\n\
|
||||
@@ -324,11 +315,7 @@ def liquid_step_$ID$():\n\
|
||||
curvature_s$ID$.clamp(-1.0, 1.0)\n\
|
||||
\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
if using_viscosity_s$ID$:\n\
|
||||
viscosity_s$ID$.setConst(viscosityValue_s$ID$)\n\
|
||||
applyViscosity(flags=flags_s$ID$, phi=phi_s$ID$, vel=vel_s$ID$, volumes=volumes_s$ID$, viscosity=viscosity_s$ID$)\n\
|
||||
\n\
|
||||
setWallBcs(flags=flags_s$ID$, vel=vel_s$ID$, obvel=None if using_fractions_s$ID$ else obvel_s$ID$, phiObs=phiObs_s$ID$, fractions=fractions_s$ID$)\n\
|
||||
if using_guiding_s$ID$:\n\
|
||||
mantaMsg('Guiding and pressure')\n\
|
||||
PD_fluid_guiding(vel=vel_s$ID$, velT=velT_s$ID$, flags=flags_s$ID$, phi=phi_s$ID$, curv=curvature_s$ID$, surfTens=surfaceTension_s$ID$, fractions=fractions_s$ID$, weight=weightGuide_s$ID$, blurRadius=beta_sg$ID$, pressure=pressure_s$ID$, tau=tau_sg$ID$, sigma=sigma_sg$ID$, theta=theta_sg$ID$, zeroPressureFixing=domainClosed_s$ID$)\n\
|
||||
|
@@ -17,7 +17,7 @@ inkscape_bin = os.environ.get("INKSCAPE_BIN", "inkscape")
|
||||
blender_bin = os.environ.get("BLENDER_BIN", "blender")
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_bin = inkscape_app_path
|
||||
blender_app_path = '/Applications/Blender.app/Contents/MacOS/Blender'
|
||||
@@ -29,8 +29,8 @@ cmd = (
|
||||
os.path.join(BASEDIR, "blender_icons.svg"),
|
||||
"--export-width=602",
|
||||
"--export-height=640",
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "blender_icons16.png"),
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "blender_icons16.png"),
|
||||
)
|
||||
run(cmd)
|
||||
|
||||
@@ -39,8 +39,8 @@ cmd = (
|
||||
os.path.join(BASEDIR, "blender_icons.svg"),
|
||||
"--export-width=1204",
|
||||
"--export-height=1280",
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "blender_icons32.png"),
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "blender_icons32.png"),
|
||||
)
|
||||
run(cmd)
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,7 +10,7 @@ BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
inkscape_path = 'inkscape'
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/MacOS/inkscape'
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_path = inkscape_app_path
|
||||
|
||||
@@ -19,7 +19,7 @@ cmd = (
|
||||
os.path.join(BASEDIR, "prvicons.svg"),
|
||||
"--export-width=1792",
|
||||
"--export-height=256",
|
||||
"--export-type=png",
|
||||
"--export-filename=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
)
|
||||
subprocess.check_call(cmd)
|
||||
|
@@ -558,7 +558,6 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
|
||||
"msgid": ((("msgctxt",), _ctxt_to_ctxt),
|
||||
),
|
||||
"message": (),
|
||||
"heading": (),
|
||||
}
|
||||
|
||||
context_kw_set = {}
|
||||
|
@@ -504,7 +504,6 @@ MO_FILE_NAME = DOMAIN + ".mo"
|
||||
# Where to search for py files that may contain ui strings (relative to one of the 'resource_path' of Blender).
|
||||
CUSTOM_PY_UI_FILES = [
|
||||
os.path.join("scripts", "startup", "bl_ui"),
|
||||
os.path.join("scripts", "startup", "bl_operators"),
|
||||
os.path.join("scripts", "modules", "rna_prop_ui.py"),
|
||||
]
|
||||
|
||||
|
@@ -38,7 +38,6 @@ class SpellChecker:
|
||||
"boolean", "booleans",
|
||||
"chamfer",
|
||||
"couldn", # couldn't
|
||||
"customizable",
|
||||
"decrement",
|
||||
"derivate",
|
||||
"deterministically",
|
||||
@@ -174,7 +173,7 @@ class SpellChecker:
|
||||
"premultiply", "premultiplied",
|
||||
"prepass",
|
||||
"prepend",
|
||||
"preprocess", "preprocessing", "preprocessor",
|
||||
"preprocess", "preprocessing",
|
||||
"preseek",
|
||||
"promillage",
|
||||
"pushdown",
|
||||
@@ -549,7 +548,7 @@ class SpellChecker:
|
||||
"freestyle",
|
||||
"enum", "enums",
|
||||
"gizmogroup",
|
||||
"gon", "gons", # N-Gon(s)
|
||||
"gons", # N-Gons
|
||||
"gpencil",
|
||||
"idcol",
|
||||
"keyframe", "keyframes", "keyframing", "keyframed",
|
||||
|
@@ -296,10 +296,13 @@ def bake_action_iter(
|
||||
pbone.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
euler = pbone.matrix_basis.to_euler(obj.rotation_mode, euler_prev)
|
||||
euler = pbone.rotation_euler.copy()
|
||||
euler.make_compatible(euler_prev)
|
||||
pbone.rotation_euler = euler
|
||||
euler_prev = euler
|
||||
del euler
|
||||
euler_prev = pbone.rotation_euler.copy()
|
||||
else:
|
||||
euler_prev = pbone.rotation_euler.copy()
|
||||
pbone.keyframe_insert("rotation_euler", index=-1, frame=f, group=name)
|
||||
|
||||
pbone.keyframe_insert("scale", index=-1, frame=f, group=name)
|
||||
@@ -343,8 +346,13 @@ def bake_action_iter(
|
||||
obj.keyframe_insert("rotation_axis_angle", index=-1, frame=f, group=name)
|
||||
else: # euler, XYZ, ZXY etc
|
||||
if euler_prev is not None:
|
||||
obj.rotation_euler = matrix.to_euler(obj.rotation_mode, euler_prev)
|
||||
euler_prev = obj.rotation_euler.copy()
|
||||
euler = obj.rotation_euler.copy()
|
||||
euler.make_compatible(euler_prev)
|
||||
obj.rotation_euler = euler
|
||||
euler_prev = euler
|
||||
del euler
|
||||
else:
|
||||
euler_prev = obj.rotation_euler.copy()
|
||||
obj.keyframe_insert("rotation_euler", index=-1, frame=f, group=name)
|
||||
|
||||
obj.keyframe_insert("scale", index=-1, frame=f, group=name)
|
||||
|
@@ -684,8 +684,6 @@ class ShaderImageTextureWrapper():
|
||||
self.owner_shader._grid_to_location(-1, 0 + self.grid_row_diff, dst_node=node_image, ref_node=self.node_dst)
|
||||
|
||||
tree.links.new(node_image.outputs["Alpha" if self.use_alpha else "Color"], self.socket_dst)
|
||||
if self.use_alpha:
|
||||
self.owner_shader.material.blend_method = 'BLEND'
|
||||
|
||||
self._node_image = node_image
|
||||
return self._node_image
|
||||
@@ -705,13 +703,6 @@ class ShaderImageTextureWrapper():
|
||||
if image.colorspace_settings.is_data != self.colorspace_is_data and image.users >= 1:
|
||||
image = image.copy()
|
||||
image.colorspace_settings.name = self.colorspace_name
|
||||
if self.use_alpha:
|
||||
# Try to be smart, and only use image's alpha output if image actually has alpha data.
|
||||
tree = self.owner_shader.material.node_tree
|
||||
if image.channels < 4 or image.depth in {24, 8}:
|
||||
tree.links.new(self.node_image.outputs["Color"], self.socket_dst)
|
||||
else:
|
||||
tree.links.new(self.node_image.outputs["Alpha"], self.socket_dst)
|
||||
self.node_image.image = image
|
||||
|
||||
image = property(image_get, image_set)
|
||||
|
@@ -34,16 +34,12 @@ if LANG is not None:
|
||||
url_manual_prefix = url_manual_prefix.replace("manual/en", "manual/" + LANG)
|
||||
|
||||
url_manual_mapping = (
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_tangential_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-tangential-distortion"),
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_radial_distortion*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-radial-distortion"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_max_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-trappedair"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-trappedair"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_max_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-wavecrest"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-wavecrest"),
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_principal_point*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-principal-point"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"),
|
||||
("bpy.types.movietrackingsettings.refine_intrinsics_focal_length*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-focal-length"),
|
||||
("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"),
|
||||
("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"),
|
||||
@@ -66,7 +62,6 @@ url_manual_mapping = (
|
||||
("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"),
|
||||
("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"),
|
||||
("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"),
|
||||
("bpy.types.movietrackingsettings.use_keyframe_selection*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-keyframe-selection"),
|
||||
("bpy.types.rendersettings.simplify_gpencil_antialiasing*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-antialiasing"),
|
||||
("bpy.types.toolsettings.use_transform_pivot_point_align*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-pivot-point-align"),
|
||||
("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"),
|
||||
@@ -120,7 +115,6 @@ url_manual_mapping = (
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise1d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_1d.html#bpy-types-linestylegeometrymodifier-perlinnoise1d"),
|
||||
("bpy.types.linestylegeometrymodifier_perlinnoise2d*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/perlin_noise_2d.html#bpy-types-linestylegeometrymodifier-perlinnoise2d"),
|
||||
("bpy.types.materialgpencilstyle.use_stroke_holdout*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-use-stroke-holdout"),
|
||||
("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"),
|
||||
("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"),
|
||||
("bpy.types.toolsettings.use_proportional_connected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-connected"),
|
||||
("bpy.types.toolsettings.use_proportional_projected*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-projected"),
|
||||
@@ -150,7 +144,6 @@ url_manual_mapping = (
|
||||
("bpy.types.toolsettings.proportional_edit_falloff*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-proportional-edit-falloff"),
|
||||
("bpy.types.toolsettings.use_edge_path_live_unwrap*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-edge-path-live-unwrap"),
|
||||
("bpy.types.toolsettings.use_gpencil_draw_additive*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-additive"),
|
||||
("bpy.types.toolsettings.use_snap_backface_culling*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-backface-culling"),
|
||||
("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"),
|
||||
("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/layers.html#bpy-ops-outliner-collection-indirect-only-clear"),
|
||||
@@ -183,7 +176,6 @@ url_manual_mapping = (
|
||||
("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.linestylegeometrymodifier_tipremover*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/tip_remover.html#bpy-types-linestylegeometrymodifier-tipremover"),
|
||||
("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"),
|
||||
("bpy.types.toolsettings.use_gpencil_draw_onback*", "grease_pencil/modes/draw/introduction.html#bpy-types-toolsettings-use-gpencil-draw-onback"),
|
||||
@@ -207,7 +199,6 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.particle_radius*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-particle-radius"),
|
||||
("bpy.types.fluiddomainsettings.slice_per_voxel*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-slice-per-voxel"),
|
||||
("bpy.types.fluiddomainsettings.surface_tension*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-surface-tension"),
|
||||
("bpy.types.fluiddomainsettings.viscosity_value*", "physics/fluid/type/domain/liquid/viscosity.html#bpy-types-fluiddomainsettings-viscosity-value"),
|
||||
("bpy.types.fluideffectorsettings.effector_type*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings-effector-type"),
|
||||
("bpy.types.fluidflowsettings.use_particle_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-particle-size"),
|
||||
("bpy.types.linestylegeometrymodifier_blueprint*", "render/freestyle/parameter_editor/line_style/modifiers/geometry/blueprint.html#bpy-types-linestylegeometrymodifier-blueprint"),
|
||||
@@ -216,7 +207,6 @@ url_manual_mapping = (
|
||||
("bpy.types.spacesequenceeditor.show_region_hud*", "video_editing/sequencer/navigating.html#bpy-types-spacesequenceeditor-show-region-hud"),
|
||||
("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"),
|
||||
("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"),
|
||||
("bpy.ops.object.blenderkit_material_thumbnail*", "addons/3d_view/blenderkit.html#bpy-ops-object-blenderkit-material-thumbnail"),
|
||||
("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"),
|
||||
("bpy.ops.outliner.collection_duplicate_linked*", "editors/outliner/editing.html#bpy-ops-outliner-collection-duplicate-linked"),
|
||||
("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"),
|
||||
@@ -253,7 +243,6 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.timesteps_min*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-timesteps-min"),
|
||||
("bpy.types.fluiddomainsettings.use_diffusion*", "physics/fluid/type/domain/liquid/diffusion.html#bpy-types-fluiddomainsettings-use-diffusion"),
|
||||
("bpy.types.fluiddomainsettings.use_fractions*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-fractions"),
|
||||
("bpy.types.fluiddomainsettings.use_viscosity*", "physics/fluid/type/domain/liquid/viscosity.html#bpy-types-fluiddomainsettings-use-viscosity"),
|
||||
("bpy.types.fluidflowsettings.particle_system*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-particle-system"),
|
||||
("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"),
|
||||
@@ -288,9 +277,6 @@ url_manual_mapping = (
|
||||
("bpy.types.fluidflowsettings.velocity_coord*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-velocity-coord"),
|
||||
("bpy.types.fluidflowsettings.volume_density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-volume-density"),
|
||||
("bpy.types.materialgpencilstyle.show_stroke*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-stroke"),
|
||||
("bpy.types.movietrackingcamera.focal_length*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-focal-length"),
|
||||
("bpy.types.movietrackingcamera.pixel_aspect*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-pixel-aspect"),
|
||||
("bpy.types.movietrackingcamera.sensor_width*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-sensor-width"),
|
||||
("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.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"),
|
||||
("bpy.types.spaceuveditor.sticky_select_mode*", "editors/uv/selecting.html#bpy-types-spaceuveditor-sticky-select-mode"),
|
||||
@@ -334,7 +320,6 @@ url_manual_mapping = (
|
||||
("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"),
|
||||
("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"),
|
||||
("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"),
|
||||
("bpy.types.toolsettings.use_auto_normalize*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-auto-normalize"),
|
||||
("bpy.types.toolsettings.use_snap_translate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-translate"),
|
||||
("bpy.types.toolsettings.use_uv_select_sync*", "editors/uv/selecting.html#bpy-types-toolsettings-use-uv-select-sync"),
|
||||
("bpy.ops.gpencil.active_frames_delete_all*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-active-frames-delete-all"),
|
||||
@@ -359,8 +344,6 @@ url_manual_mapping = (
|
||||
("bpy.types.fluiddomainsettings.time_scale*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-time-scale"),
|
||||
("bpy.types.fluidflowsettings.texture_size*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-texture-size"),
|
||||
("bpy.types.fluidflowsettings.use_absolute*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-absolute"),
|
||||
("bpy.types.geometrynodeattributerandomize*", "modeling/modifiers/nodes/attribute/attribute_randomize.html#bpy-types-geometrynodeattributerandomize"),
|
||||
("bpy.types.geometrynodesubdivisionsurface*", "modeling/modifiers/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"),
|
||||
("bpy.types.linestyle*modifier_creaseangle*", "render/freestyle/parameter_editor/line_style/modifiers/color/crease_angle.html#bpy-types-linestyle-modifier-creaseangle"),
|
||||
@@ -368,17 +351,12 @@ url_manual_mapping = (
|
||||
("bpy.types.materialgpencilstyle.mix_color*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-mix-color"),
|
||||
("bpy.types.materialgpencilstyle.show_fill*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-show-fill"),
|
||||
("bpy.types.mesh.use_mirror_vertex_group_x*", "sculpt_paint/weight_paint/tool_settings/symmetry.html#bpy-types-mesh-use-mirror-vertex-group-x"),
|
||||
("bpy.types.movietrackingcamera.division_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-division-k"),
|
||||
("bpy.types.movietrackingobject.keyframe_a*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingobject-keyframe-a"),
|
||||
("bpy.types.movietrackingobject.keyframe_b*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingobject-keyframe-b"),
|
||||
("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.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"),
|
||||
("bpy.types.spacetexteditor.use_match_case*", "editors/text_editor.html#bpy-types-spacetexteditor-use-match-case"),
|
||||
("bpy.types.spaceview3d.show_object_select*", "editors/3dview/display/visibility.html#bpy-types-spaceview3d-show-object-select"),
|
||||
("bpy.types.toolsettings.use_lock_relative*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-lock-relative"),
|
||||
("bpy.types.vertexpaint.use_group_restrict*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-vertexpaint-use-group-restrict"),
|
||||
("bpy.types.volumedisplay.wireframe_detail*", "modeling/volumes/properties.html#bpy-types-volumedisplay-wireframe-detail"),
|
||||
("bpy.ops.armature.rigify_add_bone_groups*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-add-bone-groups"),
|
||||
("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"),
|
||||
@@ -408,8 +386,6 @@ url_manual_mapping = (
|
||||
("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"),
|
||||
("bpy.types.movietrackingcamera.principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-principal"),
|
||||
("bpy.types.object.use_camera_lock_parent*", "scene_layout/object/properties/relations.html#bpy-types-object-use-camera-lock-parent"),
|
||||
("bpy.types.rendersettings.pixel_aspect_x*", "render/output/properties/dimensions.html#bpy-types-rendersettings-pixel-aspect-x"),
|
||||
("bpy.types.rendersettings.pixel_aspect_y*", "render/output/properties/dimensions.html#bpy-types-rendersettings-pixel-aspect-y"),
|
||||
("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"),
|
||||
@@ -425,7 +401,6 @@ url_manual_mapping = (
|
||||
("bpy.types.vertexweightproximitymodifier*", "modeling/modifiers/modify/weight_proximity.html#bpy-types-vertexweightproximitymodifier"),
|
||||
("bpy.types.view3doverlay.show_wireframes*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-wireframes"),
|
||||
("bpy.ops.mesh.vertices_smooth_laplacian*", "modeling/meshes/editing/vertex/laplacian_smooth.html#bpy-ops-mesh-vertices-smooth-laplacian"),
|
||||
("bpy.ops.view3d.blenderkit_set_category*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-set-category"),
|
||||
("bpy.types.armature.rigify_colors_index*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-colors-index"),
|
||||
("bpy.types.armature.rigify_theme_to_add*", "addons/rigging/rigify/metarigs.html#bpy-types-armature-rigify-theme-to-add"),
|
||||
("bpy.types.brush.pose_smooth_iterations*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-smooth-iterations"),
|
||||
@@ -435,7 +410,6 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"),
|
||||
("bpy.types.fluiddomainsettings.clipping*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-clipping"),
|
||||
("bpy.types.fluiddomainsettings.use_mesh*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-use-mesh"),
|
||||
("bpy.types.geometrynodeattributecompare*", "modeling/modifiers/nodes/attribute/attribute_compare.html#bpy-types-geometrynodeattributecompare"),
|
||||
("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"),
|
||||
("bpy.types.materialgpencilstyle.pattern*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-pattern"),
|
||||
("bpy.types.materialgpencilstyle.texture*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-texture"),
|
||||
@@ -475,11 +449,8 @@ url_manual_mapping = (
|
||||
("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.geometrynodepointdistribute*", "modeling/modifiers/nodes/point/point_distribute.html#bpy-types-geometrynodepointdistribute"),
|
||||
("bpy.types.imagepaint.screen_grab_size*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-screen-grab-size"),
|
||||
("bpy.types.linestyle*modifier_material*", "render/freestyle/parameter_editor/line_style/modifiers/color/material.html#bpy-types-linestyle-modifier-material"),
|
||||
("bpy.types.movietrackingcamera.brown_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-k"),
|
||||
("bpy.types.movietrackingcamera.brown_p*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-brown-p"),
|
||||
("bpy.types.particlesettingstextureslot*", "physics/particles/texture_influence.html#bpy-types-particlesettingstextureslot"),
|
||||
("bpy.types.posebone.ik_rotation_weight*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-ik-rotation-weight"),
|
||||
("bpy.types.regionview3d.show_sync_view*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-show-sync-view"),
|
||||
@@ -494,7 +465,6 @@ url_manual_mapping = (
|
||||
("bpy.types.sequenceeditor.show_overlay*", "video_editing/preview/sidebar.html#bpy-types-sequenceeditor-show-overlay"),
|
||||
("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"),
|
||||
("bpy.types.toolsettings.use_multipaint*", "sculpt_paint/weight_paint/tool_settings/options.html#bpy-types-toolsettings-use-multipaint"),
|
||||
("bpy.types.toolsettings.use_snap_scale*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-scale"),
|
||||
("bpy.types.toolsettings.uv_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-select-mode"),
|
||||
("bpy.types.viewlayer.material_override*", "render/layers/layers.html#bpy-types-viewlayer-material-override"),
|
||||
@@ -502,7 +472,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.normals_make_consistent*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-normals-make-consistent"),
|
||||
("bpy.ops.mesh.offset_edge_loops_slide*", "modeling/meshes/editing/edge/offset_edge_slide.html#bpy-ops-mesh-offset-edge-loops-slide"),
|
||||
("bpy.ops.object.duplicate_move_linked*", "scene_layout/object/editing/duplicate_linked.html#bpy-ops-object-duplicate-move-linked"),
|
||||
("bpy.ops.object.parent_no_inverse_set*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-no-inverse-set"),
|
||||
("bpy.ops.object.vertex_group_quantize*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-quantize"),
|
||||
("bpy.ops.outliner.collection_instance*", "editors/outliner/editing.html#bpy-ops-outliner-collection-instance"),
|
||||
("bpy.ops.sequencer.change_effect_type*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-change-effect-type"),
|
||||
@@ -525,7 +494,6 @@ url_manual_mapping = (
|
||||
("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"),
|
||||
("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"),
|
||||
("bpy.types.materialgpencilstyle.color*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-color"),
|
||||
("bpy.types.movietrackingcamera.nuke_k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-nuke-k"),
|
||||
("bpy.types.movietrackingstabilization*", "movie_clip/tracking/clip/sidebar/stabilization/index.html#bpy-types-movietrackingstabilization"),
|
||||
("bpy.types.object.display_bounds_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-bounds-type"),
|
||||
("bpy.types.regionview3d.lock_rotation*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-lock-rotation"),
|
||||
@@ -550,7 +518,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.outliner.collection_isolate*", "editors/outliner/editing.html#bpy-ops-outliner-collection-isolate"),
|
||||
("bpy.ops.pose.visual_transform_apply*", "animation/armatures/posing/editing/apply.html#bpy-ops-pose-visual-transform-apply"),
|
||||
("bpy.ops.sequencer.view_ghost_border*", "video_editing/preview/sidebar.html#bpy-ops-sequencer-view-ghost-border"),
|
||||
("bpy.ops.view3d.blenderkit_asset_bar*", "addons/3d_view/blenderkit.html#bpy-ops-view3d-blenderkit-asset-bar"),
|
||||
("bpy.types.animdata.action_influence*", "editors/nla/sidebar.html#bpy-types-animdata-action-influence"),
|
||||
("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"),
|
||||
("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"),
|
||||
@@ -566,10 +533,6 @@ url_manual_mapping = (
|
||||
("bpy.types.dynamicpaintbrushsettings*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings"),
|
||||
("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/modifiers/nodes/attribute/attribute_fill.html#bpy-types-geometrynodeattributefill"),
|
||||
("bpy.types.geometrynodeattributemath*", "modeling/modifiers/nodes/attribute/attribute_math.html#bpy-types-geometrynodeattributemath"),
|
||||
("bpy.types.geometrynodepointinstance*", "modeling/modifiers/nodes/point/point_instance.html#bpy-types-geometrynodepointinstance"),
|
||||
("bpy.types.geometrynodepointseparate*", "modeling/modifiers/nodes/point/point_separate.html#bpy-types-geometrynodepointseparate"),
|
||||
("bpy.types.light.use_custom_distance*", "render/eevee/lighting.html#bpy-types-light-use-custom-distance"),
|
||||
("bpy.types.materialgpencilstyle.flip*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-flip"),
|
||||
("bpy.types.materialgpencilstyle.mode*", "grease_pencil/materials/grease_pencil_shader.html#bpy-types-materialgpencilstyle-mode"),
|
||||
@@ -633,8 +596,6 @@ url_manual_mapping = (
|
||||
("bpy.types.cyclesvisibilitysettings*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesvisibilitysettings"),
|
||||
("bpy.types.fluiddomainsettings.beta*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-beta"),
|
||||
("bpy.types.fluidmodifier.fluid_type*", "physics/fluid/type/index.html#bpy-types-fluidmodifier-fluid-type"),
|
||||
("bpy.types.functionnodefloatcompare*", "modeling/modifiers/nodes/utilities/float_compare.html#bpy-types-functionnodefloatcompare"),
|
||||
("bpy.types.geometrynodejoingeometry*", "modeling/modifiers/nodes/geometry/join_geometry.html#bpy-types-geometrynodejoingeometry"),
|
||||
("bpy.types.image.use_half_precision*", "editors/image/image_settings.html#bpy-types-image-use-half-precision"),
|
||||
("bpy.types.imagepaint.interpolation*", "sculpt_paint/texture_paint/tool_settings/texture_slots.html#bpy-types-imagepaint-interpolation"),
|
||||
("bpy.types.linestyle*modifier_noise*", "render/freestyle/parameter_editor/line_style/modifiers/color/noise.html#bpy-types-linestyle-modifier-noise"),
|
||||
@@ -654,7 +615,6 @@ url_manual_mapping = (
|
||||
("bpy.types.vertexweighteditmodifier*", "modeling/modifiers/modify/weight_edit.html#bpy-types-vertexweighteditmodifier"),
|
||||
("bpy.types.volumedisplay.slice_axis*", "modeling/volumes/properties.html#bpy-types-volumedisplay-slice-axis"),
|
||||
("bpy.ops.anim.channels_clean_empty*", "editors/nla/editing.html#bpy-ops-anim-channels-clean-empty"),
|
||||
("bpy.ops.clip.set_center_principal*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-ops-clip-set-center-principal"),
|
||||
("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"),
|
||||
@@ -664,7 +624,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.object.vertex_group_clean*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-clean"),
|
||||
("bpy.ops.preferences.theme_install*", "editors/preferences/themes.html#bpy-ops-preferences-theme-install"),
|
||||
("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.reassign_inputs*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-reassign-inputs"),
|
||||
("bpy.ops.view3d.view_center_camera*", "editors/3dview/navigate/camera_view.html#bpy-ops-view3d-view-center-camera"),
|
||||
@@ -688,8 +647,6 @@ url_manual_mapping = (
|
||||
("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.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"),
|
||||
("bpy.types.functionnodebooleanmath*", "modeling/modifiers/nodes/utilities/boolean_math.html#bpy-types-functionnodebooleanmath"),
|
||||
("bpy.types.geometrynodetriangulate*", "modeling/modifiers/nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"),
|
||||
("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"),
|
||||
("bpy.types.gpencillayer.mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-mask-layer"),
|
||||
("bpy.types.gpencilsculptguide.type*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-type"),
|
||||
@@ -736,7 +693,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.sculpt.detail_flood_fill*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-detail-flood-fill"),
|
||||
("bpy.ops.sequencer.duplicate_move*", "video_editing/sequencer/editing.html#bpy-ops-sequencer-duplicate-move"),
|
||||
("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"),
|
||||
("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.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"),
|
||||
@@ -749,7 +705,6 @@ url_manual_mapping = (
|
||||
("bpy.types.compositornodecurvergb*", "compositing/types/color/rgb_curves.html#bpy-types-compositornodecurvergb"),
|
||||
("bpy.types.compositornodecurvevec*", "compositing/types/vector/vector_curves.html#bpy-types-compositornodecurvevec"),
|
||||
("bpy.types.compositornodedisplace*", "compositing/types/distort/displace.html#bpy-types-compositornodedisplace"),
|
||||
("bpy.types.compositornodeexposure*", "compositing/types/color/exposure.html#bpy-types-compositornodeexposure"),
|
||||
("bpy.types.compositornodelensdist*", "compositing/types/distort/lens_distortion.html#bpy-types-compositornodelensdist"),
|
||||
("bpy.types.compositornodemaprange*", "compositing/types/vector/map_range.html#bpy-types-compositornodemaprange"),
|
||||
("bpy.types.compositornodemapvalue*", "compositing/types/vector/map_value.html#bpy-types-compositornodemapvalue"),
|
||||
@@ -765,7 +720,6 @@ 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.geometrynodeobjectinfo*", "modeling/modifiers/nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"),
|
||||
("bpy.types.imagepaint.use_occlude*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-use-occlude"),
|
||||
("bpy.types.latticegpencilmodifier*", "grease_pencil/modifiers/deform/lattice.html#bpy-types-latticegpencilmodifier"),
|
||||
("bpy.types.mesh.auto_smooth_angle*", "modeling/meshes/structure.html#bpy-types-mesh-auto-smooth-angle"),
|
||||
@@ -786,7 +740,6 @@ url_manual_mapping = (
|
||||
("bpy.types.volumerender.step_size*", "modeling/volumes/properties.html#bpy-types-volumerender-step-size"),
|
||||
("bpy.types.weightednormalmodifier*", "modeling/modifiers/modify/weighted_normal.html#bpy-types-weightednormalmodifier"),
|
||||
("bpy.ops.armature.autoside_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-autoside-names"),
|
||||
("bpy.ops.clip.create_plane_track*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-ops-clip-create-plane-track"),
|
||||
("bpy.ops.curve.spline_weight_set*", "modeling/curves/editing/other.html#bpy-ops-curve-spline-weight-set"),
|
||||
("bpy.ops.gpencil.blank_frame_add*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-blank-frame-add"),
|
||||
("bpy.ops.gpencil.frame_duplicate*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-frame-duplicate"),
|
||||
@@ -841,14 +794,11 @@ url_manual_mapping = (
|
||||
("bpy.types.dopesheet.filter_text*", "editors/graph_editor/channels.html#bpy-types-dopesheet-filter-text"),
|
||||
("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/modifiers/nodes/mesh/edge_split.html#bpy-types-geometrynodeedgesplit"),
|
||||
("bpy.types.geometrynodetransform*", "modeling/modifiers/nodes/geometry/transform.html#bpy-types-geometrynodetransform"),
|
||||
("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"),
|
||||
("bpy.types.light.cutoff_distance*", "render/eevee/lighting.html#bpy-types-light-cutoff-distance"),
|
||||
("bpy.types.lockedtrackconstraint*", "animation/constraints/tracking/locked_track.html#bpy-types-lockedtrackconstraint"),
|
||||
("bpy.types.material.blend_method*", "render/eevee/materials/settings.html#bpy-types-material-blend-method"),
|
||||
("bpy.types.mirrorgpencilmodifier*", "grease_pencil/modifiers/generate/mirror.html#bpy-types-mirrorgpencilmodifier"),
|
||||
("bpy.types.movietrackingcamera.k*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-k"),
|
||||
("bpy.types.offsetgpencilmodifier*", "grease_pencil/modifiers/deform/offset.html#bpy-types-offsetgpencilmodifier"),
|
||||
("bpy.types.particlefluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-particlefluidsettings"),
|
||||
("bpy.types.posebone.custom_shape*", "animation/armatures/bones/properties/display.html#bpy-types-posebone-custom-shape"),
|
||||
@@ -993,7 +943,6 @@ url_manual_mapping = (
|
||||
("bpy.types.curve.use_map_taper*", "modeling/curves/properties/geometry.html#bpy-types-curve-use-map-taper"),
|
||||
("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/modifiers/nodes/mesh/boolean.html#bpy-types-geometrynodeboolean"),
|
||||
("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"),
|
||||
@@ -1030,9 +979,7 @@ url_manual_mapping = (
|
||||
("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"),
|
||||
("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"),
|
||||
("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"),
|
||||
("bpy.ops.clip.add_marker_move*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-add-marker-move"),
|
||||
("bpy.ops.clip.bundles_to_mesh*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-bundles-to-mesh"),
|
||||
("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/toolbar/track.html#bpy-ops-clip-detect-features"),
|
||||
("bpy.ops.clip.detect_features*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-detect-features"),
|
||||
("bpy.ops.console.autocomplete*", "editors/python_console.html#bpy-ops-console-autocomplete"),
|
||||
("bpy.ops.curve.dissolve_verts*", "modeling/curves/editing/curve.html#bpy-ops-curve-dissolve-verts"),
|
||||
("bpy.ops.curve.duplicate_move*", "modeling/curves/editing/curve.html#bpy-ops-curve-duplicate-move"),
|
||||
@@ -1064,7 +1011,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.transform.edge_slide*", "modeling/meshes/editing/edge/edge_slide.html#bpy-ops-transform-edge-slide"),
|
||||
("bpy.ops.transform.vert_slide*", "modeling/meshes/editing/vertex/slide_vertices.html#bpy-ops-transform-vert-slide"),
|
||||
("bpy.ops.uv.project_from_view*", "modeling/meshes/editing/uv.html#bpy-ops-uv-project-from-view"),
|
||||
("bpy.ops.wm.blenderkit_logout*", "addons/3d_view/blenderkit.html#bpy-ops-wm-blenderkit-logout"),
|
||||
("bpy.ops.wm.memory_statistics*", "advanced/operators.html#bpy-ops-wm-memory-statistics"),
|
||||
("bpy.types.adjustmentsequence*", "video_editing/sequencer/strips/adjustment.html#bpy-types-adjustmentsequence"),
|
||||
("bpy.types.alphaundersequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaundersequence"),
|
||||
@@ -1095,7 +1041,6 @@ url_manual_mapping = (
|
||||
("bpy.types.object.empty_image*", "modeling/empties.html#bpy-types-object-empty-image"),
|
||||
("bpy.types.object.hide_render*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-render"),
|
||||
("bpy.types.object.hide_select*", "scene_layout/object/properties/visibility.html#bpy-types-object-hide-select"),
|
||||
("bpy.types.object.parent_type*", "scene_layout/object/properties/relations.html#bpy-types-object-parent-type"),
|
||||
("bpy.types.object.show_bounds*", "scene_layout/object/properties/display.html#bpy-types-object-show-bounds"),
|
||||
("bpy.types.rendersettings.fps*", "render/output/properties/dimensions.html#bpy-types-rendersettings-fps"),
|
||||
("bpy.types.scene.audio_volume*", "scene_layout/scene/properties.html#bpy-types-scene-audio-volume"),
|
||||
@@ -1123,7 +1068,6 @@ url_manual_mapping = (
|
||||
("bpy.types.volumerender.space*", "modeling/volumes/properties.html#bpy-types-volumerender-space"),
|
||||
("bpy.ops.anim.keyframe_clear*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-clear"),
|
||||
("bpy.ops.armature.flip_names*", "animation/armatures/bones/editing/naming.html#bpy-ops-armature-flip-names"),
|
||||
("bpy.ops.clip.track_to_empty*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-track-to-empty"),
|
||||
("bpy.ops.curve.cyclic_toggle*", "modeling/curves/editing/curve.html#bpy-ops-curve-cyclic-toggle"),
|
||||
("bpy.ops.curve.primitive*add*", "modeling/curves/primitives.html#bpy-ops-curve-primitive-add"),
|
||||
("bpy.ops.curve.smooth_radius*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-radius"),
|
||||
@@ -1148,7 +1092,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.mesh.smooth_normals*", "modeling/meshes/editing/mesh/normals.html#bpy-ops-mesh-smooth-normals"),
|
||||
("bpy.ops.nla.action_pushdown*", "editors/nla/tracks.html#bpy-ops-nla-action-pushdown"),
|
||||
("bpy.ops.nla.tweakmode_enter*", "editors/nla/editing.html#bpy-ops-nla-tweakmode-enter"),
|
||||
("bpy.ops.object.origin_clear*", "scene_layout/object/editing/clear.html#bpy-ops-object-origin-clear"),
|
||||
("bpy.ops.object.parent_clear*", "scene_layout/object/editing/parent.html#bpy-ops-object-parent-clear"),
|
||||
("bpy.ops.object.shade_smooth*", "scene_layout/object/editing/shading.html#bpy-ops-object-shade-smooth"),
|
||||
("bpy.ops.object.voxel_remesh*", "modeling/meshes/retopology.html#bpy-ops-object-voxel-remesh"),
|
||||
@@ -1165,7 +1108,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.uv.cylinder_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-cylinder-project"),
|
||||
("bpy.ops.uv.minimize_stretch*", "modeling/meshes/uv/editing.html#bpy-ops-uv-minimize-stretch"),
|
||||
("bpy.ops.uv.select_edge_ring*", "editors/uv/selecting.html#bpy-ops-uv-select-edge-ring"),
|
||||
("bpy.ops.wm.blenderkit_login*", "addons/3d_view/blenderkit.html#bpy-ops-wm-blenderkit-login"),
|
||||
("bpy.types.alphaoversequence*", "video_editing/sequencer/strips/effects/alpha_over_under_overdrop.html#bpy-types-alphaoversequence"),
|
||||
("bpy.types.armatureeditbones*", "animation/armatures/bones/editing/index.html#bpy-types-armatureeditbones"),
|
||||
("bpy.types.brush.pose_offset*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-pose-offset"),
|
||||
@@ -1193,7 +1135,6 @@ url_manual_mapping = (
|
||||
("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.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"),
|
||||
("bpy.types.pose.use_mirror_x*", "animation/armatures/posing/tool_settings.html#bpy-types-pose-use-mirror-x"),
|
||||
("bpy.types.preferencessystem*", "editors/preferences/system.html#bpy-types-preferencessystem"),
|
||||
@@ -1301,9 +1242,6 @@ url_manual_mapping = (
|
||||
("bpy.types.texturenodegroup*", "editors/texture_node/types/groups.html#bpy-types-texturenodegroup"),
|
||||
("bpy.types.texturenodeimage*", "editors/texture_node/types/input/image.html#bpy-types-texturenodeimage"),
|
||||
("bpy.types.viewlayer.use_ao*", "render/layers/layers.html#bpy-types-viewlayer-use-ao"),
|
||||
("bpy.ops.clip.clean_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-clean-tracks"),
|
||||
("bpy.ops.clip.delete_track*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-delete-track"),
|
||||
("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"),
|
||||
("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"),
|
||||
("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"),
|
||||
("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"),
|
||||
@@ -1374,7 +1312,6 @@ url_manual_mapping = (
|
||||
("bpy.types.subsurfmodifier*", "modeling/modifiers/generate/subdivision_surface.html#bpy-types-subsurfmodifier"),
|
||||
("bpy.types.texturenodemath*", "editors/texture_node/types/converter/math.html#bpy-types-texturenodemath"),
|
||||
("bpy.types.volume.filepath*", "modeling/volumes/properties.html#bpy-types-volume-filepath"),
|
||||
("bpy.ops.clip.join_tracks*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-join-tracks"),
|
||||
("bpy.ops.curve.select_row*", "modeling/surfaces/selecting.html#bpy-ops-curve-select-row"),
|
||||
("bpy.ops.curve.tilt_clear*", "modeling/curves/editing/control_points.html#bpy-ops-curve-tilt-clear"),
|
||||
("bpy.ops.curve.vertex_add*", "modeling/curves/editing/other.html#bpy-ops-curve-vertex-add"),
|
||||
@@ -1436,7 +1373,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.*.select_circle*", "interface/selecting.html#bpy-ops-select-circle"),
|
||||
("bpy.ops.anim.keying_set*", "animation/keyframes/keying_sets.html#bpy-ops-anim-keying-set"),
|
||||
("bpy.ops.armature.delete*", "animation/armatures/bones/editing/delete.html#bpy-ops-armature-delete"),
|
||||
("bpy.ops.clip.set_origin*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-origin"),
|
||||
("bpy.ops.curve.subdivide*", "modeling/curves/editing/segments.html#bpy-ops-curve-subdivide"),
|
||||
("bpy.ops.ed.undo_history*", "interface/undo_redo.html#bpy-ops-ed-undo-history"),
|
||||
("bpy.ops.fluid.bake_data*", "physics/fluid/type/domain/settings.html#bpy-ops-fluid-bake-data"),
|
||||
@@ -1491,7 +1427,6 @@ url_manual_mapping = (
|
||||
("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"),
|
||||
("bpy.types.nodesmodifier*", "modeling/modifiers/generate/geometry_nodes.html#bpy-types-nodesmodifier"),
|
||||
("bpy.types.object.parent*", "scene_layout/object/editing/parent.html#bpy-types-object-parent"),
|
||||
("bpy.types.oceanmodifier*", "modeling/modifiers/physics/ocean.html#bpy-types-oceanmodifier"),
|
||||
("bpy.types.particlebrush*", "physics/particles/mode.html#bpy-types-particlebrush"),
|
||||
@@ -1511,8 +1446,6 @@ url_manual_mapping = (
|
||||
("bpy.types.volumedisplay*", "modeling/volumes/properties.html#bpy-types-volumedisplay"),
|
||||
("bpy.types.windowmanager*", "interface/index.html#bpy-types-windowmanager"),
|
||||
("bpy.ops.*.select_lasso*", "interface/selecting.html#bpy-ops-select-lasso"),
|
||||
("bpy.ops.clip.set_plane*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-plane"),
|
||||
("bpy.ops.clip.set_scale*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-scale"),
|
||||
("bpy.ops.curve.decimate*", "modeling/curves/editing/curve.html#bpy-ops-curve-decimate"),
|
||||
("bpy.ops.curve.separate*", "modeling/curves/editing/curve.html#bpy-ops-curve-separate"),
|
||||
("bpy.ops.fluid.bake_all*", "physics/fluid/type/domain/cache.html#bpy-ops-fluid-bake-all"),
|
||||
@@ -1578,8 +1511,6 @@ url_manual_mapping = (
|
||||
("bpy.types.wavemodifier*", "modeling/modifiers/deform/wave.html#bpy-types-wavemodifier"),
|
||||
("bpy.types.weldmodifier*", "modeling/modifiers/generate/weld.html#bpy-types-weldmodifier"),
|
||||
("bpy.types.wipesequence*", "video_editing/sequencer/strips/transitions/wipe.html#bpy-types-wipesequence"),
|
||||
("bpy.ops.clip.prefetch*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-prefetch"),
|
||||
("bpy.ops.clip.set_axis*", "movie_clip/tracking/clip/editing/reconstruction.html#bpy-ops-clip-set-axis"),
|
||||
("bpy.ops.gpencil.paste*", "grease_pencil/modes/edit/grease_pencil_menu.html#bpy-ops-gpencil-paste"),
|
||||
("bpy.ops.image.project*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-ops-image-project"),
|
||||
("bpy.ops.mesh.decimate*", "modeling/meshes/editing/mesh/cleanup.html#bpy-ops-mesh-decimate"),
|
||||
@@ -1649,7 +1580,6 @@ url_manual_mapping = (
|
||||
("bpy.types.renderview*", "render/output/properties/stereoscopy/index.html#bpy-types-renderview"),
|
||||
("bpy.types.sceneeevee*", "render/eevee/index.html#bpy-types-sceneeevee"),
|
||||
("bpy.types.vectorfont*", "modeling/texts/index.html#bpy-types-vectorfont"),
|
||||
("bpy.ops.clip.reload*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-reload"),
|
||||
("bpy.ops.curve.split*", "modeling/curves/editing/curve.html#bpy-ops-curve-split"),
|
||||
("bpy.ops.graph.clean*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-clean"),
|
||||
("bpy.ops.graph.paste*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-paste"),
|
||||
@@ -1663,7 +1593,6 @@ url_manual_mapping = (
|
||||
("bpy.ops.uv.rip_move*", "modeling/meshes/uv/tools/rip.html#bpy-ops-uv-rip-move"),
|
||||
("bpy.ops.view3d.snap*", "scene_layout/object/editing/snap.html#bpy-ops-view3d-snap"),
|
||||
("bpy.ops.view3d.zoom*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-zoom"),
|
||||
("bpy.ops.wm.url_open*", "addons/3d_view/blenderkit.html#bpy-ops-wm-url-open"),
|
||||
("bpy.types.*texspace*", "modeling/meshes/uv/uv_texture_spaces.html#bpy-types-texspace"),
|
||||
("bpy.types.arealight*", "render/lights/light_object.html#bpy-types-arealight"),
|
||||
("bpy.types.blenddata*", "files/data_blocks.html#bpy-types-blenddata"),
|
||||
@@ -1718,7 +1647,6 @@ url_manual_mapping = (
|
||||
("bpy.types.shapekey*", "animation/shape_keys/index.html#bpy-types-shapekey"),
|
||||
("bpy.types.spacenla*", "editors/nla/index.html#bpy-types-spacenla"),
|
||||
("bpy.types.sunlight*", "render/lights/light_object.html#bpy-types-sunlight"),
|
||||
("bpy.ops.clip.open*", "movie_clip/tracking/clip/editing/clip.html#bpy-ops-clip-open"),
|
||||
("bpy.ops.mesh.fill*", "modeling/meshes/editing/face/fill.html#bpy-ops-mesh-fill"),
|
||||
("bpy.ops.mesh.poke*", "modeling/meshes/editing/face/poke_faces.html#bpy-ops-mesh-poke"),
|
||||
("bpy.ops.mesh.spin*", "modeling/meshes/tools/spin.html#bpy-ops-mesh-spin"),
|
||||
|
@@ -130,7 +130,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
||||
description=(
|
||||
"The action when Middle-Mouse dragging in the viewport. "
|
||||
"Shift-Middle-Mouse is used for the other action. "
|
||||
"This applies to trackpad as well"
|
||||
"This applies to Track-Pad as well"
|
||||
),
|
||||
update=update_fn,
|
||||
)
|
||||
|
@@ -1563,7 +1563,7 @@ def km_graph_editor(params):
|
||||
("graph.sample", {"type": 'O', "value": 'PRESS', "shift": True, "alt": True}, None),
|
||||
("graph.bake", {"type": 'C', "value": 'PRESS', "alt": True}, None),
|
||||
op_menu("GRAPH_MT_delete", {"type": 'X', "value": 'PRESS'}),
|
||||
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
|
||||
op_menu("GRAPH_MT_delete", {"type": 'DEL', "value": 'PRESS'}),
|
||||
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("graph.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("graph.click_insert", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True},
|
||||
@@ -2113,7 +2113,7 @@ def km_dopesheet(params):
|
||||
("action.keyframe_type", {"type": 'R', "value": 'PRESS'}, None),
|
||||
("action.sample", {"type": 'O', "value": 'PRESS', "shift": True, "alt": True}, None),
|
||||
op_menu("DOPESHEET_MT_delete", {"type": 'X', "value": 'PRESS'}),
|
||||
("action.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
|
||||
op_menu("DOPESHEET_MT_delete", {"type": 'DEL', "value": 'PRESS'}),
|
||||
("action.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
("action.keyframe_insert", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("action.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
@@ -4566,7 +4566,7 @@ def km_mesh(params):
|
||||
op_menu("VIEW3D_MT_edit_mesh_merge", {"type": 'M', "value": 'PRESS'}),
|
||||
op_menu("VIEW3D_MT_edit_mesh_split", {"type": 'M', "value": 'PRESS', "alt": True}),
|
||||
("transform.shrink_fatten", {"type": 'S', "value": 'PRESS', "alt": True}, None),
|
||||
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS', "repeat": True}, None),
|
||||
("mesh.edge_face_add", {"type": 'F', "value": 'PRESS'}, None),
|
||||
("mesh.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None),
|
||||
op_menu("VIEW3D_MT_mesh_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
("mesh.separate", {"type": 'P', "value": 'PRESS'}, None),
|
||||
|
@@ -929,7 +929,7 @@ def km_graph_editor(params):
|
||||
("graph.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None),
|
||||
("graph.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None),
|
||||
op_menu("GRAPH_MT_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}),
|
||||
("graph.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
|
||||
op_menu("GRAPH_MT_delete", {"type": 'DEL', "value": 'PRESS'}),
|
||||
*_template_items_context_menu("GRAPH_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("graph.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None),
|
||||
("graph.keyframe_insert", {"type": 'S', "value": 'PRESS'}, None),
|
||||
@@ -1416,7 +1416,7 @@ def km_dopesheet(params):
|
||||
op_menu_pie("DOPESHEET_MT_snap_pie", {"type": 'X', "value": 'PRESS', "shift": True}),
|
||||
*_template_items_context_menu("DOPESHEET_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
op_menu("DOPESHEET_MT_delete", {"type": 'BACK_SPACE', "value": 'PRESS'}),
|
||||
("action.delete", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("confirm", False)]}),
|
||||
op_menu("DOPESHEET_MT_delete", {"type": 'DEL', "value": 'PRESS'}),
|
||||
("action.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None),
|
||||
("action.keyframe_insert", {"type": 'S', "value": 'PRESS'}, None),
|
||||
("action.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
@@ -198,7 +198,7 @@ class ANIM_OT_keying_set_export(Operator):
|
||||
|
||||
|
||||
class NLA_OT_bake(Operator):
|
||||
"""Bake all selected objects location/scale/rotation animation to an action"""
|
||||
"""Bake all selected objects loc/scale/rotation animation to an action"""
|
||||
bl_idname = "nla.bake"
|
||||
bl_label = "Bake Action"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
@@ -347,7 +347,7 @@ class ClearUselessActions(Operator):
|
||||
|
||||
|
||||
class UpdateAnimatedTransformConstraint(Operator):
|
||||
"""Update f-curves/drivers affecting Transform constraints (use it with files from 2.70 and earlier)"""
|
||||
"""Update fcurves/drivers affecting Transform constraints (use it with files from 2.70 and earlier)"""
|
||||
bl_idname = "anim.update_animated_transform_constraints"
|
||||
bl_label = "Update Animated Transform Constraints"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
@@ -27,9 +27,6 @@ def geometry_node_group_empty_new(context):
|
||||
output_node = group.nodes.new('NodeGroupOutput')
|
||||
output_node.is_active_output = True
|
||||
|
||||
input_node.select = False
|
||||
output_node.select = False
|
||||
|
||||
input_node.location.x = -200 - input_node.width
|
||||
output_node.location.x = 200
|
||||
|
||||
@@ -41,8 +38,8 @@ def geometry_node_group_empty_new(context):
|
||||
def geometry_modifier_poll(context) -> bool:
|
||||
ob = context.object
|
||||
|
||||
# Test object support for geometry node modifier (No volume, curve, or hair object support yet)
|
||||
if not ob or ob.type not in {'MESH', 'POINTCLOUD'}:
|
||||
# Test object support for geometry node modifier (No volume or hair object support yet)
|
||||
if not ob or ob.type not in {'MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'POINTCLOUD'}:
|
||||
return False
|
||||
|
||||
return True
|
||||
@@ -65,11 +62,14 @@ class NewGeometryNodesModifier(bpy.types.Operator):
|
||||
if not modifier:
|
||||
return {'CANCELLED'}
|
||||
|
||||
group = geometry_node_group_empty_new(context)
|
||||
modifier.node_group = group
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NewGeometryNodeTreeAssign(bpy.types.Operator):
|
||||
"""Create a new geometry node group and assign it to the active modifier"""
|
||||
"""Create a new geometry node group and assign it the the active modifier"""
|
||||
|
||||
bl_idname = "node.new_geometry_node_group_assign"
|
||||
bl_label = "Assign New Geometry Node Group"
|
||||
|
@@ -181,20 +181,23 @@ class MeshMirrorUV(Operator):
|
||||
bpy.ops.object.mode_set(mode='EDIT', toggle=False)
|
||||
|
||||
if total_duplicates and total_no_active_UV:
|
||||
self.report({'WARNING'},
|
||||
"%d mesh(es) with no active UV layer, "
|
||||
"%d duplicates found in %d mesh(es), mirror may be incomplete"
|
||||
self.report({'WARNING'}, "%d %s with no active UV layer. "
|
||||
"%d duplicates found in %d %s, mirror may be incomplete."
|
||||
% (total_no_active_UV,
|
||||
"mesh" if total_no_active_UV == 1 else "meshes",
|
||||
total_duplicates,
|
||||
meshes_with_duplicates))
|
||||
meshes_with_duplicates,
|
||||
"mesh" if meshes_with_duplicates == 1 else "meshes"))
|
||||
elif total_no_active_UV:
|
||||
self.report({'WARNING'},
|
||||
"%d mesh(es) with no active UV layer"
|
||||
% (total_no_active_UV,))
|
||||
self.report({'WARNING'}, "%d %s with no active UV layer."
|
||||
% (total_no_active_UV,
|
||||
"mesh" if total_no_active_UV == 1 else "meshes"))
|
||||
elif total_duplicates:
|
||||
self.report({'WARNING'},
|
||||
"%d duplicates found in %d mesh(es), mirror may be incomplete"
|
||||
% (total_duplicates, meshes_with_duplicates))
|
||||
self.report({'WARNING'}, "%d duplicates found in %d %s,"
|
||||
" mirror may be incomplete."
|
||||
% (total_duplicates,
|
||||
meshes_with_duplicates,
|
||||
"mesh" if meshes_with_duplicates == 1 else "meshes"))
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@@ -566,7 +566,7 @@ class JoinUVs(Operator):
|
||||
uv_other = mesh_other.uv_layers.active
|
||||
if not uv_other:
|
||||
self.report({'ERROR'}, "Could not add "
|
||||
"a new UV map to object "
|
||||
"a new UV map tp object "
|
||||
"'%s' (Mesh '%s')\n"
|
||||
% (obj_other.name,
|
||||
mesh_other.name,
|
||||
|
@@ -254,7 +254,7 @@ class ExecutePreset(Operator):
|
||||
ext = splitext(filepath)[1].lower()
|
||||
|
||||
if ext not in {".py", ".xml"}:
|
||||
self.report({'ERROR'}, "Unknown file type: %r" % ext)
|
||||
self.report({'ERROR'}, "unknown filetype: %r" % ext)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if hasattr(preset_class, "reset_cb"):
|
||||
|
@@ -80,7 +80,7 @@ class SequencerCrossfadeSounds(Operator):
|
||||
|
||||
|
||||
class SequencerSplitMulticam(Operator):
|
||||
"""Split multicam strip and select camera"""
|
||||
"""Split multi-cam strip and select camera"""
|
||||
|
||||
bl_idname = "sequencer.split_multicam"
|
||||
bl_label = "Split Multicam"
|
||||
@@ -242,7 +242,7 @@ class SequencerFadesAdd(Operator):
|
||||
sequence.invalidate_cache('COMPOSITE')
|
||||
|
||||
sequence_string = "sequence" if len(faded_sequences) == 1 else "sequences"
|
||||
self.report({'INFO'}, "Added fade animation to %d %s" % (len(faded_sequences), sequence_string))
|
||||
self.report({'INFO'}, "Added fade animation to %d %s." % (len(faded_sequences), sequence_string))
|
||||
return {'FINISHED'}
|
||||
|
||||
def calculate_fade_duration(self, context, sequence):
|
||||
|
@@ -187,7 +187,7 @@ class PREFERENCES_OT_copy_prev(Operator):
|
||||
|
||||
|
||||
class PREFERENCES_OT_keyconfig_test(Operator):
|
||||
"""Test key configuration for conflicts"""
|
||||
"""Test key-config for conflicts"""
|
||||
bl_idname = "preferences.keyconfig_test"
|
||||
bl_label = "Test Key Configuration for Conflicts"
|
||||
|
||||
@@ -868,7 +868,7 @@ class PREFERENCES_OT_addon_show(Operator):
|
||||
# Note: shares some logic with PREFERENCES_OT_addon_install
|
||||
# but not enough to de-duplicate. Fixes here may apply to both.
|
||||
class PREFERENCES_OT_app_template_install(Operator):
|
||||
"""Install an application template"""
|
||||
"""Install an application-template"""
|
||||
bl_idname = "preferences.app_template_install"
|
||||
bl_label = "Install Template from File..."
|
||||
|
||||
@@ -969,9 +969,9 @@ class PREFERENCES_OT_app_template_install(Operator):
|
||||
# Studio Light Operations
|
||||
|
||||
class PREFERENCES_OT_studiolight_install(Operator):
|
||||
"""Install a user defined light"""
|
||||
"""Install a user defined studio light"""
|
||||
bl_idname = "preferences.studiolight_install"
|
||||
bl_label = "Install Light"
|
||||
bl_label = "Install Custom Studio Light"
|
||||
|
||||
files: CollectionProperty(
|
||||
name="File Path",
|
||||
@@ -981,7 +981,7 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
||||
subtype='DIR_PATH',
|
||||
)
|
||||
filter_folder: BoolProperty(
|
||||
name="Filter Folders",
|
||||
name="Filter folders",
|
||||
default=True,
|
||||
options={'HIDDEN'},
|
||||
)
|
||||
@@ -992,9 +992,9 @@ class PREFERENCES_OT_studiolight_install(Operator):
|
||||
type: EnumProperty(
|
||||
name="Type",
|
||||
items=(
|
||||
('MATCAP', "MatCap", "Install custom MatCaps"),
|
||||
('WORLD', "World", "Install custom HDRIs"),
|
||||
('STUDIO', "Studio", "Install custom Studio Lights"),
|
||||
('MATCAP', "MatCap", ""),
|
||||
('WORLD', "World", ""),
|
||||
('STUDIO', "Studio", ""),
|
||||
)
|
||||
)
|
||||
|
||||
|
@@ -635,14 +635,14 @@ class LightMapPack(Operator):
|
||||
)
|
||||
PREF_IMG_PX_SIZE: IntProperty(
|
||||
name="Image Size",
|
||||
description="Width and height for the new image",
|
||||
description="Width and Height for the new image",
|
||||
min=64, max=5000,
|
||||
default=512,
|
||||
)
|
||||
# UV Packing...
|
||||
PREF_BOX_DIV: IntProperty(
|
||||
name="Pack Quality",
|
||||
description="Pre-packing before the complex boxpack",
|
||||
description="Pre Packing before the complex boxpack",
|
||||
min=1, max=48,
|
||||
default=12,
|
||||
)
|
||||
|
@@ -834,7 +834,7 @@ class WM_OT_context_modal_mouse(Operator):
|
||||
|
||||
|
||||
class WM_OT_url_open(Operator):
|
||||
"""Open a website in the web browser"""
|
||||
"""Open a website in the web-browser"""
|
||||
bl_idname = "wm.url_open"
|
||||
bl_label = ""
|
||||
bl_options = {'INTERNAL'}
|
||||
@@ -851,7 +851,7 @@ class WM_OT_url_open(Operator):
|
||||
|
||||
|
||||
class WM_OT_url_open_preset(Operator):
|
||||
"""Open a preset website in the web browser"""
|
||||
"""Open a preset website in the web-browser"""
|
||||
bl_idname = "wm.url_open_preset"
|
||||
bl_label = "Open Preset Website"
|
||||
bl_options = {'INTERNAL'}
|
||||
@@ -893,7 +893,7 @@ class WM_OT_url_open_preset(Operator):
|
||||
(('BUG', "Bug",
|
||||
"Report a bug with pre-filled version information"),
|
||||
_url_from_bug),
|
||||
(('BUG_ADDON', "Add-on Bug",
|
||||
(('BUG_ADDON', "Add-On Bug",
|
||||
"Report a bug in an add-on"),
|
||||
_url_from_bug_addon),
|
||||
(('RELEASE_NOTES', "Release Notes",
|
||||
@@ -974,7 +974,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=""):
|
||||
|
||||
def operator_exists_pair(a, b):
|
||||
# Not fast, this is only for docs.
|
||||
@@ -1025,11 +1025,6 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix="", report=None):
|
||||
# Check class for dynamically registered types.
|
||||
rna_class = bpy.types.PropertyGroup.bl_rna_get_subclass_py(class_name)
|
||||
|
||||
if rna_class is None:
|
||||
if report is not None:
|
||||
report({'ERROR'}, iface_("Type \"%s\" can not be found") % class_name)
|
||||
return None
|
||||
|
||||
# Detect if this is a inherited member and use that name instead.
|
||||
rna_parent = rna_class.bl_rna
|
||||
rna_prop = rna_parent.properties.get(class_prop)
|
||||
@@ -1089,9 +1084,9 @@ class WM_OT_doc_view_manual(Operator):
|
||||
return url
|
||||
|
||||
def execute(self, _context):
|
||||
rna_id = _wm_doc_get_id(self.doc_id, do_url=False, report=self.report)
|
||||
rna_id = _wm_doc_get_id(self.doc_id, do_url=False)
|
||||
if rna_id is None:
|
||||
return {'CANCELLED'}
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
url = self._lookup_rna_url(rna_id)
|
||||
|
||||
@@ -1123,9 +1118,9 @@ class WM_OT_doc_view(Operator):
|
||||
_prefix = ("https://docs.blender.org/api/master")
|
||||
|
||||
def execute(self, _context):
|
||||
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix, report=self.report)
|
||||
url = _wm_doc_get_id(self.doc_id, do_url=True, url_prefix=self._prefix)
|
||||
if url is None:
|
||||
return {'CANCELLED'}
|
||||
return {'PASS_THROUGH'}
|
||||
|
||||
import webbrowser
|
||||
webbrowser.open(url)
|
||||
@@ -1180,7 +1175,7 @@ rna_use_soft_limits = BoolProperty(
|
||||
|
||||
rna_is_overridable_library = BoolProperty(
|
||||
name="Is Library Overridable",
|
||||
description="Allow the property to be overridden when the data-block is linked",
|
||||
description="Allow the property to be overridden when the Data-Block is linked",
|
||||
default=False,
|
||||
)
|
||||
|
||||
@@ -1609,7 +1604,7 @@ class WM_OT_sysinfo(Operator):
|
||||
|
||||
|
||||
class WM_OT_operator_cheat_sheet(Operator):
|
||||
"""List all the operators in a text-block, useful for scripting"""
|
||||
"""List all the Operators in a text-block, useful for scripting"""
|
||||
bl_idname = "wm.operator_cheat_sheet"
|
||||
bl_label = "Operator Cheat Sheet"
|
||||
|
||||
@@ -1630,7 +1625,7 @@ class WM_OT_operator_cheat_sheet(Operator):
|
||||
textblock = bpy.data.texts.new("OperatorList.txt")
|
||||
textblock.write('# %d Operators\n\n' % tot)
|
||||
textblock.write('\n'.join(op_strings))
|
||||
self.report({'INFO'}, "See OperatorList.txt text block")
|
||||
self.report({'INFO'}, "See OperatorList.txt textblock")
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
@@ -1722,7 +1717,7 @@ class WM_OT_tool_set_by_id(Operator):
|
||||
tool_settings.workspace_tool_type = 'FALLBACK'
|
||||
return {'FINISHED'}
|
||||
else:
|
||||
self.report({'WARNING'}, "Tool %r not found for space %r" % (self.name, space_type))
|
||||
self.report({'WARNING'}, "Tool %r not found for space %r." % (self.name, space_type))
|
||||
return {'CANCELLED'}
|
||||
|
||||
|
||||
@@ -1731,7 +1726,7 @@ class WM_OT_tool_set_by_index(Operator):
|
||||
bl_idname = "wm.tool_set_by_index"
|
||||
bl_label = "Set Tool by Index"
|
||||
index: IntProperty(
|
||||
name="Index in Toolbar",
|
||||
name="Index in toolbar",
|
||||
default=0,
|
||||
)
|
||||
cycle: BoolProperty(
|
||||
@@ -1742,7 +1737,7 @@ class WM_OT_tool_set_by_index(Operator):
|
||||
)
|
||||
|
||||
expand: BoolProperty(
|
||||
description="Include tool subgroups",
|
||||
description="Include tool sub-groups",
|
||||
default=True,
|
||||
)
|
||||
|
||||
@@ -2168,13 +2163,13 @@ class WM_OT_batch_rename(Operator):
|
||||
object_data_type_attrs_map = {
|
||||
'MESH': ("meshes", "Mesh(es)"),
|
||||
'CURVE': ("curves", "Curve(s)"),
|
||||
'META': ("metaballs", "Metaball(s)"),
|
||||
'META': ("metaballs", "MetaBall(s)"),
|
||||
'ARMATURE': ("armatures", "Armature(s)"),
|
||||
'LATTICE': ("lattices", "Lattice(s)"),
|
||||
'GPENCIL': ("grease_pencils", "Grease Pencil(s)"),
|
||||
'CAMERA': ("cameras", "Camera(s)"),
|
||||
'SPEAKER': ("speakers", "Speaker(s)"),
|
||||
'LIGHT_PROBE': ("light_probes", "Light Probe(s)"),
|
||||
'LIGHT_PROBE': ("light_probes", "LightProbe(s)"),
|
||||
}
|
||||
|
||||
# Finish with space types.
|
||||
|
@@ -59,7 +59,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
|
||||
col.prop(ob, "show_empty_image_perspective", text="Perspective")
|
||||
col.prop(ob, "show_empty_image_only_axis_aligned", text="Only Axis Aligned")
|
||||
|
||||
col = layout.column(align=False, heading="Opacity")
|
||||
col = layout.column(align=False, heading="Transparency")
|
||||
col.use_property_decorate = False
|
||||
row = col.row(align=True)
|
||||
sub = row.row(align=True)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user