Compare commits

..

85 Commits

Author SHA1 Message Date
2d0c84cf76 Merge branch 'master' into soc-2020-testing-frameworks 2020-12-17 20:37:01 +05:30
167eace0e7 Merge branch 'master' into soc-2020-testing-frameworks 2020-12-17 17:36:26 +05:30
f066bf923c Disabling particle instance modifier test 2020-12-17 17:34:44 +05:30
6e60b3cf59 Updated frame end value for Build modifier, now shows non-empty mesh in blend file 2020-12-17 17:33:07 +05:30
098be40b53 Removed unused variable modifier_copy 2020-12-16 12:53:31 +05:30
30021b0416 Merge branch 'master' into soc-2021-testing-frameworks 2020-12-15 22:37:12 +05:30
1e41a9a86b Post Review: fix coding styles, remove try..except, using value for enumerate 2020-12-15 22:18:41 +05:30
5b7c621787 Merge branch 'master' into soc-2021-testing-frameworks 2020-12-08 20:56:55 +05:30
77cde6f1a1 Resolved merge conflict, reformatted, break long lines, parameters 2020-12-01 01:19:01 +05:30
191ab5990b Resolved a merge conflict related to the threshold of Weld modifier 2020-09-27 16:32:24 +05:30
6196b6df92 Added misisng space before parameter type in doc string 2020-09-27 16:22:12 +05:30
14efcadcb2 Merge branch 'master' into soc-2021-testing-frameworks 2020-09-17 02:09:37 +05:30
fcf7337748 Post Review: Minor fixes, renaming, removing confuisng comments 2020-09-07 02:51:42 +05:30
07e11b54ab Added a new compare flag do_compare for run-test
do_compare is set to False if no comparison is needed, like when running
run-test for investigation purpose
2020-09-06 18:07:08 +05:30
685609c5ea Added apply_modifiers flag for run-test and run-all-tests 2020-09-06 16:38:01 +05:30
81f16d2f80 Merge branch 'master' into soc-2020-testing-frameworks 2020-09-06 15:29:23 +05:30
95d3aac846 Added comment for not comparing in run-test and message 2020-09-02 01:56:50 +05:30
d63e7a997d Merge branch 'master' into soc-2021-testing-frameworks 2020-08-31 21:43:34 +05:30
d2a70fbd43 saving state, not running compare unit test for run-test 2020-08-31 21:40:49 +05:30
c2134cd13c removed extra str in cloth 2020-08-30 19:01:53 +05:30
501c0bfccb Solved merge conflict 2020-08-30 18:43:22 +05:30
9231bc646c Increased the frame number for visible differnce 2020-08-30 18:30:24 +05:30
0db26fd828 Remove extra import statement 2020-08-30 18:23:05 +05:30
a09ae63e2b Minor fix 2020-08-30 17:04:12 +05:30
39da831001 Merge branch 'soc-2020-testing-frameworks' of git.blender.org:blender into soc-2020-testing-frameworks 2020-08-28 23:37:46 +05:30
500bf1f2bb Merge branch 'master' into soc-2021-testing-frameworks 2020-08-28 22:24:18 +05:30
eb5fd291cf Removed extra import statement 2020-08-27 23:38:22 +05:30
7c1656d0e6 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-27 19:37:03 +05:30
1c6302a7e5 Merge branch 'master' into soc-2021-testing-frameworks 2020-08-27 19:33:25 +05:30
4a5165d945 Changed from ModifierTest to RunTest 2020-08-27 18:46:49 +05:30
4d2d536747 Changed the interface, now operators,bevel and boolean use MeshTest, no helper class 2020-08-27 18:44:51 +05:30
c2918d8525 Removed OperatorTest and ModifierTest, added a generic RunTest 2020-08-27 18:42:55 +05:30
e6abea5ce6 Merge branch 'master' into soc-2021-testing-frameworks 2020-08-27 00:45:23 +05:30
5dda36d875 Removed the abstract base class as there is now only 1 Helper Test class, updated deform modifiers to ModifierTest 2020-08-27 00:41:20 +05:30
e3e81f60a8 Updating test files to use MeshTest Class in ModifierTest 2020-08-26 10:37:53 +05:30
f7d2ed66a6 Using an abstract base class as a parent to ModifierTest
Change in implementation of ModifierTest, input parameter changed from a
list to using MeshTest Class
2020-08-26 10:33:51 +05:30
6490eeabd5 Updated test file for Cloth and Dynamic Paint to bake less frames 2020-08-23 21:09:23 +05:30
92fdbcc283 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-21 20:51:08 +05:30
f91a54a86d Removed cloth Pressure and Self Collision tests 2020-08-21 20:49:09 +05:30
94781b3453 Re-formatting PEP8 2020-08-21 01:50:40 +05:30
1942c8293e Fixing runtime error for operator tests, updating class names 2020-08-21 01:38:09 +05:30
41b536e116 Better names for classes, minor fixes 2020-08-20 23:06:46 +05:30
28a0ffcfc8 Added physics to particle system and particle instance 2020-08-20 23:05:55 +05:30
739788e75d Post Review: removed extra str, extra lines, minor fixes 2020-08-20 23:03:16 +05:30
0b6586ed0e Renamed test names to be more descriptive 2020-08-20 22:59:19 +05:30
cad0c94745 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-19 15:33:16 +05:30
5da0776a76 Merge branch 'master' into soc-2021-testing-frameworks 2020-08-18 18:12:24 +05:30
a79e7e51c4 removed generator script 2020-08-18 18:08:20 +05:30
34fce0c470 saving last state of generator script 2020-08-18 18:07:06 +05:30
fa1ad74f6f Better error wrapping and minor fixes 2020-08-18 18:05:33 +05:30
e86e217e74 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-15 20:51:58 +05:30
571212afcf Post Review: Doc and comments and minor correction 2020-08-14 01:26:29 +05:30
8f0b9e8186 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-11 22:43:30 +05:30
1ecde4370e Added 3 new test cases for cloth, a check if no modiifer is added 2020-08-11 22:16:23 +05:30
ee4742c0b7 Added test file for Particle Instance and some minor fixes 2020-08-09 00:58:25 +05:30
d1debd9602 Merge branch 'master' into soc-2020-testing-frameworks 2020-08-08 16:36:39 +05:30
7583dc6cc3 Deleted physics fluid python test file 2020-08-08 15:02:47 +05:30
d83e7b7987 Saving last state of Fluids before deleting 2020-08-08 15:01:54 +05:30
6d6dc32279 Post review: Made a single try..catch, clean up 2020-08-08 14:37:56 +05:30
b4038986c1 Cleaned up mesh test file and added/updated physics test files 2020-08-08 00:36:31 +05:30
c7cdca0e33 Post review: Minor fixes, add documentation 2020-08-07 18:13:21 +05:30
04049a2080 WIP: Merged Dynamic paint and Physics Spec into ModifierSpec 2020-08-07 02:42:47 +05:30
75c1016853 Refactor 1: Traversing nested parameters using DFS 2020-08-06 14:50:59 +05:30
2db15f52c1 Minor fixes, adding GPL license and wave modifier test 2020-08-05 22:46:05 +05:30
23614570b4 Extended FluidSpec to contain DynamicPaint Spec
FluidSpec is now called FluidDynamicPaintSpec, added test file for
Dynamic Paint
2020-07-31 13:52:03 +05:30
d758139af4 Added Particle system class and Tests to extend the framework 2020-07-30 02:26:23 +05:30
3c0a407511 Solved merge conflicts in bevel operator caused due to change 2020-07-29 17:21:42 +05:30
b94856d804 Added tests for Curves both generate and deform 2020-07-24 14:39:39 +05:30
f534e9928d Added FluidSpec for Fluid simulations and a test.
Note the test should be run in 2.90
2020-07-24 14:39:39 +05:30
9236fb2725 WIP: FluidSpec for Fluid simulations 2020-07-21 14:08:00 +05:30
d21ad2cc39 Updated the run_test command from index to name 2020-07-20 12:45:35 +05:30
911a2b1d78 Post Review: Added minor improvements 2020-07-20 12:43:21 +05:30
16d58a509a Added Curve support in framework and tests for Generate Modifiers 2020-07-20 00:27:53 +05:30
49f00b597e Merge branch 'master' into soc-2020-testing-frameworks 2020-07-14 00:09:26 +05:30
a7d2ca5064 Post Review: Added DeformModifierTest class to run Deform Tests by name, added run test by name for Modifers and Operators, removed deform flag, modifier is applied separately 2020-07-14 00:06:53 +05:30
f447d2748b Merge branch 'master' into soc-2020-testing-frameworks 2020-07-09 23:07:53 +05:30
59c817bf8a Added Object operator class and DeformModifierSpec class, check for
unique name for operators
2020-07-09 21:54:35 +05:30
235cd70da8 Tests: Added test for Skin, Ocean and Hook modifiers 2020-07-09 21:04:43 +05:30
84446e055d Added unique test names to modifiers, operators, bevel, boolean, cloth and
softbody tests
2020-07-09 21:03:46 +05:30
b4d2cbafb7 Added unique name parameter for modifiers as well as MeshTest class 2020-06-14 20:14:38 +05:30
ce46e80b87 Review: Added Exception safety, some minor improvements and works as
intended.
2020-06-12 00:58:00 +05:30
eef4792627 Review: added comments, doc strings, improvements, support for random vertices 2020-06-11 02:16:42 +05:30
ea00f1b416 Merge branch 'master' into soc-2020-testing-frameworks
Updating with master
2020-06-06 23:20:35 +05:30
0ee4f5cb0b Tests: almost finished with the protoype, added support for
generating vertex groups from script.

Some minor improvements left, work in progress, saving.
2020-06-06 17:38:13 +05:30
2e5576237d Tests: created a prototype for generating blend objects for modifiers
regression tests

Work in progress, saving.
2020-05-26 01:31:49 +05:30
784 changed files with 9170 additions and 18302 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View 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()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,3 @@
#define MANTA_GIT_VERSION "commit e2285cb9bc492987f728123be6cfc1fe11fe73d6"
#define MANTA_GIT_VERSION "commit 327917cd59b03bef3a953b5f58fc1637b3a83e01"

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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. */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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), &currentPoint, 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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -558,7 +558,6 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
"msgid": ((("msgctxt",), _ctxt_to_ctxt),
),
"message": (),
"heading": (),
}
context_kw_set = {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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