diff options
1014 files changed, 20994 insertions, 16055 deletions
diff --git a/.clang-tidy b/.clang-tidy index 9a1392407b9..f80f484ffdf 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -15,7 +15,6 @@ Checks: > -readability-misleading-indentation, - -readability-redundant-member-init, -readability-use-anyofallof, -readability-function-cognitive-complexity, diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 00000000000..d36bce18613 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,93 @@ +# git config blame.ignoreRevsFile .git-blame-ignore-revs +# +# After running the above, commits listed in this file will be +# ignored by git blame. The blame will be shifted to the person +# who edited the line(s) before the ignored commit. +# +# To disable this ignorance for a command, run as follows +# git blame --ignore-revs-file="" <other options> +# +# Changes that belong here: +# - Massive comment, doxy-sections, or spelling corrections. +# - Clang-format, PEP8 or other automated changes which are *strictly* "no functional change". +# - Several smaller commits should be added to this list at once, because adding +# one extra commit (to edit this file) after every small cleanup is noisy. +# +# Note: +# - The comment above the SHA should be the first line of the commit. +# - It is fine to pack together similar commits if they have the same explanatory comment. +# - Use only 40 character git SHAs; not smaller ones, not prefixed with rB. +# +# https://git-scm.com/docs/git-blame/2.23.0 + +# white space commit. (2 spaces -> tab). +0a3694cd6ebec710da7110e9f168a72d47c71ee0 + +# Cycles: Cleanup, spacing after preprocessor +cb4b5e12abf1fc6cf9ffc0944e0a1bc406286c63 + +# ClangFormat: apply to source, most of intern +e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 + +# Code Style: use "#pragma once" in source directory +91694b9b58ab953f3b313be9389cc1303e472fc2 + +# Code Style: use "#pragma once" in some newer headers +8198dbb888856b8c11757586df02aca15f132f90 + +# Code Style: use "#pragma once" in intern/ghost +1b1129f82a9cf316b54fbc025f8cfcc1a74b8589 + +# Cleanup: mostly comments, use doxy syntax & typos +e0cb02587012b4b2f4b18363dc7d0a7da2c02093 + +# Cleanup: use C comments for descriptive text +2abfcebb0eb7989e3d1e7d03f37ecf5c088210af + +# use lowercase for cmake builtin names and macros, remove contents in else() and endif() which is no longer needed. +afacd184982e58a9c830a3d5366e25983939a7ba + +# Spelling: It's Versus Its +3a7fd309fce89213b0224b3c6807adb2d1fe7ca8 + +# Spelling: Then Versus Than +d1eefc421544e2ea632fb35cb6bcaade4c39ce6b + +# Spelling: Miscellaneous +84ef3b80de4915a24a9fd2fd214d0fa44e59b854 + +# Spelling: Loose Versus Lose +c0a6bc19794c69843c38451c762e91bc10136e0f + +# Spelling: Apart Versus A Part +3d26cd01b9ba6381eb165e11536345ae652dfb41 + +# Cleanup: use 2 space indentation for CMake +3076d95ba441cd32706a27d18922a30f8fd28b8a + +# Cleanup: use over-line for doxy comments +4b188bb08cf5aaae3c68ab57bbcfa037eef1ac10 + +# Cleanup: General comment style clean up of graph_edit.c and fcurve.c +0105f146bb40bd609ccbda3d3f6aeb8e14ad3f9e + +# Cleanup: pep8 (indentation, spacing, long lines) +41d2d6da0c96d351b47acb64d3e0decdba16cb16 + +# Cleanup: pep8, blank lines +bab9de2a52929fe2b45ecddb1eb09da3378e303b + +# Cleanup: PEP8 for python changes +1e7e94588daa66483190f45a9de5e98228f80e05 + +# GPencil: Cleanup pep8 +a09cc3ee1a99f2cd5040bbf30c8ab8c588bb2bb1 + +# Cleanup: trailing space, remove tabs, pep8 +c42a6b77b52560d257279de2cb624b4ef2c0d24c + +# Cleanup: use C style doxygen comments +8c1726918374e1d2d2123e17bae8db5aadde3433 + +# Cleanup: use doxy sections for imbuf +c207f7c22e1439e0b285fba5d2c072bdae23f981 diff --git a/CMakeLists.txt b/CMakeLists.txt index eb04da749ab..15b272a8d2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -526,10 +526,10 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") # Silence the warning that object-size is not effective in -O0. set(_asan_defaults "${_asan_defaults}") else() - set(_asan_defaults "${_asan_defaults} -fsanitize=object-size") + string(APPEND _asan_defaults " -fsanitize=object-size") endif() else() - set(_asan_defaults "${_asan_defaults} -fsanitize=leak -fsanitize=object-size") + string(APPEND _asan_defaults " -fsanitize=leak -fsanitize=object-size") endif() set(COMPILER_ASAN_CFLAGS "${_asan_defaults}" CACHE STRING "C flags for address sanitizer") @@ -570,6 +570,11 @@ if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") endif() endif() +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") + option(WITH_COMPILER_SHORT_FILE_MACRO "Make paths in macros like __FILE__ relative to top level source and build directories." ON) + mark_as_advanced(WITH_COMPILER_SHORT_FILE_MACRO) +endif() + if(WIN32) # Use hardcoded paths or find_package to find externals option(WITH_WINDOWS_FIND_MODULES "Use find_package to locate libraries" OFF) @@ -858,11 +863,11 @@ if(NOT CMAKE_BUILD_TYPE MATCHES "Release") # Since linker flags are not set, all compiler checks and `find_package` # calls that rely on `try_compile` will fail. # See CMP0066 also. - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${COMPILER_ASAN_CFLAGS}") - set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CFLAGS}") + string(APPEND CMAKE_C_FLAGS_DEBUG " ${COMPILER_ASAN_CFLAGS}") + string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " ${COMPILER_ASAN_CFLAGS}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COMPILER_ASAN_CXXFLAGS}") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COMPILER_ASAN_CXXFLAGS}") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " ${COMPILER_ASAN_CXXFLAGS}") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " ${COMPILER_ASAN_CXXFLAGS}") endif() if(MSVC) set(COMPILER_ASAN_LINKER_FLAGS "/FUNCTIONPADMIN:6") @@ -941,11 +946,11 @@ endif() # Do it globally, SSE2 is required for quite some time now. # Doing it now allows to use SSE/SSE2 in inline headers. if(SUPPORT_SSE_BUILD) - set(PLATFORM_CFLAGS " ${COMPILER_SSE_FLAG} ${PLATFORM_CFLAGS}") + string(PREPEND PLATFORM_CFLAGS "${COMPILER_SSE_FLAG} ") add_definitions(-D__SSE__ -D__MMX__) endif() if(SUPPORT_SSE2_BUILD) - set(PLATFORM_CFLAGS " ${PLATFORM_CFLAGS} ${COMPILER_SSE2_FLAG}") + string(APPEND PLATFORM_CFLAGS " ${COMPILER_SSE2_FLAG}") add_definitions(-D__SSE2__) if(NOT SUPPORT_SSE_BUILD) # don't double up add_definitions(-D__MMX__) @@ -1157,8 +1162,8 @@ if(WITH_OPENMP) if(OPENMP_FOUND) if(NOT WITH_OPENMP_STATIC) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + string(APPEND CMAKE_C_FLAGS " ${OpenMP_C_FLAGS}") + string(APPEND CMAKE_CXX_FLAGS " ${OpenMP_CXX_FLAGS}") else() # Typically avoid adding flags as defines but we can't # pass OpenMP flags to the linker for static builds, meaning @@ -1548,8 +1553,8 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_SIGN_COMPARE -Wno-sign-compare) # disable numbered, false positives - set(C_WARNINGS "${C_WARNINGS} -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199") - set(CXX_WARNINGS "${CXX_WARNINGS} -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199") + string(APPEND C_WARNINGS " -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199") + string(APPEND CXX_WARNINGS " -wd188,186,144,913,556,858,597,177,1292,167,279,592,94,2722,3199") elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") # most msvc warnings are C & C++ set(_WARNINGS @@ -1580,7 +1585,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "MSVC") if(MSVC_VERSION GREATER_EQUAL 1911) # see https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/c5038?view=vs-2017 - set(_WARNINGS "${_WARNINGS} /w35038") # order of initialization in c++ constructors + string(APPEND _WARNINGS " /w35038") # order of initialization in c++ constructors endif() string(REPLACE ";" " " _WARNINGS "${_WARNINGS}") @@ -1621,19 +1626,19 @@ if(WITH_PYTHON) endif() if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17") + string(APPEND CMAKE_CXX_FLAGS " /std:c++17") # Make MSVC properly report the value of the __cplusplus preprocessor macro # Available MSVC 15.7 (1914) and up, without this it reports 199711L regardless # of the C++ standard chosen above if(MSVC_VERSION GREATER 1913) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") + string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus") endif() elseif( CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "Intel" ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") + string(APPEND CMAKE_CXX_FLAGS " -std=c++17") else() message(FATAL_ERROR "Unknown compiler ${CMAKE_C_COMPILER_ID}, can't enable C++17 build") endif() @@ -1646,12 +1651,47 @@ if( (CMAKE_C_COMPILER_ID MATCHES "Intel") ) # Use C11 + GNU extensions, works with GCC, Clang, ICC - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu11") + string(APPEND CMAKE_C_FLAGS " -std=gnu11") endif() if(UNIX AND NOT APPLE) if(NOT WITH_CXX11_ABI) - set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -D_GLIBCXX_USE_CXX11_ABI=0") + string(APPEND PLATFORM_CFLAGS " -D_GLIBCXX_USE_CXX11_ABI=0") + endif() +endif() + +if(WITH_COMPILER_SHORT_FILE_MACRO) + # Use '-fmacro-prefix-map' for Clang and GCC (MSVC doesn't support this). + ADD_CHECK_C_COMPILER_FLAG(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar) + ADD_CHECK_CXX_COMPILER_FLAG(CXX_PREFIX_MAP_FLAGS CXX_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar) + if(C_MACRO_PREFIX_MAP AND CXX_MACRO_PREFIX_MAP) + if(APPLE) + if(XCODE AND ${XCODE_VERSION} VERSION_LESS 12.0) + # Developers may have say LLVM Clang-10.0.1 toolchain (which supports the flag) + # with Xcode-11 (the Clang of which doesn't support the flag). + message(WARNING + "-fmacro-prefix-map flag is NOT supported by Clang shipped with Xcode-${XCODE_VERSION}." + " Some Xcode functionality in Product menu may not work. Disabling WITH_COMPILER_SHORT_FILE_MACRO." + ) + set(WITH_COMPILER_SHORT_FILE_MACRO OFF) + endif() + endif() + if(WITH_COMPILER_SHORT_FILE_MACRO) + path_ensure_trailing_slash(_src_dir "${CMAKE_SOURCE_DIR}") + path_ensure_trailing_slash(_bin_dir "${CMAKE_BINARY_DIR}") + # Keep this variable so it can be stripped from build-info. + set(PLATFORM_CFLAGS_FMACRO_PREFIX_MAP + "-fmacro-prefix-map=\"${_src_dir}\"=\"\" -fmacro-prefix-map=\"${_bin_dir}\"=\"\"") + string(APPEND PLATFORM_CFLAGS " ${PLATFORM_CFLAGS_FMACRO_PREFIX_MAP}") + unset(_src_dir) + unset(_bin_dir) + endif() + else() + message(WARNING + "-fmacro-prefix-map flag is NOT supported by C/C++ compiler." + " Disabling WITH_COMPILER_SHORT_FILE_MACRO." + ) + set(WITH_COMPILER_SHORT_FILE_MACRO OFF) endif() endif() @@ -1755,7 +1795,7 @@ if(FIRST_RUN) set(_msg " - ${_setting}") string(LENGTH "${_msg}" _len) while("32" GREATER "${_len}") - set(_msg "${_msg} ") + string(APPEND _msg " ") math(EXPR _len "${_len} + 1") endwhile() @@ -1773,24 +1813,24 @@ if(FIRST_RUN) message(STATUS "C++ Compiler: \"${CMAKE_CXX_COMPILER_ID}\"") info_cfg_text("Build Options:") + info_cfg_option(WITH_ALEMBIC) info_cfg_option(WITH_BULLET) - info_cfg_option(WITH_IK_SOLVER) - info_cfg_option(WITH_IK_ITASC) - info_cfg_option(WITH_OPENCOLLADA) - info_cfg_option(WITH_FFTW3) - info_cfg_option(WITH_INTERNATIONAL) - info_cfg_option(WITH_INPUT_NDOF) info_cfg_option(WITH_CYCLES) + info_cfg_option(WITH_FFTW3) info_cfg_option(WITH_FREESTYLE) + info_cfg_option(WITH_GMP) + info_cfg_option(WITH_IK_ITASC) + info_cfg_option(WITH_IK_SOLVER) + info_cfg_option(WITH_INPUT_NDOF) + info_cfg_option(WITH_INTERNATIONAL) + info_cfg_option(WITH_OPENCOLLADA) info_cfg_option(WITH_OPENCOLORIO) - info_cfg_option(WITH_XR_OPENXR) info_cfg_option(WITH_OPENIMAGEDENOISE) info_cfg_option(WITH_OPENVDB) - info_cfg_option(WITH_ALEMBIC) info_cfg_option(WITH_QUADRIFLOW) - info_cfg_option(WITH_USD) info_cfg_option(WITH_TBB) - info_cfg_option(WITH_GMP) + info_cfg_option(WITH_USD) + info_cfg_option(WITH_XR_OPENXR) info_cfg_text("Compiler Options:") info_cfg_option(WITH_BUILDINFO) @@ -1798,58 +1838,58 @@ if(FIRST_RUN) info_cfg_text("System Options:") info_cfg_option(WITH_INSTALL_PORTABLE) + info_cfg_option(WITH_MEM_JEMALLOC) + info_cfg_option(WITH_MEM_VALGRIND) + info_cfg_option(WITH_SYSTEM_GLEW) info_cfg_option(WITH_X11_ALPHA) info_cfg_option(WITH_X11_XF86VMODE) info_cfg_option(WITH_X11_XFIXES) info_cfg_option(WITH_X11_XINPUT) - info_cfg_option(WITH_MEM_JEMALLOC) - info_cfg_option(WITH_MEM_VALGRIND) - info_cfg_option(WITH_SYSTEM_GLEW) info_cfg_text("Image Formats:") - info_cfg_option(WITH_OPENIMAGEIO) info_cfg_option(WITH_IMAGE_CINEON) info_cfg_option(WITH_IMAGE_DDS) info_cfg_option(WITH_IMAGE_HDR) info_cfg_option(WITH_IMAGE_OPENEXR) info_cfg_option(WITH_IMAGE_OPENJPEG) info_cfg_option(WITH_IMAGE_TIFF) + info_cfg_option(WITH_OPENIMAGEIO) info_cfg_text("Audio:") - info_cfg_option(WITH_OPENAL) - info_cfg_option(WITH_SDL) - info_cfg_option(WITH_SDL_DYNLOAD) - info_cfg_option(WITH_JACK) - info_cfg_option(WITH_JACK_DYNLOAD) info_cfg_option(WITH_CODEC_AVI) info_cfg_option(WITH_CODEC_FFMPEG) info_cfg_option(WITH_CODEC_SNDFILE) + info_cfg_option(WITH_JACK) + info_cfg_option(WITH_JACK_DYNLOAD) + info_cfg_option(WITH_OPENAL) + info_cfg_option(WITH_SDL) + info_cfg_option(WITH_SDL_DYNLOAD) info_cfg_text("Compression:") info_cfg_option(WITH_LZMA) info_cfg_option(WITH_LZO) info_cfg_text("Python:") + if(APPLE) + info_cfg_option(WITH_PYTHON_FRAMEWORK) + endif() info_cfg_option(WITH_PYTHON_INSTALL) info_cfg_option(WITH_PYTHON_INSTALL_NUMPY) info_cfg_option(WITH_PYTHON_MODULE) info_cfg_option(WITH_PYTHON_SAFETY) - if(APPLE) - info_cfg_option(WITH_PYTHON_FRAMEWORK) - endif() info_cfg_text("Modifiers:") - info_cfg_option(WITH_MOD_REMESH) info_cfg_option(WITH_MOD_FLUID) info_cfg_option(WITH_MOD_OCEANSIM) + info_cfg_option(WITH_MOD_REMESH) info_cfg_text("OpenGL:") - info_cfg_option(WITH_GLEW_ES) - info_cfg_option(WITH_GL_EGL) - info_cfg_option(WITH_GL_PROFILE_ES20) if(WIN32) info_cfg_option(WITH_GL_ANGLE) endif() + info_cfg_option(WITH_GL_EGL) + info_cfg_option(WITH_GL_PROFILE_ES20) + info_cfg_option(WITH_GLEW_ES) info_cfg_text("") diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt index 59c15a03119..0bc85f20c16 100644 --- a/build_files/build_environment/CMakeLists.txt +++ b/build_files/build_environment/CMakeLists.txt @@ -85,6 +85,7 @@ include(cmake/flexbison.cmake) include(cmake/osl.cmake) include(cmake/tbb.cmake) include(cmake/openvdb.cmake) +include(cmake/nanovdb.cmake) include(cmake/python.cmake) include(cmake/python_site_packages.cmake) include(cmake/package_python.cmake) diff --git a/build_files/build_environment/cmake/check_software.cmake b/build_files/build_environment/cmake/check_software.cmake index 56d6db70ea7..09883221091 100644 --- a/build_files/build_environment/cmake/check_software.cmake +++ b/build_files/build_environment/cmake/check_software.cmake @@ -43,7 +43,7 @@ if(UNIX) if(APPLE) if(NOT EXISTS "/usr/local/opt/bison/bin/bison") - set(_software_missing "${_software_missing} bison") + string(APPEND _software_missing " bison") endif() endif() diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 1fb56c4d568..1c5354aeb42 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -146,10 +146,8 @@ harvest(openjpeg/lib openjpeg/lib "*.a") harvest(opensubdiv/include opensubdiv/include "*.h") harvest(opensubdiv/lib opensubdiv/lib "*.a") harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h") -if(WITH_NANOVDB) - harvest(openvdb/nanovdb nanovdb/include/nanovdb "*.h") -endif() harvest(openvdb/lib openvdb/lib "*.a") +harvest(nanovdb/nanovdb nanovdb/include/nanovdb "*.h") harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h") harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a") harvest(osl/bin osl/bin "oslc") diff --git a/build_files/build_environment/cmake/nanovdb.cmake b/build_files/build_environment/cmake/nanovdb.cmake new file mode 100644 index 00000000000..89e7c38642d --- /dev/null +++ b/build_files/build_environment/cmake/nanovdb.cmake @@ -0,0 +1,54 @@ +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ***** END GPL LICENSE BLOCK ***** + +set(NANOVDB_EXTRA_ARGS + # NanoVDB is header-only, so only need the install target + -DNANOVDB_BUILD_UNITTESTS=OFF + -DNANOVDB_BUILD_EXAMPLES=OFF + -DNANOVDB_BUILD_BENCHMARK=OFF + -DNANOVDB_BUILD_DOCS=OFF + -DNANOVDB_BUILD_TOOLS=OFF + -DNANOVDB_CUDA_KEEP_PTX=OFF + # Do not need to include any of the dependencies because of this + -DNANOVDB_USE_OPENVDB=OFF + -DNANOVDB_USE_OPENGL=OFF + -DNANOVDB_USE_OPENCL=OFF + -DNANOVDB_USE_CUDA=OFF + -DNANOVDB_USE_TBB=OFF + -DNANOVDB_USE_BLOSC=OFF + -DNANOVDB_USE_ZLIB=OFF + -DNANOVDB_USE_OPTIX=OFF + -DNANOVDB_ALLOW_FETCHCONTENT=OFF +) + +ExternalProject_Add(nanovdb + URL ${NANOVDB_URI} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH MD5=${NANOVDB_HASH} + PREFIX ${BUILD_DIR}/nanovdb + SOURCE_SUBDIR nanovdb + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/nanovdb ${DEFAULT_CMAKE_FLAGS} ${NANOVDB_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/nanovdb +) + +if(WIN32) + ExternalProject_Add_Step(nanovdb after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/nanovdb/nanovdb ${HARVEST_TARGET}/nanovdb/include/nanovdb + DEPENDEES install + ) +endif() diff --git a/build_files/build_environment/cmake/openvdb.cmake b/build_files/build_environment/cmake/openvdb.cmake index 07d0297d5aa..2962f085e1b 100644 --- a/build_files/build_environment/cmake/openvdb.cmake +++ b/build_files/build_environment/cmake/openvdb.cmake @@ -54,20 +54,6 @@ set(OPENVDB_EXTRA_ARGS -DOPENVDB_CORE_STATIC=${OPENVDB_STATIC} -DOPENVDB_BUILD_BINARIES=Off -DCMAKE_DEBUG_POSTFIX=_d - # NanoVDB is header-only, so only need the install target - -DNANOVDB_BUILD_UNITTESTS=OFF - -DNANOVDB_BUILD_EXAMPLES=OFF - -DNANOVDB_BUILD_BENCHMARK=OFF - -DNANOVDB_BUILD_DOCS=OFF - -DNANOVDB_BUILD_TOOLS=OFF - -DNANOVDB_CUDA_KEEP_PTX=OFF - -DNANOVDB_USE_OPENGL=OFF - -DNANOVDB_USE_OPENGL=OFF - -DNANOVDB_USE_CUDA=OFF - -DNANOVDB_USE_TBB=OFF - -DNANOVDB_USE_OPTIX=OFF - -DNANOVDB_USE_OPENVDB=OFF - -DNANOVDB_ALLOW_FETCHCONTENT=OFF ) if(WIN32) @@ -88,18 +74,12 @@ else() ) endif() -if(WITH_NANOVDB) - set(OPENVDB_PATCH_FILE openvdb_nanovdb.diff) -else() - set(OPENVDB_PATCH_FILE openvdb.diff) -endif() - ExternalProject_Add(openvdb URL ${OPENVDB_URI} DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH MD5=${OPENVDB_HASH} PREFIX ${BUILD_DIR}/openvdb - PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/${OPENVDB_PATCH_FILE} + PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb.diff CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openvdb ${DEFAULT_CMAKE_FLAGS} ${OPENVDB_EXTRA_ARGS} INSTALL_DIR ${LIBDIR}/openvdb ) @@ -121,12 +101,6 @@ if(WIN32) COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/bin/openvdb.dll ${HARVEST_TARGET}/openvdb/bin/openvdb.dll DEPENDEES install ) - if(WITH_NANOVDB) - ExternalProject_Add_Step(openvdb nanovdb_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openvdb/nanovdb ${HARVEST_TARGET}/nanovdb/include/nanovdb - DEPENDEES after_install - ) - endif() endif() if(BUILD_MODE STREQUAL Debug) ExternalProject_Add_Step(openvdb after_install diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index d6b5762ccbc..cfbe28b99c7 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -21,7 +21,6 @@ if(WIN32) endif() option(WITH_WEBP "Enable building of oiio with webp support" OFF) option(WITH_BOOST_PYTHON "Enable building of boost with python support" OFF) -option(WITH_NANOVDB "Enable building of OpenVDB with NanoVDB included" OFF) set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with") if(NOT BUILD_MODE) @@ -57,7 +56,7 @@ if(WIN32) if(MSVC_VERSION GREATER 1909) set(COMMON_MSVC_FLAGS "/Wv:18") #some deps with warnings as error aren't quite ready for dealing with the new 2017 warnings. endif() - set(COMMON_MSVC_FLAGS "${COMMON_MSVC_FLAGS} /bigobj") + string(APPEND COMMON_MSVC_FLAGS " /bigobj") if(WITH_OPTIMIZED_DEBUG) set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MDd ${COMMON_MSVC_FLAGS} /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS") else() diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 244ca6dd49f..653db9f740c 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -145,15 +145,13 @@ set(TBB_VERSION 2019_U9) set(TBB_URI https://github.com/oneapi-src/oneTBB/archive/${TBB_VERSION}.tar.gz) set(TBB_HASH 26263622e9187212ec240dcf01b66207) -if(WITH_NANOVDB) - set(OPENVDB_GIT_UID e62f7a0bf1e27397223c61ddeaaf57edf111b77f) - set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/${OPENVDB_GIT_UID}.tar.gz) - set(OPENVDB_HASH 90919510bc6ccd630fedc56f748cb199) -else() - set(OPENVDB_VERSION 7.0.0) - set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz) - set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8) -endif() +set(OPENVDB_VERSION 7.0.0) +set(OPENVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz) +set(OPENVDB_HASH fd6c4f168282f7e0e494d290cd531fa8) + +set(NANOVDB_GIT_UID e62f7a0bf1e27397223c61ddeaaf57edf111b77f) +set(NANOVDB_URI https://github.com/AcademySoftwareFoundation/openvdb/archive/${NANOVDB_GIT_UID}.tar.gz) +set(NANOVDB_HASH 90919510bc6ccd630fedc56f748cb199) set(IDNA_VERSION 2.9) set(CHARDET_VERSION 3.0.4) diff --git a/build_files/build_environment/patches/openvdb_nanovdb.diff b/build_files/build_environment/patches/openvdb_nanovdb.diff deleted file mode 100644 index 50984e91f37..00000000000 --- a/build_files/build_environment/patches/openvdb_nanovdb.diff +++ /dev/null @@ -1,135 +0,0 @@ -diff -Naur orig/cmake/FindIlmBase.cmake openvdb/cmake/FindIlmBase.cmake ---- orig/cmake/FindIlmBase.cmake 2019-12-06 12:11:33 -0700 -+++ openvdb/cmake/FindIlmBase.cmake 2020-08-12 12:48:44 -0600 -@@ -217,6 +217,8 @@ - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") - endif() - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_IlmBase_Version_Suffix}.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s_d.lib") - else() - if(ILMBASE_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") -diff -Naur orig/cmake/FindOpenEXR.cmake openvdb/cmake/FindOpenEXR.cmake ---- orig/cmake/FindOpenEXR.cmake 2019-12-06 12:11:33 -0700 -+++ openvdb/cmake/FindOpenEXR.cmake 2020-08-12 12:48:44 -0600 -@@ -210,6 +210,8 @@ - set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") - endif() - list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "${_OpenEXR_Version_Suffix}.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s.lib") -+ list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES "_s_d.lib") - else() - if(OPENEXR_USE_STATIC_LIBS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") -diff -Naur orig/openvdb/openvdb/CMakeLists.txt openvdb/openvdb/openvdb/CMakeLists.txt ---- orig/openvdb/openvdb/CMakeLists.txt 2019-12-06 12:11:33 -0700 -+++ openvdb/openvdb/openvdb/CMakeLists.txt 2020-08-12 14:12:26 -0600 -@@ -105,7 +105,9 @@ - # http://boost.2283326.n4.nabble.com/CMake-config-scripts-broken-in-1-70-td4708957.html - # https://github.com/boostorg/boost_install/commit/160c7cb2b2c720e74463865ef0454d4c4cd9ae7c - set(BUILD_SHARED_LIBS ON) -- set(Boost_USE_STATIC_LIBS OFF) -+ if(NOT WIN32) # blender links boost statically on windows -+ set(Boost_USE_STATIC_LIBS OFF) -+ endif() - endif() - - find_package(Boost ${MINIMUM_BOOST_VERSION} REQUIRED COMPONENTS iostreams system) -@@ -193,6 +195,7 @@ - if(OPENVDB_DISABLE_BOOST_IMPLICIT_LINKING) - add_definitions(-DBOOST_ALL_NO_LIB) - endif() -+ add_definitions(-D__TBB_NO_IMPLICIT_LINKAGE -DOPENVDB_OPENEXR_STATICLIB) - endif() - - # @todo Should be target definitions -@@ -383,7 +386,12 @@ - # imported targets. - - if(OPENVDB_CORE_SHARED) -- add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES}) -+ if(WIN32) -+ configure_file(version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) -+ add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) -+ else() -+ add_library(openvdb_shared SHARED ${OPENVDB_LIBRARY_SOURCE_FILES}) -+ endif() - endif() - - if(OPENVDB_CORE_STATIC) -diff -Naur orig/openvdb/openvdb/version.rc.in openvdb/openvdb/openvdb/version.rc.in ---- orig/openvdb/openvdb/version.rc.in 1969-12-31 17:00:00 -0700 -+++ openvdb/openvdb/openvdb/version.rc.in 2020-08-12 14:15:01 -0600 -@@ -0,0 +1,48 @@ -+#include <winver.h> -+ -+#define VER_FILEVERSION @OpenVDB_MAJOR_VERSION@,@OpenVDB_MINOR_VERSION@,@OpenVDB_PATCH_VERSION@,0 -+#define VER_FILEVERSION_STR "@OpenVDB_MAJOR_VERSION@.@OpenVDB_MINOR_VERSION@.@OpenVDB_PATCH_VERSION@.0\0" -+ -+#define VER_PRODUCTVERSION @OpenVDB_MAJOR_VERSION@,@OpenVDB_MINOR_VERSION@,@OpenVDB_PATCH_VERSION@,0 -+#define VER_PRODUCTVERSION_STR "@OpenVDB_MAJOR_VERSION@.@OpenVDB_MINOR_VERSION@\0" -+ -+#ifndef DEBUG -+#define VER_DEBUG 0 -+#else -+#define VER_DEBUG VS_FF_DEBUG -+#endif -+ -+VS_VERSION_INFO VERSIONINFO -+FILEVERSION VER_FILEVERSION -+PRODUCTVERSION VER_PRODUCTVERSION -+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -+FILEFLAGS (VER_DEBUG) -+FILEOS VOS__WINDOWS32 -+FILETYPE VFT_DLL -+FILESUBTYPE VFT2_UNKNOWN -+BEGIN -+ BLOCK "StringFileInfo" -+ BEGIN -+ BLOCK "040904E4" -+ BEGIN -+ VALUE "FileDescription", "OpenVDB" -+ VALUE "FileVersion", VER_FILEVERSION_STR -+ VALUE "InternalName", "OpenVDB" -+ VALUE "ProductName", "OpenVDB" -+ VALUE "ProductVersion", VER_PRODUCTVERSION_STR -+ END -+ END -+ -+ BLOCK "VarFileInfo" -+ BEGIN -+ /* The following line should only be modified for localized versions. */ -+ /* It consists of any number of WORD,WORD pairs, with each pair */ -+ /* describing a language,codepage combination supported by the file. */ -+ /* */ -+ /* For example, a file might have values "0x409,1252" indicating that it */ -+ /* supports English language (0x409) in the Windows ANSI codepage (1252). */ -+ -+ VALUE "Translation", 0x409, 1252 -+ -+ END -+END -diff -Naur openvdb-original/CMakeLists.txt openvdb/CMakeLists.txt ---- openvdb-original/CMakeLists.txt 2020-08-27 03:34:02.000000000 +0200 -+++ openvdb/CMakeLists.txt 2020-09-02 10:56:21.665735244 +0200 -@@ -68,6 +68,7 @@ - option(OPENVDB_INSTALL_HOUDINI_PYTHONRC [=[Install a Houdini startup script that sets - the visibilty of OpenVDB nodes and their native equivalents.]=] OFF) - option(OPENVDB_BUILD_MAYA_PLUGIN "Build the Maya plugin" OFF) -+option(OPENVDB_BUILD_NANOVDB "Build nanovdb" ON) - option(OPENVDB_ENABLE_RPATH "Build with RPATH information" ON) - option(OPENVDB_CXX_STRICT "Enable or disable pre-defined compiler warnings" OFF) - option(OPENVDB_CODE_COVERAGE "Enable code coverage. This also overrides CMAKE_BUILD_TYPE to Debug" OFF) -@@ -740,6 +741,10 @@ - add_subdirectory(openvdb_maya) - endif() - -+if(OPENVDB_BUILD_NANOVDB) -+ add_subdirectory(nanovdb) -+endif() -+ - ########################################################################## - - add_custom_target(uninstall -
\ No newline at end of file diff --git a/build_files/cmake/buildinfo.cmake b/build_files/cmake/buildinfo.cmake index cef6b94ee2e..a349ffc1b56 100644 --- a/build_files/cmake/buildinfo.cmake +++ b/build_files/cmake/buildinfo.cmake @@ -128,7 +128,7 @@ if(EXISTS ${SOURCE_DIR}/.git) OUTPUT_STRIP_TRAILING_WHITESPACE) if(NOT _git_changed_files STREQUAL "") - set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)") + string(APPEND MY_WC_BRANCH " (modified)") else() # Unpushed commits are also considered local modifications execute_process(COMMAND git log @{u}.. @@ -137,7 +137,7 @@ if(EXISTS ${SOURCE_DIR}/.git) OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET) if(NOT _git_unpushed_log STREQUAL "") - set(MY_WC_BRANCH "${MY_WC_BRANCH} (modified)") + string(APPEND MY_WC_BRANCH " (modified)") endif() unset(_git_unpushed_log) endif() @@ -161,6 +161,7 @@ file(WRITE buildinfo.h.txt "#define BUILD_BRANCH \"${MY_WC_BRANCH}\"\n" "#define BUILD_DATE \"${BUILD_DATE}\"\n" "#define BUILD_TIME \"${BUILD_TIME}\"\n" + "#include \"buildinfo_static.h\"\n" ) # cleanup diff --git a/build_files/cmake/buildinfo_static.h.in b/build_files/cmake/buildinfo_static.h.in new file mode 100644 index 00000000000..9dd45b95b8a --- /dev/null +++ b/build_files/cmake/buildinfo_static.h.in @@ -0,0 +1,8 @@ +/* CMake expanded values that won't change between CMake execution (unlike date/time). + * This is included by `buildinfo.h` generated by `buildinfo.cmake`. */ +#define BUILD_PLATFORM "@BUILD_PLATFORM@" +#define BUILD_TYPE "@BUILD_TYPE@" +#define BUILD_CFLAGS "@BUILD_CFLAGS@" +#define BUILD_CXXFLAGS "@BUILD_CXXFLAGS@" +#define BUILD_LINKFLAGS "@BUILD_LINKFLAGS@" +#define BUILD_SYSTEM "@BUILD_SYSTEM@" diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 8498c68c21c..202b44f611c 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -60,6 +60,19 @@ function(list_assert_duplicates unset(_len_after) endfunction() +# Adds a native path separator to the end of the path: +# +# - 'example' -> 'example/' +# - '/example///' -> '/example/' +# +macro(path_ensure_trailing_slash + path_new path_input + ) + file(TO_NATIVE_PATH "/" _path_sep) + string(REGEX REPLACE "[${_path_sep}]+$" "" ${path_new} ${path_input}) + set(${path_new} "${${path_new}}${_path_sep}") + unset(_path_sep) +endmacro() # foo_bar.spam --> foo_barMySuffix.spam macro(file_suffix @@ -183,7 +196,7 @@ function(blender_user_header_search_paths foreach(_INC ${includes}) get_filename_component(_ABS_INC ${_INC} ABSOLUTE) # _ALL_INCS is a space-separated string of file paths in quotes. - set(_ALL_INCS "${_ALL_INCS} \"${_ABS_INC}\"") + string(APPEND _ALL_INCS " \"${_ABS_INC}\"") endforeach() set_target_properties(${name} PROPERTIES XCODE_ATTRIBUTE_USER_HEADER_SEARCH_PATHS "${_ALL_INCS}") endif() @@ -250,11 +263,11 @@ macro(add_cc_flags_custom_test string(TOUPPER ${name} _name_upper) if(DEFINED CMAKE_C_FLAGS_${_name_upper}) message(STATUS "Using custom CFLAGS: CMAKE_C_FLAGS_${_name_upper} in \"${CMAKE_CURRENT_SOURCE_DIR}\"") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${_name_upper}}" ${ARGV1}) + string(APPEND CMAKE_C_FLAGS " ${CMAKE_C_FLAGS_${_name_upper}}" ${ARGV1}) endif() if(DEFINED CMAKE_CXX_FLAGS_${_name_upper}) message(STATUS "Using custom CXXFLAGS: CMAKE_CXX_FLAGS_${_name_upper} in \"${CMAKE_CURRENT_SOURCE_DIR}\"") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_name_upper}}" ${ARGV1}) + string(APPEND CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS_${_name_upper}}" ${ARGV1}) endif() unset(_name_upper) @@ -675,14 +688,14 @@ endmacro() macro(add_c_flag flag) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") + string(APPEND CMAKE_C_FLAGS " ${flag}") + string(APPEND CMAKE_CXX_FLAGS " ${flag}") endmacro() macro(add_cxx_flag flag) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") + string(APPEND CMAKE_CXX_FLAGS " ${flag}") endmacro() macro(remove_strict_flags) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index d529fbb9d92..b1168cf28da 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -194,7 +194,7 @@ if(SYSTEMSTUBS_LIBRARY) list(APPEND PLATFORM_LINKLIBS SystemStubs) endif() -set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -pipe -funsigned-char -fno-strict-aliasing") +string(APPEND PLATFORM_CFLAGS " -pipe -funsigned-char -fno-strict-aliasing") set(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework Metal -framework QuartzCore" ) @@ -202,12 +202,12 @@ set(PLATFORM_LINKFLAGS list(APPEND PLATFORM_LINKLIBS c++) if(WITH_JACK) - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -F/Library/Frameworks -weak_framework jackmp") + string(APPEND PLATFORM_LINKFLAGS " -F/Library/Frameworks -weak_framework jackmp") endif() if(WITH_PYTHON_MODULE OR WITH_PYTHON_FRAMEWORK) # force cmake to link right framework - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/Python") + string(APPEND PLATFORM_LINKFLAGS " /Library/Frameworks/Python.framework/Versions/${PYTHON_VERSION}/Python") endif() if(WITH_OPENCOLLADA) @@ -222,7 +222,7 @@ if(WITH_SDL) find_package(SDL2) set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIRS}) set(SDL_LIBRARY ${SDL2_LIBRARIES}) - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -framework ForceFeedback") + string(APPEND PLATFORM_LINKFLAGS " -framework ForceFeedback") endif() set(PNG_ROOT ${LIBDIR}/png) @@ -266,7 +266,7 @@ if(WITH_BOOST) endif() if(WITH_INTERNATIONAL OR WITH_CODEC_FFMPEG) - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -liconv") # boost_locale and ffmpeg needs it ! + string(APPEND PLATFORM_LINKFLAGS " -liconv") # boost_locale and ffmpeg needs it ! endif() if(WITH_OPENIMAGEIO) @@ -335,7 +335,10 @@ endif() if(WITH_CYCLES_EMBREE) find_package(Embree 3.8.0 REQUIRED) - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Xlinker -stack_size -Xlinker 0x100000") + # Increase stack size for Embree, only works for executables. + if(NOT WITH_PYTHON_MODULE) + string(APPEND PLATFORM_LINKFLAGS " -Xlinker -stack_size -Xlinker 0x100000") + endif() # Embree static library linking can mix up SSE and AVX symbols, causing # crashes on macOS systems with older CPUs that don't have AVX. Using @@ -378,7 +381,7 @@ if(WITH_OPENMP) set(OPENMP_FOUND ON) set(OpenMP_C_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'") set(OpenMP_CXX_FLAGS "-Xclang -fopenmp -I'${LIBDIR}/openmp/include'") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L'${LIBDIR}/openmp/lib' -lomp") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -L'${LIBDIR}/openmp/lib' -lomp") # Copy libomp.dylib to allow executables like datatoc and tests to work. # `@executable_path/../Resources/lib/` is a default dylib search path. @@ -431,8 +434,8 @@ if(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" OR CMAKE_OSX_ARCHITECTURES MATCHES " set(CMAKE_CXX_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3") set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic -msse -msse2 -msse3 -mssse3") if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -ftree-vectorize -fvariable-expansion-in-unroller") + string(APPEND CMAKE_C_FLAGS_RELEASE " -ftree-vectorize -fvariable-expansion-in-unroller") + string(APPEND CMAKE_CXX_FLAGS_RELEASE " -ftree-vectorize -fvariable-expansion-in-unroller") endif() else() set(CMAKE_C_FLAGS_RELEASE "-O2 -mdynamic-no-pic") @@ -441,7 +444,7 @@ endif() if(${XCODE_VERSION} VERSION_EQUAL 5 OR ${XCODE_VERSION} VERSION_GREATER 5) # Xcode 5 is always using CLANG, which has too low template depth of 128 for libmv - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=1024") + string(APPEND CMAKE_CXX_FLAGS " -ftemplate-depth=1024") endif() # Avoid conflicts with Luxrender, and other plug-ins that may use the same @@ -450,8 +453,8 @@ set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Xlinker -unexported_symbols_list -Xlinker '${CMAKE_SOURCE_DIR}/source/creator/osx_locals.map'" ) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") -set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -stdlib=libc++") +string(APPEND CMAKE_CXX_FLAGS " -stdlib=libc++") +string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++") # Suppress ranlib "has no symbols" warnings (workaround for T48250) set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>") diff --git a/build_files/cmake/platform/platform_apple_xcode.cmake b/build_files/cmake/platform/platform_apple_xcode.cmake index 3a43ca317dd..e4b804fc4ea 100644 --- a/build_files/cmake/platform/platform_apple_xcode.cmake +++ b/build_files/cmake/platform/platform_apple_xcode.cmake @@ -150,7 +150,7 @@ endif() if(NOT ${CMAKE_GENERATOR} MATCHES "Xcode") # Force CMAKE_OSX_DEPLOYMENT_TARGET for makefiles, will not work else (CMake bug?) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + string(APPEND CMAKE_C_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + string(APPEND CMAKE_CXX_FLAGS " -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") add_definitions("-DMACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 1aa96c8b842..97bd4981c22 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -73,7 +73,7 @@ if(EXISTS ${LIBDIR}) endif() if(WITH_STATIC_LIBS) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -static-libstdc++") endif() # Wrapper to prefer static libraries @@ -620,7 +620,7 @@ if(CMAKE_COMPILER_IS_GNUCC) set(CMAKE_C_FLAGS_RELEASE "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELWITHDEBINFO}") set(CMAKE_CXX_FLAGS_RELEASE "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(PREPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO "${GCC_EXTRA_FLAGS_RELEASE} ") unset(GCC_EXTRA_FLAGS_RELEASE) if(WITH_LINKER_GOLD) @@ -628,8 +628,8 @@ if(CMAKE_COMPILER_IS_GNUCC) COMMAND ${CMAKE_C_COMPILER} -fuse-ld=gold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) if("${LD_VERSION}" MATCHES "GNU gold") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=gold") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=gold") + string(APPEND CMAKE_C_FLAGS " -fuse-ld=gold") + string(APPEND CMAKE_CXX_FLAGS " -fuse-ld=gold") else() message(STATUS "GNU gold linker isn't available, using the default system linker.") endif() @@ -641,8 +641,8 @@ if(CMAKE_COMPILER_IS_GNUCC) COMMAND ${CMAKE_C_COMPILER} -fuse-ld=lld -Wl,--version ERROR_QUIET OUTPUT_VARIABLE LD_VERSION) if("${LD_VERSION}" MATCHES "LLD") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fuse-ld=lld") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fuse-ld=lld") + string(APPEND CMAKE_C_FLAGS " -fuse-ld=lld") + string(APPEND CMAKE_CXX_FLAGS " -fuse-ld=lld") else() message(STATUS "LLD linker isn't available, using the default system linker.") endif() @@ -667,12 +667,12 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "Intel") endif() mark_as_advanced(XILD) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fp-model precise -prec_div -parallel") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fp-model precise -prec_div -parallel") + string(APPEND CMAKE_C_FLAGS " -fp-model precise -prec_div -parallel") + string(APPEND CMAKE_CXX_FLAGS " -fp-model precise -prec_div -parallel") - # set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -diag-enable sc3") + # string(APPEND PLATFORM_CFLAGS " -diag-enable sc3") set(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing") - set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -static-intel") + string(APPEND PLATFORM_LINKFLAGS " -static-intel") endif() # Avoid conflicts with Mesa llvmpipe, Luxrender, and other plug-ins that may @@ -685,5 +685,5 @@ set(PLATFORM_LINKFLAGS # browsers can't properly detect blender as an executable then. Still enabled # for non-portable installs as typically used by Linux distributions. if(WITH_INSTALL_PORTABLE) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") + string(APPEND CMAKE_EXE_LINKER_FLAGS " -no-pie") endif() diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index e7474b0035d..ac08c1a5fa9 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -49,7 +49,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(NOT EXISTS "${CLANG_OPENMP_DLL}") message(FATAL_ERROR "Clang OpenMP library (${CLANG_OPENMP_DLL}) not found.") endif() - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} \"${CLANG_OPENMP_LIB}\"") + string(APPEND CMAKE_EXE_LINKER_FLAGS " \"${CLANG_OPENMP_LIB}\"") endif() if(WITH_WINDOWS_STRIPPED_PDB) message(WARNING "stripped pdb not supported with clang, disabling..") @@ -112,9 +112,9 @@ unset(_min_ver) # needed for some MSVC installations # 4099 : PDB 'filename' was not found with 'object/library' -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO /ignore:4099") -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO /ignore:4099") -set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO /ignore:4099") +string(APPEND CMAKE_EXE_LINKER_FLAGS " /SAFESEH:NO /ignore:4099") +string(APPEND CMAKE_SHARED_LINKER_FLAGS " /SAFESEH:NO /ignore:4099") +string(APPEND CMAKE_MODULE_LINKER_FLAGS " /SAFESEH:NO /ignore:4099") list(APPEND PLATFORM_LINKLIBS ws2_32 vfw32 winmm kernel32 user32 gdi32 comdlg32 Comctl32 version @@ -154,18 +154,18 @@ if(WITH_WINDOWS_PDB) endif() if(MSVC_CLANG) # Clangs version of cl doesn't support all flags - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ") + string(APPEND CMAKE_CXX_FLAGS " ${CXX_WARN_FLAGS} /nologo /J /Gd /EHsc -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference ") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd -Wno-unused-command-line-argument -Wno-microsoft-enum-forward-reference") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /nologo /J /Gd /MP /EHsc /bigobj") + string(APPEND CMAKE_CXX_FLAGS " /nologo /J /Gd /MP /EHsc /bigobj") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /nologo /J /Gd /MP /bigobj") endif() # C++ standards conformace (/permissive-) is available on msvc 15.5 (1912) and up if(MSVC_VERSION GREATER 1911 AND NOT MSVC_CLANG) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /permissive-") + string(APPEND CMAKE_CXX_FLAGS " /permissive-") # Two-phase name lookup does not place nicely with OpenMP yet, so disable for now - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:twoPhase-") + string(APPEND CMAKE_CXX_FLAGS " /Zc:twoPhase-") endif() if(WITH_WINDOWS_SCCACHE AND CMAKE_VS_MSBUILD_COMMAND) @@ -183,33 +183,33 @@ else() set(SYMBOL_FORMAT /ZI) endif() -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd ${SYMBOL_FORMAT}") -set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MDd ${SYMBOL_FORMAT}") -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD ${PDB_INFO_OVERRIDE_FLAGS}") -set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MD ${PDB_INFO_OVERRIDE_FLAGS}") -set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /MD ${PDB_INFO_OVERRIDE_FLAGS}") -set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} /MD ${PDB_INFO_OVERRIDE_FLAGS}") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /MD ${SYMBOL_FORMAT}") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} /MD ${SYMBOL_FORMAT}") +string(APPEND CMAKE_CXX_FLAGS_DEBUG " /MDd ${SYMBOL_FORMAT}") +string(APPEND CMAKE_C_FLAGS_DEBUG " /MDd ${SYMBOL_FORMAT}") +string(APPEND CMAKE_CXX_FLAGS_RELEASE " /MD ${PDB_INFO_OVERRIDE_FLAGS}") +string(APPEND CMAKE_C_FLAGS_RELEASE " /MD ${PDB_INFO_OVERRIDE_FLAGS}") +string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}") +string(APPEND CMAKE_C_FLAGS_MINSIZEREL " /MD ${PDB_INFO_OVERRIDE_FLAGS}") +string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}") +string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " /MD ${SYMBOL_FORMAT}") unset(SYMBOL_FORMAT) # JMC is available on msvc 15.8 (1915) and up if(MSVC_VERSION GREATER 1914 AND NOT MSVC_CLANG) - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /JMC") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " /JMC") endif() -set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /SUBSYSTEM:CONSOLE /STACK:2097152") +string(APPEND PLATFORM_LINKFLAGS " /SUBSYSTEM:CONSOLE /STACK:2097152") set(PLATFORM_LINKFLAGS_RELEASE "/NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:msvcrtd.lib") -set(PLATFORM_LINKFLAGS_DEBUG "${PLATFORM_LINKFLAGS_DEBUG} /IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib") +string(APPEND PLATFORM_LINKFLAGS_DEBUG " /IGNORE:4099 /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcmtd.lib") # Ignore meaningless for us linker warnings. -set(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} /ignore:4049 /ignore:4217 /ignore:4221") +string(APPEND PLATFORM_LINKFLAGS " /ignore:4049 /ignore:4217 /ignore:4221") set(PLATFORM_LINKFLAGS_RELEASE "${PLATFORM_LINKFLAGS} ${PDB_INFO_OVERRIDE_LINKER_FLAGS}") -set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") +string(APPEND CMAKE_STATIC_LINKER_FLAGS " /ignore:4221") if(CMAKE_CL_64) - set(PLATFORM_LINKFLAGS "/MACHINE:X64 ${PLATFORM_LINKFLAGS}") + string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:X64 ") else() - set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}") + string(PREPEND PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ") endif() if(NOT DEFINED LIBDIR) diff --git a/build_files/cmake/platform/platform_win32_bundle_crt.cmake b/build_files/cmake/platform/platform_win32_bundle_crt.cmake index 29ecb8d5afa..f5bc024e4e0 100644 --- a/build_files/cmake/platform/platform_win32_bundle_crt.cmake +++ b/build_files/cmake/platform/platform_win32_bundle_crt.cmake @@ -31,7 +31,7 @@ if(WITH_WINDOWS_BUNDLE_CRT) foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS}) get_filename_component(filename ${lib} NAME) file(SHA1 "${lib}" sha1_file) - set(CRTLIBS "${CRTLIBS} <file name=\"${filename}\" hash=\"${sha1_file}\" hashalg=\"SHA1\" />\n") + string(APPEND CRTLIBS " <file name=\"${filename}\" hash=\"${sha1_file}\" hashalg=\"SHA1\" />\n") endforeach() configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.crt.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/blender.crt.manifest @ONLY) file(TOUCH ${manifest_trigger_file}) diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index 6e4a087fa36..ca545eec4ca 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = Blender # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "V2.91" +PROJECT_NUMBER = "V2.92" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt index 2c63d76296c..6138795f241 100644 --- a/extern/bullet2/CMakeLists.txt +++ b/extern/bullet2/CMakeLists.txt @@ -423,7 +423,7 @@ set(LIB if(CMAKE_COMPILER_IS_GNUCXX) # needed for gcc 4.6+ - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") + string(APPEND CMAKE_CXX_FLAGS " -fpermissive") endif() if(MSVC) diff --git a/extern/draco/dracoenc/cmake/compiler_flags.cmake b/extern/draco/dracoenc/cmake/compiler_flags.cmake index d842a8ab1f4..bbfb069d2d3 100644 --- a/extern/draco/dracoenc/cmake/compiler_flags.cmake +++ b/extern/draco/dracoenc/cmake/compiler_flags.cmake @@ -23,9 +23,9 @@ macro (add_c_flag_if_supported c_flag) message("Checking C compiler flag support for: " ${c_flag}) check_c_compiler_flag("${c_flag}" C_FLAG_SUPPORTED) if (${C_FLAG_SUPPORTED}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${c_flag}" CACHE STRING "") + string(APPEND CMAKE_C_FLAGS " ${c_flag}" CACHE STRING "") else () - set(DRACO_FAILED_C_FLAGS "${DRACO_FAILED_C_FLAGS} ${c_flag}" CACHE STRING + string(APPEND DRACO_FAILED_C_FLAGS " ${c_flag}" CACHE STRING "" FORCE) endif () endif () @@ -45,9 +45,9 @@ macro (add_cxx_flag_if_supported cxx_flag) message("Checking CXX compiler flag support for: " ${cxx_flag}) check_cxx_compiler_flag("${cxx_flag}" CXX_FLAG_SUPPORTED) if (${CXX_FLAG_SUPPORTED}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${cxx_flag}" CACHE STRING "") + string(APPEND CMAKE_CXX_FLAGS " ${cxx_flag}" CACHE STRING "") else() - set(DRACO_FAILED_CXX_FLAGS "${DRACO_FAILED_CXX_FLAGS} ${cxx_flag}" CACHE + string(APPEND DRACO_FAILED_CXX_FLAGS " ${cxx_flag}" CACHE STRING "" FORCE) endif () endif () @@ -138,7 +138,7 @@ macro (append_as_flag flag) string(FIND "${DRACO_AS_FLAGS}" "${flag}" AS_FLAG_FOUND) if (${AS_FLAG_FOUND} EQUAL -1) - set(DRACO_AS_FLAGS "${DRACO_AS_FLAGS} ${flag}") + string(APPEND DRACO_AS_FLAGS " ${flag}") endif () endmacro () @@ -148,7 +148,7 @@ macro (append_c_flag flag) string(FIND "${CMAKE_C_FLAGS}" "${flag}" C_FLAG_FOUND) if (${C_FLAG_FOUND} EQUAL -1) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}") + string(APPEND CMAKE_C_FLAGS " ${flag}") endif () endmacro () @@ -158,7 +158,7 @@ macro (append_cxx_flag flag) string(FIND "${CMAKE_CXX_FLAGS}" "${flag}" CXX_FLAG_FOUND) if (${CXX_FLAG_FOUND} EQUAL -1) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") + string(APPEND CMAKE_CXX_FLAGS " ${flag}") endif () endmacro () @@ -174,7 +174,7 @@ macro (append_exe_linker_flag flag) string(FIND "${CMAKE_EXE_LINKER_FLAGS}" "${flag}" LINKER_FLAG_FOUND) if (${LINKER_FLAG_FOUND} EQUAL -1) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${flag}") + string(APPEND CMAKE_EXE_LINKER_FLAGS " ${flag}") endif () endmacro () @@ -191,7 +191,7 @@ function (append_link_flag_to_target target flags) return() endif () - set(target_link_flags "${target_link_flags} ${flags}") + string(APPEND target_link_flags " ${flags}") else () set(target_link_flags "${flags}") endif () diff --git a/extern/draco/dracoenc/cmake/compiler_tests.cmake b/extern/draco/dracoenc/cmake/compiler_tests.cmake index e529ba11253..7cc3fbfc67d 100644 --- a/extern/draco/dracoenc/cmake/compiler_tests.cmake +++ b/extern/draco/dracoenc/cmake/compiler_tests.cmake @@ -41,9 +41,9 @@ macro(draco_check_c_compiles test_name test_source result_var) set(${result_var} ${C_TEST_COMPILED}) if (${C_TEST_COMPILED}) - set(DRACO_C_PASSED_TESTS "${DRACO_C_PASSED_TESTS} ${test_name}") + string(APPEND DRACO_C_PASSED_TESTS " ${test_name}") else () - set(DRACO_C_FAILED_TESTS "${DRACO_C_FAILED_TESTS} ${test_name}") + string(APPEND DRACO_C_FAILED_TESTS " ${test_name}") message("C Compiler test ${test_name} failed.") endif () elseif (NOT ${C_TEST_PASSED} EQUAL -1) @@ -71,9 +71,9 @@ macro(draco_check_cxx_compiles test_name test_source result_var) set(${result_var} ${CXX_TEST_COMPILED}) if (${CXX_TEST_COMPILED}) - set(DRACO_CXX_PASSED_TESTS "${DRACO_CXX_PASSED_TESTS} ${test_name}") + string(APPEND DRACO_CXX_PASSED_TESTS " ${test_name}") else () - set(DRACO_CXX_FAILED_TESTS "${DRACO_CXX_FAILED_TESTS} ${test_name}") + string(APPEND DRACO_CXX_FAILED_TESTS " ${test_name}") message("CXX Compiler test ${test_name} failed.") endif () elseif (NOT ${CXX_TEST_PASSED} EQUAL -1) diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt index fe6c72660e0..ee155ee8636 100644 --- a/extern/mantaflow/CMakeLists.txt +++ b/extern/mantaflow/CMakeLists.txt @@ -37,8 +37,8 @@ endif() if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")) if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") + string(APPEND CMAKE_C_FLAGS " -fvisibility=hidden") + string(APPEND CMAKE_CXX_FLAGS " -fvisibility=hidden") endif() endif() diff --git a/extern/mantaflow/preprocessed/plugin/apic.cpp b/extern/mantaflow/preprocessed/plugin/apic.cpp index 6ff893014c9..0312544c56b 100644 --- a/extern/mantaflow/preprocessed/plugin/apic.cpp +++ b/extern/mantaflow/preprocessed/plugin/apic.cpp @@ -6,7 +6,7 @@ // ---------------------------------------------------------------------------- // // MantaFlow fluid solver framework -// Copyright 2016-2017 Kiwon Um, Nils Thuerey +// Copyright 2016-2020 Kiwon Um, Nils Thuerey // // This program is free software, distributed under the terms of the // Apache License, Version 2.0 @@ -21,6 +21,52 @@ namespace Manta { +#define FOR_INT_IJK(num) \ + for (int i = 0; i < num; ++i) \ + for (int j = 0; j < num; ++j) \ + for (int k = 0; k < num; ++k) + +static inline IndexInt indexUFace(const Vec3 &pos, const MACGrid &ref) +{ + const Vec3i f = toVec3i(pos), c = toVec3i(pos - 0.5); + const IndexInt index = f.x * ref.getStrideX() + c.y * ref.getStrideY() + c.z * ref.getStrideZ(); + assertDeb(ref.isInBounds(index), + "U face index out of bounds for particle position [" << pos.x << ", " << pos.y << ", " + << pos.z << "]"); + return (ref.isInBounds(index)) ? index : -1; +} + +static inline IndexInt indexVFace(const Vec3 &pos, const MACGrid &ref) +{ + const Vec3i f = toVec3i(pos), c = toVec3i(pos - 0.5); + const IndexInt index = c.x * ref.getStrideX() + f.y * ref.getStrideY() + c.z * ref.getStrideZ(); + assertDeb(ref.isInBounds(index), + "V face index out of bounds for particle position [" << pos.x << ", " << pos.y << ", " + << pos.z << "]"); + return (ref.isInBounds(index)) ? index : -1; +} + +static inline IndexInt indexWFace(const Vec3 &pos, const MACGrid &ref) +{ + const Vec3i f = toVec3i(pos), c = toVec3i(pos - 0.5); + const IndexInt index = c.x * ref.getStrideX() + c.y * ref.getStrideY() + f.z * ref.getStrideZ(); + assertDeb(ref.isInBounds(index), + "W face index out of bounds for particle position [" << pos.x << ", " << pos.y << ", " + << pos.z << "]"); + return (ref.isInBounds(index)) ? index : -1; +} + +static inline IndexInt indexOffset( + const IndexInt gidx, const int i, const int j, const int k, const MACGrid &ref) +{ + const IndexInt dX[2] = {0, ref.getStrideX()}; + const IndexInt dY[2] = {0, ref.getStrideY()}; + const IndexInt dZ[2] = {0, ref.getStrideZ()}; + const IndexInt index = gidx + dX[i] + dY[j] + dZ[k]; + assertDeb(ref.isInBounds(index), "Offset index " << index << " is out of bounds"); + return (ref.isInBounds(index)) ? index : -1; +} + struct knApicMapLinearVec3ToMACGrid : public KernelBase { knApicMapLinearVec3ToMACGrid(const BasicParticleSystem &p, MACGrid &mg, @@ -30,7 +76,8 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { const ParticleDataImpl<Vec3> &cpy, const ParticleDataImpl<Vec3> &cpz, const ParticleDataImpl<int> *ptype, - const int exclude) + const int exclude, + const int boundaryWidth) : KernelBase(p.size()), p(p), mg(mg), @@ -40,7 +87,8 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { cpy(cpy), cpz(cpz), ptype(ptype), - exclude(exclude) + exclude(exclude), + boundaryWidth(boundaryWidth) { runMessage(); run(); @@ -54,73 +102,91 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { const ParticleDataImpl<Vec3> &cpy, const ParticleDataImpl<Vec3> &cpz, const ParticleDataImpl<int> *ptype, - const int exclude) + const int exclude, + const int boundaryWidth) { if (!p.isActive(idx) || (ptype && ((*ptype)[idx] & exclude))) return; - const IndexInt dX[2] = {0, vg.getStrideX()}; - const IndexInt dY[2] = {0, vg.getStrideY()}; - const IndexInt dZ[2] = {0, vg.getStrideZ()}; - - const Vec3 &pos = p[idx].pos, &vel = vp[idx]; - const IndexInt fi = static_cast<IndexInt>(pos.x), fj = static_cast<IndexInt>(pos.y), - fk = static_cast<IndexInt>(pos.z); - const IndexInt ci = static_cast<IndexInt>(pos.x - 0.5), - cj = static_cast<IndexInt>(pos.y - 0.5), - ck = static_cast<IndexInt>(pos.z - 0.5); - const Real wfi = clamp(pos.x - fi, Real(0), Real(1)), - wfj = clamp(pos.y - fj, Real(0), Real(1)), - wfk = clamp(pos.z - fk, Real(0), Real(1)); - const Real wci = clamp(Real(pos.x - ci - 0.5), Real(0), Real(1)), - wcj = clamp(Real(pos.y - cj - 0.5), Real(0), Real(1)), - wck = clamp(Real(pos.z - ck - 0.5), Real(0), Real(1)); - // TODO: check index for safety + if (!vg.isInBounds(p.getPos(idx), boundaryWidth)) { + debMsg("Skipping particle at index " << idx + << ". Is out of bounds and cannot be applied to grid.", + 1); + return; + } + + const Vec3 &pos = p.getPos(idx), &vel = vp[idx]; + const Vec3i f = toVec3i(pos); + const Vec3i c = toVec3i(pos - 0.5); + const Vec3 wf = clamp(pos - toVec3(f), Vec3(0.), Vec3(1.)); + const Vec3 wc = clamp(pos - toVec3(c) - 0.5, Vec3(0.), Vec3(1.)); + { // u-face - const IndexInt gidx = fi * dX[1] + cj * dY[1] + ck * dZ[1]; - const Vec3 gpos(fi, cj + 0.5, ck + 0.5); - const Real wi[2] = {Real(1) - wfi, wfi}; - const Real wj[2] = {Real(1) - wcj, wcj}; - const Real wk[2] = {Real(1) - wck, wck}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const Real w = wi[i] * wj[j] * wk[k]; - mg[gidx + dX[i] + dY[j] + dZ[k]].x += w; - vg[gidx + dX[i] + dY[j] + dZ[k]].x += w * vel.x; - vg[gidx + dX[i] + dY[j] + dZ[k]].x += w * dot(cpx[idx], gpos + Vec3(i, j, k) - pos); - } + const IndexInt gidx = indexUFace(pos, vg); + if (gidx < 0) + return; // debug will fail before + + const Vec3 gpos(f.x, c.y + 0.5, c.z + 0.5); + const Real wi[2] = {Real(1) - wf.x, wf.x}; + const Real wj[2] = {Real(1) - wc.y, wc.y}; + const Real wk[2] = {Real(1) - wc.z, wc.z}; + + FOR_INT_IJK(2) + { + const Real w = wi[i] * wj[j] * wk[k]; + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; // debug will fail before + + mg[vidx].x += w; + vg[vidx].x += w * vel.x; + vg[vidx].x += w * dot(cpx[idx], gpos + Vec3(i, j, k) - pos); + } } { // v-face - const IndexInt gidx = ci * dX[1] + fj * dY[1] + ck * dZ[1]; - const Vec3 gpos(ci + 0.5, fj, ck + 0.5); - const Real wi[2] = {Real(1) - wci, wci}; - const Real wj[2] = {Real(1) - wfj, wfj}; - const Real wk[2] = {Real(1) - wck, wck}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const Real w = wi[i] * wj[j] * wk[k]; - mg[gidx + dX[i] + dY[j] + dZ[k]].y += w; - vg[gidx + dX[i] + dY[j] + dZ[k]].y += w * vel.y; - vg[gidx + dX[i] + dY[j] + dZ[k]].y += w * dot(cpy[idx], gpos + Vec3(i, j, k) - pos); - } + const IndexInt gidx = indexVFace(pos, vg); + if (gidx < 0) + return; + + const Vec3 gpos(c.x + 0.5, f.y, c.z + 0.5); + const Real wi[2] = {Real(1) - wc.x, wc.x}; + const Real wj[2] = {Real(1) - wf.y, wf.y}; + const Real wk[2] = {Real(1) - wc.z, wc.z}; + + FOR_INT_IJK(2) + { + const Real w = wi[i] * wj[j] * wk[k]; + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; + + mg[vidx].y += w; + vg[vidx].y += w * vel.y; + vg[vidx].y += w * dot(cpy[idx], gpos + Vec3(i, j, k) - pos); + } } if (!vg.is3D()) return; { // w-face - const IndexInt gidx = ci * dX[1] + cj * dY[1] + fk * dZ[1]; - const Vec3 gpos(ci + 0.5, cj + 0.5, fk); - const Real wi[2] = {Real(1) - wci, wci}; - const Real wj[2] = {Real(1) - wcj, wcj}; - const Real wk[2] = {Real(1) - wfk, wfk}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const Real w = wi[i] * wj[j] * wk[k]; - mg[gidx + dX[i] + dY[j] + dZ[k]].z += w; - vg[gidx + dX[i] + dY[j] + dZ[k]].z += w * vel.z; - vg[gidx + dX[i] + dY[j] + dZ[k]].z += w * dot(cpz[idx], gpos + Vec3(i, j, k) - pos); - } + const IndexInt gidx = indexWFace(pos, vg); + if (gidx < 0) + return; + + const Vec3 gpos(c.x + 0.5, c.y + 0.5, f.z); + const Real wi[2] = {Real(1) - wc.x, wc.x}; + const Real wj[2] = {Real(1) - wc.y, wc.y}; + const Real wk[2] = {Real(1) - wf.z, wf.z}; + + FOR_INT_IJK(2) + { + const Real w = wi[i] * wj[j] * wk[k]; + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; + + mg[vidx].z += w; + vg[vidx].z += w * vel.z; + vg[vidx].z += w * dot(cpz[idx], gpos + Vec3(i, j, k) - pos); + } } } inline const BasicParticleSystem &getArg0() @@ -168,6 +234,11 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { return exclude; } typedef int type8; + inline const int &getArg9() + { + return boundaryWidth; + } + typedef int type9; void runMessage() { debMsg("Executing kernel knApicMapLinearVec3ToMACGrid ", 3); @@ -179,7 +250,7 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { { const IndexInt _sz = size; for (IndexInt i = 0; i < _sz; i++) - op(i, p, mg, vg, vp, cpx, cpy, cpz, ptype, exclude); + op(i, p, mg, vg, vp, cpx, cpy, cpz, ptype, exclude, boundaryWidth); } const BasicParticleSystem &p; MACGrid &mg; @@ -190,6 +261,7 @@ struct knApicMapLinearVec3ToMACGrid : public KernelBase { const ParticleDataImpl<Vec3> &cpz; const ParticleDataImpl<int> *ptype; const int exclude; + const int boundaryWidth; }; void apicMapPartsToMAC(const FlagGrid &flags, @@ -201,23 +273,22 @@ void apicMapPartsToMAC(const FlagGrid &flags, const ParticleDataImpl<Vec3> &cpz, MACGrid *mass = NULL, const ParticleDataImpl<int> *ptype = NULL, - const int exclude = 0) + const int exclude = 0, + const int boundaryWidth = 0) { - // affine map - // let's assume that the particle mass is constant, 1.0 - const bool freeMass = !mass; - if (!mass) - mass = new MACGrid(flags.getParent()); - else - mass->clear(); + // affine map: let's assume that the particle mass is constant, 1.0 + MACGrid tmpmass(vel.getParent()); + tmpmass.clear(); vel.clear(); - knApicMapLinearVec3ToMACGrid(parts, *mass, vel, partVel, cpx, cpy, cpz, ptype, exclude); - mass->stomp(VECTOR_EPSILON); - vel.safeDivide(*mass); - if (freeMass) - delete mass; + knApicMapLinearVec3ToMACGrid( + parts, tmpmass, vel, partVel, cpx, cpy, cpz, ptype, exclude, boundaryWidth); + tmpmass.stomp(VECTOR_EPSILON); + vel.safeDivide(tmpmass); + + if (mass) + (*mass).swap(tmpmass); } static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { @@ -241,8 +312,10 @@ static PyObject *_W_0(PyObject *_self, PyObject *_linargs, PyObject *_kwds) const ParticleDataImpl<int> *ptype = _args.getPtrOpt<ParticleDataImpl<int>>( "ptype", 8, NULL, &_lock); const int exclude = _args.getOpt<int>("exclude", 9, 0, &_lock); + const int boundaryWidth = _args.getOpt<int>("boundaryWidth", 10, 0, &_lock); _retval = getPyNone(); - apicMapPartsToMAC(flags, vel, parts, partVel, cpx, cpy, cpz, mass, ptype, exclude); + apicMapPartsToMAC( + flags, vel, parts, partVel, cpx, cpy, cpz, mass, ptype, exclude, boundaryWidth); _args.check(); } pbFinalizePlugin(parent, "apicMapPartsToMAC", !noTiming); @@ -270,7 +343,8 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { const MACGrid &vg, const FlagGrid &flags, const ParticleDataImpl<int> *ptype, - const int exclude) + const int exclude, + const int boundaryWidth) : KernelBase(vp.size()), vp(vp), cpx(cpx), @@ -280,7 +354,8 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { vg(vg), flags(flags), ptype(ptype), - exclude(exclude) + exclude(exclude), + boundaryWidth(boundaryWidth) { runMessage(); run(); @@ -294,78 +369,94 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { const MACGrid &vg, const FlagGrid &flags, const ParticleDataImpl<int> *ptype, - const int exclude) const + const int exclude, + const int boundaryWidth) const { if (!p.isActive(idx) || (ptype && ((*ptype)[idx] & exclude))) return; + if (!vg.isInBounds(p.getPos(idx), boundaryWidth)) { + debMsg("Skipping particle at index " << idx + << ". Is out of bounds and cannot get value from grid.", + 1); + return; + } vp[idx] = cpx[idx] = cpy[idx] = cpz[idx] = Vec3(Real(0)); - const IndexInt dX[2] = {0, vg.getStrideX()}, dY[2] = {0, vg.getStrideY()}, - dZ[2] = {0, vg.getStrideZ()}; const Real gw[2] = {-Real(1), Real(1)}; - const Vec3 &pos = p[idx].pos; - const IndexInt fi = static_cast<IndexInt>(pos.x), fj = static_cast<IndexInt>(pos.y), - fk = static_cast<IndexInt>(pos.z); - const IndexInt ci = static_cast<IndexInt>(pos.x - 0.5), - cj = static_cast<IndexInt>(pos.y - 0.5), - ck = static_cast<IndexInt>(pos.z - 0.5); - const Real wfi = clamp(pos.x - fi, Real(0), Real(1)), - wfj = clamp(pos.y - fj, Real(0), Real(1)), - wfk = clamp(pos.z - fk, Real(0), Real(1)); - const Real wci = clamp(Real(pos.x - ci - 0.5), Real(0), Real(1)), - wcj = clamp(Real(pos.y - cj - 0.5), Real(0), Real(1)), - wck = clamp(Real(pos.z - ck - 0.5), Real(0), Real(1)); - // TODO: check index for safety - { // u - const IndexInt gidx = fi * dX[1] + cj * dY[1] + ck * dZ[1]; - const Real wx[2] = {Real(1) - wfi, wfi}; - const Real wy[2] = {Real(1) - wcj, wcj}; - const Real wz[2] = {Real(1) - wck, wck}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const IndexInt vidx = gidx + dX[i] + dY[j] + dZ[k]; - Real vgx = vg[vidx].x; - vp[idx].x += wx[i] * wy[j] * wz[k] * vgx; - cpx[idx].x += gw[i] * wy[j] * wz[k] * vgx; - cpx[idx].y += wx[i] * gw[j] * wz[k] * vgx; - cpx[idx].z += wx[i] * wy[j] * gw[k] * vgx; - } + const Vec3 &pos = p.getPos(idx); + const Vec3i f = toVec3i(pos); + const Vec3i c = toVec3i(pos - 0.5); + const Vec3 wf = clamp(pos - toVec3(f), Vec3(0.), Vec3(1.)); + const Vec3 wc = clamp(pos - toVec3(c) - 0.5, Vec3(0.), Vec3(1.)); + + { // u-face + const IndexInt gidx = indexUFace(pos, vg); + if (gidx < 0) + return; // debug will fail before + + const Real wx[2] = {Real(1) - wf.x, wf.x}; + const Real wy[2] = {Real(1) - wc.y, wc.y}; + const Real wz[2] = {Real(1) - wc.z, wc.z}; + + FOR_INT_IJK(2) + { + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; // debug will fail before + + const Real vgx = vg[vidx].x; + vp[idx].x += wx[i] * wy[j] * wz[k] * vgx; + cpx[idx].x += gw[i] * wy[j] * wz[k] * vgx; + cpx[idx].y += wx[i] * gw[j] * wz[k] * vgx; + cpx[idx].z += wx[i] * wy[j] * gw[k] * vgx; + } } - { // v - const IndexInt gidx = ci * dX[1] + fj * dY[1] + ck * dZ[1]; - const Real wx[2] = {Real(1) - wci, wci}; - const Real wy[2] = {Real(1) - wfj, wfj}; - const Real wz[2] = {Real(1) - wck, wck}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const IndexInt vidx = gidx + dX[i] + dY[j] + dZ[k]; - Real vgy = vg[vidx].y; - vp[idx].y += wx[i] * wy[j] * wz[k] * vgy; - cpy[idx].x += gw[i] * wy[j] * wz[k] * vgy; - cpy[idx].y += wx[i] * gw[j] * wz[k] * vgy; - cpy[idx].z += wx[i] * wy[j] * gw[k] * vgy; - } + { // v-face + const IndexInt gidx = indexVFace(pos, vg); + if (gidx < 0) + return; + + const Real wx[2] = {Real(1) - wc.x, wc.x}; + const Real wy[2] = {Real(1) - wf.y, wf.y}; + const Real wz[2] = {Real(1) - wc.z, wc.z}; + + FOR_INT_IJK(2) + { + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; + + const Real vgy = vg[vidx].y; + vp[idx].y += wx[i] * wy[j] * wz[k] * vgy; + cpy[idx].x += gw[i] * wy[j] * wz[k] * vgy; + cpy[idx].y += wx[i] * gw[j] * wz[k] * vgy; + cpy[idx].z += wx[i] * wy[j] * gw[k] * vgy; + } } if (!vg.is3D()) return; - { // w - const IndexInt gidx = ci * dX[1] + cj * dY[1] + fk * dZ[1]; - const Real wx[2] = {Real(1) - wci, wci}; - const Real wy[2] = {Real(1) - wcj, wcj}; - const Real wz[2] = {Real(1) - wfk, wfk}; - for (int i = 0; i < 2; ++i) - for (int j = 0; j < 2; ++j) - for (int k = 0; k < 2; ++k) { - const IndexInt vidx = gidx + dX[i] + dY[j] + dZ[k]; - Real vgz = vg[vidx].z; - vp[idx].z += wx[i] * wy[j] * wz[k] * vgz; - cpz[idx].x += gw[i] * wy[j] * wz[k] * vgz; - cpz[idx].y += wx[i] * gw[j] * wz[k] * vgz; - cpz[idx].z += wx[i] * wy[j] * gw[k] * vgz; - } + { // w-face + const IndexInt gidx = indexWFace(pos, vg); + if (gidx < 0) + return; + + const Real wx[2] = {Real(1) - wc.x, wc.x}; + const Real wy[2] = {Real(1) - wc.y, wc.y}; + const Real wz[2] = {Real(1) - wf.z, wf.z}; + + FOR_INT_IJK(2) + { + const IndexInt vidx = indexOffset(gidx, i, j, k, vg); + if (vidx < 0) + continue; + + const Real vgz = vg[vidx].z; + vp[idx].z += wx[i] * wy[j] * wz[k] * vgz; + cpz[idx].x += gw[i] * wy[j] * wz[k] * vgz; + cpz[idx].y += wx[i] * gw[j] * wz[k] * vgz; + cpz[idx].z += wx[i] * wy[j] * gw[k] * vgz; + } } } inline ParticleDataImpl<Vec3> &getArg0() @@ -413,6 +504,11 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { return exclude; } typedef int type8; + inline const int &getArg9() + { + return boundaryWidth; + } + typedef int type9; void runMessage() { debMsg("Executing kernel knApicMapLinearMACGridToVec3 ", 3); @@ -423,7 +519,7 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { void operator()(const tbb::blocked_range<IndexInt> &__r) const { for (IndexInt idx = __r.begin(); idx != (IndexInt)__r.end(); idx++) - op(idx, vp, cpx, cpy, cpz, p, vg, flags, ptype, exclude); + op(idx, vp, cpx, cpy, cpz, p, vg, flags, ptype, exclude, boundaryWidth); } void run() { @@ -438,6 +534,7 @@ struct knApicMapLinearMACGridToVec3 : public KernelBase { const FlagGrid &flags; const ParticleDataImpl<int> *ptype; const int exclude; + const int boundaryWidth; }; void apicMapMACGridToParts(ParticleDataImpl<Vec3> &partVel, @@ -448,9 +545,11 @@ void apicMapMACGridToParts(ParticleDataImpl<Vec3> &partVel, const MACGrid &vel, const FlagGrid &flags, const ParticleDataImpl<int> *ptype = NULL, - const int exclude = 0) + const int exclude = 0, + const int boundaryWidth = 0) { - knApicMapLinearMACGridToVec3(partVel, cpx, cpy, cpz, parts, vel, flags, ptype, exclude); + knApicMapLinearMACGridToVec3( + partVel, cpx, cpy, cpz, parts, vel, flags, ptype, exclude, boundaryWidth); } static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds) { @@ -473,8 +572,10 @@ static PyObject *_W_1(PyObject *_self, PyObject *_linargs, PyObject *_kwds) const ParticleDataImpl<int> *ptype = _args.getPtrOpt<ParticleDataImpl<int>>( "ptype", 7, NULL, &_lock); const int exclude = _args.getOpt<int>("exclude", 8, 0, &_lock); + const int boundaryWidth = _args.getOpt<int>("boundaryWidth", 9, 0, &_lock); _retval = getPyNone(); - apicMapMACGridToParts(partVel, cpx, cpy, cpz, parts, vel, flags, ptype, exclude); + apicMapMACGridToParts( + partVel, cpx, cpy, cpz, parts, vel, flags, ptype, exclude, boundaryWidth); _args.check(); } pbFinalizePlugin(parent, "apicMapMACGridToParts", !noTiming); diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 9d5b5a2d1a6..b1bb1d3654d 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -45,7 +45,7 @@ if(WITH_CYCLES_NATIVE_ONLY) ) if(NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native") + string(APPEND CMAKE_CXX_FLAGS " -march=native") set(CYCLES_KERNEL_FLAGS "-march=native") else() if(NOT MSVC_NATIVE_ARCH_FLAGS) @@ -101,10 +101,10 @@ elseif(WIN32 AND MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox") - set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox") + string(APPEND CMAKE_CXX_FLAGS " ${CYCLES_KERNEL_FLAGS}") + string(APPEND CMAKE_CXX_FLAGS_RELEASE " /Ox") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " /Ox") + string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " /Ox") elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) check_cxx_compiler_flag(-msse CXX_HAS_SSE) check_cxx_compiler_flag(-mavx CXX_HAS_AVX) @@ -113,20 +113,20 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) # Assume no signal trapping for better code generation. set(CYCLES_KERNEL_FLAGS "-fno-trapping-math") # Avoid overhead of setting errno for NaNs. - set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-math-errno") + string(APPEND CYCLES_KERNEL_FLAGS " -fno-math-errno") # Let compiler optimize 0.0 - x without worrying about signed zeros. - set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signed-zeros") + string(APPEND CYCLES_KERNEL_FLAGS " -fno-signed-zeros") if(CMAKE_COMPILER_IS_GNUCC) # Assume no signal trapping for better code generation. - set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-signaling-nans") + string(APPEND CYCLES_KERNEL_FLAGS " -fno-signaling-nans") # Assume a fixed rounding mode for better constant folding. - set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -fno-rounding-math") + string(APPEND CYCLES_KERNEL_FLAGS " -fno-rounding-math") endif() if(CXX_HAS_SSE) if(CMAKE_COMPILER_IS_GNUCC) - set(CYCLES_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -mfpmath=sse") + string(APPEND CYCLES_KERNEL_FLAGS " -mfpmath=sse") endif() set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -msse -msse2") @@ -140,7 +140,7 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) endif() endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CYCLES_KERNEL_FLAGS}") + string(APPEND CMAKE_CXX_FLAGS " ${CYCLES_KERNEL_FLAGS}") elseif(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Intel") check_cxx_compiler_flag(/QxSSE2 CXX_HAS_SSE) check_cxx_compiler_flag(/arch:AVX CXX_HAS_AVX) diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt index 0d805dc8683..2d48563d8a6 100644 --- a/intern/cycles/blender/CMakeLists.txt +++ b/intern/cycles/blender/CMakeLists.txt @@ -130,7 +130,7 @@ blender_add_lib(bf_intern_cycles "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # avoid link failure with clang 3.4 debug if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND NOT ${CMAKE_C_COMPILER_VERSION} VERSION_LESS '3.4') - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -gline-tables-only") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -gline-tables-only") endif() add_dependencies(bf_intern_cycles bf_rna) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 72d98e78c4d..6b88be3e7aa 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -1271,7 +1271,7 @@ class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel): layout.prop(ob, "hide_select", text="Selectable", invert_checkbox=True, toggle=False) - col = layout.column(heading="Show in") + col = layout.column(heading="Show In") col.prop(ob, "hide_viewport", text="Viewports", invert_checkbox=True, toggle=False) col.prop(ob, "hide_render", text="Renders", invert_checkbox=True, toggle=False) diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index e1ab3b3fbc1..c1da9f1983f 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -388,18 +388,19 @@ static void blender_camera_sync(Camera *cam, const char *viewname, PointerRNA *cscene) { - /* copy camera to compare later */ - Camera prevcam = *cam; float aspectratio, sensor_size; /* viewplane */ - blender_camera_viewplane(bcam, width, height, &cam->viewplane, &aspectratio, &sensor_size); + BoundBox2D viewplane; + blender_camera_viewplane(bcam, width, height, &viewplane, &aspectratio, &sensor_size); - cam->width = bcam->full_width; - cam->height = bcam->full_height; + cam->set_viewplane_left(viewplane.left); + cam->set_viewplane_right(viewplane.right); + cam->set_viewplane_top(viewplane.top); + cam->set_viewplane_bottom(viewplane.bottom); - cam->full_width = width; - cam->full_height = height; + cam->set_full_width(width); + cam->set_full_height(height); /* panorama sensor */ if (bcam->type == CAMERA_PANORAMA && bcam->panorama_type == PANORAMA_FISHEYE_EQUISOLID) { @@ -422,85 +423,91 @@ static void blender_camera_sync(Camera *cam, } if (horizontal_fit) { - cam->sensorwidth = sensor_size; - cam->sensorheight = sensor_size * fit_yratio / fit_xratio; + cam->set_sensorwidth(sensor_size); + cam->set_sensorheight(sensor_size * fit_yratio / fit_xratio); } else { - cam->sensorwidth = sensor_size * fit_xratio / fit_yratio; - cam->sensorheight = sensor_size; + cam->set_sensorwidth(sensor_size * fit_xratio / fit_yratio); + cam->set_sensorheight(sensor_size); } } /* clipping distances */ - cam->nearclip = bcam->nearclip; - cam->farclip = bcam->farclip; + cam->set_nearclip(bcam->nearclip); + cam->set_farclip(bcam->farclip); /* type */ - cam->type = bcam->type; + cam->set_camera_type(bcam->type); /* panorama */ - cam->panorama_type = bcam->panorama_type; - cam->fisheye_fov = bcam->fisheye_fov; - cam->fisheye_lens = bcam->fisheye_lens; - cam->latitude_min = bcam->latitude_min; - cam->latitude_max = bcam->latitude_max; + cam->set_panorama_type(bcam->panorama_type); + cam->set_fisheye_fov(bcam->fisheye_fov); + cam->set_fisheye_lens(bcam->fisheye_lens); + cam->set_latitude_min(bcam->latitude_min); + cam->set_latitude_max(bcam->latitude_max); - cam->longitude_min = bcam->longitude_min; - cam->longitude_max = bcam->longitude_max; + cam->set_longitude_min(bcam->longitude_min); + cam->set_longitude_max(bcam->longitude_max); /* panorama stereo */ - cam->interocular_distance = bcam->interocular_distance; - cam->convergence_distance = bcam->convergence_distance; - cam->use_spherical_stereo = bcam->use_spherical_stereo; + cam->set_interocular_distance(bcam->interocular_distance); + cam->set_convergence_distance(bcam->convergence_distance); + cam->set_use_spherical_stereo(bcam->use_spherical_stereo); - if (cam->use_spherical_stereo) { + if (cam->get_use_spherical_stereo()) { if (strcmp(viewname, "left") == 0) - cam->stereo_eye = Camera::STEREO_LEFT; + cam->set_stereo_eye(Camera::STEREO_LEFT); else if (strcmp(viewname, "right") == 0) - cam->stereo_eye = Camera::STEREO_RIGHT; + cam->set_stereo_eye(Camera::STEREO_RIGHT); else - cam->stereo_eye = Camera::STEREO_NONE; + cam->set_stereo_eye(Camera::STEREO_NONE); } - cam->use_pole_merge = bcam->use_pole_merge; - cam->pole_merge_angle_from = bcam->pole_merge_angle_from; - cam->pole_merge_angle_to = bcam->pole_merge_angle_to; + cam->set_use_pole_merge(bcam->use_pole_merge); + cam->set_pole_merge_angle_from(bcam->pole_merge_angle_from); + cam->set_pole_merge_angle_to(bcam->pole_merge_angle_to); /* anamorphic lens bokeh */ - cam->aperture_ratio = bcam->aperture_ratio; + cam->set_aperture_ratio(bcam->aperture_ratio); /* perspective */ - cam->fov = 2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio); - cam->focaldistance = bcam->focaldistance; - cam->aperturesize = bcam->aperturesize; - cam->blades = bcam->apertureblades; - cam->bladesrotation = bcam->aperturerotation; + cam->set_fov(2.0f * atanf((0.5f * sensor_size) / bcam->lens / aspectratio)); + cam->set_focaldistance(bcam->focaldistance); + cam->set_aperturesize(bcam->aperturesize); + cam->set_blades(bcam->apertureblades); + cam->set_bladesrotation(bcam->aperturerotation); /* transform */ - cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type); - cam->motion.clear(); - cam->motion.resize(bcam->motion_steps, cam->matrix); - cam->use_perspective_motion = false; - cam->shuttertime = bcam->shuttertime; - cam->fov_pre = cam->fov; - cam->fov_post = cam->fov; - cam->motion_position = bcam->motion_position; + cam->set_matrix(blender_camera_matrix(bcam->matrix, bcam->type, bcam->panorama_type)); - cam->rolling_shutter_type = bcam->rolling_shutter_type; - cam->rolling_shutter_duration = bcam->rolling_shutter_duration; + array<Transform> motion; + motion.resize(bcam->motion_steps, cam->get_matrix()); + cam->set_motion(motion); + cam->set_use_perspective_motion(false); - cam->shutter_curve = bcam->shutter_curve; + cam->set_shuttertime(bcam->shuttertime); + cam->set_fov_pre(cam->get_fov()); + cam->set_fov_post(cam->get_fov()); + cam->set_motion_position(bcam->motion_position); + + cam->set_rolling_shutter_type(bcam->rolling_shutter_type); + cam->set_rolling_shutter_duration(bcam->rolling_shutter_duration); + + cam->set_shutter_curve(bcam->shutter_curve); /* border */ - cam->border = bcam->border; - cam->viewport_camera_border = bcam->viewport_camera_border; + cam->set_border_left(bcam->border.left); + cam->set_border_right(bcam->border.right); + cam->set_border_top(bcam->border.top); + cam->set_border_bottom(bcam->border.bottom); - bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale"); - cam->offscreen_dicing_scale = bcam->offscreen_dicing_scale; + cam->set_viewport_camera_border_left(bcam->viewport_camera_border.left); + cam->set_viewport_camera_border_right(bcam->viewport_camera_border.right); + cam->set_viewport_camera_border_top(bcam->viewport_camera_border.top); + cam->set_viewport_camera_border_bottom(bcam->viewport_camera_border.bottom); - /* set update flag */ - if (cam->modified(prevcam)) - cam->tag_update(); + bcam->offscreen_dicing_scale = RNA_float_get(cscene, "offscreen_dicing_scale"); + cam->set_offscreen_dicing_scale(bcam->offscreen_dicing_scale); } /* Sync Render Camera */ @@ -582,22 +589,24 @@ void BlenderSync::sync_camera_motion( Camera *cam = scene->camera; BL::Array<float, 16> b_ob_matrix; - b_engine.camera_model_matrix(b_ob, cam->use_spherical_stereo, b_ob_matrix); + b_engine.camera_model_matrix(b_ob, cam->get_use_spherical_stereo(), b_ob_matrix); Transform tfm = get_transform(b_ob_matrix); - tfm = blender_camera_matrix(tfm, cam->type, cam->panorama_type); + tfm = blender_camera_matrix(tfm, cam->get_camera_type(), cam->get_panorama_type()); if (motion_time == 0.0f) { /* When motion blur is not centered in frame, cam->matrix gets reset. */ - cam->matrix = tfm; + cam->set_matrix(tfm); } /* Set transform in motion array. */ int motion_step = cam->motion_step(motion_time); if (motion_step >= 0) { - cam->motion[motion_step] = tfm; + array<Transform> motion = cam->get_motion(); + motion[motion_step] = tfm; + cam->set_motion(motion); } - if (cam->type == CAMERA_PERSPECTIVE) { + if (cam->get_camera_type() == CAMERA_PERSPECTIVE) { BlenderCamera bcam; float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); @@ -610,18 +619,18 @@ void BlenderSync::sync_camera_motion( blender_camera_viewplane(&bcam, width, height, NULL, &aspectratio, &sensor_size); /* TODO(sergey): De-duplicate calculation with camera sync. */ float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio); - if (fov != cam->fov) { + if (fov != cam->get_fov()) { VLOG(1) << "Camera " << b_ob.name() << " FOV change detected."; if (motion_time == 0.0f) { - cam->fov = fov; + cam->set_fov(fov); } else if (motion_time == -1.0f) { - cam->fov_pre = fov; - cam->use_perspective_motion = true; + cam->set_fov_pre(fov); + cam->set_use_perspective_motion(true); } else if (motion_time == 1.0f) { - cam->fov_post = fov; - cam->use_perspective_motion = true; + cam->set_fov_post(fov); + cam->set_use_perspective_motion(true); } } } diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index 6288c370567..8344684ac64 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -77,7 +77,7 @@ static bool ObtainCacheParticleData( if ((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) { - int shader = clamp(b_part.material() - 1, 0, hair->used_shaders.size() - 1); + int shader = clamp(b_part.material() - 1, 0, hair->get_used_shaders().size() - 1); int display_step = background ? b_part.render_step() : b_part.display_step(); int totparts = b_psys.particles.length(); int totchild = background ? b_psys.child_particles.length() : @@ -307,7 +307,7 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa VLOG(1) << "Exporting curve segments for mesh " << hair->name; } - hair->reserve_curves(hair->num_curves() + num_curves, hair->curve_keys.size() + num_keys); + hair->reserve_curves(hair->num_curves() + num_curves, hair->get_curve_keys().size() + num_keys); num_keys = 0; num_curves = 0; @@ -350,9 +350,9 @@ static void ExportCurveSegments(Scene *scene, Hair *hair, ParticleCurveData *CDa } /* check allocation */ - if ((hair->curve_keys.size() != num_keys) || (hair->num_curves() != num_curves)) { + if ((hair->get_curve_keys().size() != num_keys) || (hair->num_curves() != num_curves)) { VLOG(1) << "Allocation failed, clearing data"; - hair->clear(); + hair->clear(true); } } @@ -402,7 +402,7 @@ static void export_hair_motion_validate_attribute(Hair *hair, bool have_motion) { Attribute *attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - const int num_keys = hair->curve_keys.size(); + const int num_keys = hair->get_curve_keys().size(); if (num_motion_keys != num_keys || !have_motion) { /* No motion or hair "topology" changed, remove attributes again. */ @@ -423,8 +423,8 @@ static void export_hair_motion_validate_attribute(Hair *hair, float4 *mP = attr_mP->data_float4() + step * num_keys; for (int key = 0; key < num_keys; key++) { - mP[key] = float3_to_float4(hair->curve_keys[key]); - mP[key].w = hair->curve_radius[key]; + mP[key] = float3_to_float4(hair->get_curve_keys()[key]); + mP[key].w = hair->get_curve_radius()[key]; } } } @@ -447,7 +447,7 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int } /* export motion vectors for curve keys */ - size_t numkeys = hair->curve_keys.size(); + size_t numkeys = hair->get_curve_keys().size(); float4 *mP = attr_mP->data_float4() + motion_step * numkeys; bool have_motion = false; int i = 0; @@ -458,24 +458,24 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int curve < CData->psys_firstcurve[sys] + CData->psys_curvenum[sys]; curve++) { /* Curve lengths may not match! Curves can be clipped. */ - int curve_key_end = (num_curves + 1 < (int)hair->curve_first_key.size() ? - hair->curve_first_key[num_curves + 1] : - (int)hair->curve_keys.size()); - const int num_center_curve_keys = curve_key_end - hair->curve_first_key[num_curves]; + int curve_key_end = (num_curves + 1 < (int)hair->get_curve_first_key().size() ? + hair->get_curve_first_key()[num_curves + 1] : + (int)hair->get_curve_keys().size()); + const int num_center_curve_keys = curve_key_end - hair->get_curve_first_key()[num_curves]; const int is_num_keys_different = CData->curve_keynum[curve] - num_center_curve_keys; if (!is_num_keys_different) { for (int curvekey = CData->curve_firstkey[curve]; curvekey < CData->curve_firstkey[curve] + CData->curve_keynum[curve]; curvekey++) { - if (i < hair->curve_keys.size()) { + if (i < hair->get_curve_keys().size()) { mP[i] = CurveSegmentMotionCV(CData, sys, curve, curvekey); if (!have_motion) { /* unlike mesh coordinates, these tend to be slightly different * between frames due to particle transforms into/out of object * space, so we use an epsilon to detect actual changes */ - float4 curve_key = float3_to_float4(hair->curve_keys[i]); - curve_key.w = hair->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]); + curve_key.w = hair->get_curve_radius()[i]; if (len_squared(mP[i] - curve_key) > 1e-5f * 1e-5f) have_motion = true; } @@ -560,7 +560,7 @@ void BlenderSync::sync_particle_hair( float3 *generated = attr_generated->data_float3(); for (size_t i = 0; i < hair->num_curves(); i++) { - float3 co = hair->curve_keys[hair->get_curve(i).first_key]; + float3 co = hair->get_curve_keys()[hair->get_curve(i).first_key]; generated[i] = co * size - loc; } } @@ -742,7 +742,7 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st } /* Export motion keys. */ - const int num_keys = hair->curve_keys.size(); + const int num_keys = hair->get_curve_keys().size(); float4 *mP = attr_mP->data_float4() + motion_step * num_keys; bool have_motion = false; int num_motion_keys = 0; @@ -769,8 +769,8 @@ static void export_hair_curves_motion(Hair *hair, BL::Hair b_hair, int motion_st if (!have_motion) { /* TODO: use epsilon for comparison? Was needed for particles due to * transform, but ideally should not happen anymore. */ - float4 curve_key = float3_to_float4(hair->curve_keys[i]); - curve_key.w = hair->curve_radius[i]; + float4 curve_key = float3_to_float4(hair->get_curve_keys()[i]); + curve_key.w = hair->get_curve_radius()[i]; have_motion = !(mP[i] == curve_key); } } @@ -817,42 +817,53 @@ void BlenderSync::sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motio } #endif -void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, - BL::Object b_ob, - Hair *hair, - const vector<Shader *> &used_shaders) +void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair) { - /* Compares curve_keys rather than strands in order to handle quick hair - * adjustments in dynamic BVH - other methods could probably do this better. */ - array<float3> oldcurve_keys; - array<float> oldcurve_radius; - oldcurve_keys.steal_data(hair->curve_keys); - oldcurve_radius.steal_data(hair->curve_radius); + /* make a copy of the shaders as the caller in the main thread still need them for syncing the + * attributes */ + array<Node *> used_shaders = hair->get_used_shaders(); - hair->clear(); - hair->used_shaders = used_shaders; + Hair new_hair; + new_hair.set_used_shaders(used_shaders); if (view_layer.use_hair) { if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ - sync_hair(hair, b_ob, false); + sync_hair(&new_hair, b_ob, false); } else { /* Particle hair. */ - bool need_undeformed = hair->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = new_hair.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( b_data, b_ob, b_depsgraph, need_undeformed, Mesh::SUBDIVISION_NONE); if (b_mesh) { - sync_particle_hair(hair, b_mesh, b_ob, false); + sync_particle_hair(&new_hair, b_mesh, b_ob, false); free_object_to_mesh(b_data, b_ob, b_mesh); } } } + /* update original sockets */ + + for (const SocketType &socket : new_hair.type->inputs) { + /* Those sockets are updated in sync_object, so do not modify them. */ + if (socket.name == "use_motion_blur" || socket.name == "motion_steps" || + socket.name == "used_shaders") { + continue; + } + hair->set_value(socket, new_hair, socket); + } + + foreach (Attribute &attr, new_hair.attributes.attributes) { + hair->attributes.attributes.push_back(std::move(attr)); + } + /* tag update */ - const bool rebuild = ((oldcurve_keys != hair->curve_keys) || - (oldcurve_radius != hair->curve_radius)); + + /* Compares curve_keys rather than strands in order to handle quick hair + * adjustments in dynamic BVH - other methods could probably do this better. */ + const bool rebuild = (hair->curve_keys_is_modified() || hair->curve_radius_is_modified()); hair->tag_update(scene, rebuild); } diff --git a/intern/cycles/blender/blender_device.cpp b/intern/cycles/blender/blender_device.cpp index 0293223864d..ffcaef0b2a9 100644 --- a/intern/cycles/blender/blender_device.cpp +++ b/intern/cycles/blender/blender_device.cpp @@ -47,8 +47,7 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen vector<DeviceInfo> devices = Device::available_devices(BlenderSession::device_override); if (devices.empty()) { - printf("Found no Cycles device of the specified type, falling back to CPU...\n"); - return Device::available_devices(DEVICE_MASK_CPU).front(); + return Device::dummy_device("Found no Cycles device of the specified type"); } int threads = blender_device_threads(b_scene); diff --git a/intern/cycles/blender/blender_geometry.cpp b/intern/cycles/blender/blender_geometry.cpp index a665bd97a8d..bd2f0731030 100644 --- a/intern/cycles/blender/blender_geometry.cpp +++ b/intern/cycles/blender/blender_geometry.cpp @@ -25,6 +25,7 @@ #include "blender/blender_util.h" #include "util/util_foreach.h" +#include "util/util_task.h" CCL_NAMESPACE_BEGIN @@ -45,7 +46,8 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool use_particle_hair) + bool use_particle_hair, + TaskPool *task_pool) { /* Test if we can instance or if the object is modified. */ BL::ID b_ob_data = b_ob.data(); @@ -57,7 +59,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, GeometryKey key(b_key_id.ptr.data, geom_type); /* Find shader indices. */ - vector<Shader *> used_shaders; + array<Node *> used_shaders; BL::Object::material_slots_iterator slot; for (b_ob.material_slots.begin(slot); slot != b_ob.material_slots.end(); ++slot) { @@ -74,11 +76,18 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, if (material_override) find_shader(material_override, used_shaders, default_shader); else - used_shaders.push_back(default_shader); + used_shaders.push_back_slow(default_shader); } - /* Test if we need to sync. */ + /* Ensure we only sync instanced geometry once. */ Geometry *geom = geometry_map.find(key); + if (geom) { + if (geometry_synced.find(geom) != geometry_synced.end()) { + return geom; + } + } + + /* Test if we need to sync. */ bool sync = true; if (geom == NULL) { /* Add new geometry if it did not exist yet. */ @@ -105,7 +114,7 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } /* Test if shaders changed, these can be object level so geometry * does not get tagged for recalc. */ - else if (geom->used_shaders != used_shaders) { + else if (geom->get_used_shaders() != used_shaders) { ; } else { @@ -113,7 +122,8 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, * because the shader needs different geometry attributes. */ bool attribute_recalc = false; - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->need_update_geometry) { attribute_recalc = true; } @@ -125,28 +135,39 @@ Geometry *BlenderSync::sync_geometry(BL::Depsgraph &b_depsgraph, } } - /* Ensure we only sync instanced geometry once. */ - if (geometry_synced.find(geom) != geometry_synced.end()) { - return geom; - } - - progress.set_sync_status("Synchronizing object", b_ob.name()); - geometry_synced.insert(geom); geom->name = ustring(b_ob_data.name().c_str()); - if (geom_type == Geometry::HAIR) { - Hair *hair = static_cast<Hair *>(geom); - sync_hair(b_depsgraph, b_ob, hair, used_shaders); - } - else if (geom_type == Geometry::VOLUME) { - Volume *volume = static_cast<Volume *>(geom); - sync_volume(b_ob, volume, used_shaders); + /* Store the shaders immediately for the object attribute code. */ + geom->set_used_shaders(used_shaders); + + auto sync_func = [=]() mutable { + if (progress.get_cancel()) + return; + + progress.set_sync_status("Synchronizing object", b_ob.name()); + + if (geom_type == Geometry::HAIR) { + Hair *hair = static_cast<Hair *>(geom); + sync_hair(b_depsgraph, b_ob, hair); + } + else if (geom_type == Geometry::VOLUME) { + Volume *volume = static_cast<Volume *>(geom); + sync_volume(b_ob, volume); + } + else { + Mesh *mesh = static_cast<Mesh *>(geom); + sync_mesh(b_depsgraph, b_ob, mesh); + } + }; + + /* Defer the actual geometry sync to the task_pool for multithreading */ + if (task_pool) { + task_pool->push(sync_func); } else { - Mesh *mesh = static_cast<Mesh *>(geom); - sync_mesh(b_depsgraph, b_ob, mesh, used_shaders); + sync_func(); } return geom; @@ -156,10 +177,11 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, Object *object, float motion_time, - bool use_particle_hair) + bool use_particle_hair, + TaskPool *task_pool) { /* Ensure we only sync instanced geometry once. */ - Geometry *geom = object->geometry; + Geometry *geom = object->get_geometry(); if (geometry_motion_synced.find(geom) != geometry_motion_synced.end()) return; @@ -177,16 +199,29 @@ void BlenderSync::sync_geometry_motion(BL::Depsgraph &b_depsgraph, return; } - if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { - Hair *hair = static_cast<Hair *>(geom); - sync_hair_motion(b_depsgraph, b_ob, hair, motion_step); - } - else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { - /* No volume motion blur support yet. */ + auto sync_func = [=]() mutable { + if (progress.get_cancel()) + return; + + if (b_ob.type() == BL::Object::type_HAIR || use_particle_hair) { + Hair *hair = static_cast<Hair *>(geom); + sync_hair_motion(b_depsgraph, b_ob, hair, motion_step); + } + else if (b_ob.type() == BL::Object::type_VOLUME || object_fluid_gas_domain_find(b_ob)) { + /* No volume motion blur support yet. */ + } + else { + Mesh *mesh = static_cast<Mesh *>(geom); + sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); + } + }; + + /* Defer the actual geometry sync to the task_pool for multithreading */ + if (task_pool) { + task_pool->push(sync_func); } else { - Mesh *mesh = static_cast<Mesh *>(geom); - sync_mesh_motion(b_depsgraph, b_ob, mesh, motion_step); + sync_func(); } } diff --git a/intern/cycles/blender/blender_light.cpp b/intern/cycles/blender/blender_light.cpp index 6f95821e31e..ff4ecc5a3f9 100644 --- a/intern/cycles/blender/blender_light.cpp +++ b/intern/cycles/blender/blender_light.cpp @@ -42,7 +42,7 @@ void BlenderSync::sync_light(BL::Object &b_parent, if (!light_map.add_or_update(&light, b_ob, b_parent, key)) { Shader *shader; if (!shader_map.add_or_update(&shader, b_light)) { - if (light->is_portal) + if (light->get_is_portal()) *use_portal = true; return; } @@ -52,16 +52,16 @@ void BlenderSync::sync_light(BL::Object &b_parent, switch (b_light.type()) { case BL::Light::type_POINT: { BL::PointLight b_point_light(b_light); - light->size = b_point_light.shadow_soft_size(); - light->type = LIGHT_POINT; + light->set_size(b_point_light.shadow_soft_size()); + light->set_light_type(LIGHT_POINT); break; } case BL::Light::type_SPOT: { BL::SpotLight b_spot_light(b_light); - light->size = b_spot_light.shadow_soft_size(); - light->type = LIGHT_SPOT; - light->spot_angle = b_spot_light.spot_size(); - light->spot_smooth = b_spot_light.spot_blend(); + light->set_size(b_spot_light.shadow_soft_size()); + light->set_light_type(LIGHT_SPOT); + light->set_spot_angle(b_spot_light.spot_size()); + light->set_spot_smooth(b_spot_light.spot_blend()); break; } /* Hemi were removed from 2.8 */ @@ -72,88 +72,88 @@ void BlenderSync::sync_light(BL::Object &b_parent, // } case BL::Light::type_SUN: { BL::SunLight b_sun_light(b_light); - light->angle = b_sun_light.angle(); - light->type = LIGHT_DISTANT; + light->set_angle(b_sun_light.angle()); + light->set_light_type(LIGHT_DISTANT); break; } case BL::Light::type_AREA: { BL::AreaLight b_area_light(b_light); - light->size = 1.0f; - light->axisu = transform_get_column(&tfm, 0); - light->axisv = transform_get_column(&tfm, 1); - light->sizeu = b_area_light.size(); + light->set_size(1.0f); + light->set_axisu(transform_get_column(&tfm, 0)); + light->set_axisv(transform_get_column(&tfm, 1)); + light->set_sizeu(b_area_light.size()); switch (b_area_light.shape()) { case BL::AreaLight::shape_SQUARE: - light->sizev = light->sizeu; - light->round = false; + light->set_sizev(light->get_sizeu()); + light->set_round(false); break; case BL::AreaLight::shape_RECTANGLE: - light->sizev = b_area_light.size_y(); - light->round = false; + light->set_sizev(b_area_light.size_y()); + light->set_round(false); break; case BL::AreaLight::shape_DISK: - light->sizev = light->sizeu; - light->round = true; + light->set_sizev(light->get_sizeu()); + light->set_round(true); break; case BL::AreaLight::shape_ELLIPSE: - light->sizev = b_area_light.size_y(); - light->round = true; + light->set_sizev(b_area_light.size_y()); + light->set_round(true); break; } - light->type = LIGHT_AREA; + light->set_light_type(LIGHT_AREA); break; } } /* strength */ - light->strength = get_float3(b_light.color()); - light->strength *= BL::PointLight(b_light).energy(); + float3 strength = get_float3(b_light.color()) * BL::PointLight(b_light).energy(); + light->set_strength(strength); /* location and (inverted!) direction */ - light->co = transform_get_column(&tfm, 3); - light->dir = -transform_get_column(&tfm, 2); - light->tfm = tfm; + light->set_co(transform_get_column(&tfm, 3)); + light->set_dir(-transform_get_column(&tfm, 2)); + light->set_tfm(tfm); /* shader */ - vector<Shader *> used_shaders; + array<Node *> used_shaders; find_shader(b_light, used_shaders, scene->default_light); - light->shader = used_shaders[0]; + light->set_shader(static_cast<Shader *>(used_shaders[0])); /* shadow */ PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); PointerRNA clight = RNA_pointer_get(&b_light.ptr, "cycles"); - light->cast_shadow = get_boolean(clight, "cast_shadow"); - light->use_mis = get_boolean(clight, "use_multiple_importance_sampling"); + light->set_cast_shadow(get_boolean(clight, "cast_shadow")); + light->set_use_mis(get_boolean(clight, "use_multiple_importance_sampling")); int samples = get_int(clight, "samples"); if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; + light->set_samples(samples * samples); else - light->samples = samples; + light->set_samples(samples); - light->max_bounces = get_int(clight, "max_bounces"); + light->set_max_bounces(get_int(clight, "max_bounces")); if (b_ob != b_ob_instance) { - light->random_id = random_id; + light->set_random_id(random_id); } else { - light->random_id = hash_uint2(hash_string(b_ob.name().c_str()), 0); + light->set_random_id(hash_uint2(hash_string(b_ob.name().c_str()), 0)); } - if (light->type == LIGHT_AREA) - light->is_portal = get_boolean(clight, "is_portal"); + if (light->get_light_type() == LIGHT_AREA) + light->set_is_portal(get_boolean(clight, "is_portal")); else - light->is_portal = false; + light->set_is_portal(false); - if (light->is_portal) + if (light->get_is_portal()) *use_portal = true; /* visibility */ uint visibility = object_ray_visibility(b_ob); - light->use_diffuse = (visibility & PATH_RAY_DIFFUSE) != 0; - light->use_glossy = (visibility & PATH_RAY_GLOSSY) != 0; - light->use_transmission = (visibility & PATH_RAY_TRANSMIT) != 0; - light->use_scatter = (visibility & PATH_RAY_VOLUME_SCATTER) != 0; + light->set_use_diffuse((visibility & PATH_RAY_DIFFUSE) != 0); + light->set_use_glossy((visibility & PATH_RAY_GLOSSY) != 0); + light->set_use_transmission((visibility & PATH_RAY_TRANSMIT) != 0); + light->set_use_scatter((visibility & PATH_RAY_VOLUME_SCATTER) != 0); /* tag */ light->tag_update(scene); @@ -178,25 +178,25 @@ void BlenderSync::sync_background_light(BL::SpaceView3D &b_v3d, bool use_portal) if (light_map.add_or_update(&light, b_world, b_world, key) || world_recalc || b_world.ptr.data != world_map) { - light->type = LIGHT_BACKGROUND; + light->set_light_type(LIGHT_BACKGROUND); if (sampling_method == SAMPLING_MANUAL) { - light->map_resolution = get_int(cworld, "sample_map_resolution"); + light->set_map_resolution(get_int(cworld, "sample_map_resolution")); } else { - light->map_resolution = 0; + light->set_map_resolution(0); } - light->shader = scene->default_background; - light->use_mis = sample_as_light; - light->max_bounces = get_int(cworld, "max_bounces"); + light->set_shader(scene->default_background); + light->set_use_mis(sample_as_light); + light->set_max_bounces(get_int(cworld, "max_bounces")); /* force enable light again when world is resynced */ - light->is_enabled = true; + light->set_is_enabled(true); int samples = get_int(cworld, "samples"); if (get_boolean(cscene, "use_square_samples")) - light->samples = samples * samples; + light->set_samples(samples * samples); else - light->samples = samples; + light->set_samples(samples); light->tag_update(scene); light_map.set_recalc(b_world); diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index e40e1f5f001..20637af96df 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -48,8 +48,8 @@ struct MikkUserData { float *tangent_sign) : mesh(mesh), texface(NULL), orco(NULL), tangent(tangent), tangent_sign(tangent_sign) { - const AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : - mesh->attributes; + const AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : + mesh->attributes; Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL); vertex_normal = attr_vN->data_float3(); @@ -85,8 +85,8 @@ struct MikkUserData { static int mikk_get_num_faces(const SMikkTSpaceContext *context) { const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; - if (userdata->mesh->subd_faces.size()) { - return userdata->mesh->subd_faces.size(); + if (userdata->mesh->get_num_subd_faces()) { + return userdata->mesh->get_num_subd_faces(); } else { return userdata->mesh->num_triangles(); @@ -96,9 +96,9 @@ static int mikk_get_num_faces(const SMikkTSpaceContext *context) static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num) { const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; - if (userdata->mesh->subd_faces.size()) { + if (userdata->mesh->get_num_subd_faces()) { const Mesh *mesh = userdata->mesh; - return mesh->subd_faces[face_num].num_corners; + return mesh->get_subd_num_corners()[face_num]; } else { return 3; @@ -107,19 +107,19 @@ static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const i static int mikk_vertex_index(const Mesh *mesh, const int face_num, const int vert_num) { - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; - return mesh->subd_face_corners[face.start_corner + vert_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); + return mesh->get_subd_face_corners()[face.start_corner + vert_num]; } else { - return mesh->triangles[face_num * 3 + vert_num]; + return mesh->get_triangles()[face_num * 3 + vert_num]; } } static int mikk_corner_index(const Mesh *mesh, const int face_num, const int vert_num) { - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); return face.start_corner + vert_num; } else { @@ -135,7 +135,7 @@ static void mikk_get_position(const SMikkTSpaceContext *context, const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; const Mesh *mesh = userdata->mesh; const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); - const float3 vP = mesh->verts[vertex_index]; + const float3 vP = mesh->get_verts()[vertex_index]; P[0] = vP.x; P[1] = vP.y; P[2] = vP.z; @@ -178,8 +178,8 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, const MikkUserData *userdata = (const MikkUserData *)context->m_pUserData; const Mesh *mesh = userdata->mesh; float3 vN; - if (mesh->subd_faces.size()) { - const Mesh::SubdFace &face = mesh->subd_faces[face_num]; + if (mesh->get_num_subd_faces()) { + const Mesh::SubdFace &face = mesh->get_subd_face(face_num); if (face.smooth) { const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); vN = userdata->vertex_normal[vertex_index]; @@ -189,13 +189,13 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, } } else { - if (mesh->smooth[face_num]) { + if (mesh->get_smooth()[face_num]) { const int vertex_index = mikk_vertex_index(mesh, face_num, vert_num); vN = userdata->vertex_normal[vertex_index]; } else { const Mesh::Triangle tri = mesh->get_triangle(face_num); - vN = tri.compute_normal(&mesh->verts[0]); + vN = tri.compute_normal(&mesh->get_verts()[0]); } } N[0] = vN.x; @@ -222,7 +222,8 @@ static void mikk_compute_tangents( const BL::Mesh &b_mesh, const char *layer_name, Mesh *mesh, bool need_sign, bool active_render) { /* Create tangent attributes. */ - AttributeSet &attributes = (mesh->subd_faces.size()) ? mesh->subd_attributes : mesh->attributes; + AttributeSet &attributes = (mesh->get_num_subd_faces()) ? mesh->subd_attributes : + mesh->attributes; Attribute *attr; ustring name; if (layer_name != NULL) { @@ -554,7 +555,7 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b for (int vert_index = 0; vert_index < num_verts; ++vert_index) { sorted_vert_indeices[vert_index] = vert_index; } - VertexAverageComparator compare(mesh->verts); + VertexAverageComparator compare(mesh->get_verts()); sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare); /* This array stores index of the original vertex for the given vertex * index. @@ -562,12 +563,12 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b vector<int> vert_orig_index(num_verts); for (int sorted_vert_index = 0; sorted_vert_index < num_verts; ++sorted_vert_index) { const int vert_index = sorted_vert_indeices[sorted_vert_index]; - const float3 &vert_co = mesh->verts[vert_index]; + const float3 &vert_co = mesh->get_verts()[vert_index]; bool found = false; for (int other_sorted_vert_index = sorted_vert_index + 1; other_sorted_vert_index < num_verts; ++other_sorted_vert_index) { const int other_vert_index = sorted_vert_indeices[other_sorted_vert_index]; - const float3 &other_vert_co = mesh->verts[other_vert_index]; + const float3 &other_vert_co = mesh->get_verts()[other_vert_index]; /* We are too far away now, we wouldn't have duplicate. */ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) - (vert_co.x + vert_co.y + vert_co.z) > @@ -732,7 +733,7 @@ static void attr_create_random_per_island(Scene *scene, static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, - const vector<Shader *> &used_shaders, + const array<Node *> &used_shaders, bool subdivision = false, bool subdivide_uvs = true) { @@ -743,7 +744,7 @@ static void create_mesh(Scene *scene, int numcorners = 0; int numngons = 0; bool use_loop_normals = b_mesh.use_auto_smooth() && - (mesh->subdivision_type != Mesh::SUBDIVISION_CATMULL_CLARK); + (mesh->get_subdivision_type() != Mesh::SUBDIVISION_CATMULL_CLARK); /* If no faces, create empty mesh. */ if (numfaces == 0) { @@ -762,8 +763,11 @@ static void create_mesh(Scene *scene, } /* allocate memory */ + if (subdivision) { + mesh->reserve_subd_faces(numfaces, numngons, numcorners); + } + mesh->reserve_mesh(numverts, numtris); - mesh->reserve_subd_faces(numfaces, numngons, numcorners); /* create vertex coordinates and normals */ BL::Mesh::vertices_iterator v; @@ -875,7 +879,7 @@ static void create_subd_mesh(Scene *scene, Mesh *mesh, BL::Object &b_ob, BL::Mesh &b_mesh, - const vector<Shader *> &used_shaders, + const array<Node *> &used_shaders, float dicing_rate, int max_subdivisions) { @@ -894,31 +898,21 @@ static void create_subd_mesh(Scene *scene, } } - mesh->subd_creases.resize(num_creases); + mesh->reserve_subd_creases(num_creases); - Mesh::SubdEdgeCrease *crease = mesh->subd_creases.data(); for (b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e) { if (e->crease() != 0.0f) { - crease->v[0] = e->vertices()[0]; - crease->v[1] = e->vertices()[1]; - crease->crease = e->crease(); - - crease++; + mesh->add_crease(e->vertices()[0], e->vertices()[1], e->crease()); } } /* set subd params */ - if (!mesh->subd_params) { - mesh->subd_params = new SubdParams(mesh); - } - SubdParams &sdparams = *mesh->subd_params; - PointerRNA cobj = RNA_pointer_get(&b_ob.ptr, "cycles"); + float subd_dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate); - sdparams.dicing_rate = max(0.1f, RNA_float_get(&cobj, "dicing_rate") * dicing_rate); - sdparams.max_level = max_subdivisions; - - sdparams.objecttoworld = get_transform(b_ob.matrix_world()); + mesh->set_subd_dicing_rate(subd_dicing_rate); + mesh->set_subd_max_level(max_subdivisions); + mesh->set_subd_objecttoworld(get_transform(b_ob.matrix_world())); } /* Sync */ @@ -955,14 +949,14 @@ static void sync_mesh_cached_velocities(BL::Object &b_ob, Scene *scene, Mesh *me return; } - const size_t numverts = mesh->verts.size(); + const size_t numverts = mesh->get_verts().size(); if (b_mesh_cache.vertex_velocities.length() != numverts) { return; } /* Find or add attribute */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (!attr_mP) { @@ -996,11 +990,11 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) return; /* If the mesh has modifiers following the fluid domain we can't export motion. */ - if (b_fluid_domain.mesh_vertices.length() != mesh->verts.size()) + if (b_fluid_domain.mesh_vertices.length() != mesh->get_verts().size()) return; /* Find or add attribute */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; Attribute *attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (!attr_mP) { @@ -1011,7 +1005,7 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) float motion_times[2] = {-1.0f, 1.0f}; for (int step = 0; step < 2; step++) { float relative_time = motion_times[step] * scene->motion_shutter_time() * 0.5f; - float3 *mP = attr_mP->data_float3() + step * mesh->verts.size(); + float3 *mP = attr_mP->data_float3() + step * mesh->get_verts().size(); BL::FluidDomainSettings::mesh_vertices_iterator svi; int i = 0; @@ -1023,56 +1017,77 @@ static void sync_mesh_fluid_motion(BL::Object &b_ob, Scene *scene, Mesh *mesh) } } -void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, - BL::Object b_ob, - Mesh *mesh, - const vector<Shader *> &used_shaders) +void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh) { - array<int> oldtriangles; - array<Mesh::SubdFace> oldsubd_faces; - array<int> oldsubd_face_corners; - oldtriangles.steal_data(mesh->triangles); - oldsubd_faces.steal_data(mesh->subd_faces); - oldsubd_face_corners.steal_data(mesh->subd_face_corners); + /* make a copy of the shaders as the caller in the main thread still need them for syncing the + * attributes */ + array<Node *> used_shaders = mesh->get_used_shaders(); - mesh->clear(); - mesh->used_shaders = used_shaders; - - mesh->subdivision_type = Mesh::SUBDIVISION_NONE; + Mesh new_mesh; + new_mesh.set_used_shaders(used_shaders); if (view_layer.use_surfaces) { /* Adaptive subdivision setup. Not for baking since that requires * exact mapping to the Blender mesh. */ if (!scene->bake_manager->get_baking()) { - mesh->subdivision_type = object_subdivision_type(b_ob, preview, experimental); + new_mesh.set_subdivision_type(object_subdivision_type(b_ob, preview, experimental)); } /* For some reason, meshes do not need this... */ - bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); BL::Mesh b_mesh = object_to_mesh( - b_data, b_ob, b_depsgraph, need_undeformed, mesh->subdivision_type); + b_data, b_ob, b_depsgraph, need_undeformed, new_mesh.get_subdivision_type()); if (b_mesh) { /* Sync mesh itself. */ - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) - create_subd_mesh( - scene, mesh, b_ob, b_mesh, mesh->used_shaders, dicing_rate, max_subdivisions); + if (new_mesh.get_subdivision_type() != Mesh::SUBDIVISION_NONE) + create_subd_mesh(scene, + &new_mesh, + b_ob, + b_mesh, + new_mesh.get_used_shaders(), + dicing_rate, + max_subdivisions); else - create_mesh(scene, mesh, b_mesh, mesh->used_shaders, false); + create_mesh(scene, &new_mesh, b_mesh, new_mesh.get_used_shaders(), false); free_object_to_mesh(b_data, b_ob, b_mesh); } } /* cached velocities (e.g. from alembic archive) */ - sync_mesh_cached_velocities(b_ob, scene, mesh); + sync_mesh_cached_velocities(b_ob, scene, &new_mesh); /* mesh fluid motion mantaflow */ - sync_mesh_fluid_motion(b_ob, scene, mesh); + sync_mesh_fluid_motion(b_ob, scene, &new_mesh); + + /* update original sockets */ + + for (const SocketType &socket : new_mesh.type->inputs) { + /* Those sockets are updated in sync_object, so do not modify them. */ + if (socket.name == "use_motion_blur" || socket.name == "motion_steps" || + socket.name == "used_shaders") { + continue; + } + mesh->set_value(socket, new_mesh, socket); + } + + foreach (Attribute &attr, new_mesh.attributes.attributes) { + mesh->attributes.attributes.push_back(std::move(attr)); + } + + foreach (Attribute &attr, new_mesh.subd_attributes.attributes) { + mesh->subd_attributes.attributes.push_back(std::move(attr)); + } + + mesh->set_num_subd_faces(new_mesh.get_num_subd_faces()); /* tag update */ - bool rebuild = (oldtriangles != mesh->triangles) || (oldsubd_faces != mesh->subd_faces) || - (oldsubd_face_corners != mesh->subd_face_corners); + bool rebuild = (mesh->triangles_is_modified()) || (mesh->subd_num_corners_is_modified()) || + (mesh->subd_shader_is_modified()) || (mesh->subd_smooth_is_modified()) || + (mesh->subd_ptex_offset_is_modified()) || + (mesh->subd_start_corner_is_modified()) || + (mesh->subd_face_corners_is_modified()); mesh->tag_update(scene, rebuild); } @@ -1095,7 +1110,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, } /* Skip if no vertices were exported. */ - size_t numverts = mesh->verts.size(); + size_t numverts = mesh->get_verts().size(); if (numverts == 0) { return; } @@ -1140,7 +1155,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, if (new_attribute) { /* In case of new attribute, we verify if there really was any motion. */ if (b_mesh.vertices.length() != numverts || - memcmp(mP, &mesh->verts[0], sizeof(float3) * numverts) == 0) { + memcmp(mP, &mesh->get_verts()[0], sizeof(float3) * numverts) == 0) { /* no motion, remove attributes again */ if (b_mesh.vertices.length() != numverts) { VLOG(1) << "Topology differs, disabling motion blur for object " << b_ob.name(); @@ -1156,7 +1171,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, VLOG(1) << "Filling deformation motion for object " << b_ob.name(); /* motion, fill up previous steps that we might have skipped because * they had no motion, but we need them anyway now */ - float3 *P = &mesh->verts[0]; + float3 *P = &mesh->get_verts()[0]; float3 *N = (attr_N) ? attr_N->data_float3() : NULL; for (int step = 0; step < motion_step; step++) { memcpy(attr_mP->data_float3() + step * numverts, P, sizeof(float3) * numverts); @@ -1169,7 +1184,7 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, if (b_mesh.vertices.length() != numverts) { VLOG(1) << "Topology differs, discarding motion blur for object " << b_ob.name() << " at time " << motion_step; - memcpy(mP, &mesh->verts[0], sizeof(float3) * numverts); + memcpy(mP, &mesh->get_verts()[0], sizeof(float3) * numverts); if (mN != NULL) { memcpy(mN, attr_N->data_float3(), sizeof(float3) * numverts); } diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 4146d87ad2e..4a70cbbf41f 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -32,6 +32,7 @@ #include "util/util_foreach.h" #include "util/util_hash.h" #include "util/util_logging.h" +#include "util/util_task.h" CCL_NAMESPACE_BEGIN @@ -103,7 +104,8 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, - bool *use_portal) + bool *use_portal, + TaskPool *geom_task_pool) { const bool is_instance = b_instance.is_instance(); BL::Object b_ob = b_instance.object(); @@ -181,6 +183,10 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, return NULL; } + /* Use task pool only for non-instances, since sync_dupli_particle accesses + * geometry. This restriction should be removed for better performance. */ + TaskPool *object_geom_task_pool = (is_instance) ? NULL : geom_task_pool; + /* key to lookup object */ ObjectKey key(b_parent, persistent_id, b_ob_instance, use_particle_hair); Object *object; @@ -193,12 +199,19 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* Set transform at matching motion time step. */ int time_index = object->motion_step(motion_time); if (time_index >= 0) { - object->motion[time_index] = tfm; + array<Transform> motion = object->get_motion(); + motion[time_index] = tfm; + object->set_motion(motion); } /* mesh deformation */ - if (object->geometry) - sync_geometry_motion(b_depsgraph, b_ob, object, motion_time, use_particle_hair); + if (object->get_geometry()) + sync_geometry_motion(b_depsgraph, + b_ob_instance, + object, + motion_time, + use_particle_hair, + object_geom_task_pool); } return object; @@ -211,34 +224,36 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, object_updated = true; /* mesh sync */ - object->geometry = sync_geometry( - b_depsgraph, b_ob, b_ob_instance, object_updated, use_particle_hair); + /* b_ob is owned by the iterator and will go out of scope at the end of the block. + * b_ob_instance is the original object and will remain valid for deferred geometry + * sync. */ + Geometry *geometry = sync_geometry(b_depsgraph, + b_ob_instance, + b_ob_instance, + object_updated, + use_particle_hair, + object_geom_task_pool); + object->set_geometry(geometry); /* special case not tracked by object update flags */ - /* holdout */ - if (use_holdout != object->use_holdout) { - object->use_holdout = use_holdout; - scene->object_manager->tag_update(scene); + if (sync_object_attributes(b_instance, object)) { object_updated = true; } - if (visibility != object->visibility) { - object->visibility = visibility; - object_updated = true; + /* holdout */ + object->set_use_holdout(use_holdout); + if (object->use_holdout_is_modified()) { + scene->object_manager->tag_update(scene); } + object->set_visibility(visibility); + bool is_shadow_catcher = get_boolean(cobject, "is_shadow_catcher"); - if (is_shadow_catcher != object->is_shadow_catcher) { - object->is_shadow_catcher = is_shadow_catcher; - object_updated = true; - } + object->set_is_shadow_catcher(is_shadow_catcher); float shadow_terminator_offset = get_float(cobject, "shadow_terminator_offset"); - if (shadow_terminator_offset != object->shadow_terminator_offset) { - object->shadow_terminator_offset = shadow_terminator_offset; - object_updated = true; - } + object->set_shadow_terminator_offset(shadow_terminator_offset); /* sync the asset name for Cryptomatte */ BL::Object parent = b_ob.parent(); @@ -252,48 +267,49 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, else { parent_name = b_ob.name(); } - if (object->asset_name != parent_name) { - object->asset_name = parent_name; - object_updated = true; - } + object->set_asset_name(parent_name); /* object sync * transform comparison should not be needed, but duplis don't work perfect * in the depsgraph and may not signal changes, so this is a workaround */ - if (object_updated || (object->geometry && object->geometry->need_update) || - tfm != object->tfm) { + if (object->is_modified() || object_updated || + (object->get_geometry() && object->get_geometry()->is_modified()) || + tfm != object->get_tfm()) { object->name = b_ob.name().c_str(); - object->pass_id = b_ob.pass_index(); - object->color = get_float3(b_ob.color()); - object->tfm = tfm; - object->motion.clear(); + object->set_pass_id(b_ob.pass_index()); + object->set_color(get_float3(b_ob.color())); + object->set_tfm(tfm); + array<Transform> motion; + object->set_motion(motion); /* motion blur */ Scene::MotionType need_motion = scene->need_motion(); - if (need_motion != Scene::MOTION_NONE && object->geometry) { - Geometry *geom = object->geometry; - geom->use_motion_blur = false; - geom->motion_steps = 0; + if (need_motion != Scene::MOTION_NONE && object->get_geometry()) { + Geometry *geom = object->get_geometry(); + geom->set_use_motion_blur(false); + geom->set_motion_steps(0); uint motion_steps; if (need_motion == Scene::MOTION_BLUR) { motion_steps = object_motion_steps(b_parent, b_ob, Object::MAX_MOTION_STEPS); - geom->motion_steps = motion_steps; + geom->set_motion_steps(motion_steps); if (motion_steps && object_use_deform_motion(b_parent, b_ob)) { - geom->use_motion_blur = true; + geom->set_use_motion_blur(true); } } else { motion_steps = 3; - geom->motion_steps = motion_steps; + geom->set_motion_steps(motion_steps); } - object->motion.clear(); - object->motion.resize(motion_steps, transform_empty()); + motion.resize(motion_steps, transform_empty()); if (motion_steps) { - object->motion[motion_steps / 2] = tfm; + motion[motion_steps / 2] = tfm; + + /* update motion socket before trying to access object->motion_time */ + object->set_motion(motion); for (size_t step = 0; step < motion_steps; step++) { motion_times.insert(object->motion_time(step)); @@ -303,15 +319,15 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, /* dupli texture coordinates and random_id */ if (is_instance) { - object->dupli_generated = 0.5f * get_float3(b_instance.orco()) - - make_float3(0.5f, 0.5f, 0.5f); - object->dupli_uv = get_float2(b_instance.uv()); - object->random_id = b_instance.random_id(); + object->set_dupli_generated(0.5f * get_float3(b_instance.orco()) - + make_float3(0.5f, 0.5f, 0.5f)); + object->set_dupli_uv(get_float2(b_instance.uv())); + object->set_random_id(b_instance.random_id()); } else { - object->dupli_generated = make_float3(0.0f, 0.0f, 0.0f); - object->dupli_uv = make_float2(0.0f, 0.0f); - object->random_id = hash_uint2(hash_string(object->name.c_str()), 0); + object->set_dupli_generated(make_float3(0.0f, 0.0f, 0.0f)); + object->set_dupli_uv(make_float2(0.0f, 0.0f)); + object->set_random_id(hash_uint2(hash_string(object->name.c_str()), 0)); } object->tag_update(scene); @@ -325,12 +341,141 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, return object; } +/* This function mirrors drw_uniform_property_lookup in draw_instance_data.cpp */ +static bool lookup_property(BL::ID b_id, const string &name, float4 *r_value) +{ + PointerRNA ptr; + PropertyRNA *prop; + + if (!RNA_path_resolve(&b_id.ptr, name.c_str(), &ptr, &prop)) { + return false; + } + + PropertyType type = RNA_property_type(prop); + int arraylen = RNA_property_array_length(&ptr, prop); + + if (arraylen == 0) { + float value; + + if (type == PROP_FLOAT) + value = RNA_property_float_get(&ptr, prop); + else if (type == PROP_INT) + value = RNA_property_int_get(&ptr, prop); + else + return false; + + *r_value = make_float4(value, value, value, 1.0f); + return true; + } + else if (type == PROP_FLOAT && arraylen <= 4) { + *r_value = make_float4(0.0f, 0.0f, 0.0f, 1.0f); + RNA_property_float_get_array(&ptr, prop, &r_value->x); + return true; + } + + return false; +} + +/* This function mirrors drw_uniform_attribute_lookup in draw_instance_data.cpp */ +static float4 lookup_instance_property(BL::DepsgraphObjectInstance &b_instance, + const string &name, + bool use_instancer) +{ + string idprop_name = string_printf("[\"%s\"]", name.c_str()); + float4 value; + + /* If requesting instance data, check the parent particle system and object. */ + if (use_instancer && b_instance.is_instance()) { + BL::ParticleSystem b_psys = b_instance.particle_system(); + + if (b_psys) { + if (lookup_property(b_psys.settings(), idprop_name, &value) || + lookup_property(b_psys.settings(), name, &value)) { + return value; + } + } + if (lookup_property(b_instance.parent(), idprop_name, &value) || + lookup_property(b_instance.parent(), name, &value)) { + return value; + } + } + + /* Check the object and mesh. */ + BL::Object b_ob = b_instance.object(); + BL::ID b_data = b_ob.data(); + + if (lookup_property(b_ob, idprop_name, &value) || lookup_property(b_ob, name, &value) || + lookup_property(b_data, idprop_name, &value) || lookup_property(b_data, name, &value)) { + return value; + } + + return make_float4(0.0f); +} + +bool BlenderSync::sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object) +{ + /* Find which attributes are needed. */ + AttributeRequestSet requests = object->get_geometry()->needed_attributes(); + + /* Delete attributes that became unnecessary. */ + vector<ParamValue> &attributes = object->attributes; + bool changed = false; + + for (int i = attributes.size() - 1; i >= 0; i--) { + if (!requests.find(attributes[i].name())) { + attributes.erase(attributes.begin() + i); + changed = true; + } + } + + /* Update attribute values. */ + foreach (AttributeRequest &req, requests.requests) { + ustring name = req.name; + + std::string real_name; + BlenderAttributeType type = blender_attribute_name_split_type(name, &real_name); + + if (type != BL::ShaderNodeAttribute::attribute_type_GEOMETRY) { + bool use_instancer = (type == BL::ShaderNodeAttribute::attribute_type_INSTANCER); + float4 value = lookup_instance_property(b_instance, real_name, use_instancer); + + /* Try finding the existing attribute value. */ + ParamValue *param = NULL; + + for (size_t i = 0; i < attributes.size(); i++) { + if (attributes[i].name() == name) { + param = &attributes[i]; + break; + } + } + + /* Replace or add the value. */ + ParamValue new_param(name, TypeDesc::TypeFloat4, 1, &value); + assert(new_param.datasize() == sizeof(value)); + + if (!param) { + changed = true; + attributes.push_back(new_param); + } + else if (memcmp(param->data(), &value, sizeof(value)) != 0) { + changed = true; + *param = new_param; + } + } + } + + return changed; +} + /* Object Loop */ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, float motion_time) { + /* Task pool for multithreaded geometry sync. */ + TaskPool geom_task_pool; + /* layer data */ bool motion = motion_time != 0.0f; @@ -355,8 +500,8 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, const bool show_lights = BlenderViewportParameters(b_v3d).use_scene_lights; BL::ViewLayer b_view_layer = b_depsgraph.view_layer_eval(); - BL::Depsgraph::object_instances_iterator b_instance_iter; + for (b_depsgraph.object_instances.begin(b_instance_iter); b_instance_iter != b_depsgraph.object_instances.end() && !cancel; ++b_instance_iter) { @@ -372,6 +517,11 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, /* Load per-object culling data. */ culling.init_object(scene, b_ob); + /* Ensure the object geom supporting the hair is processed before adding + * the hair processing task to the task pool, calling .to_mesh() on the + * same object in parallel does not work. */ + const bool sync_hair = b_instance.show_particles() && object_has_particle_hair(b_ob); + /* Object itself. */ if (b_instance.show_self()) { sync_object(b_depsgraph, @@ -381,11 +531,12 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, false, show_lights, culling, - &use_portal); + &use_portal, + sync_hair ? NULL : &geom_task_pool); } /* Particle hair as separate object. */ - if (b_instance.show_particles() && object_has_particle_hair(b_ob)) { + if (sync_hair) { sync_object(b_depsgraph, b_view_layer, b_instance, @@ -393,12 +544,15 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, true, show_lights, culling, - &use_portal); + &use_portal, + &geom_task_pool); } cancel = progress.get_cancel(); } + geom_task_pool.wait_work(); + progress.set_sync_status(""); if (!cancel && !motion) { @@ -431,20 +585,18 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, if (b_override) b_cam = b_override; - Camera prevcam = *(scene->camera); - int frame_center = b_scene.frame_current(); float subframe_center = b_scene.frame_subframe(); float frame_center_delta = 0.0f; if (scene->need_motion() != Scene::MOTION_PASS && - scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) { - float shuttertime = scene->camera->shuttertime; - if (scene->camera->motion_position == Camera::MOTION_POSITION_END) { + scene->camera->get_motion_position() != Camera::MOTION_POSITION_CENTER) { + float shuttertime = scene->camera->get_shuttertime(); + if (scene->camera->get_motion_position() == Camera::MOTION_POSITION_END) { frame_center_delta = -shuttertime * 0.5f; } else { - assert(scene->camera->motion_position == Camera::MOTION_POSITION_START); + assert(scene->camera->get_motion_position() == Camera::MOTION_POSITION_START); frame_center_delta = shuttertime * 0.5f; } @@ -505,10 +657,6 @@ void BlenderSync::sync_motion(BL::RenderSettings &b_render, python_thread_state_restore(python_thread_state); b_engine.frame_set(frame_center, subframe_center); python_thread_state_save(python_thread_state); - - /* tag camera for motion update */ - if (scene->camera->motion_modified(prevcam)) - scene->camera->tag_update(); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object_cull.cpp b/intern/cycles/blender/blender_object_cull.cpp index bebecb364eb..cb7827b3c4a 100644 --- a/intern/cycles/blender/blender_object_cull.cpp +++ b/intern/cycles/blender/blender_object_cull.cpp @@ -34,10 +34,10 @@ BlenderObjectCulling::BlenderObjectCulling(Scene *scene, BL::Scene &b_scene) if (b_scene.render().use_simplify()) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - use_scene_camera_cull_ = scene->camera->type != CAMERA_PANORAMA && + use_scene_camera_cull_ = scene->camera->get_camera_type() != CAMERA_PANORAMA && !b_scene.render().use_multiview() && get_boolean(cscene, "use_camera_cull"); - use_scene_distance_cull_ = scene->camera->type != CAMERA_PANORAMA && + use_scene_distance_cull_ = scene->camera->get_camera_type() != CAMERA_PANORAMA && !b_scene.render().use_multiview() && get_boolean(cscene, "use_distance_cull"); @@ -123,7 +123,7 @@ bool BlenderObjectCulling::test_camera(Scene *scene, float3 bb[8]) bool BlenderObjectCulling::test_distance(Scene *scene, float3 bb[8]) { - float3 camera_position = transform_get_column(&scene->camera->matrix, 3); + float3 camera_position = transform_get_column(&scene->camera->get_matrix(), 3); float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp index e5eab1ae62b..ca221b229b4 100644 --- a/intern/cycles/blender/blender_particles.cpp +++ b/intern/cycles/blender/blender_particles.cpp @@ -36,10 +36,10 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, if (!b_psys) return false; - object->hide_on_missing_motion = true; + object->set_hide_on_missing_motion(true); /* test if we need particle data */ - if (!object->geometry->need_attribute(scene, ATTR_STD_PARTICLE)) + if (!object->get_geometry()->need_attribute(scene, ATTR_STD_PARTICLE)) return false; /* don't handle child particles yet */ @@ -56,7 +56,8 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, bool need_update = particle_system_map.add_or_update(&psys, b_ob, b_instance.object(), key); /* no update needed? */ - if (!need_update && !object->geometry->need_update && !scene->object_manager->need_update) + if (!need_update && !object->get_geometry()->is_modified() && + !scene->object_manager->need_update) return true; /* first time used in this sync loop? clear and tag update */ @@ -80,10 +81,11 @@ bool BlenderSync::sync_dupli_particle(BL::Object &b_ob, psys->particles.push_back_slow(pa); - if (object->particle_index != psys->particles.size() - 1) + object->set_particle_system(psys); + object->set_particle_index(psys->particles.size() - 1); + + if (object->particle_index_is_modified()) scene->object_manager->tag_update(scene); - object->particle_system = psys; - object->particle_index = psys->particles.size() - 1; /* return that this object has particle data */ return true; diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 513cac1e0e9..770f4ca51c9 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -442,17 +442,17 @@ void BlenderSession::stamp_view_layer_metadata(Scene *scene, const string &view_ } /* Write cryptomatte metadata. */ - if (scene->film->cryptomatte_passes & CRYPT_OBJECT) { + if (scene->film->get_cryptomatte_passes() & CRYPT_OBJECT) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoObject", scene->object_manager->get_cryptomatte_objects(scene)); } - if (scene->film->cryptomatte_passes & CRYPT_MATERIAL) { + if (scene->film->get_cryptomatte_passes() & CRYPT_MATERIAL) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoMaterial", scene->shader_manager->get_cryptomatte_materials(scene)); } - if (scene->film->cryptomatte_passes & CRYPT_ASSET) { + if (scene->film->get_cryptomatte_passes() & CRYPT_ASSET) { add_cryptomatte_layer(b_rr, view_layer_name + ".CryptoAsset", scene->object_manager->get_cryptomatte_assets(scene)); @@ -473,6 +473,11 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) { b_depsgraph = b_depsgraph_; + if (session->progress.get_cancel()) { + update_status_progress(); + return; + } + /* set callback to write out render results */ session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1); session->update_render_tile_cb = function_bind( @@ -503,9 +508,9 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) /* Set buffer params, using film settings from sync_render_passes. */ buffer_params.passes = passes; - buffer_params.denoising_data_pass = scene->film->denoising_data_pass; - buffer_params.denoising_clean_pass = scene->film->denoising_clean_pass; - buffer_params.denoising_prefiltered_pass = scene->film->denoising_prefiltered_pass; + buffer_params.denoising_data_pass = scene->film->get_denoising_data_pass(); + buffer_params.denoising_clean_pass = scene->film->get_denoising_clean_pass(); + buffer_params.denoising_prefiltered_pass = scene->film->get_denoising_prefiltered_pass(); BL::RenderResult::views_iterator b_view_iter; @@ -542,8 +547,9 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_) /* Make sure all views have different noise patterns. - hardcoded value just to make it random */ if (view_index != 0) { - scene->integrator->seed += hash_uint2(scene->integrator->seed, - hash_uint2(view_index * 0xdeadbeef, 0)); + int seed = scene->integrator->get_seed(); + seed += hash_uint2(seed, hash_uint2(view_index * 0xdeadbeef, 0)); + scene->integrator->set_seed(seed); scene->integrator->tag_update(scene); } @@ -715,7 +721,7 @@ void BlenderSession::do_write_update_render_result(BL::RenderLayer &b_rlay, if (!buffers->copy_from_device()) return; - float exposure = scene->film->exposure; + float exposure = scene->film->get_exposure(); vector<float> pixels(rtile.w * rtile.h * 4); @@ -832,10 +838,7 @@ void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_) session->set_denoising(session_params.denoising); /* Update film if denoising data was enabled or disabled. */ - if (scene->film->denoising_data_pass != buffer_params.denoising_data_pass) { - scene->film->denoising_data_pass = buffer_params.denoising_data_pass; - scene->film->tag_update(scene); - } + scene->film->set_denoising_data_pass(buffer_params.denoising_data_pass); /* reset if needed */ if (scene->need_reset()) { @@ -894,7 +897,7 @@ bool BlenderSession::draw(int w, int h) sync->sync_view(b_v3d, b_rv3d, width, height); - if (scene->camera->need_update) + if (scene->camera->is_modified()) reset = true; session->scene->mutex.unlock(); @@ -1109,8 +1112,11 @@ void BlenderSession::update_resumable_tile_manager(int num_samples) VLOG(1) << "Samples range start is " << range_start_sample << ", " << "number of samples to render is " << range_num_samples; - scene->integrator->start_sample = rounded_range_start_sample; - scene->integrator->tag_update(scene); + scene->integrator->set_start_sample(rounded_range_start_sample); + + if (scene->integrator->is_modified()) { + scene->integrator->tag_update(scene); + } session->tile_manager.range_start_sample = rounded_range_start_sample; session->tile_manager.range_num_samples = rounded_range_num_samples; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index c171982b29d..ac86cf3345c 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -42,11 +42,11 @@ typedef map<string, ConvertNode *> ProxyMap; /* Find */ -void BlenderSync::find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader) +void BlenderSync::find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader) { Shader *shader = (id) ? shader_map.find(id) : default_shader; - used_shaders.push_back(shader); + used_shaders.push_back_slow(shader); shader->tag_used(scene); } @@ -97,6 +97,53 @@ static ImageAlphaType get_image_alpha_type(BL::Image &b_image) return (ImageAlphaType)validate_enum_value(value, IMAGE_ALPHA_NUM_TYPES, IMAGE_ALPHA_AUTO); } +/* Attribute name translation utilities */ + +/* Since Eevee needs to know whether the attribute is uniform or varying + * at the time it compiles the shader for the material, Blender had to + * introduce different namespaces (types) in its attribute node. However, + * Cycles already has object attributes that form a uniform namespace with + * the more common varying attributes. Without completely reworking the + * attribute handling in Cycles to introduce separate namespaces (this could + * be especially hard for OSL which directly uses the name string), the + * space identifier has to be added to the attribute name as a prefix. + * + * The prefixes include a control character to ensure the user specified + * name can't accidentally include a special prefix. + */ + +static const string_view object_attr_prefix("\x01object:"); +static const string_view instancer_attr_prefix("\x01instancer:"); + +static ustring blender_attribute_name_add_type(const string &name, BlenderAttributeType type) +{ + switch (type) { + case BL::ShaderNodeAttribute::attribute_type_OBJECT: + return ustring::concat(object_attr_prefix, name); + case BL::ShaderNodeAttribute::attribute_type_INSTANCER: + return ustring::concat(instancer_attr_prefix, name); + default: + return ustring(name); + } +} + +BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name) +{ + string_view sname(name); + + if (sname.substr(0, object_attr_prefix.size()) == object_attr_prefix) { + *r_real_name = sname.substr(object_attr_prefix.size()); + return BL::ShaderNodeAttribute::attribute_type_OBJECT; + } + + if (sname.substr(0, instancer_attr_prefix.size()) == instancer_attr_prefix) { + *r_real_name = sname.substr(instancer_attr_prefix.size()); + return BL::ShaderNodeAttribute::attribute_type_INSTANCER; + } + + return BL::ShaderNodeAttribute::attribute_type_GEOMETRY; +} + /* Graph */ static BL::NodeSocket get_node_output(BL::Node &b_node, const string &name) @@ -194,19 +241,19 @@ static void set_default_value(ShaderInput *input, } } -static void get_tex_mapping(TextureMapping *mapping, BL::TexMapping &b_mapping) +static void get_tex_mapping(TextureNode *mapping, BL::TexMapping &b_mapping) { if (!b_mapping) return; - mapping->translation = get_float3(b_mapping.translation()); - mapping->rotation = get_float3(b_mapping.rotation()); - mapping->scale = get_float3(b_mapping.scale()); - mapping->type = (TextureMapping::Type)b_mapping.vector_type(); + mapping->set_tex_mapping_translation(get_float3(b_mapping.translation())); + mapping->set_tex_mapping_rotation(get_float3(b_mapping.rotation())); + mapping->set_tex_mapping_scale(get_float3(b_mapping.scale())); + mapping->set_tex_mapping_type((TextureMapping::Type)b_mapping.vector_type()); - mapping->x_mapping = (TextureMapping::Mapping)b_mapping.mapping_x(); - mapping->y_mapping = (TextureMapping::Mapping)b_mapping.mapping_y(); - mapping->z_mapping = (TextureMapping::Mapping)b_mapping.mapping_z(); + mapping->set_tex_mapping_x_mapping((TextureMapping::Mapping)b_mapping.mapping_x()); + mapping->set_tex_mapping_y_mapping((TextureMapping::Mapping)b_mapping.mapping_y()); + mapping->set_tex_mapping_z_mapping((TextureMapping::Mapping)b_mapping.mapping_z()); } static ShaderNode *add_node(Scene *scene, @@ -225,34 +272,48 @@ static ShaderNode *add_node(Scene *scene, BL::ShaderNodeRGBCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); RGBCurvesNode *curves = graph->create_node<RGBCurvesNode>(); - curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, true); - curvemapping_minmax(mapping, true, &curves->min_x, &curves->max_x); + array<float3> curve_mapping_curves; + float min_x, max_x; + curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, true); + curvemapping_minmax(mapping, true, &min_x, &max_x); + curves->set_min_x(min_x); + curves->set_max_x(max_x); + curves->set_curves(curve_mapping_curves); node = curves; } if (b_node.is_a(&RNA_ShaderNodeVectorCurve)) { BL::ShaderNodeVectorCurve b_curve_node(b_node); BL::CurveMapping mapping(b_curve_node.mapping()); VectorCurvesNode *curves = graph->create_node<VectorCurvesNode>(); - curvemapping_color_to_array(mapping, curves->curves, RAMP_TABLE_SIZE, false); - curvemapping_minmax(mapping, false, &curves->min_x, &curves->max_x); + array<float3> curve_mapping_curves; + float min_x, max_x; + curvemapping_color_to_array(mapping, curve_mapping_curves, RAMP_TABLE_SIZE, false); + curvemapping_minmax(mapping, false, &min_x, &max_x); + curves->set_min_x(min_x); + curves->set_max_x(max_x); + curves->set_curves(curve_mapping_curves); node = curves; } else if (b_node.is_a(&RNA_ShaderNodeValToRGB)) { RGBRampNode *ramp = graph->create_node<RGBRampNode>(); BL::ShaderNodeValToRGB b_ramp_node(b_node); BL::ColorRamp b_color_ramp(b_ramp_node.color_ramp()); - colorramp_to_array(b_color_ramp, ramp->ramp, ramp->ramp_alpha, RAMP_TABLE_SIZE); - ramp->interpolate = b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT; + array<float3> ramp_values; + array<float> ramp_alpha; + colorramp_to_array(b_color_ramp, ramp_values, ramp_alpha, RAMP_TABLE_SIZE); + ramp->set_ramp(ramp_values); + ramp->set_ramp_alpha(ramp_alpha); + ramp->set_interpolate(b_color_ramp.interpolation() != BL::ColorRamp::interpolation_CONSTANT); node = ramp; } else if (b_node.is_a(&RNA_ShaderNodeRGB)) { ColorNode *color = graph->create_node<ColorNode>(); - color->value = get_node_output_rgba(b_node, "Color"); + color->set_value(get_node_output_rgba(b_node, "Color")); node = color; } else if (b_node.is_a(&RNA_ShaderNodeValue)) { ValueNode *value = graph->create_node<ValueNode>(); - value->value = get_node_output_value(b_node, "Value"); + value->set_value(get_node_output_value(b_node, "Value")); node = value; } else if (b_node.is_a(&RNA_ShaderNodeCameraData)) { @@ -270,8 +331,8 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeMixRGB)) { BL::ShaderNodeMixRGB b_mix_node(b_node); MixNode *mix = graph->create_node<MixNode>(); - mix->type = (NodeMix)b_mix_node.blend_type(); - mix->use_clamp = b_mix_node.use_clamp(); + mix->set_mix_type((NodeMix)b_mix_node.blend_type()); + mix->set_use_clamp(b_mix_node.use_clamp()); node = mix; } else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) { @@ -301,43 +362,45 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeMapRange)) { BL::ShaderNodeMapRange b_map_range_node(b_node); MapRangeNode *map_range_node = graph->create_node<MapRangeNode>(); - map_range_node->clamp = b_map_range_node.clamp(); - map_range_node->type = (NodeMapRangeType)b_map_range_node.interpolation_type(); + map_range_node->set_clamp(b_map_range_node.clamp()); + map_range_node->set_range_type((NodeMapRangeType)b_map_range_node.interpolation_type()); node = map_range_node; } else if (b_node.is_a(&RNA_ShaderNodeClamp)) { BL::ShaderNodeClamp b_clamp_node(b_node); ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = (NodeClampType)b_clamp_node.clamp_type(); + clamp_node->set_clamp_type((NodeClampType)b_clamp_node.clamp_type()); node = clamp_node; } else if (b_node.is_a(&RNA_ShaderNodeMath)) { BL::ShaderNodeMath b_math_node(b_node); MathNode *math_node = graph->create_node<MathNode>(); - math_node->type = (NodeMathType)b_math_node.operation(); - math_node->use_clamp = b_math_node.use_clamp(); + math_node->set_math_type((NodeMathType)b_math_node.operation()); + math_node->set_use_clamp(b_math_node.use_clamp()); node = math_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) { BL::ShaderNodeVectorMath b_vector_math_node(b_node); VectorMathNode *vector_math_node = graph->create_node<VectorMathNode>(); - vector_math_node->type = (NodeVectorMathType)b_vector_math_node.operation(); + vector_math_node->set_math_type((NodeVectorMathType)b_vector_math_node.operation()); node = vector_math_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorRotate)) { BL::ShaderNodeVectorRotate b_vector_rotate_node(b_node); VectorRotateNode *vector_rotate_node = graph->create_node<VectorRotateNode>(); - vector_rotate_node->type = (NodeVectorRotateType)b_vector_rotate_node.rotation_type(); - vector_rotate_node->invert = b_vector_rotate_node.invert(); + vector_rotate_node->set_rotate_type( + (NodeVectorRotateType)b_vector_rotate_node.rotation_type()); + vector_rotate_node->set_invert(b_vector_rotate_node.invert()); node = vector_rotate_node; } else if (b_node.is_a(&RNA_ShaderNodeVectorTransform)) { BL::ShaderNodeVectorTransform b_vector_transform_node(b_node); VectorTransformNode *vtransform = graph->create_node<VectorTransformNode>(); - vtransform->type = (NodeVectorTransformType)b_vector_transform_node.vector_type(); - vtransform->convert_from = (NodeVectorTransformConvertSpace) - b_vector_transform_node.convert_from(); - vtransform->convert_to = (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to(); + vtransform->set_transform_type((NodeVectorTransformType)b_vector_transform_node.vector_type()); + vtransform->set_convert_from( + (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_from()); + vtransform->set_convert_to( + (NodeVectorTransformConvertSpace)b_vector_transform_node.convert_to()); node = vtransform; } else if (b_node.is_a(&RNA_ShaderNodeNormal)) { @@ -345,13 +408,13 @@ static ShaderNode *add_node(Scene *scene, b_node.outputs.begin(out_it); NormalNode *norm = graph->create_node<NormalNode>(); - norm->direction = get_node_output_vector(b_node, "Normal"); + norm->set_direction(get_node_output_vector(b_node, "Normal")); node = norm; } else if (b_node.is_a(&RNA_ShaderNodeMapping)) { BL::ShaderNodeMapping b_mapping_node(b_node); MappingNode *mapping = graph->create_node<MappingNode>(); - mapping->type = (NodeMappingType)b_mapping_node.vector_type(); + mapping->set_mapping_type((NodeMappingType)b_mapping_node.vector_type()); node = mapping; } else if (b_node.is_a(&RNA_ShaderNodeFresnel)) { @@ -369,7 +432,8 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeAttribute)) { BL::ShaderNodeAttribute b_attr_node(b_node); AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = b_attr_node.attribute_name(); + attr->set_attribute(blender_attribute_name_add_type(b_attr_node.attribute_name(), + b_attr_node.attribute_type())); node = attr; } else if (b_node.is_a(&RNA_ShaderNodeBackground)) { @@ -384,16 +448,16 @@ static ShaderNode *add_node(Scene *scene, switch (b_aniso_node.distribution()) { case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN: - aniso->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_GGX: - aniso->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX: - aniso->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; + aniso->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); break; case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY: - aniso->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID; + aniso->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); break; } @@ -409,16 +473,16 @@ static ShaderNode *add_node(Scene *scene, switch (b_subsurface_node.falloff()) { case BL::ShaderNodeSubsurfaceScattering::falloff_CUBIC: - subsurface->falloff = CLOSURE_BSSRDF_CUBIC_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_CUBIC_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_GAUSSIAN: - subsurface->falloff = CLOSURE_BSSRDF_GAUSSIAN_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_GAUSSIAN_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_BURLEY: - subsurface->falloff = CLOSURE_BSSRDF_BURLEY_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_BURLEY_ID); break; case BL::ShaderNodeSubsurfaceScattering::falloff_RANDOM_WALK: - subsurface->falloff = CLOSURE_BSSRDF_RANDOM_WALK_ID; + subsurface->set_falloff(CLOSURE_BSSRDF_RANDOM_WALK_ID); break; } @@ -430,19 +494,19 @@ static ShaderNode *add_node(Scene *scene, switch (b_glossy_node.distribution()) { case BL::ShaderNodeBsdfGlossy::distribution_SHARP: - glossy->distribution = CLOSURE_BSDF_REFLECTION_ID; + glossy->set_distribution(CLOSURE_BSDF_REFLECTION_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN: - glossy->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_GGX: - glossy->distribution = CLOSURE_BSDF_MICROFACET_GGX_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY: - glossy->distribution = CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID; + glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID); break; case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX: - glossy->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID; + glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID); break; } node = glossy; @@ -452,16 +516,16 @@ static ShaderNode *add_node(Scene *scene, GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>(); switch (b_glass_node.distribution()) { case BL::ShaderNodeBsdfGlass::distribution_SHARP: - glass->distribution = CLOSURE_BSDF_SHARP_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_SHARP_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_BECKMANN: - glass->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_GGX: - glass->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); break; case BL::ShaderNodeBsdfGlass::distribution_MULTI_GGX: - glass->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; + glass->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); break; } node = glass; @@ -471,13 +535,13 @@ static ShaderNode *add_node(Scene *scene, RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>(); switch (b_refraction_node.distribution()) { case BL::ShaderNodeBsdfRefraction::distribution_SHARP: - refraction->distribution = CLOSURE_BSDF_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_REFRACTION_ID); break; case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN: - refraction->distribution = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); break; case BL::ShaderNodeBsdfRefraction::distribution_GGX: - refraction->distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; + refraction->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); break; } node = refraction; @@ -487,10 +551,10 @@ static ShaderNode *add_node(Scene *scene, ToonBsdfNode *toon = graph->create_node<ToonBsdfNode>(); switch (b_toon_node.component()) { case BL::ShaderNodeBsdfToon::component_DIFFUSE: - toon->component = CLOSURE_BSDF_DIFFUSE_TOON_ID; + toon->set_component(CLOSURE_BSDF_DIFFUSE_TOON_ID); break; case BL::ShaderNodeBsdfToon::component_GLOSSY: - toon->component = CLOSURE_BSDF_GLOSSY_TOON_ID; + toon->set_component(CLOSURE_BSDF_GLOSSY_TOON_ID); break; } node = toon; @@ -500,10 +564,10 @@ static ShaderNode *add_node(Scene *scene, HairBsdfNode *hair = graph->create_node<HairBsdfNode>(); switch (b_hair_node.component()) { case BL::ShaderNodeBsdfHair::component_Reflection: - hair->component = CLOSURE_BSDF_HAIR_REFLECTION_ID; + hair->set_component(CLOSURE_BSDF_HAIR_REFLECTION_ID); break; case BL::ShaderNodeBsdfHair::component_Transmission: - hair->component = CLOSURE_BSDF_HAIR_TRANSMISSION_ID; + hair->set_component(CLOSURE_BSDF_HAIR_TRANSMISSION_ID); break; } node = hair; @@ -511,11 +575,11 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeBsdfHairPrincipled)) { BL::ShaderNodeBsdfHairPrincipled b_principled_hair_node(b_node); PrincipledHairBsdfNode *principled_hair = graph->create_node<PrincipledHairBsdfNode>(); - principled_hair->parametrization = (NodePrincipledHairParametrization)get_enum( - b_principled_hair_node.ptr, - "parametrization", - NODE_PRINCIPLED_HAIR_NUM, - NODE_PRINCIPLED_HAIR_REFLECTANCE); + principled_hair->set_parametrization( + (NodePrincipledHairParametrization)get_enum(b_principled_hair_node.ptr, + "parametrization", + NODE_PRINCIPLED_HAIR_NUM, + NODE_PRINCIPLED_HAIR_REFLECTANCE)); node = principled_hair; } else if (b_node.is_a(&RNA_ShaderNodeBsdfPrincipled)) { @@ -523,18 +587,18 @@ static ShaderNode *add_node(Scene *scene, PrincipledBsdfNode *principled = graph->create_node<PrincipledBsdfNode>(); switch (b_principled_node.distribution()) { case BL::ShaderNodeBsdfPrincipled::distribution_GGX: - principled->distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID; + principled->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID); break; case BL::ShaderNodeBsdfPrincipled::distribution_MULTI_GGX: - principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID; + principled->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID); break; } switch (b_principled_node.subsurface_method()) { case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY: - principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID; + principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_ID); break; case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK: - principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID; + principled->set_subsurface_method(CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID); break; } node = principled; @@ -554,9 +618,9 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeAmbientOcclusion)) { BL::ShaderNodeAmbientOcclusion b_ao_node(b_node); AmbientOcclusionNode *ao = graph->create_node<AmbientOcclusionNode>(); - ao->samples = b_ao_node.samples(); - ao->inside = b_ao_node.inside(); - ao->only_local = b_ao_node.only_local(); + ao->set_samples(b_ao_node.samples()); + ao->set_inside(b_ao_node.inside()); + ao->set_only_local(b_ao_node.only_local()); node = ao; } else if (b_node.is_a(&RNA_ShaderNodeVolumeScatter)) { @@ -575,7 +639,7 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeWireframe)) { BL::ShaderNodeWireframe b_wireframe_node(b_node); WireframeNode *wire = graph->create_node<WireframeNode>(); - wire->use_pixel_size = b_wireframe_node.use_pixel_size(); + wire->set_use_pixel_size(b_wireframe_node.use_pixel_size()); node = wire; } else if (b_node.is_a(&RNA_ShaderNodeWavelength)) { @@ -605,13 +669,13 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeVertexColor)) { BL::ShaderNodeVertexColor b_vertex_color_node(b_node); VertexColorNode *vertex_color_node = graph->create_node<VertexColorNode>(); - vertex_color_node->layer_name = b_vertex_color_node.layer_name(); + vertex_color_node->set_layer_name(ustring(b_vertex_color_node.layer_name())); node = vertex_color_node; } else if (b_node.is_a(&RNA_ShaderNodeBump)) { BL::ShaderNodeBump b_bump_node(b_node); BumpNode *bump = graph->create_node<BumpNode>(); - bump->invert = b_bump_node.invert(); + bump->set_invert(b_bump_node.invert()); node = bump; } else if (b_node.is_a(&RNA_ShaderNodeScript)) { @@ -644,25 +708,26 @@ static ShaderNode *add_node(Scene *scene, BL::ImageUser b_image_user(b_image_node.image_user()); ImageTextureNode *image = graph->create_node<ImageTextureNode>(); - image->interpolation = get_image_interpolation(b_image_node); - image->extension = get_image_extension(b_image_node); - image->projection = (NodeImageProjection)b_image_node.projection(); - image->projection_blend = b_image_node.projection_blend(); + image->set_interpolation(get_image_interpolation(b_image_node)); + image->set_extension(get_image_extension(b_image_node)); + image->set_projection((NodeImageProjection)b_image_node.projection()); + image->set_projection_blend(b_image_node.projection_blend()); BL::TexMapping b_texture_mapping(b_image_node.texture_mapping()); - get_tex_mapping(&image->tex_mapping, b_texture_mapping); + get_tex_mapping(image, b_texture_mapping); if (b_image) { PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; - image->colorspace = get_enum_identifier(colorspace_ptr, "name"); + image->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - image->animated = b_image_node.image_user().use_auto_refresh(); - image->alpha_type = get_image_alpha_type(b_image); + image->set_animated(b_image_node.image_user().use_auto_refresh()); + image->set_alpha_type(get_image_alpha_type(b_image)); - image->tiles.clear(); + array<int> tiles; BL::Image::tiles_iterator b_iter; for (b_image.tiles.begin(b_iter); b_iter != b_image.tiles.end(); ++b_iter) { - image->tiles.push_back(b_iter->number()); + tiles.push_back_slow(b_iter->number()); } + image->set_tiles(tiles); /* builtin images will use callback-based reading because * they could only be loaded correct from blender side @@ -684,8 +749,9 @@ static ShaderNode *add_node(Scene *scene, new BlenderImageLoader(b_image, image_frame), image->image_params()); } else { - image->filename = image_user_file_path( - b_image_user, b_image, b_scene.frame_current(), true); + ustring filename = ustring( + image_user_file_path(b_image_user, b_image, b_scene.frame_current(), true)); + image->set_filename(filename); } } node = image; @@ -696,17 +762,17 @@ static ShaderNode *add_node(Scene *scene, BL::ImageUser b_image_user(b_env_node.image_user()); EnvironmentTextureNode *env = graph->create_node<EnvironmentTextureNode>(); - env->interpolation = get_image_interpolation(b_env_node); - env->projection = (NodeEnvironmentProjection)b_env_node.projection(); + env->set_interpolation(get_image_interpolation(b_env_node)); + env->set_projection((NodeEnvironmentProjection)b_env_node.projection()); BL::TexMapping b_texture_mapping(b_env_node.texture_mapping()); - get_tex_mapping(&env->tex_mapping, b_texture_mapping); + get_tex_mapping(env, b_texture_mapping); if (b_image) { PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr; - env->colorspace = get_enum_identifier(colorspace_ptr, "name"); + env->set_colorspace(ustring(get_enum_identifier(colorspace_ptr, "name"))); - env->animated = b_env_node.image_user().use_auto_refresh(); - env->alpha_type = get_image_alpha_type(b_image); + env->set_animated(b_env_node.image_user().use_auto_refresh()); + env->set_alpha_type(get_image_alpha_type(b_image)); bool is_builtin = b_image.packed_file() || b_image.source() == BL::Image::source_GENERATED || b_image.source() == BL::Image::source_MOVIE || @@ -719,8 +785,8 @@ static ShaderNode *add_node(Scene *scene, env->image_params()); } else { - env->filename = image_user_file_path( - b_image_user, b_image, b_scene.frame_current(), false); + env->set_filename( + ustring(image_user_file_path(b_image_user, b_image, b_scene.frame_current(), false))); } } node = env; @@ -728,103 +794,103 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeTexGradient)) { BL::ShaderNodeTexGradient b_gradient_node(b_node); GradientTextureNode *gradient = graph->create_node<GradientTextureNode>(); - gradient->type = (NodeGradientType)b_gradient_node.gradient_type(); + gradient->set_gradient_type((NodeGradientType)b_gradient_node.gradient_type()); BL::TexMapping b_texture_mapping(b_gradient_node.texture_mapping()); - get_tex_mapping(&gradient->tex_mapping, b_texture_mapping); + get_tex_mapping(gradient, b_texture_mapping); node = gradient; } else if (b_node.is_a(&RNA_ShaderNodeTexVoronoi)) { BL::ShaderNodeTexVoronoi b_voronoi_node(b_node); VoronoiTextureNode *voronoi = graph->create_node<VoronoiTextureNode>(); - voronoi->dimensions = b_voronoi_node.voronoi_dimensions(); - voronoi->feature = (NodeVoronoiFeature)b_voronoi_node.feature(); - voronoi->metric = (NodeVoronoiDistanceMetric)b_voronoi_node.distance(); + voronoi->set_dimensions(b_voronoi_node.voronoi_dimensions()); + voronoi->set_feature((NodeVoronoiFeature)b_voronoi_node.feature()); + voronoi->set_metric((NodeVoronoiDistanceMetric)b_voronoi_node.distance()); BL::TexMapping b_texture_mapping(b_voronoi_node.texture_mapping()); - get_tex_mapping(&voronoi->tex_mapping, b_texture_mapping); + get_tex_mapping(voronoi, b_texture_mapping); node = voronoi; } else if (b_node.is_a(&RNA_ShaderNodeTexMagic)) { BL::ShaderNodeTexMagic b_magic_node(b_node); MagicTextureNode *magic = graph->create_node<MagicTextureNode>(); - magic->depth = b_magic_node.turbulence_depth(); + magic->set_depth(b_magic_node.turbulence_depth()); BL::TexMapping b_texture_mapping(b_magic_node.texture_mapping()); - get_tex_mapping(&magic->tex_mapping, b_texture_mapping); + get_tex_mapping(magic, b_texture_mapping); node = magic; } else if (b_node.is_a(&RNA_ShaderNodeTexWave)) { BL::ShaderNodeTexWave b_wave_node(b_node); WaveTextureNode *wave = graph->create_node<WaveTextureNode>(); - wave->type = (NodeWaveType)b_wave_node.wave_type(); - wave->bands_direction = (NodeWaveBandsDirection)b_wave_node.bands_direction(); - wave->rings_direction = (NodeWaveRingsDirection)b_wave_node.rings_direction(); - wave->profile = (NodeWaveProfile)b_wave_node.wave_profile(); + wave->set_wave_type((NodeWaveType)b_wave_node.wave_type()); + wave->set_bands_direction((NodeWaveBandsDirection)b_wave_node.bands_direction()); + wave->set_rings_direction((NodeWaveRingsDirection)b_wave_node.rings_direction()); + wave->set_profile((NodeWaveProfile)b_wave_node.wave_profile()); BL::TexMapping b_texture_mapping(b_wave_node.texture_mapping()); - get_tex_mapping(&wave->tex_mapping, b_texture_mapping); + get_tex_mapping(wave, b_texture_mapping); node = wave; } else if (b_node.is_a(&RNA_ShaderNodeTexChecker)) { BL::ShaderNodeTexChecker b_checker_node(b_node); CheckerTextureNode *checker = graph->create_node<CheckerTextureNode>(); BL::TexMapping b_texture_mapping(b_checker_node.texture_mapping()); - get_tex_mapping(&checker->tex_mapping, b_texture_mapping); + get_tex_mapping(checker, b_texture_mapping); node = checker; } else if (b_node.is_a(&RNA_ShaderNodeTexBrick)) { BL::ShaderNodeTexBrick b_brick_node(b_node); BrickTextureNode *brick = graph->create_node<BrickTextureNode>(); - brick->offset = b_brick_node.offset(); - brick->offset_frequency = b_brick_node.offset_frequency(); - brick->squash = b_brick_node.squash(); - brick->squash_frequency = b_brick_node.squash_frequency(); + brick->set_offset(b_brick_node.offset()); + brick->set_offset_frequency(b_brick_node.offset_frequency()); + brick->set_squash(b_brick_node.squash()); + brick->set_squash_frequency(b_brick_node.squash_frequency()); BL::TexMapping b_texture_mapping(b_brick_node.texture_mapping()); - get_tex_mapping(&brick->tex_mapping, b_texture_mapping); + get_tex_mapping(brick, b_texture_mapping); node = brick; } else if (b_node.is_a(&RNA_ShaderNodeTexNoise)) { BL::ShaderNodeTexNoise b_noise_node(b_node); NoiseTextureNode *noise = graph->create_node<NoiseTextureNode>(); - noise->dimensions = b_noise_node.noise_dimensions(); + noise->set_dimensions(b_noise_node.noise_dimensions()); BL::TexMapping b_texture_mapping(b_noise_node.texture_mapping()); - get_tex_mapping(&noise->tex_mapping, b_texture_mapping); + get_tex_mapping(noise, b_texture_mapping); node = noise; } else if (b_node.is_a(&RNA_ShaderNodeTexMusgrave)) { BL::ShaderNodeTexMusgrave b_musgrave_node(b_node); MusgraveTextureNode *musgrave_node = graph->create_node<MusgraveTextureNode>(); - musgrave_node->type = (NodeMusgraveType)b_musgrave_node.musgrave_type(); - musgrave_node->dimensions = b_musgrave_node.musgrave_dimensions(); + musgrave_node->set_musgrave_type((NodeMusgraveType)b_musgrave_node.musgrave_type()); + musgrave_node->set_dimensions(b_musgrave_node.musgrave_dimensions()); BL::TexMapping b_texture_mapping(b_musgrave_node.texture_mapping()); - get_tex_mapping(&musgrave_node->tex_mapping, b_texture_mapping); + get_tex_mapping(musgrave_node, b_texture_mapping); node = musgrave_node; } else if (b_node.is_a(&RNA_ShaderNodeTexCoord)) { BL::ShaderNodeTexCoord b_tex_coord_node(b_node); TextureCoordinateNode *tex_coord = graph->create_node<TextureCoordinateNode>(); - tex_coord->from_dupli = b_tex_coord_node.from_instancer(); + tex_coord->set_from_dupli(b_tex_coord_node.from_instancer()); if (b_tex_coord_node.object()) { - tex_coord->use_transform = true; - tex_coord->ob_tfm = get_transform(b_tex_coord_node.object().matrix_world()); + tex_coord->set_use_transform(true); + tex_coord->set_ob_tfm(get_transform(b_tex_coord_node.object().matrix_world())); } node = tex_coord; } else if (b_node.is_a(&RNA_ShaderNodeTexSky)) { BL::ShaderNodeTexSky b_sky_node(b_node); SkyTextureNode *sky = graph->create_node<SkyTextureNode>(); - sky->type = (NodeSkyType)b_sky_node.sky_type(); - sky->sun_direction = normalize(get_float3(b_sky_node.sun_direction())); - sky->turbidity = b_sky_node.turbidity(); - sky->ground_albedo = b_sky_node.ground_albedo(); - sky->sun_disc = b_sky_node.sun_disc(); - sky->sun_size = b_sky_node.sun_size(); - sky->sun_intensity = b_sky_node.sun_intensity(); - sky->sun_elevation = b_sky_node.sun_elevation(); - sky->sun_rotation = b_sky_node.sun_rotation(); - sky->altitude = 1000.0f * b_sky_node.altitude(); - sky->air_density = b_sky_node.air_density(); - sky->dust_density = b_sky_node.dust_density(); - sky->ozone_density = b_sky_node.ozone_density(); + sky->set_sky_type((NodeSkyType)b_sky_node.sky_type()); + sky->set_sun_direction(normalize(get_float3(b_sky_node.sun_direction()))); + sky->set_turbidity(b_sky_node.turbidity()); + sky->set_ground_albedo(b_sky_node.ground_albedo()); + sky->set_sun_disc(b_sky_node.sun_disc()); + sky->set_sun_size(b_sky_node.sun_size()); + sky->set_sun_intensity(b_sky_node.sun_intensity()); + sky->set_sun_elevation(b_sky_node.sun_elevation()); + sky->set_sun_rotation(b_sky_node.sun_rotation()); + sky->set_altitude(1000.0f * b_sky_node.altitude()); + sky->set_air_density(b_sky_node.air_density()); + sky->set_dust_density(b_sky_node.dust_density()); + sky->set_ozone_density(b_sky_node.ozone_density()); BL::TexMapping b_texture_mapping(b_sky_node.texture_mapping()); - get_tex_mapping(&sky->tex_mapping, b_texture_mapping); + get_tex_mapping(sky, b_texture_mapping); node = sky; } else if (b_node.is_a(&RNA_ShaderNodeTexIES)) { @@ -832,13 +898,14 @@ static ShaderNode *add_node(Scene *scene, IESLightNode *ies = graph->create_node<IESLightNode>(); switch (b_ies_node.mode()) { case BL::ShaderNodeTexIES::mode_EXTERNAL: - ies->filename = blender_absolute_path(b_data, b_ntree, b_ies_node.filepath()); + ies->set_filename(ustring(blender_absolute_path(b_data, b_ntree, b_ies_node.filepath()))); break; case BL::ShaderNodeTexIES::mode_INTERNAL: - ies->ies = get_text_datablock_content(b_ies_node.ies().ptr); - if (ies->ies.empty()) { - ies->ies = "\n"; + ustring ies_content = ustring(get_text_datablock_content(b_ies_node.ies().ptr)); + if (ies_content.empty()) { + ies_content = "\n"; } + ies->set_ies(ies_content); break; } node = ies; @@ -846,36 +913,36 @@ static ShaderNode *add_node(Scene *scene, else if (b_node.is_a(&RNA_ShaderNodeTexWhiteNoise)) { BL::ShaderNodeTexWhiteNoise b_tex_white_noise_node(b_node); WhiteNoiseTextureNode *white_noise_node = graph->create_node<WhiteNoiseTextureNode>(); - white_noise_node->dimensions = b_tex_white_noise_node.noise_dimensions(); + white_noise_node->set_dimensions(b_tex_white_noise_node.noise_dimensions()); node = white_noise_node; } else if (b_node.is_a(&RNA_ShaderNodeNormalMap)) { BL::ShaderNodeNormalMap b_normal_map_node(b_node); NormalMapNode *nmap = graph->create_node<NormalMapNode>(); - nmap->space = (NodeNormalMapSpace)b_normal_map_node.space(); - nmap->attribute = b_normal_map_node.uv_map(); + nmap->set_space((NodeNormalMapSpace)b_normal_map_node.space()); + nmap->set_attribute(ustring(b_normal_map_node.uv_map())); node = nmap; } else if (b_node.is_a(&RNA_ShaderNodeTangent)) { BL::ShaderNodeTangent b_tangent_node(b_node); TangentNode *tangent = graph->create_node<TangentNode>(); - tangent->direction_type = (NodeTangentDirectionType)b_tangent_node.direction_type(); - tangent->axis = (NodeTangentAxis)b_tangent_node.axis(); - tangent->attribute = b_tangent_node.uv_map(); + tangent->set_direction_type((NodeTangentDirectionType)b_tangent_node.direction_type()); + tangent->set_axis((NodeTangentAxis)b_tangent_node.axis()); + tangent->set_attribute(ustring(b_tangent_node.uv_map())); node = tangent; } else if (b_node.is_a(&RNA_ShaderNodeUVMap)) { BL::ShaderNodeUVMap b_uvmap_node(b_node); UVMapNode *uvm = graph->create_node<UVMapNode>(); - uvm->attribute = b_uvmap_node.uv_map(); - uvm->from_dupli = b_uvmap_node.from_instancer(); + uvm->set_attribute(ustring(b_uvmap_node.uv_map())); + uvm->set_from_dupli(b_uvmap_node.from_instancer()); node = uvm; } else if (b_node.is_a(&RNA_ShaderNodeTexPointDensity)) { BL::ShaderNodeTexPointDensity b_point_density_node(b_node); PointDensityTextureNode *point_density = graph->create_node<PointDensityTextureNode>(); - point_density->space = (NodeTexVoxelSpace)b_point_density_node.space(); - point_density->interpolation = get_image_interpolation(b_point_density_node); + point_density->set_space((NodeTexVoxelSpace)b_point_density_node.space()); + point_density->set_interpolation(get_image_interpolation(b_point_density_node)); point_density->handle = scene->image_manager->add_image( new BlenderPointDensityLoader(b_depsgraph, b_point_density_node), point_density->image_params()); @@ -892,33 +959,33 @@ static ShaderNode *add_node(Scene *scene, if (b_ob) { float3 loc, size; point_density_texture_space(b_depsgraph, b_point_density_node, loc, size); - point_density->tfm = transform_translate(-loc) * transform_scale(size) * - transform_inverse(get_transform(b_ob.matrix_world())); + point_density->set_tfm(transform_translate(-loc) * transform_scale(size) * + transform_inverse(get_transform(b_ob.matrix_world()))); } } else if (b_node.is_a(&RNA_ShaderNodeBevel)) { BL::ShaderNodeBevel b_bevel_node(b_node); BevelNode *bevel = graph->create_node<BevelNode>(); - bevel->samples = b_bevel_node.samples(); + bevel->set_samples(b_bevel_node.samples()); node = bevel; } else if (b_node.is_a(&RNA_ShaderNodeDisplacement)) { BL::ShaderNodeDisplacement b_disp_node(b_node); DisplacementNode *disp = graph->create_node<DisplacementNode>(); - disp->space = (NodeNormalMapSpace)b_disp_node.space(); + disp->set_space((NodeNormalMapSpace)b_disp_node.space()); node = disp; } else if (b_node.is_a(&RNA_ShaderNodeVectorDisplacement)) { BL::ShaderNodeVectorDisplacement b_disp_node(b_node); VectorDisplacementNode *disp = graph->create_node<VectorDisplacementNode>(); - disp->space = (NodeNormalMapSpace)b_disp_node.space(); - disp->attribute = ""; + disp->set_space((NodeNormalMapSpace)b_disp_node.space()); + disp->set_attribute(ustring("")); node = disp; } else if (b_node.is_a(&RNA_ShaderNodeOutputAOV)) { BL::ShaderNodeOutputAOV b_aov_node(b_node); OutputAOVNode *aov = graph->create_node<OutputAOVNode>(); - aov->name = b_aov_node.name(); + aov->set_name(ustring(b_aov_node.name())); node = aov; } @@ -1245,7 +1312,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) ShaderGraph *graph = new ShaderGraph(); shader->name = b_mat.name().c_str(); - shader->pass_id = b_mat.pass_index(); + shader->set_pass_id(b_mat.pass_index()); /* create nodes */ if (b_mat.use_nodes() && b_mat.node_tree()) { @@ -1255,7 +1322,7 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) } else { DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>(); - diffuse->color = get_float3(b_mat.diffuse_color()); + diffuse->set_color(get_float3(b_mat.diffuse_color())); graph->add(diffuse); ShaderNode *out = graph->output(); @@ -1264,13 +1331,13 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) /* settings */ PointerRNA cmat = RNA_pointer_get(&b_mat.ptr, "cycles"); - shader->use_mis = get_boolean(cmat, "sample_as_light"); - shader->use_transparent_shadow = get_boolean(cmat, "use_transparent_shadow"); - shader->heterogeneous_volume = !get_boolean(cmat, "homogeneous_volume"); - shader->volume_sampling_method = get_volume_sampling(cmat); - shader->volume_interpolation_method = get_volume_interpolation(cmat); - shader->volume_step_rate = get_float(cmat, "volume_step_rate"); - shader->displacement_method = get_displacement_method(cmat); + shader->set_use_mis(get_boolean(cmat, "sample_as_light")); + shader->set_use_transparent_shadow(get_boolean(cmat, "use_transparent_shadow")); + shader->set_heterogeneous_volume(!get_boolean(cmat, "homogeneous_volume")); + shader->set_volume_sampling_method(get_volume_sampling(cmat)); + shader->set_volume_interpolation_method(get_volume_interpolation(cmat)); + shader->set_volume_step_rate(get_float(cmat, "volume_step_rate")); + shader->set_displacement_method(get_displacement_method(cmat)); shader->set_graph(graph); @@ -1311,7 +1378,6 @@ void BlenderSync::sync_materials(BL::Depsgraph &b_depsgraph, bool update_all) void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, bool update_all) { Background *background = scene->background; - Background prevbackground = *background; BL::World b_world = b_scene.world(); @@ -1331,14 +1397,14 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, /* volume */ PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles"); - shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume"); - shader->volume_sampling_method = get_volume_sampling(cworld); - shader->volume_interpolation_method = get_volume_interpolation(cworld); - shader->volume_step_rate = get_float(cworld, "volume_step_size"); + shader->set_heterogeneous_volume(!get_boolean(cworld, "homogeneous_volume")); + shader->set_volume_sampling_method(get_volume_sampling(cworld)); + shader->set_volume_interpolation_method(get_volume_interpolation(cworld)); + shader->set_volume_step_rate(get_float(cworld, "volume_step_size")); } else if (new_viewport_parameters.use_scene_world && b_world) { BackgroundNode *background = graph->create_node<BackgroundNode>(); - background->color = get_float3(b_world.color()); + background->set_color(get_float3(b_world.color())); graph->add(background); ShaderNode *out = graph->output(); @@ -1360,29 +1426,32 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, graph->add(light_path); MixNode *mix_scene_with_background = graph->create_node<MixNode>(); - mix_scene_with_background->color2 = world_color; + mix_scene_with_background->set_color2(world_color); graph->add(mix_scene_with_background); EnvironmentTextureNode *texture_environment = graph->create_node<EnvironmentTextureNode>(); - texture_environment->tex_mapping.type = TextureMapping::VECTOR; - texture_environment->tex_mapping.rotation[2] = new_viewport_parameters.studiolight_rotate_z; - texture_environment->filename = new_viewport_parameters.studiolight_path; + texture_environment->set_tex_mapping_type(TextureMapping::VECTOR); + float3 rotation_z = texture_environment->get_tex_mapping_rotation(); + rotation_z[2] = new_viewport_parameters.studiolight_rotate_z; + texture_environment->set_tex_mapping_rotation(rotation_z); + texture_environment->set_filename(new_viewport_parameters.studiolight_path); graph->add(texture_environment); MixNode *mix_intensity = graph->create_node<MixNode>(); - mix_intensity->type = NODE_MIX_MUL; - mix_intensity->fac = 1.0f; - mix_intensity->color2 = make_float3(new_viewport_parameters.studiolight_intensity, - new_viewport_parameters.studiolight_intensity, - new_viewport_parameters.studiolight_intensity); + mix_intensity->set_mix_type(NODE_MIX_MUL); + mix_intensity->set_fac(1.0f); + mix_intensity->set_color2(make_float3(new_viewport_parameters.studiolight_intensity, + new_viewport_parameters.studiolight_intensity, + new_viewport_parameters.studiolight_intensity)); graph->add(mix_intensity); TextureCoordinateNode *texture_coordinate = graph->create_node<TextureCoordinateNode>(); graph->add(texture_coordinate); MixNode *mix_background_with_environment = graph->create_node<MixNode>(); - mix_background_with_environment->fac = new_viewport_parameters.studiolight_background_alpha; - mix_background_with_environment->color1 = world_color; + mix_background_with_environment->set_fac( + new_viewport_parameters.studiolight_background_alpha); + mix_background_with_environment->set_color1(world_color); graph->add(mix_background_with_environment); ShaderNode *out = graph->output(); @@ -1404,9 +1473,9 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, /* AO */ BL::WorldLighting b_light = b_world.light_settings(); - background->use_ao = b_light.use_ambient_occlusion(); - background->ao_factor = b_light.ao_factor(); - background->ao_distance = b_light.distance(); + background->set_use_ao(b_light.use_ambient_occlusion()); + background->set_ao_factor(b_light.ao_factor()); + background->set_ao_distance(b_light.distance()); /* visibility */ PointerRNA cvisibility = RNA_pointer_get(&b_world.ptr, "cycles_visibility"); @@ -1418,12 +1487,12 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, visibility |= get_boolean(cvisibility, "transmission") ? PATH_RAY_TRANSMIT : 0; visibility |= get_boolean(cvisibility, "scatter") ? PATH_RAY_VOLUME_SCATTER : 0; - background->visibility = visibility; + background->set_visibility(visibility); } else { - background->use_ao = false; - background->ao_factor = 0.0f; - background->ao_distance = FLT_MAX; + background->set_use_ao(false); + background->set_ao_factor(0.0f); + background->set_ao_distance(FLT_MAX); } shader->set_graph(graph); @@ -1432,22 +1501,23 @@ void BlenderSync::sync_world(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d, } PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); - background->transparent = b_scene.render().film_transparent(); + background->set_transparent(b_scene.render().film_transparent()); - if (background->transparent) { - background->transparent_glass = get_boolean(cscene, "film_transparent_glass"); - background->transparent_roughness_threshold = get_float(cscene, "film_transparent_roughness"); + if (background->get_transparent()) { + background->set_transparent_glass(get_boolean(cscene, "film_transparent_glass")); + background->set_transparent_roughness_threshold( + get_float(cscene, "film_transparent_roughness")); } else { - background->transparent_glass = false; - background->transparent_roughness_threshold = 0.0f; + background->set_transparent_glass(false); + background->set_transparent_roughness_threshold(0.0f); } - background->use_shader = view_layer.use_background_shader | - viewport_parameters.custom_viewport_parameters(); - background->use_ao = background->use_ao && view_layer.use_background_ao; + background->set_use_shader(view_layer.use_background_shader | + viewport_parameters.custom_viewport_parameters()); + background->set_use_ao(background->get_use_ao() && view_layer.use_background_ao); - if (background->modified(prevbackground)) + if (background->is_modified()) background->tag_update(scene); } @@ -1480,8 +1550,8 @@ void BlenderSync::sync_lights(BL::Depsgraph &b_depsgraph, bool update_all) } else { EmissionNode *emission = graph->create_node<EmissionNode>(); - emission->color = make_float3(1.0f, 1.0f, 1.0f); - emission->strength = 1.0f; + emission->set_color(make_float3(1.0f, 1.0f, 1.0f)); + emission->set_strength(1.0f); graph->add(emission); ShaderNode *out = graph->output(); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 0139afb711d..94ff0ff1473 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -118,9 +118,9 @@ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d if (dicing_prop_changed) { for (const pair<const GeometryKey, Geometry *> &iter : geometry_map.key_to_scene_data()) { Geometry *geom = iter.second; - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) { PointerRNA id_ptr; RNA_id_pointer_create((::ID *)iter.first.id, &id_ptr); geometry_map.set_recalc(BL::ID(id_ptr)); @@ -238,7 +238,7 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, geometry_synced.clear(); /* use for objects and motion sync */ if (scene->need_motion() == Scene::MOTION_PASS || scene->need_motion() == Scene::MOTION_NONE || - scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) { + scene->camera->get_motion_position() == Camera::MOTION_POSITION_CENTER) { sync_objects(b_depsgraph, b_v3d); } sync_motion(b_render, b_depsgraph, b_v3d, b_override, width, height, python_thread_state); @@ -264,70 +264,75 @@ void BlenderSync::sync_integrator() experimental = (get_enum(cscene, "feature_set") != 0); Integrator *integrator = scene->integrator; - Integrator previntegrator = *integrator; - integrator->min_bounce = get_int(cscene, "min_light_bounces"); - integrator->max_bounce = get_int(cscene, "max_bounces"); + integrator->set_min_bounce(get_int(cscene, "min_light_bounces")); + integrator->set_max_bounce(get_int(cscene, "max_bounces")); - integrator->max_diffuse_bounce = get_int(cscene, "diffuse_bounces"); - integrator->max_glossy_bounce = get_int(cscene, "glossy_bounces"); - integrator->max_transmission_bounce = get_int(cscene, "transmission_bounces"); - integrator->max_volume_bounce = get_int(cscene, "volume_bounces"); + integrator->set_max_diffuse_bounce(get_int(cscene, "diffuse_bounces")); + integrator->set_max_glossy_bounce(get_int(cscene, "glossy_bounces")); + integrator->set_max_transmission_bounce(get_int(cscene, "transmission_bounces")); + integrator->set_max_volume_bounce(get_int(cscene, "volume_bounces")); - integrator->transparent_min_bounce = get_int(cscene, "min_transparent_bounces"); - integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces"); + integrator->set_transparent_min_bounce(get_int(cscene, "min_transparent_bounces")); + integrator->set_transparent_max_bounce(get_int(cscene, "transparent_max_bounces")); - integrator->volume_max_steps = get_int(cscene, "volume_max_steps"); - integrator->volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") : - get_float(cscene, "volume_step_rate"); + integrator->set_volume_max_steps(get_int(cscene, "volume_max_steps")); + float volume_step_rate = (preview) ? get_float(cscene, "volume_preview_step_rate") : + get_float(cscene, "volume_step_rate"); + integrator->set_volume_step_rate(volume_step_rate); - integrator->caustics_reflective = get_boolean(cscene, "caustics_reflective"); - integrator->caustics_refractive = get_boolean(cscene, "caustics_refractive"); - integrator->filter_glossy = get_float(cscene, "blur_glossy"); + integrator->set_caustics_reflective(get_boolean(cscene, "caustics_reflective")); + integrator->set_caustics_refractive(get_boolean(cscene, "caustics_refractive")); + integrator->set_filter_glossy(get_float(cscene, "blur_glossy")); - integrator->seed = get_int(cscene, "seed"); + int seed = get_int(cscene, "seed"); if (get_boolean(cscene, "use_animated_seed")) { - integrator->seed = hash_uint2(b_scene.frame_current(), get_int(cscene, "seed")); + seed = hash_uint2(b_scene.frame_current(), get_int(cscene, "seed")); if (b_scene.frame_subframe() != 0.0f) { /* TODO(sergey): Ideally should be some sort of hash_merge, * but this is good enough for now. */ - integrator->seed += hash_uint2((int)(b_scene.frame_subframe() * (float)INT_MAX), - get_int(cscene, "seed")); + seed += hash_uint2((int)(b_scene.frame_subframe() * (float)INT_MAX), + get_int(cscene, "seed")); } } - integrator->sampling_pattern = (SamplingPattern)get_enum( - cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); + integrator->set_seed(seed); - integrator->sample_clamp_direct = get_float(cscene, "sample_clamp_direct"); - integrator->sample_clamp_indirect = get_float(cscene, "sample_clamp_indirect"); + integrator->set_sample_clamp_direct(get_float(cscene, "sample_clamp_direct")); + integrator->set_sample_clamp_indirect(get_float(cscene, "sample_clamp_indirect")); if (!preview) { - if (integrator->motion_blur != r.use_motion_blur()) { + if (integrator->get_motion_blur() != r.use_motion_blur()) { scene->object_manager->tag_update(scene); - scene->camera->tag_update(); + scene->camera->tag_modified(); } - integrator->motion_blur = r.use_motion_blur(); + integrator->set_motion_blur(r.use_motion_blur()); } - integrator->method = (Integrator::Method)get_enum( - cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH); + integrator->set_method((Integrator::Method)get_enum( + cscene, "progressive", Integrator::NUM_METHODS, Integrator::PATH)); + + integrator->set_sample_all_lights_direct(get_boolean(cscene, "sample_all_lights_direct")); + integrator->set_sample_all_lights_indirect(get_boolean(cscene, "sample_all_lights_indirect")); + integrator->set_light_sampling_threshold(get_float(cscene, "light_sampling_threshold")); + + SamplingPattern sampling_pattern = (SamplingPattern)get_enum( + cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_SOBOL); - integrator->sample_all_lights_direct = get_boolean(cscene, "sample_all_lights_direct"); - integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect"); - integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold"); + int adaptive_min_samples = INT_MAX; if (RNA_boolean_get(&cscene, "use_adaptive_sampling")) { - integrator->sampling_pattern = SAMPLING_PATTERN_PMJ; - integrator->adaptive_min_samples = get_int(cscene, "adaptive_min_samples"); - integrator->adaptive_threshold = get_float(cscene, "adaptive_threshold"); + sampling_pattern = SAMPLING_PATTERN_PMJ; + adaptive_min_samples = get_int(cscene, "adaptive_min_samples"); + integrator->set_adaptive_threshold(get_float(cscene, "adaptive_threshold")); } else { - integrator->adaptive_min_samples = INT_MAX; - integrator->adaptive_threshold = 0.0f; + integrator->set_adaptive_threshold(0.0f); } + integrator->set_sampling_pattern(sampling_pattern); + int diffuse_samples = get_int(cscene, "diffuse_samples"); int glossy_samples = get_int(cscene, "glossy_samples"); int transmission_samples = get_int(cscene, "transmission_samples"); @@ -337,39 +342,40 @@ void BlenderSync::sync_integrator() int volume_samples = get_int(cscene, "volume_samples"); if (get_boolean(cscene, "use_square_samples")) { - integrator->diffuse_samples = diffuse_samples * diffuse_samples; - integrator->glossy_samples = glossy_samples * glossy_samples; - integrator->transmission_samples = transmission_samples * transmission_samples; - integrator->ao_samples = ao_samples * ao_samples; - integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples; - integrator->subsurface_samples = subsurface_samples * subsurface_samples; - integrator->volume_samples = volume_samples * volume_samples; - integrator->adaptive_min_samples = min( - integrator->adaptive_min_samples * integrator->adaptive_min_samples, INT_MAX); + integrator->set_diffuse_samples(diffuse_samples * diffuse_samples); + integrator->set_glossy_samples(glossy_samples * glossy_samples); + integrator->set_transmission_samples(transmission_samples * transmission_samples); + integrator->set_ao_samples(ao_samples * ao_samples); + integrator->set_mesh_light_samples(mesh_light_samples * mesh_light_samples); + integrator->set_subsurface_samples(subsurface_samples * subsurface_samples); + integrator->set_volume_samples(volume_samples * volume_samples); + adaptive_min_samples = min(adaptive_min_samples * adaptive_min_samples, INT_MAX); } else { - integrator->diffuse_samples = diffuse_samples; - integrator->glossy_samples = glossy_samples; - integrator->transmission_samples = transmission_samples; - integrator->ao_samples = ao_samples; - integrator->mesh_light_samples = mesh_light_samples; - integrator->subsurface_samples = subsurface_samples; - integrator->volume_samples = volume_samples; + integrator->set_diffuse_samples(diffuse_samples); + integrator->set_glossy_samples(glossy_samples); + integrator->set_transmission_samples(transmission_samples); + integrator->set_ao_samples(ao_samples); + integrator->set_mesh_light_samples(mesh_light_samples); + integrator->set_subsurface_samples(subsurface_samples); + integrator->set_volume_samples(volume_samples); } + integrator->set_adaptive_min_samples(adaptive_min_samples); + if (b_scene.render().use_simplify()) { if (preview) { - integrator->ao_bounces = get_int(cscene, "ao_bounces"); + integrator->set_ao_bounces(get_int(cscene, "ao_bounces")); } else { - integrator->ao_bounces = get_int(cscene, "ao_bounces_render"); + integrator->set_ao_bounces(get_int(cscene, "ao_bounces_render")); } } else { - integrator->ao_bounces = 0; + integrator->set_ao_bounces(0); } - if (integrator->modified(previntegrator)) + if (integrator->is_modified()) integrator->tag_update(scene); } @@ -380,46 +386,42 @@ void BlenderSync::sync_film(BL::SpaceView3D &b_v3d) PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); Film *film = scene->film; - Film prevfilm = *film; vector<Pass> prevpasses = scene->passes; if (b_v3d) { - film->display_pass = update_viewport_display_passes(b_v3d, scene->passes); + film->set_display_pass(update_viewport_display_passes(b_v3d, scene->passes)); } - film->exposure = get_float(cscene, "film_exposure"); - film->filter_type = (FilterType)get_enum( - cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS); - film->filter_width = (film->filter_type == FILTER_BOX) ? 1.0f : - get_float(cscene, "filter_width"); + film->set_exposure(get_float(cscene, "film_exposure")); + film->set_filter_type( + (FilterType)get_enum(cscene, "pixel_filter_type", FILTER_NUM_TYPES, FILTER_BLACKMAN_HARRIS)); + float filter_width = (film->get_filter_type() == FILTER_BOX) ? 1.0f : + get_float(cscene, "filter_width"); + film->set_filter_width(filter_width); if (b_scene.world()) { BL::WorldMistSettings b_mist = b_scene.world().mist_settings(); - film->mist_start = b_mist.start(); - film->mist_depth = b_mist.depth(); + film->set_mist_start(b_mist.start()); + film->set_mist_depth(b_mist.depth()); switch (b_mist.falloff()) { case BL::WorldMistSettings::falloff_QUADRATIC: - film->mist_falloff = 2.0f; + film->set_mist_falloff(2.0f); break; case BL::WorldMistSettings::falloff_LINEAR: - film->mist_falloff = 1.0f; + film->set_mist_falloff(1.0f); break; case BL::WorldMistSettings::falloff_INVERSE_QUADRATIC: - film->mist_falloff = 0.5f; + film->set_mist_falloff(0.5f); break; } } - if (film->modified(prevfilm)) { - film->tag_update(scene); - } - if (!Pass::equals(prevpasses, scene->passes)) { film->tag_passes_update(scene, prevpasses, false); - film->tag_update(scene); + film->tag_modified(); } } @@ -585,7 +587,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, BL::RenderPass b_pass(*b_pass_iter); PassType pass_type = get_pass_type(b_pass); - if (pass_type == PASS_MOTION && scene->integrator->motion_blur) + if (pass_type == PASS_MOTION && scene->integrator->get_motion_blur()) continue; if (pass_type != PASS_NONE) Pass::add(pass_type, passes, b_pass.name().c_str()); @@ -593,12 +595,12 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, PointerRNA crl = RNA_pointer_get(&b_view_layer.ptr, "cycles"); - scene->film->denoising_flags = 0; + int denoising_flags = 0; if (denoising.use || denoising.store_passes) { if (denoising.type == DENOISER_NLM) { #define MAP_OPTION(name, flag) \ if (!get_boolean(crl, name)) { \ - scene->film->denoising_flags |= flag; \ + denoising_flags |= flag; \ } \ ((void)0) MAP_OPTION("denoising_diffuse_direct", DENOISING_CLEAN_DIFFUSE_DIR); @@ -611,6 +613,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, } b_engine.add_pass("Noisy Image", 4, "RGBA", b_view_layer.name().c_str()); } + scene->film->set_denoising_flags(denoising_flags); if (denoising.store_passes) { b_engine.add_pass("Denoising Normal", 3, "XYZ", b_view_layer.name().c_str()); @@ -622,7 +625,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass("Denoising Intensity", 1, "X", b_view_layer.name().c_str()); } - if (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES) { + if (scene->film->get_denoising_flags() & DENOISING_CLEAN_ALL_PASSES) { b_engine.add_pass("Denoising Clean", 3, "RGB", b_view_layer.name().c_str()); } } @@ -665,16 +668,15 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, /* Cryptomatte stores two ID/weight pairs per RGBA layer. * User facing parameter is the number of pairs. */ int crypto_depth = divide_up(min(16, get_int(crl, "pass_crypto_depth")), 2); - scene->film->cryptomatte_depth = crypto_depth; - scene->film->cryptomatte_passes = CRYPT_NONE; + scene->film->set_cryptomatte_depth(crypto_depth); + CryptomatteType cryptomatte_passes = CRYPT_NONE; if (get_boolean(crl, "use_pass_crypto_object")) { for (int i = 0; i < crypto_depth; i++) { string passname = cryptomatte_prefix + string_printf("Object%02d", i); b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_OBJECT); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_OBJECT); } if (get_boolean(crl, "use_pass_crypto_material")) { for (int i = 0; i < crypto_depth; i++) { @@ -682,8 +684,7 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_MATERIAL); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_MATERIAL); } if (get_boolean(crl, "use_pass_crypto_asset")) { for (int i = 0; i < crypto_depth; i++) { @@ -691,13 +692,12 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, b_engine.add_pass(passname.c_str(), 4, "RGBA", b_view_layer.name().c_str()); Pass::add(PASS_CRYPTOMATTE, passes, passname.c_str()); } - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_ASSET); + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ASSET); } - if (get_boolean(crl, "pass_crypto_accurate") && scene->film->cryptomatte_passes != CRYPT_NONE) { - scene->film->cryptomatte_passes = (CryptomatteType)(scene->film->cryptomatte_passes | - CRYPT_ACCURATE); + if (get_boolean(crl, "pass_crypto_accurate") && cryptomatte_passes != CRYPT_NONE) { + cryptomatte_passes = (CryptomatteType)(cryptomatte_passes | CRYPT_ACCURATE); } + scene->film->set_cryptomatte_passes(cryptomatte_passes); if (adaptive_sampling) { Pass::add(PASS_ADAPTIVE_AUX_BUFFER, passes); @@ -721,14 +721,14 @@ vector<Pass> BlenderSync::sync_render_passes(BL::RenderLayer &b_rlay, } RNA_END; - scene->film->denoising_data_pass = denoising.use || denoising.store_passes; - scene->film->denoising_clean_pass = (scene->film->denoising_flags & DENOISING_CLEAN_ALL_PASSES); - scene->film->denoising_prefiltered_pass = denoising.store_passes && - denoising.type == DENOISER_NLM; + scene->film->set_denoising_data_pass(denoising.use || denoising.store_passes); + scene->film->set_denoising_clean_pass(scene->film->get_denoising_flags() & + DENOISING_CLEAN_ALL_PASSES); + scene->film->set_denoising_prefiltered_pass(denoising.store_passes && + denoising.type == DENOISER_NLM); - scene->film->pass_alpha_threshold = b_view_layer.pass_alpha_threshold(); + scene->film->set_pass_alpha_threshold(b_view_layer.pass_alpha_threshold()); scene->film->tag_passes_update(scene, passes); - scene->film->tag_update(scene); scene->integrator->tag_update(scene); return passes; diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 62fd1ac2351..ccf059d7704 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -50,6 +50,7 @@ class ViewLayer; class Shader; class ShaderGraph; class ShaderNode; +class TaskPool; class BlenderSync { public: @@ -145,23 +146,20 @@ class BlenderSync { bool use_particle_hair, bool show_lights, BlenderObjectCulling &culling, - bool *use_portal); + bool *use_portal, + TaskPool *geom_task_pool); + + bool sync_object_attributes(BL::DepsgraphObjectInstance &b_instance, Object *object); /* Volume */ - void sync_volume(BL::Object &b_ob, Volume *volume, const vector<Shader *> &used_shaders); + void sync_volume(BL::Object &b_ob, Volume *volume); /* Mesh */ - void sync_mesh(BL::Depsgraph b_depsgraph, - BL::Object b_ob, - Mesh *mesh, - const vector<Shader *> &used_shaders); + void sync_mesh(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh); void sync_mesh_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Mesh *mesh, int motion_step); /* Hair */ - void sync_hair(BL::Depsgraph b_depsgraph, - BL::Object b_ob, - Hair *hair, - const vector<Shader *> &used_shaders); + void sync_hair(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair); void sync_hair_motion(BL::Depsgraph b_depsgraph, BL::Object b_ob, Hair *hair, int motion_step); void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_particle_hair( @@ -177,12 +175,15 @@ class BlenderSync { BL::Object &b_ob, BL::Object &b_ob_instance, bool object_updated, - bool use_particle_hair); + bool use_particle_hair, + TaskPool *task_pool); + void sync_geometry_motion(BL::Depsgraph &b_depsgraph, BL::Object &b_ob, Object *object, float motion_time, - bool use_particle_hair); + bool use_particle_hair, + TaskPool *task_pool); /* Light */ void sync_light(BL::Object &b_parent, @@ -206,7 +207,7 @@ class BlenderSync { void free_data_after_sync(BL::Depsgraph &b_depsgraph); /* util */ - void find_shader(BL::ID &id, vector<Shader *> &used_shaders, Shader *default_shader); + void find_shader(BL::ID &id, array<Node *> &used_shaders, Shader *default_shader); bool BKE_object_is_modified(BL::Object &b_ob); bool object_is_geometry(BL::Object &b_ob); bool object_is_light(BL::Object &b_ob); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 1ea34b41aa2..5185ebae789 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -40,6 +40,9 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame, int tile); CCL_NAMESPACE_BEGIN +typedef BL::ShaderNodeAttribute::attribute_type_enum BlenderAttributeType; +BlenderAttributeType blender_attribute_name_split_type(ustring name, string *r_real_name); + void python_thread_state_save(void **python_thread_state); void python_thread_state_restore(void **python_thread_state); diff --git a/intern/cycles/blender/blender_volume.cpp b/intern/cycles/blender/blender_volume.cpp index e039d8a4895..1843fecd586 100644 --- a/intern/cycles/blender/blender_volume.cpp +++ b/intern/cycles/blender/blender_volume.cpp @@ -202,7 +202,7 @@ static void sync_smoke_volume(Scene *scene, BL::Object &b_ob, Volume *volume, fl continue; } - volume->clipping = b_domain.clipping(); + volume->set_clipping(b_domain.clipping()); Attribute *attr = volume->attributes.add(std); @@ -262,9 +262,9 @@ static void sync_volume_object(BL::BlendData &b_data, BL::VolumeRender b_render(b_volume.render()); - volume->clipping = b_render.clipping(); - volume->step_size = b_render.step_size(); - volume->object_space = (b_render.space() == BL::VolumeRender::space_OBJECT); + volume->set_clipping(b_render.clipping()); + volume->set_step_size(b_render.step_size()); + volume->set_object_space((b_render.space() == BL::VolumeRender::space_OBJECT)); /* Find grid with matching name. */ BL::Volume::grids_iterator b_grid_iter; @@ -320,14 +320,11 @@ static vector<int> get_voxel_image_slots(Mesh *mesh) return slots; } -void BlenderSync::sync_volume(BL::Object &b_ob, - Volume *volume, - const vector<Shader *> &used_shaders) +void BlenderSync::sync_volume(BL::Object &b_ob, Volume *volume) { vector<int> old_voxel_slots = get_voxel_image_slots(volume); - volume->clear(); - volume->used_shaders = used_shaders; + volume->clear(true); if (view_layer.use_volumes) { if (b_ob.type() == BL::Object::type_VOLUME) { diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp index 222c1c40f92..a51ac4cf4a9 100644 --- a/intern/cycles/bvh/bvh.cpp +++ b/intern/cycles/bvh/bvh.cpp @@ -209,30 +209,30 @@ void BVH::refit_primitives(int start, int end, BoundBox &bbox, uint &visibility) /* Primitives. */ if (pack.prim_type[prim] & PRIMITIVE_ALL_CURVE) { /* Curves. */ - const Hair *hair = static_cast<const Hair *>(ob->geometry); + const Hair *hair = static_cast<const Hair *>(ob->get_geometry()); int prim_offset = (params.top_level) ? hair->prim_offset : 0; Hair::Curve curve = hair->get_curve(pidx - prim_offset); int k = PRIMITIVE_UNPACK_SEGMENT(pack.prim_type[prim]); - curve.bounds_grow(k, &hair->curve_keys[0], &hair->curve_radius[0], bbox); + curve.bounds_grow(k, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], bbox); /* Motion curves. */ - if (hair->use_motion_blur) { + if (hair->get_use_motion_blur()) { Attribute *attr = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr) { - size_t hair_size = hair->curve_keys.size(); - size_t steps = hair->motion_steps - 1; + size_t hair_size = hair->get_curve_keys().size(); + size_t steps = hair->get_motion_steps() - 1; float3 *key_steps = attr->data_float3(); for (size_t i = 0; i < steps; i++) - curve.bounds_grow(k, key_steps + i * hair_size, &hair->curve_radius[0], bbox); + curve.bounds_grow(k, key_steps + i * hair_size, &hair->get_curve_radius()[0], bbox); } } } else { /* Triangles. */ - const Mesh *mesh = static_cast<const Mesh *>(ob->geometry); + const Mesh *mesh = static_cast<const Mesh *>(ob->get_geometry()); int prim_offset = (params.top_level) ? mesh->prim_offset : 0; Mesh::Triangle triangle = mesh->get_triangle(pidx - prim_offset); const float3 *vpos = &mesh->verts[0]; @@ -264,7 +264,7 @@ void BVH::pack_triangle(int idx, float4 tri_verts[3]) { int tob = pack.prim_object[idx]; assert(tob >= 0 && tob < objects.size()); - const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->geometry); + const Mesh *mesh = static_cast<const Mesh *>(objects[tob]->get_geometry()); int tidx = pack.prim_index[idx]; Mesh::Triangle t = mesh->get_triangle(tidx); @@ -329,7 +329,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) */ for (size_t i = 0; i < pack.prim_index.size(); i++) { if (pack.prim_index[i] != -1) { - pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset; } } @@ -390,7 +390,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size) /* merge */ foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 360cac59e9b..1727082b7ec 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -169,12 +169,12 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair const size_t num_curves = hair->num_curves(); for (uint j = 0; j < num_curves; j++) { const Hair::Curve curve = hair->get_curve(j); - const float *curve_radius = &hair->curve_radius[0]; + const float *curve_radius = &hair->get_curve_radius()[0]; for (int k = 0; k < curve.num_keys - 1; k++) { if (curve_attr_mP == NULL) { /* Really simple logic for static hair. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); + curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds); if (bounds.valid()) { int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k); references.push_back(BVHReference(bounds, j, i, packed_type)); @@ -189,9 +189,9 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair */ /* TODO(sergey): Support motion steps for spatially split BVH. */ BoundBox bounds = BoundBox::empty; - curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); - const size_t num_keys = hair->curve_keys.size(); - const size_t num_steps = hair->motion_steps; + curve.bounds_grow(k, &hair->get_curve_keys()[0], curve_radius, bounds); + const size_t num_keys = hair->get_curve_keys().size(); + const size_t num_steps = hair->get_motion_steps(); const float3 *key_steps = curve_attr_mP->data_float3(); for (size_t step = 0; step < num_steps - 1; step++) { curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds); @@ -210,10 +210,10 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair */ const int num_bvh_steps = params.num_motion_curve_steps * 2 + 1; const float num_bvh_steps_inv_1 = 1.0f / (num_bvh_steps - 1); - const size_t num_steps = hair->motion_steps; - const float3 *curve_keys = &hair->curve_keys[0]; + const size_t num_steps = hair->get_motion_steps(); + const float3 *curve_keys = &hair->get_curve_keys()[0]; const float3 *key_steps = curve_attr_mP->data_float3(); - const size_t num_keys = hair->curve_keys.size(); + const size_t num_keys = hair->get_curve_keys().size(); /* Calculate bounding box of the previous time step. * Will be reused later to avoid duplicated work on * calculating BVH time step boundbox. @@ -270,11 +270,11 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair void BVHBuild::add_reference_geometry(BoundBox &root, BoundBox ¢er, Geometry *geom, int i) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); add_reference_triangles(root, center, mesh, i); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); add_reference_curves(root, center, hair, i); } @@ -299,11 +299,11 @@ static size_t count_curve_segments(Hair *hair) static size_t count_primitives(Geometry *geom) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); return mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); return count_curve_segments(hair); } @@ -321,14 +321,14 @@ void BVHBuild::add_references(BVHRange &root) if (!ob->is_traceable()) { continue; } - if (!ob->geometry->is_instanced()) { - num_alloc_references += count_primitives(ob->geometry); + if (!ob->get_geometry()->is_instanced()) { + num_alloc_references += count_primitives(ob->get_geometry()); } else num_alloc_references++; } else { - num_alloc_references += count_primitives(ob->geometry); + num_alloc_references += count_primitives(ob->get_geometry()); } } @@ -344,13 +344,13 @@ void BVHBuild::add_references(BVHRange &root) ++i; continue; } - if (!ob->geometry->is_instanced()) - add_reference_geometry(bounds, center, ob->geometry, i); + if (!ob->get_geometry()->is_instanced()) + add_reference_geometry(bounds, center, ob->get_geometry(), i); else add_reference_object(bounds, center, ob, i); } else - add_reference_geometry(bounds, center, ob->geometry, i); + add_reference_geometry(bounds, center, ob->get_geometry(), i); i++; diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index 53776a55257..910e3780b2e 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -300,11 +300,11 @@ static bool rtc_progress_func(void *user_ptr, const double n) static size_t count_primitives(Geometry *geom) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); return mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); return hair->num_segments(); } @@ -402,15 +402,15 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) if (!ob->is_traceable()) { continue; } - if (!ob->geometry->is_instanced()) { - prim_count += count_primitives(ob->geometry); + if (!ob->get_geometry()->is_instanced()) { + prim_count += count_primitives(ob->get_geometry()); } else { ++prim_count; } } else { - prim_count += count_primitives(ob->geometry); + prim_count += count_primitives(ob->get_geometry()); } } @@ -429,7 +429,7 @@ void BVHEmbree::build(Progress &progress, Stats *stats_) ++i; continue; } - if (!ob->geometry->is_instanced()) { + if (!ob->get_geometry()->is_instanced()) { add_object(ob, i); } else { @@ -480,15 +480,15 @@ BVHNode *BVHEmbree::widen_children_nodes(const BVHNode * /*root*/) void BVHEmbree::add_object(Object *ob, int i) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->num_triangles() > 0) { add_triangles(ob, mesh, i); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); if (hair->num_curves() > 0) { add_curves(ob, hair, i); @@ -498,17 +498,17 @@ void BVHEmbree::add_object(Object *ob, int i) void BVHEmbree::add_instance(Object *ob, int i) { - if (!ob || !ob->geometry) { + if (!ob || !ob->get_geometry()) { assert(0); return; } - BVHEmbree *instance_bvh = (BVHEmbree *)(ob->geometry->bvh); + BVHEmbree *instance_bvh = (BVHEmbree *)(ob->get_geometry()->bvh); if (instance_bvh->top_level != this) { instance_bvh->top_level = this; } - const size_t num_object_motion_steps = ob->use_motion() ? ob->motion.size() : 1; + const size_t num_object_motion_steps = ob->use_motion() ? ob->get_motion().size() : 1; const size_t num_motion_steps = min(num_object_motion_steps, RTC_MAX_TIME_STEP_COUNT); assert(num_object_motion_steps <= RTC_MAX_TIME_STEP_COUNT); @@ -517,8 +517,8 @@ void BVHEmbree::add_instance(Object *ob, int i) rtcSetGeometryTimeStepCount(geom_id, num_motion_steps); if (ob->use_motion()) { - array<DecomposedTransform> decomp(ob->motion.size()); - transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); + array<DecomposedTransform> decomp(ob->get_motion().size()); + transform_motion_decompose(decomp.data(), ob->get_motion().data(), ob->get_motion().size()); for (size_t step = 0; step < num_motion_steps; ++step) { RTCQuaternionDecomposition rtc_decomp; rtcInitQuaternionDecomposition(&rtc_decomp); @@ -534,7 +534,8 @@ void BVHEmbree::add_instance(Object *ob, int i) } } else { - rtcSetGeometryTransform(geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->tfm); + rtcSetGeometryTransform( + geom_id, 0, RTC_FORMAT_FLOAT3X4_ROW_MAJOR, (const float *)&ob->get_tfm()); } pack.prim_index.push_back_slow(-1); @@ -558,7 +559,7 @@ void BVHEmbree::add_triangles(const Object *ob, const Mesh *mesh, int i) if (mesh->has_motion_blur()) { attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_geometry_motion_steps = mesh->motion_steps; + num_geometry_motion_steps = mesh->get_motion_steps(); } } @@ -620,7 +621,7 @@ void BVHEmbree::set_tri_vertex_buffer(RTCGeometry geom_id, const Mesh *mesh, con if (mesh->has_motion_blur()) { attr_mP = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = mesh->motion_steps; + num_motion_steps = mesh->get_motion_steps(); t_mid = (num_motion_steps - 1) / 2; if (num_motion_steps > RTC_MAX_TIME_STEP_COUNT) { assert(0); @@ -672,7 +673,7 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c if (hair->has_motion_blur()) { attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_motion_steps = hair->motion_steps; + num_motion_steps = hair->get_motion_steps(); } } @@ -689,11 +690,11 @@ void BVHEmbree::set_curve_vertex_buffer(RTCGeometry geom_id, const Hair *hair, c /* Copy the CV data to Embree */ const int t_mid = (num_motion_steps - 1) / 2; - const float *curve_radius = &hair->curve_radius[0]; + const float *curve_radius = &hair->get_curve_radius()[0]; for (int t = 0; t < num_motion_steps; ++t) { const float3 *verts; if (t == t_mid || attr_mP == NULL) { - verts = &hair->curve_keys[0]; + verts = &hair->get_curve_keys()[0]; } else { int t_ = (t > t_mid) ? (t - 1) : t; @@ -741,7 +742,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) if (hair->has_motion_blur()) { attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); if (attr_mP) { - num_geometry_motion_steps = hair->motion_steps; + num_geometry_motion_steps = hair->get_motion_steps(); } } @@ -826,7 +827,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) for (size_t i = 0; i < pack.prim_index.size(); ++i) { if (pack.prim_index[i] != -1) { - pack.prim_index[i] += objects[pack.prim_object[i]]->geometry->prim_offset; + pack.prim_index[i] += objects[pack.prim_object[i]]->get_geometry()->prim_offset; } } @@ -843,7 +844,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) map<Geometry *, int> geometry_map; foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); BVH *bvh = geom->bvh; if (geom->need_build_bvh(BVH_LAYOUT_EMBREE)) { @@ -873,7 +874,7 @@ void BVHEmbree::pack_nodes(const BVHNode *) /* merge */ foreach (Object *ob, objects) { - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); /* We assume that if mesh doesn't need own BVH it was already included * into a top-level BVH and no packing here is needed. @@ -948,10 +949,10 @@ void BVHEmbree::refit_nodes() /* Update all vertex buffers, then tell Embree to rebuild/-fit the BVHs. */ unsigned geom_id = 0; foreach (Object *ob, objects) { - if (!params.top_level || (ob->is_traceable() && !ob->geometry->is_instanced())) { - Geometry *geom = ob->geometry; + if (!params.top_level || (ob->is_traceable() && !ob->get_geometry()->is_instanced())) { + Geometry *geom = ob->get_geometry(); - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->num_triangles() > 0) { RTCGeometry geom = rtcGetGeometry(scene, geom_id); @@ -959,7 +960,7 @@ void BVHEmbree::refit_nodes() rtcCommitGeometry(geom); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); if (hair->num_curves() > 0) { RTCGeometry geom = rtcGetGeometry(scene, geom_id + 1); diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp index 0527c0eeda8..52fc9c0a50d 100644 --- a/intern/cycles/bvh/bvh_optix.cpp +++ b/intern/cycles/bvh/bvh_optix.cpp @@ -37,6 +37,9 @@ BVHOptiX::BVHOptiX(const BVHParams ¶ms_, const vector<Object *> &objects_) : BVH(params_, geometry_, objects_) { + optix_handle = 0; + optix_data_handle = 0; + do_refit = false; } BVHOptiX::~BVHOptiX() @@ -66,7 +69,7 @@ void BVHOptiX::pack_blas() assert(geometry.size() == 1 && objects.size() == 1); // These are built per-mesh Geometry *const geom = geometry[0]; - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *const hair = static_cast<Hair *const>(geom); if (hair->num_curves() > 0) { const size_t num_curves = hair->num_curves(); @@ -77,7 +80,7 @@ void BVHOptiX::pack_blas() // 'pack.prim_time' is only used in geom_curve_intersect.h // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH - uint type = (hair->use_motion_blur && + uint type = (hair->get_use_motion_blur() && hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) ? ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON : PRIMITIVE_MOTION_CURVE_THICK) : @@ -95,7 +98,7 @@ void BVHOptiX::pack_blas() } } } - else if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *const mesh = static_cast<Mesh *const>(geom); if (mesh->num_triangles() > 0) { const size_t num_triangles = mesh->num_triangles(); @@ -104,7 +107,7 @@ void BVHOptiX::pack_blas() pack.prim_object.reserve(pack.prim_object.size() + num_triangles); uint type = PRIMITIVE_TRIANGLE; - if (mesh->use_motion_blur && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) + if (mesh->get_use_motion_blur() && mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) type = PRIMITIVE_MOTION_TRIANGLE; for (size_t k = 0; k < num_triangles; ++k) { @@ -116,14 +119,14 @@ void BVHOptiX::pack_blas() } // Initialize visibility to zero and later update it during top-level build - uint prev_visibility = objects[0]->visibility; - objects[0]->visibility = 0; + uint prev_visibility = objects[0]->get_visibility(); + objects[0]->set_visibility(0); // Update 'pack.prim_tri_index', 'pack.prim_tri_verts' and 'pack.prim_visibility' pack_primitives(); // Reset visibility after packing - objects[0]->visibility = prev_visibility; + objects[0]->set_visibility(prev_visibility); } void BVHOptiX::pack_tlas() @@ -167,7 +170,7 @@ void BVHOptiX::pack_tlas() int object_index = 0; // Unused for instanced geometry int object_visibility = 0; foreach (Object *ob, objects) { - if (ob->geometry == geom) { + if (ob->get_geometry() == geom) { object_visibility |= ob->visibility_for_tracing(); if (!geom->is_instanced()) { object_index = ob->get_device_index(); @@ -216,8 +219,7 @@ void BVHOptiX::pack_nodes(const BVHNode *) void BVHOptiX::refit_nodes() { - // TODO(pmours): Implement? - VLOG(1) << "Refit is not yet implemented for OptiX BVH."; + do_refit = true; } BVHNode *BVHOptiX::widen_children_nodes(const BVHNode *) diff --git a/intern/cycles/bvh/bvh_optix.h b/intern/cycles/bvh/bvh_optix.h index e4745b093b5..663cba67260 100644 --- a/intern/cycles/bvh/bvh_optix.h +++ b/intern/cycles/bvh/bvh_optix.h @@ -33,6 +33,10 @@ class BVHOptiX : public BVH { friend class BVH; public: + uint64_t optix_handle; + uint64_t optix_data_handle; + bool do_refit; + BVHOptiX(const BVHParams ¶ms, const vector<Geometry *> &geometry, const vector<Object *> &objects); diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp index 2f1960d664e..834b07440d8 100644 --- a/intern/cycles/bvh/bvh_split.cpp +++ b/intern/cycles/bvh/bvh_split.cpp @@ -392,8 +392,8 @@ void BVHSpatialSplit::split_curve_primitive(const Hair *hair, Hair::Curve curve = hair->get_curve(prim_index); const int k0 = curve.first_key + segment_index; const int k1 = k0 + 1; - float3 v0 = hair->curve_keys[k0]; - float3 v1 = hair->curve_keys[k1]; + float3 v0 = hair->get_curve_keys()[k0]; + float3 v1 = hair->get_curve_keys()[k1]; if (tfm != NULL) { v0 = transform_point(tfm, v0); @@ -456,21 +456,22 @@ void BVHSpatialSplit::split_curve_reference(const BVHReference &ref, void BVHSpatialSplit::split_object_reference( const Object *object, int dim, float pos, BoundBox &left_bounds, BoundBox &right_bounds) { - Geometry *geom = object->geometry; + Geometry *geom = object->get_geometry(); - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); for (int tri_idx = 0; tri_idx < mesh->num_triangles(); ++tri_idx) { - split_triangle_primitive(mesh, &object->tfm, tri_idx, dim, pos, left_bounds, right_bounds); + split_triangle_primitive( + mesh, &object->get_tfm(), tri_idx, dim, pos, left_bounds, right_bounds); } } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); for (int curve_idx = 0; curve_idx < hair->num_curves(); ++curve_idx) { Hair::Curve curve = hair->get_curve(curve_idx); for (int segment_idx = 0; segment_idx < curve.num_keys - 1; ++segment_idx) { split_curve_primitive( - hair, &object->tfm, curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); + hair, &object->get_tfm(), curve_idx, segment_idx, dim, pos, left_bounds, right_bounds); } } } @@ -491,11 +492,11 @@ void BVHSpatialSplit::split_reference(const BVHBuild &builder, const Object *ob = builder.objects[ref.prim_object()]; if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { - Mesh *mesh = static_cast<Mesh *>(ob->geometry); + Mesh *mesh = static_cast<Mesh *>(ob->get_geometry()); split_triangle_reference(ref, mesh, dim, pos, left_bounds, right_bounds); } else if (ref.prim_type() & PRIMITIVE_ALL_CURVE) { - Hair *hair = static_cast<Hair *>(ob->geometry); + Hair *hair = static_cast<Hair *>(ob->get_geometry()); split_curve_reference(ref, hair, dim, pos, left_bounds, right_bounds); } else { diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp index c969b361643..38e55307848 100644 --- a/intern/cycles/bvh/bvh_unaligned.cpp +++ b/intern/cycles/bvh/bvh_unaligned.cpp @@ -72,10 +72,10 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = ref.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Hair *hair = static_cast<const Hair *>(object->geometry); + const Hair *hair = static_cast<const Hair *>(object->get_geometry()); const Hair::Curve &curve = hair->get_curve(curve_index); const int key = curve.first_key + segment; - const float3 v1 = hair->curve_keys[key], v2 = hair->curve_keys[key + 1]; + const float3 v1 = hair->get_curve_keys()[key], v2 = hair->get_curve_keys()[key + 1]; float length; const float3 axis = normalize_len(v2 - v1, &length); if (length > 1e-6f) { @@ -98,10 +98,10 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim, if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = prim.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); - const Hair *hair = static_cast<const Hair *>(object->geometry); + const Hair *hair = static_cast<const Hair *>(object->get_geometry()); const Hair::Curve &curve = hair->get_curve(curve_index); curve.bounds_grow( - segment, &hair->curve_keys[0], &hair->curve_radius[0], aligned_space, bounds); + segment, &hair->get_curve_keys()[0], &hair->get_curve_radius()[0], aligned_space, bounds); } else { bounds = prim.bounds().transformed(&aligned_space); diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index cc54f64b1bb..928249931a3 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -39,6 +39,7 @@ set(SRC device_cpu.cpp device_cuda.cpp device_denoising.cpp + device_dummy.cpp device_memory.cpp device_multi.cpp device_opencl.cpp diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 407f73e8451..eb8fb8040e3 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -375,7 +375,7 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool } #endif - Device *device; + Device *device = NULL; switch (info.type) { case DEVICE_CPU: @@ -385,16 +385,12 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool case DEVICE_CUDA: if (device_cuda_init()) device = device_cuda_create(info, stats, profiler, background); - else - device = NULL; break; #endif #ifdef WITH_OPTIX case DEVICE_OPTIX: if (device_optix_init()) device = device_optix_create(info, stats, profiler, background); - else - device = NULL; break; #endif #ifdef WITH_NETWORK @@ -406,12 +402,14 @@ Device *Device::create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool case DEVICE_OPENCL: if (device_opencl_init()) device = device_opencl_create(info, stats, profiler, background); - else - device = NULL; break; #endif default: - return NULL; + break; + } + + if (device == NULL) { + device = device_dummy_create(info, stats, profiler, background); } return device; @@ -549,6 +547,14 @@ vector<DeviceInfo> Device::available_devices(uint mask) return devices; } +DeviceInfo Device::dummy_device(const string &error_msg) +{ + DeviceInfo info; + info.type = DEVICE_DUMMY; + info.error_msg = error_msg; + return info; +} + string Device::device_capabilities(uint mask) { thread_scoped_lock lock(device_mutex); diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index ddf608aa430..2006db02ce7 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -48,6 +48,7 @@ enum DeviceType { DEVICE_NETWORK, DEVICE_MULTI, DEVICE_OPTIX, + DEVICE_DUMMY, }; enum DeviceTypeMask { @@ -87,6 +88,7 @@ class DeviceInfo { int cpu_threads; vector<DeviceInfo> multi_devices; vector<DeviceInfo> denoising_devices; + string error_msg; DeviceInfo() { @@ -471,6 +473,7 @@ class Device { static string string_from_type(DeviceType type); static vector<DeviceType> available_types(); static vector<DeviceInfo> available_devices(uint device_type_mask = DEVICE_MASK_ALL); + static DeviceInfo dummy_device(const string &error_msg = ""); static string device_capabilities(uint device_type_mask = DEVICE_MASK_ALL); static DeviceInfo get_multi_device(const vector<DeviceInfo> &subdevices, int threads, diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 23aedcd0c48..6912ac1e638 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -932,6 +932,11 @@ class CPUDevice : public Device { break; } + if (tile.stealing_state == RenderTile::CAN_BE_STOLEN && task.get_tile_stolen()) { + tile.stealing_state = RenderTile::WAS_STOLEN; + break; + } + if (tile.task == RenderTile::PATH_TRACE) { for (int y = tile.y; y < tile.y + tile.h; y++) { for (int x = tile.x; x < tile.x + tile.w; x++) { diff --git a/intern/cycles/device/device_dummy.cpp b/intern/cycles/device/device_dummy.cpp new file mode 100644 index 00000000000..5112fc152e5 --- /dev/null +++ b/intern/cycles/device/device_dummy.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 2011-2020 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "device/device.h" +#include "device/device_intern.h" + +CCL_NAMESPACE_BEGIN + +/* Dummy device for when creating an appropriate rendering device fails. */ + +class DummyDevice : public Device { + public: + DummyDevice(DeviceInfo &info_, Stats &stats_, Profiler &profiler_, bool background_) + : Device(info_, stats_, profiler_, background_) + { + error_msg = info.error_msg; + } + + ~DummyDevice() + { + } + + virtual BVHLayoutMask get_bvh_layout_mask() const override + { + return 0; + } + + virtual void mem_alloc(device_memory &) override + { + } + + virtual void mem_copy_to(device_memory &) override + { + } + + virtual void mem_copy_from(device_memory &, int, int, int, int) override + { + } + + virtual void mem_zero(device_memory &) override + { + } + + virtual void mem_free(device_memory &) override + { + } + + virtual void const_copy_to(const char *, void *, size_t) override + { + } + + virtual void task_add(DeviceTask &) override + { + } + + virtual void task_wait() override + { + } + + virtual void task_cancel() override + { + } +}; + +Device *device_dummy_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background) +{ + return new DummyDevice(info, stats, profiler, background); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h index 94d63e8f333..ecc79c5d7ee 100644 --- a/intern/cycles/device/device_intern.h +++ b/intern/cycles/device/device_intern.h @@ -35,6 +35,7 @@ bool device_cuda_init(); Device *device_cuda_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background); bool device_optix_init(); Device *device_optix_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background); +Device *device_dummy_create(DeviceInfo &info, Stats &stats, Profiler &profiler, bool background); Device *device_network_create(DeviceInfo &info, Stats &stats, diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index 32654e62a6f..00b2aa864aa 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -450,6 +450,14 @@ template<typename T> class device_vector : public device_memory { device_zero(); } + void move_device(Device *new_device) + { + copy_from_device(); + device_free(); + device = new_device; + copy_to_device(); + } + protected: size_t size(size_t width, size_t height, size_t depth) { diff --git a/intern/cycles/device/device_optix.cpp b/intern/cycles/device/device_optix.cpp index 43b1fb30baf..95234845f98 100644 --- a/intern/cycles/device/device_optix.cpp +++ b/intern/cycles/device/device_optix.cpp @@ -18,6 +18,7 @@ #ifdef WITH_OPTIX # include "bvh/bvh.h" +# include "bvh/bvh_optix.h" # include "device/cuda/device_cuda.h" # include "device/device_denoising.h" # include "device/device_intern.h" @@ -137,9 +138,6 @@ class OptiXDevice : public CUDADevice { PG_HITD_MOTION, PG_HITS_MOTION, # endif -# ifdef WITH_CYCLES_DEBUG - PG_EXCP, -# endif PG_BAKE, // kernel_bake_evaluate PG_DISP, // kernel_displace_evaluate PG_BACK, // kernel_background_evaluate @@ -232,6 +230,9 @@ class OptiXDevice : public CUDADevice { } }; # endif +# if OPTIX_ABI_VERSION >= 41 && defined(WITH_CYCLES_DEBUG) + options.validationMode = OPTIX_DEVICE_CONTEXT_VALIDATION_MODE_ALL; +# endif check_result_optix(optixDeviceContextCreate(cuContext, &options, &context)); # ifdef WITH_CYCLES_LOGGING check_result_optix(optixDeviceContextSetLogCallback( @@ -368,6 +369,12 @@ class OptiXDevice : public CUDADevice { module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_3; module_options.debugLevel = OPTIX_COMPILE_DEBUG_LEVEL_LINEINFO; # endif + +# if OPTIX_ABI_VERSION >= 41 + module_options.boundValues = nullptr; + module_options.numBoundValues = 0; +# endif + OptixPipelineCompileOptions pipeline_options; // Default to no motion blur and two-level graph, since it is the fastest option pipeline_options.usesMotionBlur = false; @@ -375,12 +382,7 @@ class OptiXDevice : public CUDADevice { OPTIX_TRAVERSABLE_GRAPH_FLAG_ALLOW_SINGLE_LEVEL_INSTANCING; pipeline_options.numPayloadValues = 6; pipeline_options.numAttributeValues = 2; // u, v -# ifdef WITH_CYCLES_DEBUG - pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_STACK_OVERFLOW | - OPTIX_EXCEPTION_FLAG_TRACE_DEPTH; -# else pipeline_options.exceptionFlags = OPTIX_EXCEPTION_FLAG_NONE; -# endif pipeline_options.pipelineLaunchParamsVariableName = "__params"; // See kernel_globals.h # if OPTIX_ABI_VERSION >= 36 @@ -505,12 +507,6 @@ class OptiXDevice : public CUDADevice { group_descs[PG_HITL].hitgroup.entryFunctionNameAH = "__anyhit__kernel_optix_local_hit"; } -# ifdef WITH_CYCLES_DEBUG - group_descs[PG_EXCP].kind = OPTIX_PROGRAM_GROUP_KIND_EXCEPTION; - group_descs[PG_EXCP].exception.module = optix_module; - group_descs[PG_EXCP].exception.entryFunctionName = "__exception__kernel_optix_exception"; -# endif - if (requested_features.use_baking) { group_descs[PG_BAKE].kind = OPTIX_PROGRAM_GROUP_KIND_RAYGEN; group_descs[PG_BAKE].raygen.module = optix_module; @@ -578,9 +574,6 @@ class OptiXDevice : public CUDADevice { groups[PG_HITD_MOTION], groups[PG_HITS_MOTION], # endif -# ifdef WITH_CYCLES_DEBUG - groups[PG_EXCP], -# endif }; check_result_optix_ret( optixPipelineCreate(context, @@ -618,9 +611,6 @@ class OptiXDevice : public CUDADevice { groups[PG_HITD_MOTION], groups[PG_HITS_MOTION], # endif -# ifdef WITH_CYCLES_DEBUG - groups[PG_EXCP], -# endif }; check_result_optix_ret( optixPipelineCreate(context, @@ -734,9 +724,6 @@ class OptiXDevice : public CUDADevice { OptixShaderBindingTable sbt_params = {}; sbt_params.raygenRecord = sbt_data.device_pointer + PG_RGEN * sizeof(SbtRecord); -# ifdef WITH_CYCLES_DEBUG - sbt_params.exceptionRecord = sbt_data.device_pointer + PG_EXCP * sizeof(SbtRecord); -# endif sbt_params.missRecordBase = sbt_data.device_pointer + PG_MISS * sizeof(SbtRecord); sbt_params.missRecordStrideInBytes = sizeof(SbtRecord); sbt_params.missRecordCount = 1; @@ -1064,9 +1051,6 @@ class OptiXDevice : public CUDADevice { OptixShaderBindingTable sbt_params = {}; sbt_params.raygenRecord = sbt_data.device_pointer + rgen_index * sizeof(SbtRecord); -# ifdef WITH_CYCLES_DEBUG - sbt_params.exceptionRecord = sbt_data.device_pointer + PG_EXCP * sizeof(SbtRecord); -# endif sbt_params.missRecordBase = sbt_data.device_pointer + PG_MISS * sizeof(SbtRecord); sbt_params.missRecordStrideInBytes = sizeof(SbtRecord); sbt_params.missRecordCount = 1; @@ -1095,23 +1079,23 @@ class OptiXDevice : public CUDADevice { bool build_optix_bvh(const OptixBuildInput &build_input, uint16_t num_motion_steps, - OptixTraversableHandle &out_handle) + OptixTraversableHandle &out_handle, + CUdeviceptr &out_data, + OptixBuildOperation operation) { - out_handle = 0; - const CUDAContextScope scope(cuContext); // Compute memory usage OptixAccelBufferSizes sizes = {}; OptixAccelBuildOptions options; - options.operation = OPTIX_BUILD_OPERATION_BUILD; + options.operation = operation; if (background) { // Prefer best performance and lowest memory consumption in background options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_TRACE | OPTIX_BUILD_FLAG_ALLOW_COMPACTION; } else { // Prefer fast updates in viewport - options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD; + options.buildFlags = OPTIX_BUILD_FLAG_PREFER_FAST_BUILD | OPTIX_BUILD_FLAG_ALLOW_UPDATE; } options.motionOptions.numKeys = num_motion_steps; @@ -1136,8 +1120,10 @@ class OptiXDevice : public CUDADevice { move_textures_to_host(size - free, false); } - CUdeviceptr out_data = 0; - check_result_cuda_ret(cuMemAlloc(&out_data, sizes.outputSizeInBytes)); + if (operation == OPTIX_BUILD_OPERATION_BUILD) { + check_result_cuda_ret(cuMemAlloc(&out_data, sizes.outputSizeInBytes)); + } + as_mem.push_back(out_data); // Finally build the acceleration structure @@ -1204,23 +1190,49 @@ class OptiXDevice : public CUDADevice { unordered_map<Geometry *, OptixTraversableHandle> geometry; geometry.reserve(bvh->geometry.size()); - // Free all previous acceleration structures + // Free all previous acceleration structures which can not be refit + std::set<CUdeviceptr> refit_mem; + + for (Geometry *geom : bvh->geometry) { + if (static_cast<BVHOptiX *>(geom->bvh)->do_refit) { + refit_mem.insert(static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle); + } + } + for (CUdeviceptr mem : as_mem) { - cuMemFree(mem); + if (refit_mem.find(mem) == refit_mem.end()) { + cuMemFree(mem); + } } + as_mem.clear(); // Build bottom level acceleration structures (BLAS) // Note: Always keep this logic in sync with bvh_optix.cpp! for (Object *ob : bvh->objects) { // Skip geometry for which acceleration structure already exists - Geometry *geom = ob->geometry; + Geometry *geom = ob->get_geometry(); if (geometry.find(geom) != geometry.end()) continue; - if (geom->type == Geometry::HAIR) { + OptixTraversableHandle handle; + OptixBuildOperation operation; + CUdeviceptr out_data; + // Refit is only possible in viewport for now. + if (static_cast<BVHOptiX *>(geom->bvh)->do_refit && !background) { + out_data = static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle; + handle = static_cast<BVHOptiX *>(geom->bvh)->optix_handle; + operation = OPTIX_BUILD_OPERATION_UPDATE; + } + else { + out_data = 0; + handle = 0; + operation = OPTIX_BUILD_OPERATION_BUILD; + } + + if (geom->geometry_type == Geometry::HAIR) { // Build BLAS for curve primitives - Hair *const hair = static_cast<Hair *const>(ob->geometry); + Hair *const hair = static_cast<Hair *const>(ob->get_geometry()); if (hair->num_curves() == 0) { continue; } @@ -1229,8 +1241,8 @@ class OptiXDevice : public CUDADevice { size_t num_motion_steps = 1; Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (motion_blur && hair->use_motion_blur && motion_keys) { - num_motion_steps = hair->motion_steps; + if (motion_blur && hair->get_use_motion_blur() && motion_keys) { + num_motion_steps = hair->get_motion_steps(); } device_vector<OptixAabb> aabb_data(this, "temp_aabb_data", MEM_READ_ONLY); @@ -1250,16 +1262,19 @@ class OptiXDevice : public CUDADevice { // Get AABBs for each motion step for (size_t step = 0; step < num_motion_steps; ++step) { // The center step for motion vertices is not stored in the attribute - const float3 *keys = hair->curve_keys.data(); + const float3 *keys = hair->get_curve_keys().data(); size_t center_step = (num_motion_steps - 1) / 2; if (step != center_step) { size_t attr_offset = (step > center_step) ? step - 1 : step; // Technically this is a float4 array, but sizeof(float3) is the same as sizeof(float4) - keys = motion_keys->data_float3() + attr_offset * hair->curve_keys.size(); + keys = motion_keys->data_float3() + attr_offset * hair->get_curve_keys().size(); } for (size_t j = 0, i = 0; j < hair->num_curves(); ++j) { const Hair::Curve curve = hair->get_curve(j); +# if OPTIX_ABI_VERSION >= 36 + const array<float> &curve_radius = hair->get_curve_radius(); +# endif for (int segment = 0; segment < curve.num_segments(); ++segment, ++i) { # if OPTIX_ABI_VERSION >= 36 @@ -1272,10 +1287,8 @@ class OptiXDevice : public CUDADevice { const float4 px = make_float4(keys[ka].x, keys[k0].x, keys[k1].x, keys[kb].x); const float4 py = make_float4(keys[ka].y, keys[k0].y, keys[k1].y, keys[kb].y); const float4 pz = make_float4(keys[ka].z, keys[k0].z, keys[k1].z, keys[kb].z); - const float4 pw = make_float4(hair->curve_radius[ka], - hair->curve_radius[k0], - hair->curve_radius[k1], - hair->curve_radius[kb]); + const float4 pw = make_float4( + curve_radius[ka], curve_radius[k0], curve_radius[k1], curve_radius[kb]); // Convert Catmull-Rom data to Bezier spline static const float4 cr2bsp0 = make_float4(+7, -4, +5, -2) / 6.f; @@ -1298,7 +1311,7 @@ class OptiXDevice : public CUDADevice { # endif { BoundBox bounds = BoundBox::empty; - curve.bounds_grow(segment, keys, hair->curve_radius.data(), bounds); + curve.bounds_grow(segment, keys, hair->get_curve_radius().data(), bounds); const size_t index = step * num_segments + i; aabb_data[index].minX = bounds.min.x; @@ -1381,37 +1394,41 @@ class OptiXDevice : public CUDADevice { } // Allocate memory for new BLAS and build it - OptixTraversableHandle handle; - if (build_optix_bvh(build_input, num_motion_steps, handle)) { - geometry.insert({ob->geometry, handle}); + if (build_optix_bvh(build_input, num_motion_steps, handle, out_data, operation)) { + geometry.insert({ob->get_geometry(), handle}); + static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle = out_data; + static_cast<BVHOptiX *>(geom->bvh)->optix_handle = handle; + static_cast<BVHOptiX *>(geom->bvh)->do_refit = false; } else { return false; } } - else if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + else if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { // Build BLAS for triangle primitives - Mesh *const mesh = static_cast<Mesh *const>(ob->geometry); + Mesh *const mesh = static_cast<Mesh *const>(ob->get_geometry()); if (mesh->num_triangles() == 0) { continue; } - const size_t num_verts = mesh->verts.size(); + const size_t num_verts = mesh->get_verts().size(); size_t num_motion_steps = 1; Attribute *motion_keys = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); - if (motion_blur && mesh->use_motion_blur && motion_keys) { - num_motion_steps = mesh->motion_steps; + if (motion_blur && mesh->get_use_motion_blur() && motion_keys) { + num_motion_steps = mesh->get_motion_steps(); } device_vector<int> index_data(this, "temp_index_data", MEM_READ_ONLY); - index_data.alloc(mesh->triangles.size()); - memcpy(index_data.data(), mesh->triangles.data(), mesh->triangles.size() * sizeof(int)); + index_data.alloc(mesh->get_triangles().size()); + memcpy(index_data.data(), + mesh->get_triangles().data(), + mesh->get_triangles().size() * sizeof(int)); device_vector<float3> vertex_data(this, "temp_vertex_data", MEM_READ_ONLY); vertex_data.alloc(num_verts * num_motion_steps); for (size_t step = 0; step < num_motion_steps; ++step) { - const float3 *verts = mesh->verts.data(); + const float3 *verts = mesh->get_verts().data(); size_t center_step = (num_motion_steps - 1) / 2; // The center step for motion vertices is not stored in the attribute @@ -1453,9 +1470,11 @@ class OptiXDevice : public CUDADevice { build_input.triangleArray.primitiveIndexOffset = mesh->optix_prim_offset; // Allocate memory for new BLAS and build it - OptixTraversableHandle handle; - if (build_optix_bvh(build_input, num_motion_steps, handle)) { - geometry.insert({ob->geometry, handle}); + if (build_optix_bvh(build_input, num_motion_steps, handle, out_data, operation)) { + geometry.insert({ob->get_geometry(), handle}); + static_cast<BVHOptiX *>(geom->bvh)->optix_data_handle = out_data; + static_cast<BVHOptiX *>(geom->bvh)->optix_handle = handle; + static_cast<BVHOptiX *>(geom->bvh)->do_refit = false; } else { return false; @@ -1464,8 +1483,10 @@ class OptiXDevice : public CUDADevice { } // Fill instance descriptions +# if OPTIX_ABI_VERSION < 41 device_vector<OptixAabb> aabbs(this, "tlas_aabbs", MEM_READ_ONLY); aabbs.alloc(bvh->objects.size()); +# endif device_vector<OptixInstance> instances(this, "tlas_instances", MEM_READ_ONLY); instances.alloc(bvh->objects.size()); @@ -1475,12 +1496,13 @@ class OptiXDevice : public CUDADevice { continue; // Create separate instance for triangle/curve meshes of an object - auto handle_it = geometry.find(ob->geometry); + const auto handle_it = geometry.find(ob->get_geometry()); if (handle_it == geometry.end()) { continue; } OptixTraversableHandle handle = handle_it->second; +# if OPTIX_ABI_VERSION < 41 OptixAabb &aabb = aabbs[num_instances]; aabb.minX = ob->bounds.min.x; aabb.minY = ob->bounds.min.y; @@ -1488,6 +1510,7 @@ class OptiXDevice : public CUDADevice { aabb.maxX = ob->bounds.max.x; aabb.maxY = ob->bounds.max.y; aabb.maxZ = ob->bounds.max.z; +# endif OptixInstance &instance = instances[num_instances++]; memset(&instance, 0, sizeof(instance)); @@ -1503,18 +1526,19 @@ class OptiXDevice : public CUDADevice { // Have to have at least one bit in the mask, or else instance would always be culled instance.visibilityMask = 1; - if (ob->geometry->has_volume) { + if (ob->get_geometry()->has_volume) { // Volumes have a special bit set in the visibility mask so a trace can mask only volumes instance.visibilityMask |= 2; } - if (ob->geometry->type == Geometry::HAIR) { + if (ob->get_geometry()->geometry_type == Geometry::HAIR) { // Same applies to curves (so they can be skipped in local trace calls) instance.visibilityMask |= 4; # if OPTIX_ABI_VERSION >= 36 - if (motion_blur && ob->geometry->has_motion_blur() && DebugFlags().optix.curves_api && - static_cast<const Hair *>(ob->geometry)->curve_shape == CURVE_THICK) { + if (motion_blur && ob->get_geometry()->has_motion_blur() && + DebugFlags().optix.curves_api && + static_cast<const Hair *>(ob->get_geometry())->curve_shape == CURVE_THICK) { // Select between motion blur and non-motion blur built-in intersection module instance.sbtOffset = PG_HITD_MOTION - PG_HITD; } @@ -1523,7 +1547,7 @@ class OptiXDevice : public CUDADevice { // Insert motion traversable if object has motion if (motion_blur && ob->use_motion()) { - size_t motion_keys = max(ob->motion.size(), 2) - 2; + size_t motion_keys = max(ob->get_motion().size(), 2) - 2; size_t motion_transform_size = sizeof(OptixSRTMotionTransform) + motion_keys * sizeof(OptixSRTData); @@ -1537,16 +1561,17 @@ class OptiXDevice : public CUDADevice { OptixSRTMotionTransform &motion_transform = *reinterpret_cast<OptixSRTMotionTransform *>( new uint8_t[motion_transform_size]); motion_transform.child = handle; - motion_transform.motionOptions.numKeys = ob->motion.size(); + motion_transform.motionOptions.numKeys = ob->get_motion().size(); motion_transform.motionOptions.flags = OPTIX_MOTION_FLAG_NONE; motion_transform.motionOptions.timeBegin = 0.0f; motion_transform.motionOptions.timeEnd = 1.0f; OptixSRTData *const srt_data = motion_transform.srtData; - array<DecomposedTransform> decomp(ob->motion.size()); - transform_motion_decompose(decomp.data(), ob->motion.data(), ob->motion.size()); + array<DecomposedTransform> decomp(ob->get_motion().size()); + transform_motion_decompose( + decomp.data(), ob->get_motion().data(), ob->get_motion().size()); - for (size_t i = 0; i < ob->motion.size(); ++i) { + for (size_t i = 0; i < ob->get_motion().size(); ++i) { // Scale srt_data[i].sx = decomp[i].y.w; // scale.x.x srt_data[i].sy = decomp[i].z.w; // scale.y.y @@ -1593,9 +1618,9 @@ class OptiXDevice : public CUDADevice { else { instance.traversableHandle = handle; - if (ob->geometry->is_instanced()) { + if (ob->get_geometry()->is_instanced()) { // Set transform matrix - memcpy(instance.transform, &ob->tfm, sizeof(instance.transform)); + memcpy(instance.transform, &ob->get_tfm(), sizeof(instance.transform)); } else { // Disable instance transform if geometry already has it applied to vertex data @@ -1608,20 +1633,26 @@ class OptiXDevice : public CUDADevice { } // Upload instance descriptions +# if OPTIX_ABI_VERSION < 41 aabbs.resize(num_instances); aabbs.copy_to_device(); +# endif instances.resize(num_instances); instances.copy_to_device(); // Build top-level acceleration structure (TLAS) OptixBuildInput build_input = {}; build_input.type = OPTIX_BUILD_INPUT_TYPE_INSTANCES; - build_input.instanceArray.instances = instances.device_pointer; - build_input.instanceArray.numInstances = num_instances; +# if OPTIX_ABI_VERSION < 41 // Instance AABBs no longer need to be set since OptiX 7.2 build_input.instanceArray.aabbs = aabbs.device_pointer; build_input.instanceArray.numAabbs = num_instances; +# endif + build_input.instanceArray.instances = instances.device_pointer; + build_input.instanceArray.numInstances = num_instances; - return build_optix_bvh(build_input, 0, tlas_handle); + CUdeviceptr out_data = 0; + tlas_handle = 0; + return build_optix_bvh(build_input, 0, tlas_handle, out_data, OPTIX_BUILD_OPERATION_BUILD); } void const_copy_to(const char *name, void *host, size_t size) override @@ -1725,8 +1756,8 @@ bool device_optix_init() const OptixResult result = optixInit(); if (result == OPTIX_ERROR_UNSUPPORTED_ABI_VERSION) { - VLOG(1) << "OptiX initialization failed because driver does not support ABI version " - << OPTIX_ABI_VERSION; + VLOG(1) << "OptiX initialization failed because the installed NVIDIA driver is too old. " + "Please update to the latest driver first!"; return false; } else if (result != OPTIX_SUCCESS) { diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h index fd380788282..f819f84eb43 100644 --- a/intern/cycles/device/device_task.h +++ b/intern/cycles/device/device_task.h @@ -159,6 +159,7 @@ class DeviceTask { function<void(RenderTile &)> update_tile_sample; function<void(RenderTile &)> release_tile; function<bool()> get_cancel; + function<bool()> get_tile_stolen; function<void(RenderTileNeighbors &, Device *)> map_neighbor_tiles; function<void(RenderTileNeighbors &, Device *)> unmap_neighbor_tiles; diff --git a/intern/cycles/graph/node.cpp b/intern/cycles/graph/node.cpp index f239040ee3d..0f073ed9b63 100644 --- a/intern/cycles/graph/node.cpp +++ b/intern/cycles/graph/node.cpp @@ -52,11 +52,6 @@ Node::~Node() { } -template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) -{ - return (T &)*(((char *)node) + socket.struct_offset); -} - #ifndef NDEBUG static bool is_socket_float3(const SocketType &socket) { @@ -387,6 +382,87 @@ void Node::copy_value(const SocketType &socket, const Node &other, const SocketT } } +void Node::set_value(const SocketType &socket, const Node &other, const SocketType &other_socket) +{ + assert(socket.type == other_socket.type); + (void)other_socket; + + if (socket.is_array()) { + switch (socket.type) { + case SocketType::BOOLEAN_ARRAY: + set(socket, get_socket_value<array<bool>>(&other, socket)); + break; + case SocketType::FLOAT_ARRAY: + set(socket, get_socket_value<array<float>>(&other, socket)); + break; + case SocketType::INT_ARRAY: + set(socket, get_socket_value<array<int>>(&other, socket)); + break; + case SocketType::COLOR_ARRAY: + case SocketType::VECTOR_ARRAY: + case SocketType::POINT_ARRAY: + case SocketType::NORMAL_ARRAY: + set(socket, get_socket_value<array<float3>>(&other, socket)); + break; + case SocketType::POINT2_ARRAY: + set(socket, get_socket_value<array<float2>>(&other, socket)); + break; + case SocketType::STRING_ARRAY: + set(socket, get_socket_value<array<ustring>>(&other, socket)); + break; + case SocketType::TRANSFORM_ARRAY: + set(socket, get_socket_value<array<Transform>>(&other, socket)); + break; + case SocketType::NODE_ARRAY: + set(socket, get_socket_value<array<Node *>>(&other, socket)); + break; + default: + assert(0); + break; + } + } + else { + switch (socket.type) { + case SocketType::BOOLEAN: + set(socket, get_socket_value<bool>(&other, socket)); + break; + case SocketType::FLOAT: + set(socket, get_socket_value<float>(&other, socket)); + break; + case SocketType::INT: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::UINT: + set(socket, get_socket_value<uint>(&other, socket)); + break; + case SocketType::COLOR: + case SocketType::VECTOR: + case SocketType::POINT: + case SocketType::NORMAL: + set(socket, get_socket_value<float3>(&other, socket)); + break; + case SocketType::POINT2: + set(socket, get_socket_value<float2>(&other, socket)); + break; + case SocketType::STRING: + set(socket, get_socket_value<ustring>(&other, socket)); + break; + case SocketType::ENUM: + set(socket, get_socket_value<int>(&other, socket)); + break; + case SocketType::TRANSFORM: + set(socket, get_socket_value<Transform>(&other, socket)); + break; + case SocketType::NODE: + set(socket, get_socket_value<Node *>(&other, socket)); + break; + default: + assert(0); + break; + } + } +} + template<typename T> static bool is_array_equal(const Node *node, const Node *other, const SocketType &socket) { diff --git a/intern/cycles/graph/node.h b/intern/cycles/graph/node.h index 16bd5e4358a..2fc9a1e0281 100644 --- a/intern/cycles/graph/node.h +++ b/intern/cycles/graph/node.h @@ -29,6 +29,66 @@ struct Node; struct NodeType; struct Transform; +/* Note: in the following macros we use "type const &" instead of "const type &" + * to avoid issues when pasting a pointer type. */ +#define NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) \ + const SocketType *get_##name##_socket() const \ + { \ + static const SocketType *socket = type->find_input(ustring(string_name)); \ + return socket; \ + } \ + bool name##_is_modified() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return socket_is_modified(*socket); \ + } \ + void tag_##name##_modified() \ + { \ + const SocketType *socket = get_##name##_socket(); \ + socket_modified |= socket->modified_flag_bit; \ + } \ + type_ const &get_##name() const \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return get_socket_value<type_>(this, *socket); \ + } + +#define NODE_SOCKET_API_BASE(type_, name, string_name) \ + protected: \ + type_ name; \ +\ + public: \ + NODE_SOCKET_API_BASE_METHODS(type_, name, string_name) + +#define NODE_SOCKET_API(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } + +#define NODE_SOCKET_API_ARRAY(type_, name) \ + NODE_SOCKET_API_BASE(type_, name, #name) \ + void set_##name(type_ &value) \ + { \ + const SocketType *socket = get_##name##_socket(); \ + this->set(*socket, value); \ + } \ + type_ &get_##name() \ + { \ + const SocketType *socket = get_##name##_socket(); \ + return get_socket_value<type_>(this, *socket); \ + } + +#define NODE_SOCKET_API_STRUCT_MEMBER(type_, name, member) \ + NODE_SOCKET_API_BASE_METHODS(type_, name##_##member, #name "." #member) \ + void set_##name##_##member(type_ value) \ + { \ + const SocketType *socket = get_##name##_##member##_socket(); \ + this->set(*socket, value); \ + } + /* Node */ struct NodeOwner { @@ -88,6 +148,7 @@ struct Node { void set_default_value(const SocketType &input); bool equals_value(const Node &other, const SocketType &input) const; void copy_value(const SocketType &input, const Node &other, const SocketType &other_input); + void set_value(const SocketType &input, const Node &other, const SocketType &other_input); /* equals */ bool equals(const Node &other) const; @@ -119,6 +180,11 @@ struct Node { protected: const NodeOwner *owner; + template<typename T> static T &get_socket_value(const Node *node, const SocketType &socket) + { + return (T &)*(((char *)node) + socket.struct_offset); + } + SocketModifiedFlags socket_modified; template<typename T> void set_if_different(const SocketType &input, T value); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 26d7a7eee71..c39c67afb5a 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -649,13 +649,13 @@ include_directories(SYSTEM ${INC_SYS}) if(WITH_COMPILER_ASAN) if(CMAKE_COMPILER_IS_GNUCC AND (NOT WITH_CYCLES_KERNEL_ASAN)) # GCC hangs compiling the big kernel files with asan and release, so disable by default. - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-sanitize=all") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-sanitize=vptr") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-sanitize=all") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-sanitize=vptr") elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") # With OSL, Cycles disables rtti in some modules, wich then breaks at linking # when trying to use vptr sanitizer (included into 'undefined' general option). - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fno-sanitize=vptr") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-sanitize=vptr") + string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -fno-sanitize=vptr") + string(APPEND CMAKE_CXX_FLAGS_DEBUG " -fno-sanitize=vptr") endif() endif() diff --git a/intern/cycles/kernel/geom/geom_attribute.h b/intern/cycles/kernel/geom/geom_attribute.h index e1b0e6fb81c..b37797ac21b 100644 --- a/intern/cycles/kernel/geom/geom_attribute.h +++ b/intern/cycles/kernel/geom/geom_attribute.h @@ -66,9 +66,17 @@ ccl_device_inline AttributeDescriptor find_attribute(KernelGlobals *kg, while (attr_map.x != id) { if (UNLIKELY(attr_map.x == ATTR_STD_NONE)) { - return attribute_not_found(); + if (UNLIKELY(attr_map.y == 0)) { + return attribute_not_found(); + } + else { + /* Chain jump to a different part of the table. */ + attr_offset = attr_map.z; + } + } + else { + attr_offset += ATTR_PRIM_TYPES; } - attr_offset += ATTR_PRIM_TYPES; attr_map = kernel_tex_fetch(__attributes_map, attr_offset); } diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index 6ff0c7f2044..b5a62a31ca9 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -28,18 +28,7 @@ CCL_NAMESPACE_BEGIN ccl_device float curve_attribute_float( KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { - if (desc.element == ATTR_ELEMENT_CURVE) { -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; -# endif - - return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim); - } - else if (desc.element == ATTR_ELEMENT_CURVE_KEY || - desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { + if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; @@ -56,16 +45,6 @@ ccl_device float curve_attribute_float( return (1.0f - sd->u) * f0 + sd->u * f1; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; -# endif - - return kernel_tex_fetch(__attributes_float, desc.offset); - } else { # ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -74,7 +53,14 @@ ccl_device float curve_attribute_float( *dy = 0.0f; # endif - return 0.0f; + if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float, offset); + } + else { + return 0.0f; + } } } @@ -84,22 +70,7 @@ ccl_device float2 curve_attribute_float2(KernelGlobals *kg, float2 *dx, float2 *dy) { - if (desc.element == ATTR_ELEMENT_CURVE) { - /* idea: we can't derive any useful differentials here, but for tiled - * mipmap image caching it would be useful to avoid reading the highest - * detail level always. maybe a derivative based on the hair density - * could be computed somehow? */ -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); -# endif - - return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim); - } - else if (desc.element == ATTR_ELEMENT_CURVE_KEY || - desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { + if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; @@ -116,17 +87,11 @@ ccl_device float2 curve_attribute_float2(KernelGlobals *kg, return (1.0f - sd->u) * f0 + sd->u * f1; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); -# endif - - return kernel_tex_fetch(__attributes_float2, desc.offset); - } else { + /* idea: we can't derive any useful differentials here, but for tiled + * mipmap image caching it would be useful to avoid reading the highest + * detail level always. maybe a derivative based on the hair density + * could be computed somehow? */ # ifdef __RAY_DIFFERENTIALS__ if (dx) *dx = make_float2(0.0f, 0.0f); @@ -134,7 +99,14 @@ ccl_device float2 curve_attribute_float2(KernelGlobals *kg, *dy = make_float2(0.0f, 0.0f); # endif - return make_float2(0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float2, offset); + } + else { + return make_float2(0.0f, 0.0f); + } } } @@ -144,22 +116,7 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, float3 *dx, float3 *dy) { - if (desc.element == ATTR_ELEMENT_CURVE) { - /* idea: we can't derive any useful differentials here, but for tiled - * mipmap image caching it would be useful to avoid reading the highest - * detail level always. maybe a derivative based on the hair density - * could be computed somehow? */ -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); -# endif - - return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim)); - } - else if (desc.element == ATTR_ELEMENT_CURVE_KEY || - desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { + if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; @@ -176,16 +133,6 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, return (1.0f - sd->u) * f0 + sd->u * f1; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); -# endif - - return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset)); - } else { # ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -194,7 +141,14 @@ ccl_device float3 curve_attribute_float3(KernelGlobals *kg, *dy = make_float3(0.0f, 0.0f, 0.0f); # endif - return make_float3(0.0f, 0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : + desc.offset; + return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset)); + } + else { + return make_float3(0.0f, 0.0f, 0.0f); + } } } @@ -204,22 +158,7 @@ ccl_device float4 curve_attribute_float4(KernelGlobals *kg, float4 *dx, float4 *dy) { - if (desc.element == ATTR_ELEMENT_CURVE) { - /* idea: we can't derive any useful differentials here, but for tiled - * mipmap image caching it would be useful to avoid reading the highest - * detail level always. maybe a derivative based on the hair density - * could be computed somehow? */ -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); -# endif - - return kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim); - } - else if (desc.element == ATTR_ELEMENT_CURVE_KEY || - desc.element == ATTR_ELEMENT_CURVE_KEY_MOTION) { + if (desc.element & (ATTR_ELEMENT_CURVE_KEY | ATTR_ELEMENT_CURVE_KEY_MOTION)) { float4 curvedata = kernel_tex_fetch(__curves, sd->prim); int k0 = __float_as_int(curvedata.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type); int k1 = k0 + 1; @@ -236,16 +175,6 @@ ccl_device float4 curve_attribute_float4(KernelGlobals *kg, return (1.0f - sd->u) * f0 + sd->u * f1; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { -# ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); -# endif - - return kernel_tex_fetch(__attributes_float3, desc.offset); - } else { # ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -254,7 +183,14 @@ ccl_device float4 curve_attribute_float4(KernelGlobals *kg, *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); # endif - return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_CURVE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_CURVE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float3, offset); + } + else { + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } } } diff --git a/intern/cycles/kernel/geom/geom_patch.h b/intern/cycles/kernel/geom/geom_patch.h index 8b4b91b96c8..1de05fa9e0d 100644 --- a/intern/cycles/kernel/geom/geom_patch.h +++ b/intern/cycles/kernel/geom/geom_patch.h @@ -380,6 +380,43 @@ ccl_device float3 patch_eval_float3(KernelGlobals *kg, return val; } +ccl_device float4 patch_eval_float4(KernelGlobals *kg, + const ShaderData *sd, + int offset, + int patch, + float u, + float v, + int channel, + float4 *du, + float4 *dv) +{ + int indices[PATCH_MAX_CONTROL_VERTS]; + float weights[PATCH_MAX_CONTROL_VERTS]; + float weights_du[PATCH_MAX_CONTROL_VERTS]; + float weights_dv[PATCH_MAX_CONTROL_VERTS]; + + int num_control = patch_eval_control_verts( + kg, sd->object, patch, u, v, channel, indices, weights, weights_du, weights_dv); + + float4 val = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (du) + *du = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dv) + *dv = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + for (int i = 0; i < num_control; i++) { + float4 v = kernel_tex_fetch(__attributes_float3, offset + indices[i]); + + val += v * weights[i]; + if (du) + *du += v * weights_du[i]; + if (dv) + *dv += v * weights_dv[i]; + } + + return val; +} + ccl_device float4 patch_eval_uchar4(KernelGlobals *kg, const ShaderData *sd, int offset, diff --git a/intern/cycles/kernel/geom/geom_primitive.h b/intern/cycles/kernel/geom/geom_primitive.h index 997abf438d0..2c31e5cee03 100644 --- a/intern/cycles/kernel/geom/geom_primitive.h +++ b/intern/cycles/kernel/geom/geom_primitive.h @@ -21,38 +21,11 @@ CCL_NAMESPACE_BEGIN -/* Generic primitive attribute reading functions */ -ccl_device_inline float primitive_attribute_float( - KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) -{ - if (sd->type & PRIMITIVE_ALL_TRIANGLE) { - if (subd_triangle_patch(kg, sd) == ~0) - return triangle_attribute_float(kg, sd, desc, dx, dy); - else - return subd_triangle_attribute_float(kg, sd, desc, dx, dy); - } -#ifdef __HAIR__ - else if (sd->type & PRIMITIVE_ALL_CURVE) { - return curve_attribute_float(kg, sd, desc, dx, dy); - } -#endif -#ifdef __VOLUME__ - else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; - return volume_attribute_float(kg, sd, desc); - } -#endif - else { - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; - return 0.0f; - } -} +/* Surface Attributes + * + * Read geometry attributes for surface shading. This is distinct from volume + * attributes for performance, mainly for GPU performance to avoid bringing in + * heavy volume interpolation code. */ ccl_device_inline float primitive_surface_attribute_float( KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) @@ -77,25 +50,11 @@ ccl_device_inline float primitive_surface_attribute_float( } } -#ifdef __VOLUME__ -ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc) -{ - if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { - return volume_attribute_float(kg, sd, desc); - } - else { - return 0.0f; - } -} -#endif - -ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc, - float2 *dx, - float2 *dy) +ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float2 *dx, + float2 *dy) { if (sd->type & PRIMITIVE_ALL_TRIANGLE) { if (subd_triangle_patch(kg, sd) == ~0) @@ -108,16 +67,6 @@ ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg, return curve_attribute_float2(kg, sd, desc, dx, dy); } #endif -#ifdef __VOLUME__ - else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { - kernel_assert(0); - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); - return make_float2(0.0f, 0.0f); - } -#endif else { if (dx) *dx = make_float2(0.0f, 0.0f); @@ -127,11 +76,11 @@ ccl_device_inline float2 primitive_attribute_float2(KernelGlobals *kg, } } -ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc, - float3 *dx, - float3 *dy) +ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float3 *dx, + float3 *dy) { if (sd->type & PRIMITIVE_ALL_TRIANGLE) { if (subd_triangle_patch(kg, sd) == ~0) @@ -144,15 +93,6 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, return curve_attribute_float3(kg, sd, desc, dx, dy); } #endif -#ifdef __VOLUME__ - else if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); - return volume_attribute_float3(kg, sd, desc); - } -#endif else { if (dx) *dx = make_float3(0.0f, 0.0f, 0.0f); @@ -162,11 +102,11 @@ ccl_device_inline float3 primitive_attribute_float3(KernelGlobals *kg, } } -ccl_device_inline float4 primitive_attribute_float4(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc, - float4 *dx, - float4 *dy) +ccl_device_inline float4 primitive_surface_attribute_float4(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc, + float4 *dx, + float4 *dy) { if (sd->type & PRIMITIVE_ALL_TRIANGLE) { if (subd_triangle_patch(kg, sd) == ~0) @@ -188,68 +128,52 @@ ccl_device_inline float4 primitive_attribute_float4(KernelGlobals *kg, } } -ccl_device_inline float2 primitive_surface_attribute_float2(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc, - float2 *dx, - float2 *dy) +#ifdef __VOLUME__ +/* Volume Attributes + * + * Read geometry attributes for volume shading. This is distinct from surface + * attributes for performance, mainly for GPU performance to avoid bringing in + * heavy volume interpolation code. */ + +ccl_device_inline bool primitive_is_volume_attribute(const ShaderData *sd, + const AttributeDescriptor desc) { - if (sd->type & PRIMITIVE_ALL_TRIANGLE) { - if (subd_triangle_patch(kg, sd) == ~0) - return triangle_attribute_float2(kg, sd, desc, dx, dy); - else - return subd_triangle_attribute_float2(kg, sd, desc, dx, dy); - } -#ifdef __HAIR__ - else if (sd->type & PRIMITIVE_ALL_CURVE) { - return curve_attribute_float2(kg, sd, desc, dx, dy); + return (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL); +} + +ccl_device_inline float primitive_volume_attribute_float(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc) +{ + if (primitive_is_volume_attribute(sd, desc)) { + return volume_attribute_value_to_float(volume_attribute_float4(kg, sd, desc)); } -#endif else { - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); - return make_float2(0.0f, 0.0f); + return 0.0f; } } -ccl_device_inline float3 primitive_surface_attribute_float3(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc, - float3 *dx, - float3 *dy) +ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg, + const ShaderData *sd, + const AttributeDescriptor desc) { - if (sd->type & PRIMITIVE_ALL_TRIANGLE) { - if (subd_triangle_patch(kg, sd) == ~0) - return triangle_attribute_float3(kg, sd, desc, dx, dy); - else - return subd_triangle_attribute_float3(kg, sd, desc, dx, dy); - } -#ifdef __HAIR__ - else if (sd->type & PRIMITIVE_ALL_CURVE) { - return curve_attribute_float3(kg, sd, desc, dx, dy); + if (primitive_is_volume_attribute(sd, desc)) { + return volume_attribute_value_to_float3(volume_attribute_float4(kg, sd, desc)); } -#endif else { - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); return make_float3(0.0f, 0.0f, 0.0f); } } -#ifdef __VOLUME__ -ccl_device_inline float3 primitive_volume_attribute_float3(KernelGlobals *kg, +ccl_device_inline float4 primitive_volume_attribute_float4(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc) { - if (sd->object != OBJECT_NONE && desc.element == ATTR_ELEMENT_VOXEL) { - return volume_attribute_float3(kg, sd, desc); + if (primitive_is_volume_attribute(sd, desc)) { + return volume_attribute_float4(kg, sd, desc); } else { - return make_float3(0.0f, 0.0f, 0.0f); + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); } } #endif diff --git a/intern/cycles/kernel/geom/geom_subd_triangle.h b/intern/cycles/kernel/geom/geom_subd_triangle.h index 3eef9857ae3..2a569852659 100644 --- a/intern/cycles/kernel/geom/geom_subd_triangle.h +++ b/intern/cycles/kernel/geom/geom_subd_triangle.h @@ -539,9 +539,13 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, /* p is [s, t] */ float2 p = dpdu * sd->u + dpdv * sd->v + uv[2]; - float4 dads, dadt; - - float4 a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); + float4 a, dads, dadt; + if (desc.type == NODE_ATTR_RGBA) { + a = patch_eval_uchar4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); + } + else { + a = patch_eval_float4(kg, sd, desc.offset, patch, p.x, p.y, 0, &dads, &dadt); + } # ifdef __RAY_DIFFERENTIALS__ if (dx || dy) { @@ -570,25 +574,70 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, } } # endif + return a; } else #endif /* __PATCH_EVAL__ */ - if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { + if (desc.element == ATTR_ELEMENT_FACE) { + if (dx) + *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (dy) + *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + return kernel_tex_fetch(__attributes_float3, + desc.offset + subd_triangle_patch_face(kg, patch)); + } + else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { + float2 uv[3]; + subd_triangle_patch_uv(kg, sd, uv); + + uint4 v = subd_triangle_patch_indices(kg, patch); + + float4 f0 = kernel_tex_fetch(__attributes_float3, desc.offset + v.x); + float4 f1 = kernel_tex_fetch(__attributes_float3, desc.offset + v.y); + float4 f2 = kernel_tex_fetch(__attributes_float3, desc.offset + v.z); + float4 f3 = kernel_tex_fetch(__attributes_float3, desc.offset + v.w); + + if (subd_triangle_patch_num_corners(kg, patch) != 4) { + f1 = (f1 + f0) * 0.5f; + f3 = (f3 + f0) * 0.5f; + } + + float4 a = mix(mix(f0, f1, uv[0].x), mix(f3, f2, uv[0].x), uv[0].y); + float4 b = mix(mix(f0, f1, uv[1].x), mix(f3, f2, uv[1].x), uv[1].y); + float4 c = mix(mix(f0, f1, uv[2].x), mix(f3, f2, uv[2].x), uv[2].y); + +#ifdef __RAY_DIFFERENTIALS__ + if (dx) + *dx = sd->du.dx * a + sd->dv.dx * b - (sd->du.dx + sd->dv.dx) * c; + if (dy) + *dy = sd->du.dy * a + sd->dv.dy * b - (sd->du.dy + sd->dv.dy) * c; +#endif + + return sd->u * a + sd->v * b + (1.0f - sd->u - sd->v) * c; + } + else if (desc.element == ATTR_ELEMENT_CORNER || desc.element == ATTR_ELEMENT_CORNER_BYTE) { float2 uv[3]; subd_triangle_patch_uv(kg, sd, uv); int corners[4]; subd_triangle_patch_corners(kg, patch, corners); - float4 f0 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); - float4 f1 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); - float4 f2 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); - float4 f3 = color_uchar4_to_float4( - kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); + float4 f0, f1, f2, f3; + + if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { + f0 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[0] + desc.offset)); + f1 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[1] + desc.offset)); + f2 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[2] + desc.offset)); + f3 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, corners[3] + desc.offset)); + } + else { + f0 = kernel_tex_fetch(__attributes_float3, corners[0] + desc.offset); + f1 = kernel_tex_fetch(__attributes_float3, corners[1] + desc.offset); + f2 = kernel_tex_fetch(__attributes_float3, corners[2] + desc.offset); + f3 = kernel_tex_fetch(__attributes_float3, corners[3] + desc.offset); + } if (subd_triangle_patch_num_corners(kg, patch) != 4) { f1 = (f1 + f0) * 0.5f; @@ -614,7 +663,7 @@ ccl_device_noinline float4 subd_triangle_attribute_float4(KernelGlobals *kg, if (dy) *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - return color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset)); + return kernel_tex_fetch(__attributes_float3, desc.offset); } else { if (dx) diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 0278f3ade8e..2d9da23371e 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -114,35 +114,21 @@ ccl_device_inline void triangle_dPdudv(KernelGlobals *kg, ccl_device float triangle_attribute_float( KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy) { - if (desc.element == ATTR_ELEMENT_FACE) { - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; - - return kernel_tex_fetch(__attributes_float, desc.offset + sd->prim); - } - else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); - - float f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x); - float f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y); - float f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z); - -#ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; - if (dy) - *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; -#endif - - return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; - } - else if (desc.element == ATTR_ELEMENT_CORNER) { - int tri = desc.offset + sd->prim * 3; - float f0 = kernel_tex_fetch(__attributes_float, tri + 0); - float f1 = kernel_tex_fetch(__attributes_float, tri + 1); - float f2 = kernel_tex_fetch(__attributes_float, tri + 2); + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) { + float f0, f1, f2; + + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); + f0 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.x); + f1 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.y); + f2 = kernel_tex_fetch(__attributes_float, desc.offset + tri_vindex.z); + } + else { + const int tri = desc.offset + sd->prim * 3; + f0 = kernel_tex_fetch(__attributes_float, tri + 0); + f1 = kernel_tex_fetch(__attributes_float, tri + 1); + f2 = kernel_tex_fetch(__attributes_float, tri + 2); + } #ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -153,21 +139,22 @@ ccl_device float triangle_attribute_float( return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { - if (dx) - *dx = 0.0f; - if (dy) - *dy = 0.0f; - - return kernel_tex_fetch(__attributes_float, desc.offset); - } else { +#ifdef __RAY_DIFFERENTIALS__ if (dx) *dx = 0.0f; if (dy) *dy = 0.0f; +#endif - return 0.0f; + if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float, offset); + } + else { + return 0.0f; + } } } @@ -177,35 +164,17 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals *kg, float2 *dx, float2 *dy) { - if (desc.element == ATTR_ELEMENT_FACE) { - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); - - return kernel_tex_fetch(__attributes_float2, desc.offset + sd->prim); - } - else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); - - float2 f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x); - float2 f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y); - float2 f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z); - -#ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; - if (dy) - *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; -#endif - - return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; - } - else if (desc.element == ATTR_ELEMENT_CORNER) { - int tri = desc.offset + sd->prim * 3; + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) { float2 f0, f1, f2; - if (desc.element == ATTR_ELEMENT_CORNER) { + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); + f0 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.x); + f1 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.y); + f2 = kernel_tex_fetch(__attributes_float2, desc.offset + tri_vindex.z); + } + else { + const int tri = desc.offset + sd->prim * 3; f0 = kernel_tex_fetch(__attributes_float2, tri + 0); f1 = kernel_tex_fetch(__attributes_float2, tri + 1); f2 = kernel_tex_fetch(__attributes_float2, tri + 2); @@ -220,21 +189,22 @@ ccl_device float2 triangle_attribute_float2(KernelGlobals *kg, return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { - if (dx) - *dx = make_float2(0.0f, 0.0f); - if (dy) - *dy = make_float2(0.0f, 0.0f); - - return kernel_tex_fetch(__attributes_float2, desc.offset); - } else { +#ifdef __RAY_DIFFERENTIALS__ if (dx) *dx = make_float2(0.0f, 0.0f); if (dy) *dy = make_float2(0.0f, 0.0f); +#endif - return make_float2(0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float2, offset); + } + else { + return make_float2(0.0f, 0.0f); + } } } @@ -244,40 +214,21 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, float3 *dx, float3 *dy) { - if (desc.element == ATTR_ELEMENT_FACE) { - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); - - return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + sd->prim)); - } - else if (desc.element == ATTR_ELEMENT_VERTEX || desc.element == ATTR_ELEMENT_VERTEX_MOTION) { - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); - - float3 f0 = float4_to_float3( - kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x)); - float3 f1 = float4_to_float3( - kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y)); - float3 f2 = float4_to_float3( - kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z)); - -#ifdef __RAY_DIFFERENTIALS__ - if (dx) - *dx = sd->du.dx * f0 + sd->dv.dx * f1 - (sd->du.dx + sd->dv.dx) * f2; - if (dy) - *dy = sd->du.dy * f0 + sd->dv.dy * f1 - (sd->du.dy + sd->dv.dy) * f2; -#endif - - return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; - } - else if (desc.element == ATTR_ELEMENT_CORNER) { - int tri = desc.offset + sd->prim * 3; + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER)) { float3 f0, f1, f2; - f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); - f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); - f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); + f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x)); + f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y)); + f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z)); + } + else { + const int tri = desc.offset + sd->prim * 3; + f0 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 0)); + f1 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 1)); + f2 = float4_to_float3(kernel_tex_fetch(__attributes_float3, tri + 2)); + } #ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -288,21 +239,22 @@ ccl_device float3 triangle_attribute_float3(KernelGlobals *kg, return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { - if (dx) - *dx = make_float3(0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float3(0.0f, 0.0f, 0.0f); - - return float4_to_float3(kernel_tex_fetch(__attributes_float3, desc.offset)); - } else { +#ifdef __RAY_DIFFERENTIALS__ if (dx) *dx = make_float3(0.0f, 0.0f, 0.0f); if (dy) *dy = make_float3(0.0f, 0.0f, 0.0f); +#endif - return make_float3(0.0f, 0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : + desc.offset; + return float4_to_float3(kernel_tex_fetch(__attributes_float3, offset)); + } + else { + return make_float3(0.0f, 0.0f, 0.0f); + } } } @@ -312,21 +264,29 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals *kg, float4 *dx, float4 *dy) { - if (desc.element == ATTR_ELEMENT_CORNER_BYTE || desc.element == ATTR_ELEMENT_VERTEX) { + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION | ATTR_ELEMENT_CORNER | + ATTR_ELEMENT_CORNER_BYTE)) { float4 f0, f1, f2; - if (desc.element == ATTR_ELEMENT_CORNER_BYTE) { - int tri = desc.offset + sd->prim * 3; - f0 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0)); - f1 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1)); - f2 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2)); - } - else { - uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); + if (desc.element & (ATTR_ELEMENT_VERTEX | ATTR_ELEMENT_VERTEX_MOTION)) { + const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, sd->prim); f0 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.x); f1 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.y); f2 = kernel_tex_fetch(__attributes_float3, desc.offset + tri_vindex.z); } + else { + const int tri = desc.offset + sd->prim * 3; + if (desc.element == ATTR_ELEMENT_CORNER) { + f0 = kernel_tex_fetch(__attributes_float3, tri + 0); + f1 = kernel_tex_fetch(__attributes_float3, tri + 1); + f2 = kernel_tex_fetch(__attributes_float3, tri + 2); + } + else { + f0 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 0)); + f1 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 1)); + f2 = color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, tri + 2)); + } + } #ifdef __RAY_DIFFERENTIALS__ if (dx) @@ -337,21 +297,22 @@ ccl_device float4 triangle_attribute_float4(KernelGlobals *kg, return sd->u * f0 + sd->v * f1 + (1.0f - sd->u - sd->v) * f2; } - else if (desc.element == ATTR_ELEMENT_OBJECT || desc.element == ATTR_ELEMENT_MESH) { - if (dx) - *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - if (dy) - *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); - - return color_uchar4_to_float4(kernel_tex_fetch(__attributes_uchar4, desc.offset)); - } else { +#ifdef __RAY_DIFFERENTIALS__ if (dx) *dx = make_float4(0.0f, 0.0f, 0.0f, 0.0f); if (dy) *dy = make_float4(0.0f, 0.0f, 0.0f, 0.0f); +#endif - return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + if (desc.element & (ATTR_ELEMENT_FACE | ATTR_ELEMENT_OBJECT | ATTR_ELEMENT_MESH)) { + const int offset = (desc.element == ATTR_ELEMENT_FACE) ? desc.offset + sd->prim : + desc.offset; + return kernel_tex_fetch(__attributes_float3, offset); + } + else { + return make_float4(0.0f, 0.0f, 0.0f, 0.0f); + } } } diff --git a/intern/cycles/kernel/geom/geom_volume.h b/intern/cycles/kernel/geom/geom_volume.h index f43a7841b46..13b027a5f6c 100644 --- a/intern/cycles/kernel/geom/geom_volume.h +++ b/intern/cycles/kernel/geom/geom_volume.h @@ -47,38 +47,39 @@ ccl_device_inline float3 volume_normalized_position(KernelGlobals *kg, return P; } -ccl_device float volume_attribute_float(KernelGlobals *kg, - const ShaderData *sd, - const AttributeDescriptor desc) +ccl_device float volume_attribute_value_to_float(const float4 value) { - /* todo: optimize this so we don't have to transform both here and in - * kernel_tex_image_interp_3d when possible. Also could optimize for the - * common case where transform is translation/scale only. */ - float3 P = sd->P; - object_inverse_position_transform(kg, sd, &P); - InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC : - INTERPOLATION_NONE; - float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp); - return average(float4_to_float3(r)); + return average(float4_to_float3(value)); } -ccl_device float3 volume_attribute_float3(KernelGlobals *kg, +ccl_device float volume_attribute_value_to_alpha(const float4 value) +{ + return value.w; +} + +ccl_device float3 volume_attribute_value_to_float3(const float4 value) +{ + if (value.w > 1e-6f && value.w != 1.0f) { + /* For RGBA colors, unpremultiply after interpolation. */ + return float4_to_float3(value) / value.w; + } + else { + return float4_to_float3(value); + } +} + +ccl_device float4 volume_attribute_float4(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc) { + /* todo: optimize this so we don't have to transform both here and in + * kernel_tex_image_interp_3d when possible. Also could optimize for the + * common case where transform is translation/scale only. */ float3 P = sd->P; object_inverse_position_transform(kg, sd, &P); InterpolationType interp = (sd->flag & SD_VOLUME_CUBIC) ? INTERPOLATION_CUBIC : INTERPOLATION_NONE; - float4 r = kernel_tex_image_interp_3d(kg, desc.offset, P, interp); - - if (r.w > 1e-6f && r.w != 1.0f) { - /* For RGBA colors, unpremultiply after interpolation. */ - return float4_to_float3(r) / r.w; - } - else { - return float4_to_float3(r); - } + return kernel_tex_image_interp_3d(kg, desc.offset, P, interp); } #endif diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h index 4094e173da9..ea3b78b7cef 100644 --- a/intern/cycles/kernel/kernel_compat_cuda.h +++ b/intern/cycles/kernel/kernel_compat_cuda.h @@ -32,8 +32,12 @@ /* Manual definitions so we can compile without CUDA toolkit. */ +#ifdef __CUDACC_RTC__ typedef unsigned int uint32_t; typedef unsigned long long uint64_t; +#else +# include <stdint.h> +#endif typedef unsigned short half; typedef unsigned long long CUtexObject; diff --git a/intern/cycles/kernel/kernel_compat_optix.h b/intern/cycles/kernel/kernel_compat_optix.h index e58d8b2aa63..064c99ca100 100644 --- a/intern/cycles/kernel/kernel_compat_optix.h +++ b/intern/cycles/kernel/kernel_compat_optix.h @@ -31,8 +31,12 @@ # define ATTR_FALLTHROUGH #endif +#ifdef __CUDACC_RTC__ typedef unsigned int uint32_t; typedef unsigned long long uint64_t; +#else +# include <stdint.h> +#endif typedef unsigned short half; typedef unsigned long long CUtexObject; diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 77e134da4b0..8e2b0e46a66 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -733,18 +733,18 @@ typedef enum AttributePrimitive { } AttributePrimitive; typedef enum AttributeElement { - ATTR_ELEMENT_NONE, - ATTR_ELEMENT_OBJECT, - ATTR_ELEMENT_MESH, - ATTR_ELEMENT_FACE, - ATTR_ELEMENT_VERTEX, - ATTR_ELEMENT_VERTEX_MOTION, - ATTR_ELEMENT_CORNER, - ATTR_ELEMENT_CORNER_BYTE, - ATTR_ELEMENT_CURVE, - ATTR_ELEMENT_CURVE_KEY, - ATTR_ELEMENT_CURVE_KEY_MOTION, - ATTR_ELEMENT_VOXEL + ATTR_ELEMENT_NONE = 0, + ATTR_ELEMENT_OBJECT = (1 << 0), + ATTR_ELEMENT_MESH = (1 << 1), + ATTR_ELEMENT_FACE = (1 << 2), + ATTR_ELEMENT_VERTEX = (1 << 3), + ATTR_ELEMENT_VERTEX_MOTION = (1 << 4), + ATTR_ELEMENT_CORNER = (1 << 5), + ATTR_ELEMENT_CORNER_BYTE = (1 << 6), + ATTR_ELEMENT_CURVE = (1 << 7), + ATTR_ELEMENT_CURVE_KEY = (1 << 8), + ATTR_ELEMENT_CURVE_KEY_MOTION = (1 << 9), + ATTR_ELEMENT_VOXEL = (1 << 10) } AttributeElement; typedef enum AttributeStandard { diff --git a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h index 347d0fec7f5..b466b41f456 100644 --- a/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h +++ b/intern/cycles/kernel/kernels/cpu/kernel_cpu_image.h @@ -490,21 +490,17 @@ template<typename T> struct NanoVDBInterpolator { static ccl_always_inline float4 interp_3d(const TextureInfo &info, float x, float y, float z, InterpolationType interp) { + const nanovdb::Vec3f xyz(x, y, z); nanovdb::NanoGrid<T> *const grid = (nanovdb::NanoGrid<T> *)info.data; const nanovdb::NanoRoot<T> &root = grid->tree().root(); - const nanovdb::Coord off(root.bbox().min()); - const nanovdb::Coord dim(root.bbox().dim()); - const nanovdb::Vec3f xyz(off[0] + x * dim[0], off[1] + y * dim[1], off[2] + z * dim[2]); - typedef nanovdb::ReadAccessor<nanovdb::NanoRoot<T>> ReadAccessorT; switch ((interp == INTERPOLATION_NONE) ? info.interpolation : interp) { - default: - case INTERPOLATION_LINEAR: - return read(nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz)); case INTERPOLATION_CLOSEST: return read(nanovdb::SampleFromVoxels<ReadAccessorT, 0, false>(root)(xyz)); - case INTERPOLATION_CUBIC: + case INTERPOLATION_LINEAR: + return read(nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz)); + default: return read(nanovdb::SampleFromVoxels<ReadAccessorT, 3, false>(root)(xyz)); } } diff --git a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h index 5a005a3f65b..c2a0ee06dbc 100644 --- a/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h +++ b/intern/cycles/kernel/kernels/cuda/kernel_cuda_image.h @@ -130,21 +130,17 @@ template<typename T> ccl_device_inline T kernel_tex_image_interp_nanovdb( const TextureInfo &info, float x, float y, float z, uint interpolation) { + const nanovdb::Vec3f xyz(x, y, z); nanovdb::NanoGrid<T> *const grid = (nanovdb::NanoGrid<T> *)info.data; const nanovdb::NanoRoot<T> &root = grid->tree().root(); - const nanovdb::Coord off(root.bbox().min()); - const nanovdb::Coord dim(root.bbox().dim()); - const nanovdb::Vec3f xyz(off[0] + x * dim[0], off[1] + y * dim[1], off[2] + z * dim[2]); - typedef nanovdb::ReadAccessor<nanovdb::NanoRoot<T>> ReadAccessorT; switch (interpolation) { - default: - case INTERPOLATION_LINEAR: - return nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz); case INTERPOLATION_CLOSEST: return nanovdb::SampleFromVoxels<ReadAccessorT, 0, false>(root)(xyz); - case INTERPOLATION_CUBIC: + case INTERPOLATION_LINEAR: + return nanovdb::SampleFromVoxels<ReadAccessorT, 1, false>(root)(xyz); + default: return nanovdb::SampleFromVoxels<ReadAccessorT, 3, false>(root)(xyz); } } diff --git a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h index 2f44f249c5f..cbf9a208112 100644 --- a/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h +++ b/intern/cycles/kernel/kernels/opencl/kernel_opencl_image.h @@ -229,32 +229,29 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float3 P uint interpolation = (interp == INTERPOLATION_NONE) ? info->interpolation : interp; #ifdef WITH_NANOVDB + cnanovdb_Vec3F xyz; + xyz.mVec[0] = x; + xyz.mVec[1] = y; + xyz.mVec[2] = z; + if (info->data_type == IMAGE_DATA_TYPE_NANOVDB_FLOAT) { ccl_global cnanovdb_griddata *grid = (ccl_global cnanovdb_griddata *)(kg->buffers[info->cl_buffer] + info->data); const ccl_global cnanovdb_rootdataF *root = cnanovdb_treedata_rootF( cnanovdb_griddata_tree(grid)); - cnanovdb_Vec3F xyz; - xyz.mVec[0] = root->mBBox_min.mVec[0] + - x * (root->mBBox_max.mVec[0] - root->mBBox_min.mVec[0]); - xyz.mVec[1] = root->mBBox_min.mVec[1] + - y * (root->mBBox_max.mVec[1] - root->mBBox_min.mVec[1]); - xyz.mVec[2] = root->mBBox_min.mVec[2] + - z * (root->mBBox_max.mVec[2] - root->mBBox_min.mVec[2]); - cnanovdb_readaccessor acc; cnanovdb_readaccessor_init(&acc, root); float value; switch (interpolation) { + case INTERPOLATION_CLOSEST: + value = cnanovdb_sampleF_nearest(&acc, &xyz); + break; default: case INTERPOLATION_LINEAR: value = cnanovdb_sampleF_trilinear(&acc, &xyz); break; - case INTERPOLATION_CLOSEST: - value = cnanovdb_sampleF_nearest(&acc, &xyz); - break; } return make_float4(value, value, value, 1.0f); } @@ -264,14 +261,6 @@ ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float3 P const ccl_global cnanovdb_rootdataF3 *root = cnanovdb_treedata_rootF3( cnanovdb_griddata_tree(grid)); - cnanovdb_Vec3F xyz; - xyz.mVec[0] = root->mBBox_min.mVec[0] + - x * (root->mBBox_max.mVec[0] - root->mBBox_min.mVec[0]); - xyz.mVec[1] = root->mBBox_min.mVec[1] + - y * (root->mBBox_max.mVec[1] - root->mBBox_min.mVec[1]); - xyz.mVec[2] = root->mBBox_min.mVec[2] + - z * (root->mBBox_max.mVec[2] - root->mBBox_min.mVec[2]); - cnanovdb_readaccessor acc; cnanovdb_readaccessor_init(&acc, root); diff --git a/intern/cycles/kernel/kernels/optix/kernel_optix.cu b/intern/cycles/kernel/kernels/optix/kernel_optix.cu index 3b166e59dfd..fd9065098dd 100644 --- a/intern/cycles/kernel/kernels/optix/kernel_optix.cu +++ b/intern/cycles/kernel/kernels/optix/kernel_optix.cu @@ -320,10 +320,3 @@ extern "C" __global__ void __intersection__curve_all() optix_intersection_curve(prim, type); } #endif - -#ifdef __KERNEL_DEBUG__ -extern "C" __global__ void __exception__kernel_optix_exception() -{ - printf("Unhandled exception occured: code %d!\n", optixGetExceptionCode()); -} -#endif diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt index 8144d480589..3b2d639f3a5 100644 --- a/intern/cycles/kernel/osl/CMakeLists.txt +++ b/intern/cycles/kernel/osl/CMakeLists.txt @@ -47,7 +47,7 @@ set(LIB ) # OSL and LLVM are built without RTTI -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${RTTI_DISABLE_FLAGS}") +string(APPEND CMAKE_CXX_FLAGS " ${RTTI_DISABLE_FLAGS}") if(APPLE) # Disable allocation warning on macOS prior to 10.14: the OSLRenderServices @@ -55,7 +55,7 @@ if(APPLE) # unordered_map_concurrent). This is not something what the SDK supportsm, but # since we take care of allocations ourselves is is OK to ignore the # diagnostic message. - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faligned-allocation") + string(APPEND CMAKE_CXX_FLAGS " -faligned-allocation") endif() include_directories(${INC}) diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index aee1e3a244e..2a4a1dfe325 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -403,8 +403,28 @@ bool OSLRenderServices::get_array_attribute(OSL::ShaderGlobals *sg, static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, void *val) { - if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || - type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { + if (type == TypeFloatArray4) { + float *fval = (float *)val; + fval[0] = f[0].x; + fval[1] = f[0].y; + fval[2] = 0.0f; + fval[3] = 1.0f; + + if (derivatives) { + fval[4] = f[1].x; + fval[5] = f[1].y; + fval[6] = 0.0f; + fval[7] = 0.0f; + + fval[8] = f[2].x; + fval[9] = f[2].y; + fval[10] = 0.0f; + fval[11] = 0.0f; + } + return true; + } + else if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || + type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { float *fval = (float *)val; fval[0] = f[0].x; @@ -438,10 +458,41 @@ static bool set_attribute_float2(float2 f[3], TypeDesc type, bool derivatives, v return false; } +static bool set_attribute_float2(float2 f, TypeDesc type, bool derivatives, void *val) +{ + float2 fv[3]; + + fv[0] = f; + fv[1] = make_float2(0.0f, 0.0f); + fv[2] = make_float2(0.0f, 0.0f); + + return set_attribute_float2(fv, type, derivatives, val); +} + static bool set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val) { - if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || - type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { + if (type == TypeFloatArray4) { + float *fval = (float *)val; + fval[0] = f[0].x; + fval[1] = f[0].y; + fval[2] = f[0].z; + fval[3] = 1.0f; + + if (derivatives) { + fval[4] = f[1].x; + fval[5] = f[1].y; + fval[6] = f[1].z; + fval[7] = 0.0f; + + fval[8] = f[2].x; + fval[9] = f[2].y; + fval[10] = f[2].z; + fval[11] = 0.0f; + } + return true; + } + else if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || + type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { float *fval = (float *)val; fval[0] = f[0].x; @@ -545,14 +596,45 @@ static bool set_attribute_float4(float4 f[3], TypeDesc type, bool derivatives, v return false; } +static bool set_attribute_float4(float4 f, TypeDesc type, bool derivatives, void *val) +{ + float4 fv[3]; + + fv[0] = f; + fv[1] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + fv[2] = make_float4(0.0f, 0.0f, 0.0f, 0.0f); + + return set_attribute_float4(fv, type, derivatives, val); +} + static bool set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val) { - if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || - type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { + if (type == TypeFloatArray4) { float *fval = (float *)val; fval[0] = f[0]; - fval[1] = f[1]; - fval[2] = f[2]; + fval[1] = f[0]; + fval[2] = f[0]; + fval[3] = 1.0f; + + if (derivatives) { + fval[4] = f[1]; + fval[5] = f[1]; + fval[6] = f[1]; + fval[7] = 0.0f; + + fval[8] = f[2]; + fval[9] = f[2]; + fval[10] = f[2]; + fval[11] = 0.0f; + } + return true; + } + else if (type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || + type == TypeDesc::TypeNormal || type == TypeDesc::TypeColor) { + float *fval = (float *)val; + fval[0] = f[0]; + fval[1] = f[0]; + fval[2] = f[0]; if (derivatives) { fval[3] = f[1]; @@ -675,26 +757,50 @@ static bool get_primitive_attribute(KernelGlobals *kg, if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { float3 fval[3]; - fval[0] = primitive_attribute_float3( - kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + if (primitive_is_volume_attribute(sd, attr.desc)) { + fval[0] = primitive_volume_attribute_float3(kg, sd, attr.desc); + } + else { + memset(fval, 0, sizeof(fval)); + fval[0] = primitive_surface_attribute_float3( + kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + } return set_attribute_float3(fval, type, derivatives, val); } else if (attr.type == TypeFloat2) { - float2 fval[3]; - fval[0] = primitive_attribute_float2( - kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); - return set_attribute_float2(fval, type, derivatives, val); + if (primitive_is_volume_attribute(sd, attr.desc)) { + assert(!"Float2 attribute not support for volumes"); + return false; + } + else { + float2 fval[3]; + fval[0] = primitive_surface_attribute_float2( + kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + return set_attribute_float2(fval, type, derivatives, val); + } } else if (attr.type == TypeDesc::TypeFloat) { float fval[3]; - fval[0] = primitive_attribute_float( - kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + if (primitive_is_volume_attribute(sd, attr.desc)) { + memset(fval, 0, sizeof(fval)); + fval[0] = primitive_volume_attribute_float(kg, sd, attr.desc); + } + else { + fval[0] = primitive_surface_attribute_float( + kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + } return set_attribute_float(fval, type, derivatives, val); } - else if (attr.type == TypeRGBA) { + else if (attr.type == TypeDesc::TypeFloat4 || attr.type == TypeRGBA) { float4 fval[3]; - fval[0] = primitive_attribute_float4( - kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + if (primitive_is_volume_attribute(sd, attr.desc)) { + memset(fval, 0, sizeof(fval)); + fval[0] = primitive_volume_attribute_float4(kg, sd, attr.desc); + } + else { + fval[0] = primitive_surface_attribute_float4( + kg, sd, attr.desc, (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL); + } return set_attribute_float4(fval, type, derivatives, val); } else { @@ -718,13 +824,37 @@ static bool get_mesh_attribute(KernelGlobals *kg, } } -static void get_object_attribute(const OSLGlobals::Attribute &attr, bool derivatives, void *val) +static bool get_object_attribute(const OSLGlobals::Attribute &attr, + TypeDesc type, + bool derivatives, + void *val) { - size_t datasize = attr.value.datasize(); + if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector || + attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor) { + return set_attribute_float3(*(float3 *)attr.value.data(), type, derivatives, val); + } + else if (attr.type == TypeFloat2) { + return set_attribute_float2(*(float2 *)attr.value.data(), type, derivatives, val); + } + else if (attr.type == TypeDesc::TypeFloat) { + return set_attribute_float(*(float *)attr.value.data(), type, derivatives, val); + } + else if (attr.type == TypeRGBA || attr.type == TypeDesc::TypeFloat4) { + return set_attribute_float4(*(float4 *)attr.value.data(), type, derivatives, val); + } + else if (attr.type == type) { + size_t datasize = attr.value.datasize(); + + memcpy(val, attr.value.data(), datasize); + if (derivatives) { + memset((char *)val + datasize, 0, datasize * 2); + } - memcpy(val, attr.value.data(), datasize); - if (derivatives) - memset((char *)val + datasize, 0, datasize * 2); + return true; + } + else { + return false; + } } bool OSLRenderServices::get_object_standard_attribute( @@ -987,8 +1117,7 @@ bool OSLRenderServices::get_attribute( } else { /* object attribute */ - get_object_attribute(attr, derivatives, val); - return true; + return get_object_attribute(attr, type, derivatives, val); } } else { diff --git a/intern/cycles/kernel/shaders/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl index abec8ebfbf0..205d0a21bed 100644 --- a/intern/cycles/kernel/shaders/node_attribute.osl +++ b/intern/cycles/kernel/shaders/node_attribute.osl @@ -20,20 +20,26 @@ shader node_attribute(string bump_offset = "center", string name = "", output point Vector = point(0.0, 0.0, 0.0), output color Color = 0.0, - output float Fac = 0.0) + output float Fac = 0.0, + output float Alpha = 0.0) { - getattribute(name, Color); + float data[4]; + getattribute(name, data); + Color = color(data[0], data[1], data[2]); Vector = point(Color); getattribute(name, Fac); + Alpha = data[3]; if (bump_offset == "dx") { Color += Dx(Color); Vector += Dx(Vector); Fac += Dx(Fac); + Alpha += Dx(Alpha); } else if (bump_offset == "dy") { Color += Dy(Color); Vector += Dy(Vector); Fac += Dy(Fac); + Alpha += Dy(Alpha); } } diff --git a/intern/cycles/kernel/svm/svm_attribute.h b/intern/cycles/kernel/svm/svm_attribute.h index fc7a3ba3f5a..f598bfb8f8f 100644 --- a/intern/cycles/kernel/svm/svm_attribute.h +++ b/intern/cycles/kernel/svm/svm_attribute.h @@ -19,10 +19,10 @@ CCL_NAMESPACE_BEGIN /* Attribute Node */ ccl_device AttributeDescriptor svm_node_attr_init( - KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeType *type, uint *out_offset) + KernelGlobals *kg, ShaderData *sd, uint4 node, NodeAttributeOutputType *type, uint *out_offset) { *out_offset = node.z; - *type = (NodeAttributeType)node.w; + *type = (NodeAttributeOutputType)node.w; AttributeDescriptor desc; @@ -46,144 +46,234 @@ ccl_device AttributeDescriptor svm_node_attr_init( ccl_device void svm_node_attr(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type = NODE_ATTR_FLOAT; + NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT; uint out_offset = 0; AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ - if (desc.type == NODE_ATTR_FLOAT) { - float f = primitive_attribute_float(kg, sd, desc, NULL, NULL); - if (type == NODE_ATTR_FLOAT) { +#ifdef __VOLUME__ + /* Volumes + * NOTE: moving this into its own node type might help improve performance. */ + if (primitive_is_volume_attribute(sd, desc)) { + const float4 value = volume_attribute_float4(kg, sd, desc); + + if (type == NODE_ATTR_OUTPUT_FLOAT) { + const float f = volume_attribute_value_to_float(value); stack_store_float(stack, out_offset, f); } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + const float3 f = volume_attribute_value_to_float3(value); + stack_store_float3(stack, out_offset, f); + } else { + const float f = volume_attribute_value_to_alpha(value); + stack_store_float(stack, out_offset, f); + } + return; + } +#endif + + /* Surface. */ + if (desc.type == NODE_ATTR_FLOAT) { + float f = primitive_surface_attribute_float(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, f); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f, f, f)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } else if (desc.type == NODE_ATTR_FLOAT2) { - float2 f = primitive_attribute_float2(kg, sd, desc, NULL, NULL); - if (type == NODE_ATTR_FLOAT) { + float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, f.x); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f.x, f.y, 0.0f)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } - else if (desc.type == NODE_ATTR_RGBA) { - float4 f = primitive_attribute_float4(kg, sd, desc, NULL, NULL); - if (type == NODE_ATTR_FLOAT) { + else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) { + float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(float4_to_float3(f))); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, float4_to_float3(f)); } + else { + stack_store_float(stack, out_offset, f.w); + } } else { - float3 f = primitive_attribute_float3(kg, sd, desc, NULL, NULL); - if (type == NODE_ATTR_FLOAT) { + float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(f)); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, f); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } } ccl_device void svm_node_attr_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type = NODE_ATTR_FLOAT; + NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT; uint out_offset = 0; AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ +#ifdef __VOLUME__ + /* Volume */ + if (primitive_is_volume_attribute(sd, desc)) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, 0.0f); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f)); + } + else { + stack_store_float(stack, out_offset, 1.0f); + } + return; + } +#endif + + /* Surface */ if (desc.type == NODE_ATTR_FLOAT) { float dx; float f = primitive_surface_attribute_float(kg, sd, desc, &dx, NULL); - if (type == NODE_ATTR_FLOAT) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, f + dx); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f + dx, f + dx, f + dx)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } else if (desc.type == NODE_ATTR_FLOAT2) { float2 dx; - float2 f = primitive_attribute_float2(kg, sd, desc, &dx, NULL); - if (type == NODE_ATTR_FLOAT) { + float2 f = primitive_surface_attribute_float2(kg, sd, desc, &dx, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, f.x + dx.x); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f.x + dx.x, f.y + dx.y, 0.0f)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } - else if (desc.type == NODE_ATTR_RGBA) { + else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) { float4 dx; - float4 f = primitive_attribute_float4(kg, sd, desc, &dx, NULL); - if (type == NODE_ATTR_FLOAT) { + float4 f = primitive_surface_attribute_float4(kg, sd, desc, &dx, NULL); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(float4_to_float3(f + dx))); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, float4_to_float3(f + dx)); } + else { + stack_store_float(stack, out_offset, f.w + dx.w); + } } else { float3 dx; float3 f = primitive_surface_attribute_float3(kg, sd, desc, &dx, NULL); - if (type == NODE_ATTR_FLOAT) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(f + dx)); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, f + dx); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } } ccl_device void svm_node_attr_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node) { - NodeAttributeType type = NODE_ATTR_FLOAT; + NodeAttributeOutputType type = NODE_ATTR_OUTPUT_FLOAT; uint out_offset = 0; AttributeDescriptor desc = svm_node_attr_init(kg, sd, node, &type, &out_offset); - /* fetch and store attribute */ +#ifdef __VOLUME__ + /* Volume */ + if (primitive_is_volume_attribute(sd, desc)) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { + stack_store_float(stack, out_offset, 0.0f); + } + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { + stack_store_float3(stack, out_offset, make_float3(0.0f, 0.0f, 0.0f)); + } + else { + stack_store_float(stack, out_offset, 1.0f); + } + return; + } +#endif + + /* Surface */ if (desc.type == NODE_ATTR_FLOAT) { float dy; float f = primitive_surface_attribute_float(kg, sd, desc, NULL, &dy); - if (type == NODE_ATTR_FLOAT) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, f + dy); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f + dy, f + dy, f + dy)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } else if (desc.type == NODE_ATTR_FLOAT2) { float2 dy; - float2 f = primitive_attribute_float2(kg, sd, desc, NULL, &dy); - if (type == NODE_ATTR_FLOAT) { + float2 f = primitive_surface_attribute_float2(kg, sd, desc, NULL, &dy); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, f.x + dy.x); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, make_float3(f.x + dy.x, f.y + dy.y, 0.0f)); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } - else if (desc.type == NODE_ATTR_RGBA) { + else if (desc.type == NODE_ATTR_FLOAT4 || desc.type == NODE_ATTR_RGBA) { float4 dy; - float4 f = primitive_attribute_float4(kg, sd, desc, NULL, &dy); - if (type == NODE_ATTR_FLOAT) { + float4 f = primitive_surface_attribute_float4(kg, sd, desc, NULL, &dy); + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(float4_to_float3(f + dy))); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, float4_to_float3(f + dy)); } + else { + stack_store_float(stack, out_offset, f.w + dy.w); + } } else { float3 dy; float3 f = primitive_surface_attribute_float3(kg, sd, desc, NULL, &dy); - if (type == NODE_ATTR_FLOAT) { + if (type == NODE_ATTR_OUTPUT_FLOAT) { stack_store_float(stack, out_offset, average(f + dy)); } - else { + else if (type == NODE_ATTR_OUTPUT_FLOAT3) { stack_store_float3(stack, out_offset, f + dy); } + else { + stack_store_float(stack, out_offset, 1.0f); + } } } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index f1ebb37e23e..c228df14985 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -157,10 +157,17 @@ typedef enum ShaderNodeType { * match the switch case order in svm.h. */ } ShaderNodeType; +typedef enum NodeAttributeOutputType { + NODE_ATTR_OUTPUT_FLOAT3 = 0, + NODE_ATTR_OUTPUT_FLOAT, + NODE_ATTR_OUTPUT_FLOAT_ALPHA, +} NodeAttributeOutputType; + typedef enum NodeAttributeType { NODE_ATTR_FLOAT = 0, NODE_ATTR_FLOAT2, NODE_ATTR_FLOAT3, + NODE_ATTR_FLOAT4, NODE_ATTR_RGBA, NODE_ATTR_MATRIX } NodeAttributeType; diff --git a/intern/cycles/kernel/svm/svm_vertex_color.h b/intern/cycles/kernel/svm/svm_vertex_color.h index 3c105b1cbfa..0aa45835522 100644 --- a/intern/cycles/kernel/svm/svm_vertex_color.h +++ b/intern/cycles/kernel/svm/svm_vertex_color.h @@ -25,7 +25,7 @@ ccl_device void svm_node_vertex_color(KernelGlobals *kg, { AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id); if (descriptor.offset != ATTR_STD_NOT_FOUND) { - float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, NULL, NULL); + float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, NULL, NULL); stack_store_float3(stack, color_offset, float4_to_float3(vertex_color)); stack_store_float(stack, alpha_offset, vertex_color.w); } @@ -51,7 +51,7 @@ ccl_device_noinline AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id); if (descriptor.offset != ATTR_STD_NOT_FOUND) { float4 dx; - float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, &dx, NULL); + float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, &dx, NULL); vertex_color += dx; stack_store_float3(stack, color_offset, float4_to_float3(vertex_color)); stack_store_float(stack, alpha_offset, vertex_color.w); @@ -78,7 +78,7 @@ ccl_device_noinline AttributeDescriptor descriptor = find_attribute(kg, sd, layer_id); if (descriptor.offset != ATTR_STD_NOT_FOUND) { float4 dy; - float4 vertex_color = primitive_attribute_float4(kg, sd, descriptor, NULL, &dy); + float4 vertex_color = primitive_surface_attribute_float4(kg, sd, descriptor, NULL, &dy); vertex_color += dy; stack_store_float3(stack, color_offset, float4_to_float3(vertex_color)); stack_store_float(stack, alpha_offset, vertex_color.w); diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp index cdef1036647..b478aae9ae2 100644 --- a/intern/cycles/render/attribute.cpp +++ b/intern/cycles/render/attribute.cpp @@ -34,7 +34,7 @@ Attribute::Attribute( assert(type == TypeDesc::TypeFloat || type == TypeDesc::TypeColor || type == TypeDesc::TypePoint || type == TypeDesc::TypeVector || type == TypeDesc::TypeNormal || type == TypeDesc::TypeMatrix || type == TypeFloat2 || - type == TypeRGBA); + type == TypeFloat4 || type == TypeRGBA); if (element == ATTR_ELEMENT_VOXEL) { buffer.resize(sizeof(ImageHandle)); @@ -167,62 +167,62 @@ size_t Attribute::element_size(Geometry *geom, AttributePrimitive prim) const size = 1; break; case ATTR_ELEMENT_VERTEX: - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); - size = mesh->verts.size() + mesh->num_ngons; + size = mesh->get_verts().size() + mesh->get_num_ngons(); if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts; + size -= mesh->get_num_subd_verts(); } } break; case ATTR_ELEMENT_VERTEX_MOTION: - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); - size = (mesh->verts.size() + mesh->num_ngons) * (mesh->motion_steps - 1); + size = (mesh->get_verts().size() + mesh->get_num_ngons()) * (mesh->get_motion_steps() - 1); if (prim == ATTR_PRIM_SUBD) { - size -= mesh->num_subd_verts * (mesh->motion_steps - 1); + size -= mesh->get_num_subd_verts() * (mesh->get_motion_steps() - 1); } } break; case ATTR_ELEMENT_FACE: - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles(); } else { - size = mesh->subd_faces.size() + mesh->num_ngons; + size = mesh->get_num_subd_faces() + mesh->get_num_ngons(); } } break; case ATTR_ELEMENT_CORNER: case ATTR_ELEMENT_CORNER_BYTE: - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); if (prim == ATTR_PRIM_GEOMETRY) { size = mesh->num_triangles() * 3; } else { - size = mesh->subd_face_corners.size() + mesh->num_ngons; + size = mesh->get_subd_face_corners().size() + mesh->get_num_ngons(); } } break; case ATTR_ELEMENT_CURVE: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); size = hair->num_curves(); } break; case ATTR_ELEMENT_CURVE_KEY: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); - size = hair->curve_keys.size(); + size = hair->get_curve_keys().size(); } break; case ATTR_ELEMENT_CURVE_KEY_MOTION: - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { Hair *hair = static_cast<Hair *>(geom); - size = hair->curve_keys.size() * (hair->motion_steps - 1); + size = hair->get_curve_keys().size() * (hair->get_motion_steps() - 1); } break; default: @@ -445,7 +445,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) if (name == ustring()) name = Attribute::standard_name(std); - if (geometry->type == Geometry::MESH) { + if (geometry->geometry_type == Geometry::MESH) { switch (std) { case ATTR_STD_VERTEX_NORMAL: attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX); @@ -496,7 +496,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (geometry->type == Geometry::VOLUME) { + else if (geometry->geometry_type == Geometry::VOLUME) { switch (std) { case ATTR_STD_VERTEX_NORMAL: attr = add(name, TypeDesc::TypeNormal, ATTR_ELEMENT_VERTEX); @@ -521,7 +521,7 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name) break; } } - else if (geometry->type == Geometry::HAIR) { + else if (geometry->geometry_type == Geometry::HAIR) { switch (std) { case ATTR_STD_UV: attr = add(name, TypeFloat2, ATTR_ELEMENT_CURVE); diff --git a/intern/cycles/render/attribute.h b/intern/cycles/render/attribute.h index 5871fa04a31..9990a1325a7 100644 --- a/intern/cycles/render/attribute.h +++ b/intern/cycles/render/attribute.h @@ -177,6 +177,7 @@ class AttributeSet { list<Attribute> attributes; AttributeSet(Geometry *geometry, AttributePrimitive prim); + AttributeSet(AttributeSet &&) = default; ~AttributeSet(); Attribute *add(ustring name, TypeDesc type, AttributeElement element); diff --git a/intern/cycles/render/background.cpp b/intern/cycles/render/background.cpp index d2463454522..7bdcb1578c3 100644 --- a/intern/cycles/render/background.cpp +++ b/intern/cycles/render/background.cpp @@ -54,7 +54,6 @@ NODE_DEFINE(Background) Background::Background() : Node(node_type) { - need_update = true; shader = NULL; } @@ -64,7 +63,7 @@ Background::~Background() void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -102,7 +101,7 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene else kbackground->volume_shader = SHADER_NONE; - kbackground->volume_step_size = volume_step_size * scene->integrator->volume_step_rate; + kbackground->volume_step_size = volume_step_size * scene->integrator->get_volume_step_rate(); /* No background node, make world shader invisible to all rays, to skip evaluation in kernel. */ if (bg_shader->graph->nodes.size() <= 1) { @@ -122,22 +121,17 @@ void Background::device_update(Device *device, DeviceScene *dscene, Scene *scene kbackground->surface_shader |= SHADER_EXCLUDE_CAMERA; } - need_update = false; + clear_modified(); } void Background::device_free(Device * /*device*/, DeviceScene * /*dscene*/) { } -bool Background::modified(const Background &background) -{ - return !Node::equals(background); -} - void Background::tag_update(Scene *scene) { scene->integrator->tag_update(scene); - need_update = true; + tag_modified(); } Shader *Background::get_shader(const Scene *scene) diff --git a/intern/cycles/render/background.h b/intern/cycles/render/background.h index c2ca1f75179..e89ffbc2445 100644 --- a/intern/cycles/render/background.h +++ b/intern/cycles/render/background.h @@ -32,22 +32,20 @@ class Background : public Node { public: NODE_DECLARE - float ao_factor; - float ao_distance; + NODE_SOCKET_API(float, ao_factor) + NODE_SOCKET_API(float, ao_distance) - bool use_shader; - bool use_ao; + NODE_SOCKET_API(bool, use_shader) + NODE_SOCKET_API(bool, use_ao) - uint visibility; - Shader *shader; + NODE_SOCKET_API(uint, visibility) + NODE_SOCKET_API(Shader *, shader) - bool transparent; - bool transparent_glass; - float transparent_roughness_threshold; + NODE_SOCKET_API(bool, transparent) + NODE_SOCKET_API(bool, transparent_glass) + NODE_SOCKET_API(float, transparent_roughness_threshold) - float volume_step_size; - - bool need_update; + NODE_SOCKET_API(float, volume_step_size) Background(); ~Background(); @@ -55,7 +53,6 @@ class Background : public Node { void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene); - bool modified(const Background &background); void tag_update(Scene *scene); Shader *get_shader(const Scene *scene); diff --git a/intern/cycles/render/bake.cpp b/intern/cycles/render/bake.cpp index 05f52159671..439ebdedb8e 100644 --- a/intern/cycles/render/bake.cpp +++ b/intern/cycles/render/bake.cpp @@ -33,10 +33,11 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type) } else if (type == SHADER_EVAL_NORMAL) { /* Only antialias normal if mesh has bump mapping. */ - if (object->geometry) { - foreach (Shader *shader, object->geometry->used_shaders) { + if (object->get_geometry()) { + foreach (Node *node, object->get_geometry()->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_bump) { - return scene->integrator->aa_samples; + return scene->integrator->get_aa_samples(); } } } @@ -44,7 +45,7 @@ static int aa_samples(Scene *scene, Object *object, ShaderEvalType type) return 1; } else { - return scene->integrator->aa_samples; + return scene->integrator->get_aa_samples(); } } @@ -112,7 +113,7 @@ void BakeManager::set(Scene *scene, } /* create device and update scene */ - scene->film->tag_update(scene); + scene->film->tag_modified(); scene->integrator->tag_update(scene); need_update = true; @@ -140,8 +141,8 @@ void BakeManager::device_update(Device * /*device*/, int object_index = 0; foreach (Object *object, scene->objects) { - const Geometry *geom = object->geometry; - if (object->name == object_name && geom->type == Geometry::MESH) { + const Geometry *geom = object->get_geometry(); + if (object->name == object_name && geom->geometry_type == Geometry::MESH) { kbake->object_index = object_index; kbake->tri_offset = geom->prim_offset; kintegrator->aa_samples = aa_samples(scene, object, type); diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index 3607300cee6..045931ffdac 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -125,6 +125,7 @@ RenderTile::RenderTile() buffer = 0; buffers = NULL; + stealing_state = NO_STEALING; } /* Render Buffers */ diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index 425400a2c08..4ffc628bb52 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -146,6 +146,9 @@ class RenderTile { device_ptr buffer; int device_size; + typedef enum { NO_STEALING = 0, CAN_BE_STOLEN = 1, WAS_STOLEN = 2 } StealingState; + StealingState stealing_state; + RenderBuffers *buffers; RenderTile(); diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 0f2befae320..92cf712d32a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -98,7 +98,7 @@ NODE_DEFINE(Camera) type_enum.insert("perspective", CAMERA_PERSPECTIVE); type_enum.insert("orthograph", CAMERA_ORTHOGRAPHIC); type_enum.insert("panorama", CAMERA_PANORAMA); - SOCKET_ENUM(type, "Type", type_enum, CAMERA_PERSPECTIVE); + SOCKET_ENUM(camera_type, "Type", type_enum, CAMERA_PERSPECTIVE); static NodeEnum panorama_type_enum; panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR); @@ -148,8 +148,18 @@ NODE_DEFINE(Camera) SOCKET_FLOAT(border.bottom, "Border Bottom", 0); SOCKET_FLOAT(border.top, "Border Top", 0); + SOCKET_FLOAT(viewport_camera_border.left, "Viewport Border Left", 0); + SOCKET_FLOAT(viewport_camera_border.right, "Viewport Border Right", 0); + SOCKET_FLOAT(viewport_camera_border.bottom, "Viewport Border Bottom", 0); + SOCKET_FLOAT(viewport_camera_border.top, "Viewport Border Top", 0); + SOCKET_FLOAT(offscreen_dicing_scale, "Offscreen Dicing Scale", 1.0f); + SOCKET_INT(full_width, "Full Width", 1024); + SOCKET_INT(full_height, "Full Height", 512); + + SOCKET_BOOLEAN(use_perspective_motion, "Use Perspective Motion", false); + return type; } @@ -182,7 +192,6 @@ Camera::Camera() : Node(node_type) dx = make_float3(0.0f, 0.0f, 0.0f); dy = make_float3(0.0f, 0.0f, 0.0f); - need_update = true; need_device_update = true; need_flags_update = true; previous_need_motion = -1; @@ -196,7 +205,7 @@ Camera::~Camera() void Camera::compute_auto_viewplane() { - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { viewplane.left = 0.0f; viewplane.right = 1.0f; viewplane.bottom = 0.0f; @@ -230,7 +239,7 @@ void Camera::update(Scene *scene) need_device_update = true; } - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -257,9 +266,9 @@ void Camera::update(Scene *scene) /* screen to camera */ ProjectionTransform cameratoscreen; - if (type == CAMERA_PERSPECTIVE) + if (camera_type == CAMERA_PERSPECTIVE) cameratoscreen = projection_perspective(fov, nearclip, farclip); - else if (type == CAMERA_ORTHOGRAPHIC) + else if (camera_type == CAMERA_ORTHOGRAPHIC) cameratoscreen = projection_orthographic(nearclip, farclip); else cameratoscreen = projection_identity(); @@ -284,13 +293,13 @@ void Camera::update(Scene *scene) worldtoraster = ndctoraster * worldtondc; /* differentials */ - if (type == CAMERA_ORTHOGRAPHIC) { + if (camera_type == CAMERA_ORTHOGRAPHIC) { dx = transform_perspective_direction(&rastertocamera, make_float3(1, 0, 0)); dy = transform_perspective_direction(&rastertocamera, make_float3(0, 1, 0)); full_dx = transform_perspective_direction(&full_rastertocamera, make_float3(1, 0, 0)); full_dy = transform_perspective_direction(&full_rastertocamera, make_float3(0, 1, 0)); } - else if (type == CAMERA_PERSPECTIVE) { + else if (camera_type == CAMERA_PERSPECTIVE) { dx = transform_perspective(&rastertocamera, make_float3(1, 0, 0)) - transform_perspective(&rastertocamera, make_float3(0, 0, 0)); dy = transform_perspective(&rastertocamera, make_float3(0, 1, 0)) - @@ -310,7 +319,7 @@ void Camera::update(Scene *scene) full_dx = transform_direction(&cameratoworld, full_dx); full_dy = transform_direction(&cameratoworld, full_dy); - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { float3 v = transform_perspective(&full_rastertocamera, make_float3(full_width, full_height, 1.0f)); frustum_right_normal = normalize(make_float3(v.z, 0.0f, -v.x)); @@ -348,7 +357,7 @@ void Camera::update(Scene *scene) if (need_motion == Scene::MOTION_PASS) { /* TODO(sergey): Support perspective (zoom, fov) motion. */ - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { if (have_motion) { kcam->motion_pass_pre = transform_inverse(motion[0]); kcam->motion_pass_post = transform_inverse(motion[motion.size() - 1]); @@ -377,7 +386,7 @@ void Camera::update(Scene *scene) } /* TODO(sergey): Support other types of camera. */ - if (use_perspective_motion && type == CAMERA_PERSPECTIVE) { + if (use_perspective_motion && camera_type == CAMERA_PERSPECTIVE) { /* TODO(sergey): Move to an utility function and de-duplicate with * calculation above. */ @@ -402,7 +411,7 @@ void Camera::update(Scene *scene) kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime : -1.0f; /* type */ - kcam->type = type; + kcam->type = camera_type; /* anamorphic lens bokeh */ kcam->inv_aperture_ratio = 1.0f / aperture_ratio; @@ -464,7 +473,7 @@ void Camera::update(Scene *scene) kcam->rolling_shutter_duration = rolling_shutter_duration; /* Set further update flags */ - need_update = false; + clear_modified(); need_device_update = true; need_flags_update = true; previous_need_motion = need_motion; @@ -527,7 +536,7 @@ void Camera::device_update_volume(Device * /*device*/, DeviceScene *dscene, Scen [&](const blocked_range<size_t> &r) { for (size_t i = r.begin(); i != r.end(); i++) { Object *object = scene->objects[i]; - if (object->geometry->has_volume && + if (object->get_geometry()->has_volume && viewplane_boundbox.intersects(object->bounds)) { /* TODO(sergey): Consider adding more grained check. */ VLOG(1) << "Detected camera inside volume."; @@ -553,25 +562,10 @@ void Camera::device_free(Device * /*device*/, DeviceScene *dscene, Scene *scene) dscene->camera_motion.free(); } -bool Camera::modified(const Camera &cam) -{ - return !Node::equals(cam); -} - -bool Camera::motion_modified(const Camera &cam) -{ - return !((motion == cam.motion) && (use_perspective_motion == cam.use_perspective_motion)); -} - -void Camera::tag_update() -{ - need_update = true; -} - float3 Camera::transform_raster_to_world(float raster_x, float raster_y) { float3 D, P; - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { D = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); float3 Pclip = normalize(D); P = make_float3(0.0f, 0.0f, 0.0f); @@ -584,7 +578,7 @@ float3 Camera::transform_raster_to_world(float raster_x, float raster_y) */ P += nearclip * D / Pclip.z; } - else if (type == CAMERA_ORTHOGRAPHIC) { + else if (camera_type == CAMERA_ORTHOGRAPHIC) { D = make_float3(0.0f, 0.0f, 1.0f); /* TODO(sergey): Aperture support? */ P = transform_perspective(&rastertocamera, make_float3(raster_x, raster_y, 0.0f)); @@ -603,7 +597,7 @@ BoundBox Camera::viewplane_bounds_get() * checks we need in a more clear and smart fashion? */ BoundBox bounds = BoundBox::empty; - if (type == CAMERA_PANORAMA) { + if (camera_type == CAMERA_PANORAMA) { if (use_spherical_stereo == false) { bounds.grow(make_float3(cameratoworld.x.w, cameratoworld.y.w, cameratoworld.z.w)); } @@ -628,7 +622,7 @@ BoundBox Camera::viewplane_bounds_get() bounds.grow(transform_raster_to_world(0.0f, (float)height)); bounds.grow(transform_raster_to_world((float)width, (float)height)); bounds.grow(transform_raster_to_world((float)width, 0.0f)); - if (type == CAMERA_PERSPECTIVE) { + if (camera_type == CAMERA_PERSPECTIVE) { /* Center point has the most distance in local Z axis, * use it to construct bounding box/ */ @@ -642,7 +636,7 @@ float Camera::world_to_raster_size(float3 P) { float res = 1.0f; - if (type == CAMERA_ORTHOGRAPHIC) { + if (camera_type == CAMERA_ORTHOGRAPHIC) { res = min(len(full_dx), len(full_dy)); if (offscreen_dicing_scale > 1.0f) { @@ -668,7 +662,7 @@ float Camera::world_to_raster_size(float3 P) } } } - else if (type == CAMERA_PERSPECTIVE) { + else if (camera_type == CAMERA_PERSPECTIVE) { /* Calculate as if point is directly ahead of the camera. */ float3 raster = make_float3(0.5f * full_width, 0.5f * full_height, 0.0f); float3 Pcamera = transform_perspective(&full_rastertocamera, raster); @@ -743,7 +737,7 @@ float Camera::world_to_raster_size(float3 P) } } } - else if (type == CAMERA_PANORAMA) { + else if (camera_type == CAMERA_PANORAMA) { float3 D = transform_point(&worldtocamera, P); float dist = len(D); @@ -794,6 +788,16 @@ bool Camera::use_motion() const return motion.size() > 1; } +void Camera::set_screen_size_and_resolution(int width_, int height_, int resolution_) +{ + if (width_ != width || height_ != height || resolution_ != resolution) { + width = width_; + height = height_; + resolution = resolution_; + tag_modified(); + } +} + float Camera::motion_time(int step) const { return (use_motion()) ? 2.0f * step / (motion.size() - 1) - 1.0f : 0.0f; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 21dad5eea3b..7970381f338 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -73,78 +73,92 @@ class Camera : public Node { }; /* motion blur */ - float shuttertime; - MotionPosition motion_position; - array<float> shutter_curve; + NODE_SOCKET_API(float, shuttertime) + NODE_SOCKET_API(MotionPosition, motion_position) + NODE_SOCKET_API_ARRAY(array<float>, shutter_curve) size_t shutter_table_offset; /* ** Rolling shutter effect. ** */ /* Defines rolling shutter effect type. */ - RollingShutterType rolling_shutter_type; + NODE_SOCKET_API(RollingShutterType, rolling_shutter_type) /* Specifies exposure time of scanlines when using * rolling shutter effect. */ - float rolling_shutter_duration; + NODE_SOCKET_API(float, rolling_shutter_duration) /* depth of field */ - float focaldistance; - float aperturesize; - uint blades; - float bladesrotation; + NODE_SOCKET_API(float, focaldistance) + NODE_SOCKET_API(float, aperturesize) + NODE_SOCKET_API(uint, blades) + NODE_SOCKET_API(float, bladesrotation) /* type */ - CameraType type; - float fov; + NODE_SOCKET_API(CameraType, camera_type) + NODE_SOCKET_API(float, fov) /* panorama */ - PanoramaType panorama_type; - float fisheye_fov; - float fisheye_lens; - float latitude_min; - float latitude_max; - float longitude_min; - float longitude_max; + NODE_SOCKET_API(PanoramaType, panorama_type) + NODE_SOCKET_API(float, fisheye_fov) + NODE_SOCKET_API(float, fisheye_lens) + NODE_SOCKET_API(float, latitude_min) + NODE_SOCKET_API(float, latitude_max) + NODE_SOCKET_API(float, longitude_min) + NODE_SOCKET_API(float, longitude_max) /* panorama stereo */ - StereoEye stereo_eye; - bool use_spherical_stereo; - float interocular_distance; - float convergence_distance; - bool use_pole_merge; - float pole_merge_angle_from; - float pole_merge_angle_to; + NODE_SOCKET_API(StereoEye, stereo_eye) + NODE_SOCKET_API(bool, use_spherical_stereo) + NODE_SOCKET_API(float, interocular_distance) + NODE_SOCKET_API(float, convergence_distance) + NODE_SOCKET_API(bool, use_pole_merge) + NODE_SOCKET_API(float, pole_merge_angle_from) + NODE_SOCKET_API(float, pole_merge_angle_to) /* anamorphic lens bokeh */ - float aperture_ratio; + NODE_SOCKET_API(float, aperture_ratio) /* sensor */ - float sensorwidth; - float sensorheight; + NODE_SOCKET_API(float, sensorwidth) + NODE_SOCKET_API(float, sensorheight) /* clipping */ - float nearclip; - float farclip; + NODE_SOCKET_API(float, nearclip) + NODE_SOCKET_API(float, farclip) /* screen */ - int width, height; - int resolution; BoundBox2D viewplane; + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewplane, top) + /* width and height change during preview, so we need these for calculating dice rates. */ - int full_width, full_height; + NODE_SOCKET_API(int, full_width) + NODE_SOCKET_API(int, full_height) /* controls how fast the dicing rate falls off for geometry out side of view */ - float offscreen_dicing_scale; + NODE_SOCKET_API(float, offscreen_dicing_scale) /* border */ BoundBox2D border; + NODE_SOCKET_API_STRUCT_MEMBER(float, border, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, border, top) + BoundBox2D viewport_camera_border; + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, left) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, right) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, bottom) + NODE_SOCKET_API_STRUCT_MEMBER(float, viewport_camera_border, top) /* transformation */ - Transform matrix; + NODE_SOCKET_API(Transform, matrix) /* motion */ - array<Transform> motion; - bool use_perspective_motion; - float fov_pre, fov_post; + NODE_SOCKET_API_ARRAY(array<Transform>, motion) + NODE_SOCKET_API(bool, use_perspective_motion) + NODE_SOCKET_API(float, fov_pre) + NODE_SOCKET_API(float, fov_post) /* computed camera parameters */ ProjectionTransform screentoworld; @@ -174,7 +188,6 @@ class Camera : public Node { float3 frustum_bottom_normal; /* update */ - bool need_update; bool need_device_update; bool need_flags_update; int previous_need_motion; @@ -183,6 +196,12 @@ class Camera : public Node { KernelCamera kernel_camera; array<DecomposedTransform> kernel_camera_motion; + private: + int width; + int height; + int resolution; + + public: /* functions */ Camera(); ~Camera(); @@ -195,10 +214,6 @@ class Camera : public Node { void device_update_volume(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene, Scene *scene); - bool modified(const Camera &cam); - bool motion_modified(const Camera &cam); - void tag_update(); - /* Public utility functions. */ BoundBox viewplane_bounds_get(); @@ -210,6 +225,8 @@ class Camera : public Node { int motion_step(float time) const; bool use_motion() const; + void set_screen_size_and_resolution(int width_, int height_, int resolution_); + private: /* Private utility functions. */ float3 transform_raster_to_world(float raster_x, float raster_y); diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp index e4c1e452bd5..5c3778f6ae5 100644 --- a/intern/cycles/render/film.cpp +++ b/intern/cycles/render/film.cpp @@ -40,10 +40,8 @@ static bool compare_pass_order(const Pass &a, const Pass &b) return (a.components > b.components); } -NODE_DEFINE(Pass) +static NodeEnum *get_pass_type_enum() { - NodeType *type = NodeType::add("pass", create); - static NodeEnum pass_type_enum; pass_type_enum.insert("combined", PASS_COMBINED); pass_type_enum.insert("depth", PASS_DEPTH); @@ -84,7 +82,15 @@ NODE_DEFINE(Pass) pass_type_enum.insert("bake_primitive", PASS_BAKE_PRIMITIVE); pass_type_enum.insert("bake_differential", PASS_BAKE_DIFFERENTIAL); - SOCKET_ENUM(type, "Type", pass_type_enum, PASS_COMBINED); + return &pass_type_enum; +} + +NODE_DEFINE(Pass) +{ + NodeType *type = NodeType::add("pass", create); + + NodeEnum *pass_type_enum = get_pass_type_enum(); + SOCKET_ENUM(type, "Type", *pass_type_enum, PASS_COMBINED); SOCKET_STRING(name, "Name", ustring()); return type; @@ -383,6 +389,21 @@ NODE_DEFINE(Film) SOCKET_INT(denoising_flags, "Denoising Flags", 0); SOCKET_BOOLEAN(use_adaptive_sampling, "Use Adaptive Sampling", false); + SOCKET_BOOLEAN(use_light_visibility, "Use Light Visibility", false); + + NodeEnum *pass_type_enum = get_pass_type_enum(); + SOCKET_ENUM(display_pass, "Display Pass", *pass_type_enum, PASS_COMBINED); + + static NodeEnum cryptomatte_passes_enum; + cryptomatte_passes_enum.insert("none", CRYPT_NONE); + cryptomatte_passes_enum.insert("object", CRYPT_OBJECT); + cryptomatte_passes_enum.insert("material", CRYPT_MATERIAL); + cryptomatte_passes_enum.insert("asset", CRYPT_ASSET); + cryptomatte_passes_enum.insert("accurate", CRYPT_ACCURATE); + SOCKET_ENUM(cryptomatte_passes, "Cryptomatte Passes", cryptomatte_passes_enum, CRYPT_NONE); + + SOCKET_INT(cryptomatte_depth, "Cryptomatte Depth", 0); + return type; } @@ -392,8 +413,6 @@ Film::Film() : Node(node_type) filter_table_offset = TABLE_OFFSET_INVALID; cryptomatte_passes = CRYPT_NONE; display_pass = PASS_COMBINED; - - need_update = true; } Film::~Film() @@ -407,7 +426,7 @@ void Film::add_default(Scene *scene) void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -658,7 +677,7 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene) denoising_data_offset = kfilm->pass_denoising_data; denoising_clean_offset = kfilm->pass_denoising_clean; - need_update = false; + clear_modified(); } void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *scene) @@ -666,11 +685,6 @@ void Film::device_free(Device * /*device*/, DeviceScene * /*dscene*/, Scene *sce scene->lookup_tables->remove_table(&filter_table_offset); } -bool Film::modified(const Film &film) -{ - return !Node::equals(film); -} - void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes) { if (Pass::contains(scene->passes, PASS_UV) != Pass::contains(passes_, PASS_UV)) { @@ -691,11 +705,6 @@ void Film::tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool upd } } -void Film::tag_update(Scene * /*scene*/) -{ - need_update = true; -} - int Film::get_aov_offset(Scene *scene, string name, bool &is_color) { int num_color = 0, num_value = 0; @@ -719,4 +728,24 @@ int Film::get_aov_offset(Scene *scene, string name, bool &is_color) return -1; } +int Film::get_pass_stride() const +{ + return pass_stride; +} + +int Film::get_denoising_data_offset() const +{ + return denoising_data_offset; +} + +int Film::get_denoising_clean_offset() const +{ + return denoising_clean_offset; +} + +size_t Film::get_filter_table_offset() const +{ + return filter_table_offset; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/render/film.h b/intern/cycles/render/film.h index 961058c008e..462a7275491 100644 --- a/intern/cycles/render/film.h +++ b/intern/cycles/render/film.h @@ -60,34 +60,35 @@ class Film : public Node { public: NODE_DECLARE - float exposure; - bool denoising_data_pass; - bool denoising_clean_pass; - bool denoising_prefiltered_pass; - int denoising_flags; - float pass_alpha_threshold; - - PassType display_pass; - int pass_stride; - int denoising_data_offset; - int denoising_clean_offset; + NODE_SOCKET_API(float, exposure) + NODE_SOCKET_API(bool, denoising_data_pass) + NODE_SOCKET_API(bool, denoising_clean_pass) + NODE_SOCKET_API(bool, denoising_prefiltered_pass) + NODE_SOCKET_API(int, denoising_flags) + NODE_SOCKET_API(float, pass_alpha_threshold) - FilterType filter_type; - float filter_width; - size_t filter_table_offset; + NODE_SOCKET_API(PassType, display_pass) - float mist_start; - float mist_depth; - float mist_falloff; + NODE_SOCKET_API(FilterType, filter_type) + NODE_SOCKET_API(float, filter_width) - bool use_light_visibility; - CryptomatteType cryptomatte_passes; - int cryptomatte_depth; + NODE_SOCKET_API(float, mist_start) + NODE_SOCKET_API(float, mist_depth) + NODE_SOCKET_API(float, mist_falloff) - bool use_adaptive_sampling; + NODE_SOCKET_API(bool, use_light_visibility) + NODE_SOCKET_API(CryptomatteType, cryptomatte_passes) + NODE_SOCKET_API(int, cryptomatte_depth) - bool need_update; + NODE_SOCKET_API(bool, use_adaptive_sampling) + private: + int pass_stride; + int denoising_data_offset; + int denoising_clean_offset; + size_t filter_table_offset; + + public: Film(); ~Film(); @@ -97,11 +98,14 @@ class Film : public Node { void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene, Scene *scene); - bool modified(const Film &film); void tag_passes_update(Scene *scene, const vector<Pass> &passes_, bool update_passes = true); - void tag_update(Scene *scene); int get_aov_offset(Scene *scene, string name, bool &is_color); + + int get_pass_stride() const; + int get_denoising_data_offset() const; + int get_denoising_clean_offset() const; + size_t get_filter_table_offset() const; }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index fdfce63bbeb..a63fc620c69 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -52,14 +52,14 @@ NODE_ABSTRACT_DEFINE(Geometry) SOCKET_UINT(motion_steps, "Motion Steps", 3); SOCKET_BOOLEAN(use_motion_blur, "Use Motion Blur", false); + SOCKET_NODE_ARRAY(used_shaders, "Shaders", &Shader::node_type); return type; } Geometry::Geometry(const NodeType *node_type, const Type type) - : Node(node_type), type(type), attributes(this, ATTR_PRIM_GEOMETRY) + : Node(node_type), geometry_type(type), attributes(this, ATTR_PRIM_GEOMETRY) { - need_update = true; need_update_rebuild = false; transform_applied = false; @@ -81,9 +81,11 @@ Geometry::~Geometry() delete bvh; } -void Geometry::clear() +void Geometry::clear(bool preserve_shaders) { - used_shaders.clear(); + if (!preserve_shaders) + used_shaders.clear(); + transform_applied = false; transform_negative_scaled = false; transform_normal = transform_identity(); @@ -97,9 +99,11 @@ bool Geometry::need_attribute(Scene *scene, AttributeStandard std) if (scene->need_global_attribute(std)) return true; - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->attributes.find(std)) return true; + } return false; } @@ -109,13 +113,27 @@ bool Geometry::need_attribute(Scene * /*scene*/, ustring name) if (name == ustring()) return false; - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->attributes.find(name)) return true; + } return false; } +AttributeRequestSet Geometry::needed_attributes() +{ + AttributeRequestSet result; + + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); + result.add(shader->attributes); + } + + return result; +} + float Geometry::motion_time(int step) const { return (motion_steps > 1) ? 2.0f * step / (motion_steps - 1) - 1.0f : 0.0f; @@ -159,8 +177,9 @@ bool Geometry::is_instanced() const bool Geometry::has_true_displacement() const { - foreach (Shader *shader, used_shaders) { - if (shader->has_displacement && shader->displacement_method != DISPLACE_BUMP) { + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); + if (shader->has_displacement && shader->get_displacement_method() != DISPLACE_BUMP) { return true; } } @@ -186,7 +205,7 @@ void Geometry::compute_bvh( msg += string_printf("%s %u/%u", name.c_str(), (uint)(n + 1), (uint)total); Object object; - object.geometry = this; + object.set_geometry(this); vector<Geometry *> geometry; geometry.push_back(this); @@ -220,7 +239,7 @@ void Geometry::compute_bvh( } } - need_update = false; + clear_modified(); need_update_rebuild = false; } @@ -242,16 +261,18 @@ bool Geometry::has_voxel_attributes() const void Geometry::tag_update(Scene *scene, bool rebuild) { - need_update = true; + tag_modified(); if (rebuild) { need_update_rebuild = true; scene->light_manager->need_update = true; } else { - foreach (Shader *shader, used_shaders) + foreach (Node *node, used_shaders) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_surface_emission) scene->light_manager->need_update = true; + } } scene->geometry_manager->need_update = true; @@ -305,15 +326,12 @@ void GeometryManager::update_osl_attributes(Device *device, } /* find geometry attributes */ - size_t j; - - for (j = 0; j < scene->geometry.size(); j++) - if (scene->geometry[j] == object->geometry) - break; + size_t j = object->geometry->index; + assert(j < scene->geometry.size() && scene->geometry[j] == object->geometry); AttributeRequestSet &attributes = geom_attributes[j]; - /* set object attributes */ + /* set mesh attributes */ foreach (AttributeRequest &req, attributes.requests) { OSLGlobals::Attribute osl_attr; @@ -375,10 +393,68 @@ void GeometryManager::update_osl_attributes(Device *device, #endif } +/* Generate a normal attribute map entry from an attribute descriptor. */ +static void emit_attribute_map_entry( + uint4 *attr_map, int index, uint id, TypeDesc type, const AttributeDescriptor &desc) +{ + attr_map[index].x = id; + attr_map[index].y = desc.element; + attr_map[index].z = as_uint(desc.offset); + + if (type == TypeDesc::TypeFloat) + attr_map[index].w = NODE_ATTR_FLOAT; + else if (type == TypeDesc::TypeMatrix) + attr_map[index].w = NODE_ATTR_MATRIX; + else if (type == TypeFloat2) + attr_map[index].w = NODE_ATTR_FLOAT2; + else if (type == TypeFloat4) + attr_map[index].w = NODE_ATTR_FLOAT4; + else if (type == TypeRGBA) + attr_map[index].w = NODE_ATTR_RGBA; + else + attr_map[index].w = NODE_ATTR_FLOAT3; + + attr_map[index].w |= desc.flags << 8; +} + +/* Generate an attribute map end marker, optionally including a link to another map. + * Links are used to connect object attribute maps to mesh attribute maps. */ +static void emit_attribute_map_terminator(uint4 *attr_map, int index, bool chain, uint chain_link) +{ + for (int j = 0; j < ATTR_PRIM_TYPES; j++) { + attr_map[index + j].x = ATTR_STD_NONE; + attr_map[index + j].y = chain; /* link is valid flag */ + attr_map[index + j].z = chain ? chain_link + j : 0; /* link to the correct sub-entry */ + attr_map[index + j].w = 0; + } +} + +/* Generate all necessary attribute map entries from the attribute request. */ +static void emit_attribute_mapping( + uint4 *attr_map, int index, Scene *scene, AttributeRequest &req, Geometry *geom) +{ + uint id; + + if (req.std == ATTR_STD_NONE) + id = scene->shader_manager->get_attribute_id(req.name); + else + id = scene->shader_manager->get_attribute_id(req.std); + + emit_attribute_map_entry(attr_map, index, id, req.type, req.desc); + + if (geom->is_mesh()) { + Mesh *mesh = static_cast<Mesh *>(geom); + if (mesh->get_num_subd_faces()) { + emit_attribute_map_entry(attr_map, index + 1, id, req.subd_type, req.subd_desc); + } + } +} + void GeometryManager::update_svm_attributes(Device *, DeviceScene *dscene, Scene *scene, - vector<AttributeRequestSet> &geom_attributes) + vector<AttributeRequestSet> &geom_attributes, + vector<AttributeRequestSet> &object_attributes) { /* for SVM, the attributes_map table is used to lookup the offset of an * attribute, based on a unique shader attribute id. */ @@ -392,6 +468,19 @@ void GeometryManager::update_svm_attributes(Device *, attr_map_size += (geom_attributes[i].size() + 1) * ATTR_PRIM_TYPES; } + for (size_t i = 0; i < scene->objects.size(); i++) { + Object *object = scene->objects[i]; + + /* only allocate a table for the object if it actually has attributes */ + if (object_attributes[i].size() == 0) { + object->attr_map_offset = 0; + } + else { + object->attr_map_offset = attr_map_size; + attr_map_size += (object_attributes[i].size() + 1) * ATTR_PRIM_TYPES; + } + } + if (attr_map_size == 0) return; @@ -403,69 +492,31 @@ void GeometryManager::update_svm_attributes(Device *, Geometry *geom = scene->geometry[i]; AttributeRequestSet &attributes = geom_attributes[i]; - /* set object attributes */ + /* set geometry attributes */ int index = geom->attr_map_offset; foreach (AttributeRequest &req, attributes.requests) { - uint id; - - if (req.std == ATTR_STD_NONE) - id = scene->shader_manager->get_attribute_id(req.name); - else - id = scene->shader_manager->get_attribute_id(req.std); - - attr_map[index].x = id; - attr_map[index].y = req.desc.element; - attr_map[index].z = as_uint(req.desc.offset); + emit_attribute_mapping(attr_map, index, scene, req, geom); + index += ATTR_PRIM_TYPES; + } - if (req.type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.type == TypeRGBA) - attr_map[index].w = NODE_ATTR_RGBA; - else - attr_map[index].w = NODE_ATTR_FLOAT3; + emit_attribute_map_terminator(attr_map, index, false, 0); + } - attr_map[index].w |= req.desc.flags << 8; + for (size_t i = 0; i < scene->objects.size(); i++) { + Object *object = scene->objects[i]; + AttributeRequestSet &attributes = object_attributes[i]; - index++; + /* set object attributes */ + if (attributes.size() > 0) { + int index = object->attr_map_offset; - if (geom->type == Geometry::MESH) { - Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subd_faces.size()) { - attr_map[index].x = id; - attr_map[index].y = req.subd_desc.element; - attr_map[index].z = as_uint(req.subd_desc.offset); - - if (req.subd_type == TypeDesc::TypeFloat) - attr_map[index].w = NODE_ATTR_FLOAT; - else if (req.subd_type == TypeDesc::TypeMatrix) - attr_map[index].w = NODE_ATTR_MATRIX; - else if (req.subd_type == TypeFloat2) - attr_map[index].w = NODE_ATTR_FLOAT2; - else if (req.subd_type == TypeRGBA) - attr_map[index].w = NODE_ATTR_RGBA; - else - attr_map[index].w = NODE_ATTR_FLOAT3; - - attr_map[index].w |= req.subd_desc.flags << 8; - } + foreach (AttributeRequest &req, attributes.requests) { + emit_attribute_mapping(attr_map, index, scene, req, object->geometry); + index += ATTR_PRIM_TYPES; } - index++; - } - - /* terminator */ - for (int j = 0; j < ATTR_PRIM_TYPES; j++) { - attr_map[index].x = ATTR_STD_NONE; - attr_map[index].y = 0; - attr_map[index].z = 0; - attr_map[index].w = 0; - - index++; + emit_attribute_map_terminator(attr_map, index, true, object->geometry->attr_map_offset); } } @@ -505,19 +556,19 @@ static void update_attribute_element_size(Geometry *geom, } } -static void update_attribute_element_offset(Geometry *geom, - device_vector<float> &attr_float, - size_t &attr_float_offset, - device_vector<float2> &attr_float2, - size_t &attr_float2_offset, - device_vector<float4> &attr_float3, - size_t &attr_float3_offset, - device_vector<uchar4> &attr_uchar4, - size_t &attr_uchar4_offset, - Attribute *mattr, - AttributePrimitive prim, - TypeDesc &type, - AttributeDescriptor &desc) +void GeometryManager::update_attribute_element_offset(Geometry *geom, + device_vector<float> &attr_float, + size_t &attr_float_offset, + device_vector<float2> &attr_float2, + size_t &attr_float2_offset, + device_vector<float4> &attr_float3, + size_t &attr_float3_offset, + device_vector<uchar4> &attr_uchar4, + size_t &attr_uchar4_offset, + Attribute *mattr, + AttributePrimitive prim, + TypeDesc &type, + AttributeDescriptor &desc) { if (mattr) { /* store element and type */ @@ -589,7 +640,7 @@ static void update_attribute_element_offset(Geometry *geom, /* mesh vertex/curve index is global, not per object, so we sneak * a correction for that in here */ - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->subdivision_type == Mesh::SUBDIVISION_CATMULL_CLARK && desc.flags & ATTR_SUBDIVIDED) { @@ -613,7 +664,7 @@ static void update_attribute_element_offset(Geometry *geom, offset -= mesh->corner_offset; } } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); if (element == ATTR_ELEMENT_CURVE) offset -= hair->prim_offset; @@ -645,13 +696,48 @@ void GeometryManager::device_update_attributes(Device *device, for (size_t i = 0; i < scene->geometry.size(); i++) { Geometry *geom = scene->geometry[i]; + geom->index = i; scene->need_global_attributes(geom_attributes[i]); - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); geom_attributes[i].add(shader->attributes); } } + /* convert object attributes to use the same data structures as geometry ones */ + vector<AttributeRequestSet> object_attributes(scene->objects.size()); + vector<AttributeSet> object_attribute_values; + + object_attribute_values.reserve(scene->objects.size()); + + for (size_t i = 0; i < scene->objects.size(); i++) { + Object *object = scene->objects[i]; + Geometry *geom = object->geometry; + size_t geom_idx = geom->index; + + assert(geom_idx < scene->geometry.size() && scene->geometry[geom_idx] == geom); + + object_attribute_values.push_back(AttributeSet(geom, ATTR_PRIM_GEOMETRY)); + + AttributeRequestSet &geom_requests = geom_attributes[geom_idx]; + AttributeRequestSet &attributes = object_attributes[i]; + AttributeSet &values = object_attribute_values[i]; + + for (size_t j = 0; j < object->attributes.size(); j++) { + ParamValue ¶m = object->attributes[j]; + + /* add attributes that are requested and not already handled by the mesh */ + if (geom_requests.find(param.name()) && !geom->attributes.find(param.name())) { + attributes.add(param.name()); + + Attribute *attr = values.add(param.name(), param.type(), ATTR_ELEMENT_OBJECT); + assert(param.datasize() == attr->buffer.size()); + memcpy(attr->buffer.data(), param.data(), param.datasize()); + } + } + } + /* mesh attribute are stored in a single array per data type. here we fill * those arrays, and set the offset and element type to create attribute * maps next */ @@ -663,6 +749,7 @@ void GeometryManager::device_update_attributes(Device *device, size_t attr_float2_size = 0; size_t attr_float3_size = 0; size_t attr_uchar4_size = 0; + for (size_t i = 0; i < scene->geometry.size(); i++) { Geometry *geom = scene->geometry[i]; AttributeRequestSet &attributes = geom_attributes[i]; @@ -677,7 +764,7 @@ void GeometryManager::device_update_attributes(Device *device, &attr_float3_size, &attr_uchar4_size); - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); Attribute *subd_attr = mesh->subd_attributes.find(req); @@ -692,6 +779,20 @@ void GeometryManager::device_update_attributes(Device *device, } } + for (size_t i = 0; i < scene->objects.size(); i++) { + Object *object = scene->objects[i]; + + foreach (Attribute &attr, object_attribute_values[i].attributes) { + update_attribute_element_size(object->geometry, + &attr, + ATTR_PRIM_GEOMETRY, + &attr_float_size, + &attr_float2_size, + &attr_float3_size, + &attr_uchar4_size); + } + } + dscene->attributes_float.alloc(attr_float_size); dscene->attributes_float2.alloc(attr_float2_size); dscene->attributes_float3.alloc(attr_float3_size); @@ -725,7 +826,7 @@ void GeometryManager::device_update_attributes(Device *device, req.type, req.desc); - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); Attribute *subd_attr = mesh->subd_attributes.find(req); @@ -749,11 +850,42 @@ void GeometryManager::device_update_attributes(Device *device, } } + for (size_t i = 0; i < scene->objects.size(); i++) { + Object *object = scene->objects[i]; + AttributeRequestSet &attributes = object_attributes[i]; + AttributeSet &values = object_attribute_values[i]; + + foreach (AttributeRequest &req, attributes.requests) { + Attribute *attr = values.find(req); + + update_attribute_element_offset(object->geometry, + dscene->attributes_float, + attr_float_offset, + dscene->attributes_float2, + attr_float2_offset, + dscene->attributes_float3, + attr_float3_offset, + dscene->attributes_uchar4, + attr_uchar4_offset, + attr, + ATTR_PRIM_GEOMETRY, + req.type, + req.desc); + + /* object attributes don't care about subdivision */ + req.subd_type = req.type; + req.subd_desc = req.desc; + + if (progress.get_cancel()) + return; + } + } + /* create attribute lookup maps */ if (scene->shader_manager->use_osl()) update_osl_attributes(device, scene, geom_attributes); - update_svm_attributes(device, dscene, scene, geom_attributes); + update_svm_attributes(device, dscene, scene, geom_attributes, object_attributes); if (progress.get_cancel()) return; @@ -797,7 +929,7 @@ void GeometryManager::mesh_calc_offset(Scene *scene) size_t optix_prim_size = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->vert_offset = vert_size; @@ -810,8 +942,8 @@ void GeometryManager::mesh_calc_offset(Scene *scene) vert_size += mesh->verts.size(); tri_size += mesh->num_triangles(); - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + if (mesh->get_num_subd_faces()) { + Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1); patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; /* patch tables are stored in same array so include them in patch_size */ @@ -821,19 +953,19 @@ void GeometryManager::mesh_calc_offset(Scene *scene) } } - face_size += mesh->subd_faces.size(); + face_size += mesh->get_num_subd_faces(); corner_size += mesh->subd_face_corners.size(); mesh->optix_prim_offset = optix_prim_size; optix_prim_size += mesh->num_triangles(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); hair->curvekey_offset = curve_key_size; hair->prim_offset = curve_size; - curve_key_size += hair->curve_keys.size(); + curve_key_size += hair->get_curve_keys().size(); curve_size += hair->num_curves(); hair->optix_prim_offset = optix_prim_size; @@ -855,14 +987,14 @@ void GeometryManager::device_update_mesh( size_t patch_size = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); vert_size += mesh->verts.size(); tri_size += mesh->num_triangles(); - if (mesh->subd_faces.size()) { - Mesh::SubdFace &last = mesh->subd_faces[mesh->subd_faces.size() - 1]; + if (mesh->get_num_subd_faces()) { + Mesh::SubdFace last = mesh->get_subd_face(mesh->get_num_subd_faces() - 1); patch_size += (last.ptex_offset + last.num_ptex_faces()) * 8; /* patch tables are stored in same array so include them in patch_size */ @@ -872,10 +1004,10 @@ void GeometryManager::device_update_mesh( } } } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); - curve_key_size += hair->curve_keys.size(); + curve_key_size += hair->get_curve_keys().size(); curve_size += hair->num_curves(); } } @@ -889,7 +1021,7 @@ void GeometryManager::device_update_mesh( * really use same semantic of arrays. */ foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); for (size_t i = 0; i < mesh->num_triangles(); ++i) { tri_prim_index[i + mesh->prim_offset] = 3 * (i + mesh->prim_offset); @@ -917,7 +1049,7 @@ void GeometryManager::device_update_mesh( float2 *tri_patch_uv = dscene->tri_patch_uv.alloc(vert_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->pack_shaders(scene, &tri_shader[mesh->prim_offset]); mesh->pack_normals(&vnormal[mesh->vert_offset]); @@ -949,7 +1081,7 @@ void GeometryManager::device_update_mesh( float4 *curves = dscene->curves.alloc(curve_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::HAIR) { + if (geom->is_hair()) { Hair *hair = static_cast<Hair *>(geom); hair->pack_curves(scene, &curve_keys[hair->curvekey_offset], @@ -970,7 +1102,7 @@ void GeometryManager::device_update_mesh( uint *patch_data = dscene->patches.alloc(patch_size); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); mesh->pack_patches(&patch_data[mesh->patch_offset], mesh->vert_offset, @@ -993,7 +1125,7 @@ void GeometryManager::device_update_mesh( if (for_displacement) { float4 *prim_tri_verts = dscene->prim_tri_verts.alloc(tri_size * 3); foreach (Geometry *geom, scene->geometry) { - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) { Mesh *mesh = static_cast<Mesh *>(geom); for (size_t i = 0; i < mesh->num_triangles(); ++i) { Mesh::Triangle t = mesh->get_triangle(i); @@ -1120,7 +1252,8 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro foreach (Geometry *geom, scene->geometry) { geom->has_volume = false; - foreach (const Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_volume) { geom->has_volume = true; } @@ -1132,7 +1265,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro /* Re-create volume mesh if we will rebuild or refit the BVH. Note we * should only do it in that case, otherwise the BVH and mesh can go * out of sync. */ - if (geom->need_update && geom->type == Geometry::VOLUME) { + if (geom->is_modified() && geom->geometry_type == Geometry::VOLUME) { /* Create volume meshes if there is voxel data. */ if (!volume_images_updated) { progress.set_status("Updating Meshes Volume Bounds"); @@ -1144,7 +1277,7 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro create_volume_mesh(volume, progress); } - if (geom->type == Geometry::HAIR) { + if (geom->is_hair()) { /* Set curve shape, still a global scene setting for now. */ Hair *hair = static_cast<Hair *>(geom); hair->curve_shape = scene->params.hair_shape; @@ -1163,9 +1296,10 @@ void GeometryManager::device_update_displacement_images(Device *device, ImageManager *image_manager = scene->image_manager; set<int> bump_images; foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { - foreach (Shader *shader, geom->used_shaders) { - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (geom->is_modified()) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } foreach (ShaderNode *node, shader->graph->nodes) { @@ -1199,7 +1333,7 @@ void GeometryManager::device_update_volume_images(Device *device, Scene *scene, set<int> volume_images; foreach (Geometry *geom, scene->geometry) { - if (!geom->need_update) { + if (!geom->is_modified()) { continue; } @@ -1248,12 +1382,14 @@ void GeometryManager::device_update(Device *device, }); foreach (Geometry *geom, scene->geometry) { - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->need_update_geometry) - geom->need_update = true; + geom->tag_modified(); } - if (geom->need_update && (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME)) { + if (geom->is_modified() && + (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME)) { Mesh *mesh = static_cast<Mesh *>(geom); /* Update normals. */ @@ -1265,8 +1401,7 @@ void GeometryManager::device_update(Device *device, } /* Test if we need tessellation. */ - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && - mesh->subd_params) { + if (mesh->need_tesselation()) { total_tess_needed++; } @@ -1291,17 +1426,18 @@ void GeometryManager::device_update(Device *device, }); Camera *dicing_camera = scene->dicing_camera; + dicing_camera->set_screen_size_and_resolution( + dicing_camera->get_full_width(), dicing_camera->get_full_height(), 1); dicing_camera->update(scene); size_t i = 0; foreach (Geometry *geom, scene->geometry) { - if (!(geom->need_update && geom->type == Geometry::MESH)) { + if (!(geom->is_modified() && geom->is_mesh())) { continue; } Mesh *mesh = static_cast<Mesh *>(geom); - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE && mesh->num_subd_verts == 0 && - mesh->subd_params) { + if (mesh->need_tesselation()) { string msg = "Tessellating "; if (mesh->name == "") msg += string_printf("%u/%u", (uint)(i + 1), (uint)total_tess_needed); @@ -1378,8 +1514,8 @@ void GeometryManager::device_update(Device *device, }); foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { - if (geom->type == Geometry::MESH) { + if (geom->is_modified()) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); if (displace(device, dscene, scene, mesh, progress)) { displacement_done = true; @@ -1421,7 +1557,7 @@ void GeometryManager::device_update(Device *device, size_t i = 0; foreach (Geometry *geom, scene->geometry) { - if (geom->need_update) { + if (geom->is_modified()) { pool.push(function_bind( &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh)); if (geom->need_build_bvh(bvh_layout)) { diff --git a/intern/cycles/render/geometry.h b/intern/cycles/render/geometry.h index bcadb3a8051..1c101540464 100644 --- a/intern/cycles/render/geometry.h +++ b/intern/cycles/render/geometry.h @@ -56,13 +56,13 @@ class Geometry : public Node { VOLUME, }; - Type type; + Type geometry_type; /* Attributes */ AttributeSet attributes; /* Shaders */ - vector<Shader *> used_shaders; + NODE_SOCKET_API_ARRAY(array<Node *>, used_shaders) /* Transform */ BoundBox bounds; @@ -71,8 +71,8 @@ class Geometry : public Node { Transform transform_normal; /* Motion Blur */ - uint motion_steps; - bool use_motion_blur; + NODE_SOCKET_API(uint, motion_steps) + NODE_SOCKET_API(bool, use_motion_blur) /* Maximum number of motion steps supported (due to Embree). */ static const uint MAX_MOTION_STEPS = 129; @@ -88,15 +88,17 @@ class Geometry : public Node { bool has_surface_bssrdf; /* Set in the device_update_flags(). */ /* Update Flags */ - bool need_update; bool need_update_rebuild; + /* Index into scene->geometry (only valid during update) */ + size_t index; + /* Constructor/Destructor */ explicit Geometry(const NodeType *node_type, const Type type); virtual ~Geometry(); /* Geometry */ - virtual void clear(); + virtual void clear(bool preserve_shaders = false); virtual void compute_bounds() = 0; virtual void apply_transform(const Transform &tfm, const bool apply_to_motion) = 0; @@ -104,6 +106,8 @@ class Geometry : public Node { bool need_attribute(Scene *scene, AttributeStandard std); bool need_attribute(Scene *scene, ustring name); + AttributeRequestSet needed_attributes(); + /* UDIM */ virtual void get_uv_tiles(ustring map, unordered_set<int> &tiles) = 0; @@ -138,6 +142,16 @@ class Geometry : public Node { bool has_motion_blur() const; bool has_voxel_attributes() const; + bool is_mesh() const + { + return geometry_type == MESH; + } + + bool is_hair() const + { + return geometry_type == HAIR; + } + /* Updates */ void tag_update(Scene *scene, bool rebuild); }; @@ -177,7 +191,8 @@ class GeometryManager { void update_svm_attributes(Device *device, DeviceScene *dscene, Scene *scene, - vector<AttributeRequestSet> &geom_attributes); + vector<AttributeRequestSet> &geom_attributes, + vector<AttributeRequestSet> &object_attributes); /* Compute verts/triangles/curves offsets in global arrays. */ void mesh_calc_offset(Scene *scene); @@ -200,6 +215,21 @@ class GeometryManager { void device_update_displacement_images(Device *device, Scene *scene, Progress &progress); void device_update_volume_images(Device *device, Scene *scene, Progress &progress); + + private: + static void update_attribute_element_offset(Geometry *geom, + device_vector<float> &attr_float, + size_t &attr_float_offset, + device_vector<float2> &attr_float2, + size_t &attr_float2_offset, + device_vector<float4> &attr_float3, + size_t &attr_float3_offset, + device_vector<uchar4> &attr_uchar4, + size_t &attr_uchar4_offset, + Attribute *mattr, + AttributePrimitive prim, + TypeDesc &type, + AttributeDescriptor &desc); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index 088fda00abb..4adfebf80ae 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -273,8 +273,8 @@ void ShaderGraph::connect(ShaderOutput *from, ShaderInput *to) if (to->type() == SocketType::CLOSURE) { EmissionNode *emission = create_node<EmissionNode>(); - emission->color = make_float3(1.0f, 1.0f, 1.0f); - emission->strength = 1.0f; + emission->set_color(make_float3(1.0f, 1.0f, 1.0f)); + emission->set_strength(1.0f); convert = add(emission); /* Connect float inputs to Strength to save an additional Falue->Color conversion. */ if (from->type() == SocketType::FLOAT) { @@ -586,7 +586,7 @@ void ShaderGraph::constant_fold(Scene *scene) */ if (has_displacement && !output()->input("Displacement")->link) { ColorNode *value = (ColorNode *)add(create_node<ColorNode>()); - value->value = output()->displacement; + value->set_value(output()->get_displacement()); connect(value->output("Color"), output()->input("Displacement")); } @@ -1004,8 +1004,8 @@ void ShaderGraph::bump_from_displacement(bool use_object_space) /* add bump node and connect copied graphs to it */ BumpNode *bump = (BumpNode *)add(create_node<BumpNode>()); - bump->use_object_space = use_object_space; - bump->distance = 1.0f; + bump->set_use_object_space(use_object_space); + bump->set_distance(1.0f); ShaderOutput *out = displacement_in->link; ShaderOutput *out_center = nodes_center[out->parent]->output(out->name()); @@ -1017,9 +1017,9 @@ void ShaderGraph::bump_from_displacement(bool use_object_space) VectorMathNode *dot_dx = (VectorMathNode *)add(create_node<VectorMathNode>()); VectorMathNode *dot_dy = (VectorMathNode *)add(create_node<VectorMathNode>()); - dot_center->type = NODE_VECTOR_MATH_DOT_PRODUCT; - dot_dx->type = NODE_VECTOR_MATH_DOT_PRODUCT; - dot_dy->type = NODE_VECTOR_MATH_DOT_PRODUCT; + dot_center->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); + dot_dx->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); + dot_dy->set_math_type(NODE_VECTOR_MATH_DOT_PRODUCT); GeometryNode *geom = (GeometryNode *)add(create_node<GeometryNode>()); connect(geom->output("Normal"), dot_center->input("Vector2")); @@ -1073,7 +1073,7 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if (fin->link) connect(fin->link, fac_in); else - mix_node->fac = node->get_float(fin->socket_type); + mix_node->set_fac(node->get_float(fin->socket_type)); if (weight_out) connect(weight_out, weight_in); @@ -1108,12 +1108,12 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight if (weight_in->link) connect(weight_in->link, math_node->input("Value1")); else - math_node->value1 = weight_value; + math_node->set_value1(weight_value); if (weight_out) connect(weight_out, math_node->input("Value2")); else - math_node->value2 = 1.0f; + math_node->set_value2(1.0f); weight_out = math_node->output("Value"); if (weight_in->link) diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp index 816c15cf4ef..d67bd209142 100644 --- a/intern/cycles/render/hair.cpp +++ b/intern/cycles/render/hair.cpp @@ -321,9 +321,9 @@ void Hair::reserve_curves(int numcurves, int numkeys) attributes.resize(true); } -void Hair::clear() +void Hair::clear(bool preserve_shaders) { - Geometry::clear(); + Geometry::clear(preserve_shaders); curve_keys.clear(); curve_radius.clear(); @@ -337,12 +337,18 @@ void Hair::add_curve_key(float3 co, float radius) { curve_keys.push_back_reserved(co); curve_radius.push_back_reserved(radius); + + tag_curve_keys_modified(); + tag_curve_radius_modified(); } void Hair::add_curve(int first_key, int shader) { curve_first_key.push_back_reserved(first_key); curve_shader.push_back_reserved(shader); + + tag_curve_first_key_modified(); + tag_curve_shader_modified(); } void Hair::copy_center_to_motion_step(const int motion_step) @@ -474,8 +480,9 @@ void Hair::pack_curves(Scene *scene, for (size_t i = 0; i < curve_num; i++) { Curve curve = get_curve(i); int shader_id = curve_shader[i]; - Shader *shader = (shader_id < used_shaders.size()) ? used_shaders[shader_id] : - scene->default_surface; + Shader *shader = (shader_id < used_shaders.size()) ? + static_cast<Shader *>(used_shaders[shader_id]) : + scene->default_surface; shader_id = scene->shader_manager->get_shader_id(shader, false); curve_data[i] = make_float4(__int_as_float(curve.first_key + curvekey_offset), diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h index 39d6a34d799..32c5b00e879 100644 --- a/intern/cycles/render/hair.h +++ b/intern/cycles/render/hair.h @@ -89,10 +89,10 @@ class Hair : public Geometry { float4 r_keys[4]) const; }; - array<float3> curve_keys; - array<float> curve_radius; - array<int> curve_first_key; - array<int> curve_shader; + NODE_SOCKET_API(array<float3>, curve_keys) + NODE_SOCKET_API(array<float>, curve_radius) + NODE_SOCKET_API(array<int>, curve_first_key) + NODE_SOCKET_API(array<int>, curve_shader) /* BVH */ size_t curvekey_offset; @@ -103,7 +103,7 @@ class Hair : public Geometry { ~Hair(); /* Geometry */ - void clear() override; + void clear(bool preserve_shaders = false) override; void resize_curves(int numcurves, int numkeys); void reserve_curves(int numcurves, int numkeys); diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index e50e70c8591..3e6ff289c85 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -381,7 +381,7 @@ ImageHandle ImageManager::add_image(const string &filename, const ImageParams &p ImageHandle ImageManager::add_image(const string &filename, const ImageParams ¶ms, - const vector<int> &tiles) + const array<int> &tiles) { ImageHandle handle; handle.manager = this; diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index c9eccb3468a..6ac1db9ed63 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -174,7 +174,7 @@ class ImageManager { ImageHandle add_image(const string &filename, const ImageParams ¶ms); ImageHandle add_image(const string &filename, const ImageParams ¶ms, - const vector<int> &tiles); + const array<int> &tiles); ImageHandle add_image(ImageLoader *loader, const ImageParams ¶ms, const bool builtin = true); void device_update(Device *device, Scene *scene, Progress &progress); diff --git a/intern/cycles/render/image_vdb.cpp b/intern/cycles/render/image_vdb.cpp index fc2cfe9874e..016bbf7151d 100644 --- a/intern/cycles/render/image_vdb.cpp +++ b/intern/cycles/render/image_vdb.cpp @@ -144,8 +144,13 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) } } +# ifdef WITH_NANOVDB + /* Add small offset for correct sampling between voxels. */ + Transform texture_to_index = transform_translate(0.5f, 0.5f, 0.5f); +# else Transform texture_to_index = transform_translate(min.x(), min.y(), min.z()) * transform_scale(dim.x(), dim.y(), dim.z()); +# endif metadata.transform_3d = transform_inverse(index_to_object * texture_to_index); metadata.use_transform_3d = true; @@ -159,10 +164,10 @@ bool VDBImageLoader::load_metadata(ImageMetaData &metadata) bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size_t, const bool) { -#if defined(WITH_NANOVDB) +#ifdef WITH_OPENVDB +# ifdef WITH_NANOVDB memcpy(pixels, nanogrid.data(), nanogrid.size()); - return true; -#elif defined(WITH_OPENVDB) +# else if (grid->isType<openvdb::FloatGrid>()) { openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels); openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::FloatGrid>(grid), dense); @@ -202,7 +207,7 @@ bool VDBImageLoader::load_pixels(const ImageMetaData &, void *pixels, const size openvdb::tools::Dense<float, openvdb::tools::LayoutXYZ> dense(bbox, (float *)pixels); openvdb::tools::copyToDense(*openvdb::gridConstPtrCast<openvdb::MaskGrid>(grid), dense); } - +# endif return true; #else (void)pixels; diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp index cc085af20a0..3dc4b2fd4c5 100644 --- a/intern/cycles/render/integrator.cpp +++ b/intern/cycles/render/integrator.cpp @@ -96,7 +96,6 @@ NODE_DEFINE(Integrator) Integrator::Integrator() : Node(node_type) { - need_update = true; } Integrator::~Integrator() @@ -105,7 +104,7 @@ Integrator::~Integrator() void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene) { - if (!need_update) + if (!is_modified()) return; scoped_callback_timer timer([scene](double time) { @@ -144,7 +143,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->transparent_shadows = false; foreach (Shader *shader, scene->shaders) { /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */ - if ((shader->has_surface_transparent && shader->use_transparent_shadow) || + if ((shader->has_surface_transparent && shader->get_use_transparent_shadow()) || shader->has_volume) { kintegrator->transparent_shadows = true; break; @@ -227,7 +226,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene if (method == BRANCHED_PATH) { foreach (Light *light, scene->lights) - max_samples = max(max_samples, light->samples); + max_samples = max(max_samples, light->get_samples()); max_samples = max(max_samples, max(diffuse_samples, max(glossy_samples, transmission_samples))); @@ -265,7 +264,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene dscene->sample_pattern_lut.copy_to_device(); } - need_update = false; + clear_modified(); } void Integrator::device_free(Device *, DeviceScene *dscene) @@ -273,11 +272,6 @@ void Integrator::device_free(Device *, DeviceScene *dscene) dscene->sample_pattern_lut.free(); } -bool Integrator::modified(const Integrator &integrator) -{ - return !Node::equals(integrator); -} - void Integrator::tag_update(Scene *scene) { foreach (Shader *shader, scene->shaders) { @@ -286,7 +280,7 @@ void Integrator::tag_update(Scene *scene) break; } } - need_update = true; + tag_modified(); } CCL_NAMESPACE_END diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h index 9804caebe6e..9fe46ad591c 100644 --- a/intern/cycles/render/integrator.h +++ b/intern/cycles/render/integrator.h @@ -31,52 +31,52 @@ class Integrator : public Node { public: NODE_DECLARE - int min_bounce; - int max_bounce; + NODE_SOCKET_API(int, min_bounce) + NODE_SOCKET_API(int, max_bounce) - int max_diffuse_bounce; - int max_glossy_bounce; - int max_transmission_bounce; - int max_volume_bounce; + NODE_SOCKET_API(int, max_diffuse_bounce) + NODE_SOCKET_API(int, max_glossy_bounce) + NODE_SOCKET_API(int, max_transmission_bounce) + NODE_SOCKET_API(int, max_volume_bounce) - int transparent_min_bounce; - int transparent_max_bounce; + NODE_SOCKET_API(int, transparent_min_bounce) + NODE_SOCKET_API(int, transparent_max_bounce) - int ao_bounces; + NODE_SOCKET_API(int, ao_bounces) - int volume_max_steps; - float volume_step_rate; + NODE_SOCKET_API(int, volume_max_steps) + NODE_SOCKET_API(float, volume_step_rate) - bool caustics_reflective; - bool caustics_refractive; - float filter_glossy; + NODE_SOCKET_API(bool, caustics_reflective) + NODE_SOCKET_API(bool, caustics_refractive) + NODE_SOCKET_API(float, filter_glossy) - int seed; + NODE_SOCKET_API(int, seed) - float sample_clamp_direct; - float sample_clamp_indirect; - bool motion_blur; + NODE_SOCKET_API(float, sample_clamp_direct) + NODE_SOCKET_API(float, sample_clamp_indirect) + NODE_SOCKET_API(bool, motion_blur) /* Maximum number of samples, beyond which we are likely to run into * precision issues for sampling patterns. */ static const int MAX_SAMPLES = (1 << 24); - int aa_samples; - int diffuse_samples; - int glossy_samples; - int transmission_samples; - int ao_samples; - int mesh_light_samples; - int subsurface_samples; - int volume_samples; - int start_sample; + NODE_SOCKET_API(int, aa_samples) + NODE_SOCKET_API(int, diffuse_samples) + NODE_SOCKET_API(int, glossy_samples) + NODE_SOCKET_API(int, transmission_samples) + NODE_SOCKET_API(int, ao_samples) + NODE_SOCKET_API(int, mesh_light_samples) + NODE_SOCKET_API(int, subsurface_samples) + NODE_SOCKET_API(int, volume_samples) + NODE_SOCKET_API(int, start_sample) - bool sample_all_lights_direct; - bool sample_all_lights_indirect; - float light_sampling_threshold; + NODE_SOCKET_API(bool, sample_all_lights_direct) + NODE_SOCKET_API(bool, sample_all_lights_indirect) + NODE_SOCKET_API(float, light_sampling_threshold) - int adaptive_min_samples; - float adaptive_threshold; + NODE_SOCKET_API(int, adaptive_min_samples) + NODE_SOCKET_API(float, adaptive_threshold) enum Method { BRANCHED_PATH = 0, @@ -85,11 +85,9 @@ class Integrator : public Node { NUM_METHODS, }; - Method method; + NODE_SOCKET_API(Method, method) - SamplingPattern sampling_pattern; - - bool need_update; + NODE_SOCKET_API(SamplingPattern, sampling_pattern) Integrator(); ~Integrator(); @@ -97,7 +95,6 @@ class Integrator : public Node { void device_update(Device *device, DeviceScene *dscene, Scene *scene); void device_free(Device *device, DeviceScene *dscene); - bool modified(const Integrator &integrator); void tag_update(Scene *scene); }; diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp index 100530ffba6..80190dcbf82 100644 --- a/intern/cycles/render/light.cpp +++ b/intern/cycles/render/light.cpp @@ -114,7 +114,7 @@ NODE_DEFINE(Light) type_enum.insert("background", LIGHT_BACKGROUND); type_enum.insert("area", LIGHT_AREA); type_enum.insert("spot", LIGHT_SPOT); - SOCKET_ENUM(type, "Type", type_enum, LIGHT_POINT); + SOCKET_ENUM(light_type, "Type", type_enum, LIGHT_POINT); SOCKET_COLOR(strength, "Strength", make_float3(1.0f, 1.0f, 1.0f)); @@ -162,7 +162,7 @@ Light::Light() : Node(node_type) void Light::tag_update(Scene *scene) { - scene->light_manager->need_update = true; + scene->light_manager->need_update = is_modified(); } bool Light::has_contribution(Scene *scene) @@ -173,7 +173,7 @@ bool Light::has_contribution(Scene *scene) if (is_portal) { return false; } - if (type == LIGHT_BACKGROUND) { + if (light_type == LIGHT_BACKGROUND) { return true; } return (shader) ? shader->has_surface_emission : scene->default_light->has_surface_emission; @@ -200,7 +200,7 @@ LightManager::~LightManager() bool LightManager::has_background_light(Scene *scene) { foreach (Light *light, scene->lights) { - if (light->type == LIGHT_BACKGROUND && light->is_enabled) { + if (light->light_type == LIGHT_BACKGROUND && light->is_enabled) { return true; } } @@ -217,7 +217,7 @@ void LightManager::test_enabled_lights(Scene *scene) foreach (Light *light, scene->lights) { light->is_enabled = light->has_contribution(scene); has_portal |= light->is_portal; - has_background |= light->type == LIGHT_BACKGROUND; + has_background |= light->light_type == LIGHT_BACKGROUND; } bool background_enabled = false; @@ -232,7 +232,7 @@ void LightManager::test_enabled_lights(Scene *scene) const bool disable_mis = !(has_portal || shader->has_surface_spatial_varying); VLOG_IF(1, disable_mis) << "Background MIS has been disabled.\n"; foreach (Light *light, scene->lights) { - if (light->type == LIGHT_BACKGROUND) { + if (light->light_type == LIGHT_BACKGROUND) { light->is_enabled = !disable_mis; background_enabled = !disable_mis; background_resolution = light->map_resolution; @@ -250,8 +250,8 @@ void LightManager::test_enabled_lights(Scene *scene) bool LightManager::object_usable_as_light(Object *object) { - Geometry *geom = object->geometry; - if (geom->type != Geometry::MESH && geom->type != Geometry::VOLUME) { + Geometry *geom = object->get_geometry(); + if (geom->geometry_type != Geometry::MESH && geom->geometry_type != Geometry::VOLUME) { return false; } /* Skip objects with NaNs */ @@ -259,7 +259,7 @@ bool LightManager::object_usable_as_light(Object *object) return false; } /* Skip if we are not visible for BSDFs. */ - if (!(object->visibility & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) { + if (!(object->get_visibility() & (PATH_RAY_DIFFUSE | PATH_RAY_GLOSSY | PATH_RAY_TRANSMIT))) { return false; } /* Skip if we have no emission shaders. */ @@ -267,8 +267,9 @@ bool LightManager::object_usable_as_light(Object *object) * iterate all geometry shaders twice (when counting and when calculating * triangle area. */ - foreach (const Shader *shader, geom->used_shaders) { - if (shader->use_mis && shader->has_surface_emission) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (shader->get_use_mis() && shader->has_surface_emission) { return true; } } @@ -308,15 +309,15 @@ void LightManager::device_update_distribution(Device *, } /* Count triangles. */ - Mesh *mesh = static_cast<Mesh *>(object->geometry); + Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); size_t mesh_num_triangles = mesh->num_triangles(); for (size_t i = 0; i < mesh_num_triangles; i++) { - int shader_index = mesh->shader[i]; - Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + int shader_index = mesh->get_shader()[i]; + Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? + static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : scene->default_surface; - if (shader->use_mis && shader->has_surface_emission) { + if (shader->get_use_mis() && shader->has_surface_emission) { num_triangles++; } } @@ -342,37 +343,37 @@ void LightManager::device_update_distribution(Device *, continue; } /* Sum area. */ - Mesh *mesh = static_cast<Mesh *>(object->geometry); + Mesh *mesh = static_cast<Mesh *>(object->get_geometry()); bool transform_applied = mesh->transform_applied; - Transform tfm = object->tfm; + Transform tfm = object->get_tfm(); int object_id = j; int shader_flag = 0; - if (!(object->visibility & PATH_RAY_DIFFUSE)) { + if (!(object->get_visibility() & PATH_RAY_DIFFUSE)) { shader_flag |= SHADER_EXCLUDE_DIFFUSE; use_light_visibility = true; } - if (!(object->visibility & PATH_RAY_GLOSSY)) { + if (!(object->get_visibility() & PATH_RAY_GLOSSY)) { shader_flag |= SHADER_EXCLUDE_GLOSSY; use_light_visibility = true; } - if (!(object->visibility & PATH_RAY_TRANSMIT)) { + if (!(object->get_visibility() & PATH_RAY_TRANSMIT)) { shader_flag |= SHADER_EXCLUDE_TRANSMIT; use_light_visibility = true; } - if (!(object->visibility & PATH_RAY_VOLUME_SCATTER)) { + if (!(object->get_visibility() & PATH_RAY_VOLUME_SCATTER)) { shader_flag |= SHADER_EXCLUDE_SCATTER; use_light_visibility = true; } size_t mesh_num_triangles = mesh->num_triangles(); for (size_t i = 0; i < mesh_num_triangles; i++) { - int shader_index = mesh->shader[i]; - Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + int shader_index = mesh->get_shader()[i]; + Shader *shader = (shader_index < mesh->get_used_shaders().size()) ? + static_cast<Shader *>(mesh->get_used_shaders()[shader_index]) : scene->default_surface; - if (shader->use_mis && shader->has_surface_emission) { + if (shader->get_use_mis() && shader->has_surface_emission) { distribution[offset].totarea = totarea; distribution[offset].prim = i + mesh->prim_offset; distribution[offset].mesh_light.shader_flag = shader_flag; @@ -380,12 +381,12 @@ void LightManager::device_update_distribution(Device *, offset++; Mesh::Triangle t = mesh->get_triangle(i); - if (!t.valid(&mesh->verts[0])) { + if (!t.valid(&mesh->get_verts()[0])) { continue; } - float3 p1 = mesh->verts[t.v[0]]; - float3 p2 = mesh->verts[t.v[1]]; - float3 p3 = mesh->verts[t.v[2]]; + float3 p1 = mesh->get_verts()[t.v[0]]; + float3 p2 = mesh->get_verts()[t.v[1]]; + float3 p3 = mesh->get_verts()[t.v[2]]; if (!transform_applied) { p1 = transform_point(&tfm, p1); @@ -417,16 +418,16 @@ void LightManager::device_update_distribution(Device *, distribution[offset].lamp.size = light->size; totarea += lightarea; - if (light->type == LIGHT_DISTANT) { + if (light->light_type == LIGHT_DISTANT) { use_lamp_mis |= (light->angle > 0.0f && light->use_mis); } - else if (light->type == LIGHT_POINT || light->type == LIGHT_SPOT) { + else if (light->light_type == LIGHT_POINT || light->light_type == LIGHT_SPOT) { use_lamp_mis |= (light->size > 0.0f && light->use_mis); } - else if (light->type == LIGHT_AREA) { + else if (light->light_type == LIGHT_AREA) { use_lamp_mis |= light->use_mis; } - else if (light->type == LIGHT_BACKGROUND) { + else if (light->light_type == LIGHT_BACKGROUND) { num_background_lights++; background_mis |= light->use_mis; } @@ -576,7 +577,7 @@ void LightManager::device_update_background(Device *device, /* find background light */ foreach (Light *light, scene->lights) { - if (light->type == LIGHT_BACKGROUND) { + if (light->light_type == LIGHT_BACKGROUND) { background_light = light; break; } @@ -611,7 +612,7 @@ void LightManager::device_update_background(Device *device, } if (node->type == SkyTextureNode::node_type) { SkyTextureNode *sky = (SkyTextureNode *)node; - if (sky->type == NODE_SKY_NISHITA && sky->sun_disc) { + if (sky->get_sky_type() == NODE_SKY_NISHITA && sky->get_sun_disc()) { /* Ensure that the input coordinates aren't transformed before they reach the node. * If that is the case, the logic used for sampling the sun's location does not work * and we have to fall back to map-based sampling. */ @@ -627,8 +628,8 @@ void LightManager::device_update_background(Device *device, } /* Determine sun direction from lat/long and texture mapping. */ - float latitude = sky->sun_elevation; - float longitude = M_2PI_F - sky->sun_rotation + M_PI_2_F; + float latitude = sky->get_sun_elevation(); + float longitude = M_2PI_F - sky->get_sun_rotation() + M_PI_2_F; float3 sun_direction = make_float3( cosf(latitude) * cosf(longitude), cosf(latitude) * sinf(longitude), sinf(latitude)); Transform sky_transform = transform_inverse(sky->tex_mapping.compute_transform()); @@ -771,13 +772,13 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc use_light_visibility = true; } - klights[light_index].type = light->type; + klights[light_index].type = light->light_type; klights[light_index].samples = light->samples; klights[light_index].strength[0] = light->strength.x; klights[light_index].strength[1] = light->strength.y; klights[light_index].strength[2] = light->strength.z; - if (light->type == LIGHT_POINT) { + if (light->light_type == LIGHT_POINT) { shader_id &= ~SHADER_AREA_LIGHT; float radius = light->size; @@ -793,7 +794,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc klights[light_index].spot.radius = radius; klights[light_index].spot.invarea = invarea; } - else if (light->type == LIGHT_DISTANT) { + else if (light->light_type == LIGHT_DISTANT) { shader_id &= ~SHADER_AREA_LIGHT; float angle = light->angle / 2.0f; @@ -816,8 +817,8 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc klights[light_index].distant.radius = radius; klights[light_index].distant.cosangle = cosangle; } - else if (light->type == LIGHT_BACKGROUND) { - uint visibility = scene->background->visibility; + else if (light->light_type == LIGHT_BACKGROUND) { + uint visibility = scene->background->get_visibility(); shader_id &= ~SHADER_AREA_LIGHT; shader_id |= SHADER_USE_MIS; @@ -839,7 +840,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc use_light_visibility = true; } } - else if (light->type == LIGHT_AREA) { + else if (light->light_type == LIGHT_AREA) { float3 axisu = light->axisu * (light->sizeu * light->size); float3 axisv = light->axisv * (light->sizev * light->size); float area = len(axisu) * len(axisv); @@ -869,7 +870,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc klights[light_index].area.dir[1] = dir.y; klights[light_index].area.dir[2] = dir.z; } - else if (light->type == LIGHT_SPOT) { + else if (light->light_type == LIGHT_SPOT) { shader_id &= ~SHADER_AREA_LIGHT; float radius = light->size; @@ -913,7 +914,7 @@ void LightManager::device_update_points(Device *, DeviceScene *dscene, Scene *sc foreach (Light *light, scene->lights) { if (!light->is_portal) continue; - assert(light->type == LIGHT_AREA); + assert(light->light_type == LIGHT_AREA); float3 co = light->co; float3 axisu = light->axisu * (light->sizeu * light->size); @@ -995,10 +996,7 @@ void LightManager::device_update(Device *device, if (progress.get_cancel()) return; - if (use_light_visibility != scene->film->use_light_visibility) { - scene->film->use_light_visibility = use_light_visibility; - scene->film->tag_update(scene); - } + scene->film->set_use_light_visibility(use_light_visibility); need_update = false; need_update_background = false; diff --git a/intern/cycles/render/light.h b/intern/cycles/render/light.h index d136e8f1a08..e590e13b489 100644 --- a/intern/cycles/render/light.h +++ b/intern/cycles/render/light.h @@ -21,6 +21,10 @@ #include "graph/node.h" +/* included as Light::set_shader defined through NODE_SOCKET_API does not select + * the right Node::set overload as it does not know that Shader is a Node */ +#include "render/shader.h" + #include "util/util_ies.h" #include "util/util_thread.h" #include "util/util_types.h" @@ -41,46 +45,48 @@ class Light : public Node { Light(); - LightType type; - float3 strength; - float3 co; + NODE_SOCKET_API(LightType, light_type) + NODE_SOCKET_API(float3, strength) + NODE_SOCKET_API(float3, co) - float3 dir; - float size; - float angle; + NODE_SOCKET_API(float3, dir) + NODE_SOCKET_API(float, size) + NODE_SOCKET_API(float, angle) - float3 axisu; - float sizeu; - float3 axisv; - float sizev; - bool round; + NODE_SOCKET_API(float3, axisu) + NODE_SOCKET_API(float, sizeu) + NODE_SOCKET_API(float3, axisv) + NODE_SOCKET_API(float, sizev) + NODE_SOCKET_API(bool, round) - Transform tfm; + NODE_SOCKET_API(Transform, tfm) - int map_resolution; + NODE_SOCKET_API(int, map_resolution) - float spot_angle; - float spot_smooth; + NODE_SOCKET_API(float, spot_angle) + NODE_SOCKET_API(float, spot_smooth) - bool cast_shadow; - bool use_mis; - bool use_diffuse; - bool use_glossy; - bool use_transmission; - bool use_scatter; + NODE_SOCKET_API(bool, cast_shadow) + NODE_SOCKET_API(bool, use_mis) + NODE_SOCKET_API(bool, use_diffuse) + NODE_SOCKET_API(bool, use_glossy) + NODE_SOCKET_API(bool, use_transmission) + NODE_SOCKET_API(bool, use_scatter) - bool is_portal; - bool is_enabled; + NODE_SOCKET_API(bool, is_portal) + NODE_SOCKET_API(bool, is_enabled) - Shader *shader; - int samples; - int max_bounces; - uint random_id; + NODE_SOCKET_API(Shader *, shader) + NODE_SOCKET_API(int, samples) + NODE_SOCKET_API(int, max_bounces) + NODE_SOCKET_API(uint, random_id) void tag_update(Scene *scene); /* Check whether the light has contribution the scene. */ bool has_contribution(Scene *scene); + + friend class LightManager; }; class LightManager { diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp index 3015ac5e569..11c8e240afd 100644 --- a/intern/cycles/render/mesh.cpp +++ b/intern/cycles/render/mesh.cpp @@ -132,11 +132,58 @@ NODE_DEFINE(Mesh) SOCKET_INT_ARRAY(shader, "Shader", array<int>()); SOCKET_BOOLEAN_ARRAY(smooth, "Smooth", array<bool>()); + SOCKET_INT_ARRAY(triangle_patch, "Triangle Patch", array<int>()); + SOCKET_POINT2_ARRAY(vert_patch_uv, "Patch UVs", array<float2>()); + + static NodeEnum subdivision_type_enum; + subdivision_type_enum.insert("none", SUBDIVISION_NONE); + subdivision_type_enum.insert("linear", SUBDIVISION_LINEAR); + subdivision_type_enum.insert("catmull_clark", SUBDIVISION_CATMULL_CLARK); + SOCKET_ENUM(subdivision_type, "Subdivision Type", subdivision_type_enum, SUBDIVISION_NONE); + + SOCKET_INT_ARRAY(subd_creases_edge, "Subdivision Crease Edges", array<int>()); + SOCKET_FLOAT_ARRAY(subd_creases_weight, "Subdivision Crease Weights", array<float>()); + SOCKET_INT_ARRAY(subd_face_corners, "Subdivision Face Corners", array<int>()); + SOCKET_INT_ARRAY(subd_start_corner, "Subdivision Face Start Corner", array<int>()); + SOCKET_INT_ARRAY(subd_num_corners, "Subdivision Face Corner Count", array<int>()); + SOCKET_INT_ARRAY(subd_shader, "Subdivision Face Shader", array<int>()); + SOCKET_BOOLEAN_ARRAY(subd_smooth, "Subdivision Face Smooth", array<bool>()); + SOCKET_INT_ARRAY(subd_ptex_offset, "Subdivision Face PTex Offset", array<int>()); + SOCKET_INT(num_ngons, "NGons Number", 0); + + /* Subdivisions parameters */ + SOCKET_FLOAT(subd_dicing_rate, "Subdivision Dicing Rate", 0.0f) + SOCKET_INT(subd_max_level, "Subdivision Dicing Rate", 0); + SOCKET_TRANSFORM(subd_objecttoworld, "Subdivision Object Transform", transform_identity()); + return type; } -Mesh::Mesh(const NodeType *node_type_, Type geom_type_) - : Geometry(node_type_, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD) +SubdParams *Mesh::get_subd_params() +{ + if (subdivision_type == SubdivisionType::SUBDIVISION_NONE) { + return nullptr; + } + + if (!subd_params) { + subd_params = new SubdParams(this); + } + + subd_params->dicing_rate = subd_dicing_rate; + subd_params->max_level = subd_max_level; + subd_params->objecttoworld = subd_objecttoworld; + + return subd_params; +} + +bool Mesh::need_tesselation() +{ + return get_subd_params() && (verts_is_modified() || subd_dicing_rate_is_modified() || + subd_objecttoworld_is_modified() || subd_max_level_is_modified()); +} + +Mesh::Mesh(const NodeType *node_type, Type geom_type_) + : Geometry(node_type, geom_type_), subd_attributes(this, ATTR_PRIM_SUBD) { vert_offset = 0; @@ -145,6 +192,7 @@ Mesh::Mesh(const NodeType *node_type_, Type geom_type_) corner_offset = 0; num_subd_verts = 0; + num_subd_faces = 0; num_ngons = 0; @@ -171,7 +219,7 @@ void Mesh::resize_mesh(int numverts, int numtris) shader.resize(numtris); smooth.resize(numtris); - if (subd_faces.size()) { + if (get_num_subd_faces()) { triangle_patch.resize(numtris); vert_patch_uv.resize(numverts); } @@ -187,7 +235,7 @@ void Mesh::reserve_mesh(int numverts, int numtris) shader.reserve(numtris); smooth.reserve(numtris); - if (subd_faces.size()) { + if (get_num_subd_faces()) { triangle_patch.reserve(numtris); vert_patch_uv.reserve(numverts); } @@ -197,25 +245,41 @@ void Mesh::reserve_mesh(int numverts, int numtris) void Mesh::resize_subd_faces(int numfaces, int num_ngons_, int numcorners) { - subd_faces.resize(numfaces); + subd_start_corner.resize(numfaces); + subd_num_corners.resize(numfaces); + subd_shader.resize(numfaces); + subd_smooth.resize(numfaces); + subd_ptex_offset.resize(numfaces); subd_face_corners.resize(numcorners); num_ngons = num_ngons_; + num_subd_faces = numfaces; subd_attributes.resize(); } void Mesh::reserve_subd_faces(int numfaces, int num_ngons_, int numcorners) { - subd_faces.reserve(numfaces); + subd_start_corner.reserve(numfaces); + subd_num_corners.reserve(numfaces); + subd_shader.reserve(numfaces); + subd_smooth.reserve(numfaces); + subd_ptex_offset.reserve(numfaces); subd_face_corners.reserve(numcorners); num_ngons = num_ngons_; + num_subd_faces = numfaces; subd_attributes.resize(true); } -void Mesh::clear(bool preserve_voxel_data) +void Mesh::reserve_subd_creases(size_t num_creases) { - Geometry::clear(); + subd_creases_edge.reserve(num_creases * 2); + subd_creases_weight.reserve(num_creases); +} + +void Mesh::clear(bool preserve_shaders, bool preserve_voxel_data) +{ + Geometry::clear(preserve_shaders); /* clear all verts and triangles */ verts.clear(); @@ -226,12 +290,18 @@ void Mesh::clear(bool preserve_voxel_data) triangle_patch.clear(); vert_patch_uv.clear(); - subd_faces.clear(); + subd_start_corner.clear(); + subd_num_corners.clear(); + subd_shader.clear(); + subd_smooth.clear(); + subd_ptex_offset.clear(); subd_face_corners.clear(); num_subd_verts = 0; + num_subd_faces = 0; - subd_creases.clear(); + subd_creases_edge.clear(); + subd_creases_weight.clear(); subd_attributes.clear(); attributes.clear(preserve_voxel_data); @@ -239,30 +309,36 @@ void Mesh::clear(bool preserve_voxel_data) vert_to_stitching_key_map.clear(); vert_stitching_map.clear(); + subdivision_type = SubdivisionType::SUBDIVISION_NONE; + delete patch_table; patch_table = NULL; } -void Mesh::clear() +void Mesh::clear(bool preserve_shaders) { - clear(false); + clear(preserve_shaders, false); } void Mesh::add_vertex(float3 P) { verts.push_back_reserved(P); + tag_verts_modified(); - if (subd_faces.size()) { + if (get_num_subd_faces()) { vert_patch_uv.push_back_reserved(make_float2(0.0f, 0.0f)); + tag_vert_patch_uv_modified(); } } void Mesh::add_vertex_slow(float3 P) { verts.push_back_slow(P); + tag_verts_modified(); - if (subd_faces.size()) { + if (get_num_subd_faces()) { vert_patch_uv.push_back_slow(make_float2(0.0f, 0.0f)); + tag_vert_patch_uv_modified(); } } @@ -274,8 +350,13 @@ void Mesh::add_triangle(int v0, int v1, int v2, int shader_, bool smooth_) shader.push_back_reserved(shader_); smooth.push_back_reserved(smooth_); - if (subd_faces.size()) { + tag_triangles_modified(); + tag_shader_modified(); + tag_smooth_modified(); + + if (get_num_subd_faces()) { triangle_patch.push_back_reserved(-1); + tag_triangle_patch_modified(); } } @@ -288,14 +369,47 @@ void Mesh::add_subd_face(int *corners, int num_corners, int shader_, bool smooth } int ptex_offset = 0; - - if (subd_faces.size()) { - SubdFace &s = subd_faces[subd_faces.size() - 1]; + // cannot use get_num_subd_faces here as it holds the total number of subd_faces, but we do not + // have the total amount of data yet + if (subd_shader.size()) { + SubdFace s = get_subd_face(subd_shader.size() - 1); ptex_offset = s.ptex_offset + s.num_ptex_faces(); } - SubdFace face = {start_corner, num_corners, shader_, smooth_, ptex_offset}; - subd_faces.push_back_reserved(face); + subd_start_corner.push_back_reserved(start_corner); + subd_num_corners.push_back_reserved(num_corners); + subd_shader.push_back_reserved(shader_); + subd_smooth.push_back_reserved(smooth_); + subd_ptex_offset.push_back_reserved(ptex_offset); + + tag_subd_face_corners_modified(); + tag_subd_start_corner_modified(); + tag_subd_num_corners_modified(); + tag_subd_shader_modified(); + tag_subd_smooth_modified(); + tag_subd_ptex_offset_modified(); +} + +Mesh::SubdFace Mesh::get_subd_face(size_t index) const +{ + Mesh::SubdFace s; + s.shader = subd_shader[index]; + s.num_corners = subd_num_corners[index]; + s.smooth = subd_smooth[index]; + s.ptex_offset = subd_ptex_offset[index]; + s.start_corner = subd_start_corner[index]; + return s; +} + +void Mesh::add_crease(int v0, int v1, float weight) +{ + subd_creases_edge.push_back_slow(v0); + subd_creases_edge.push_back_slow(v1); + subd_creases_weight.push_back_slow(weight); + + tag_subd_creases_edge_modified(); + tag_subd_creases_edge_modified(); + tag_subd_creases_weight_modified(); } void Mesh::copy_center_to_motion_step(const int motion_step) @@ -505,7 +619,7 @@ void Mesh::add_vertex_normals() } /* subd vertex normals */ - if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && subd_faces.size()) { + if (!subd_attributes.find(ATTR_STD_VERTEX_NORMAL) && get_num_subd_faces()) { /* get attributes */ Attribute *attr_vN = subd_attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *vN = attr_vN->data_float3(); @@ -513,8 +627,8 @@ void Mesh::add_vertex_normals() /* compute vertex normals */ memset(vN, 0, verts.size() * sizeof(float3)); - for (size_t i = 0; i < subd_faces.size(); i++) { - SubdFace &face = subd_faces[i]; + for (size_t i = 0; i < get_num_subd_faces(); i++) { + SubdFace face = get_subd_face(i); float3 fN = face.normal(this); for (size_t j = 0; j < face.num_corners; j++) { @@ -574,8 +688,9 @@ void Mesh::pack_shaders(Scene *scene, uint *tri_shader) if (shader_ptr[i] != last_shader || last_smooth != smooth[i]) { last_shader = shader_ptr[i]; last_smooth = smooth[i]; - Shader *shader = (last_shader < used_shaders.size()) ? used_shaders[last_shader] : - scene->default_surface; + Shader *shader = (last_shader < used_shaders.size()) ? + static_cast<Shader *>(used_shaders[last_shader]) : + scene->default_surface; shader_id = scene->shader_manager->get_shader_id(shader, last_smooth); } @@ -616,7 +731,7 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index, { size_t verts_size = verts.size(); - if (verts_size && subd_faces.size()) { + if (verts_size && get_num_subd_faces()) { float2 *vert_patch_uv_ptr = vert_patch_uv.data(); for (size_t i = 0; i < verts_size; i++) { @@ -633,17 +748,17 @@ void Mesh::pack_verts(const vector<uint> &tri_prim_index, t.v[2] + vert_offset, tri_prim_index[i + tri_offset]); - tri_patch[i] = (!subd_faces.size()) ? -1 : (triangle_patch[i] * 8 + patch_offset); + tri_patch[i] = (!get_num_subd_faces()) ? -1 : (triangle_patch[i] * 8 + patch_offset); } } void Mesh::pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset) { - size_t num_faces = subd_faces.size(); + size_t num_faces = get_num_subd_faces(); int ngons = 0; for (size_t f = 0; f < num_faces; f++) { - SubdFace face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { int c[4]; diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h index c8286a01e2c..6630dcd8a35 100644 --- a/intern/cycles/render/mesh.h +++ b/intern/cycles/render/mesh.h @@ -118,36 +118,57 @@ class Mesh : public Geometry { float crease; }; + SubdEdgeCrease get_subd_crease(size_t i) const + { + SubdEdgeCrease s; + s.v[0] = subd_creases_edge[i * 2]; + s.v[1] = subd_creases_edge[i * 2 + 1]; + s.crease = subd_creases_weight[i]; + return s; + } + + bool need_tesselation(); + enum SubdivisionType { SUBDIVISION_NONE, SUBDIVISION_LINEAR, SUBDIVISION_CATMULL_CLARK, }; - SubdivisionType subdivision_type; + NODE_SOCKET_API(SubdivisionType, subdivision_type) /* Mesh Data */ - array<int> triangles; - array<float3> verts; - array<int> shader; - array<bool> smooth; + NODE_SOCKET_API_ARRAY(array<int>, triangles) + NODE_SOCKET_API_ARRAY(array<float3>, verts) + NODE_SOCKET_API_ARRAY(array<int>, shader) + NODE_SOCKET_API_ARRAY(array<bool>, smooth) /* used for storing patch info for subd triangles, only allocated if there are patches */ - array<int> triangle_patch; /* must be < 0 for non subd triangles */ - array<float2> vert_patch_uv; + NODE_SOCKET_API_ARRAY(array<int>, triangle_patch) /* must be < 0 for non subd triangles */ + NODE_SOCKET_API_ARRAY(array<float2>, vert_patch_uv) + + /* SubdFaces */ + NODE_SOCKET_API_ARRAY(array<int>, subd_start_corner) + NODE_SOCKET_API_ARRAY(array<int>, subd_num_corners) + NODE_SOCKET_API_ARRAY(array<int>, subd_shader) + NODE_SOCKET_API_ARRAY(array<bool>, subd_smooth) + NODE_SOCKET_API_ARRAY(array<int>, subd_ptex_offset) - array<SubdFace> subd_faces; - array<int> subd_face_corners; - int num_ngons; + NODE_SOCKET_API_ARRAY(array<int>, subd_face_corners) + NODE_SOCKET_API(int, num_ngons) - array<SubdEdgeCrease> subd_creases; + NODE_SOCKET_API_ARRAY(array<int>, subd_creases_edge) + NODE_SOCKET_API_ARRAY(array<float>, subd_creases_weight) - SubdParams *subd_params; + /* Subdivisions parameters */ + NODE_SOCKET_API(float, subd_dicing_rate) + NODE_SOCKET_API(int, subd_max_level) + NODE_SOCKET_API(Transform, subd_objecttoworld) AttributeSet subd_attributes; + private: PackedPatchTable *patch_table; - /* BVH */ size_t vert_offset; @@ -157,13 +178,22 @@ class Mesh : public Geometry { size_t corner_offset; size_t num_subd_verts; + size_t num_subd_faces; - private: unordered_map<int, int> vert_to_stitching_key_map; /* real vert index -> stitching index */ unordered_multimap<int, int> vert_stitching_map; /* stitching index -> multiple real vert indices */ + + friend class BVH; + friend class BVHBuild; + friend class BVHEmbree; + friend class BVHSpatialSplit; friend class DiagSplit; + friend class EdgeDice; friend class GeometryManager; + friend class ObjectManager; + + SubdParams *subd_params = nullptr; public: /* Functions */ @@ -174,12 +204,13 @@ class Mesh : public Geometry { void reserve_mesh(int numverts, int numfaces); void resize_subd_faces(int numfaces, int num_ngons, int numcorners); void reserve_subd_faces(int numfaces, int num_ngons, int numcorners); - void clear(bool preserve_voxel_data); - void clear() override; + void reserve_subd_creases(size_t num_creases); + void clear(bool preserve_shaders = false) override; void add_vertex(float3 P); void add_vertex_slow(float3 P); void add_triangle(int v0, int v1, int v2, int shader, bool smooth); void add_subd_face(int *corners, int num_corners, int shader_, bool smooth_); + void add_crease(int v0, int v1, float weight); void copy_center_to_motion_step(const int motion_step); @@ -202,6 +233,28 @@ class Mesh : public Geometry { void pack_patches(uint *patch_data, uint vert_offset, uint face_offset, uint corner_offset); void tessellate(DiagSplit *split); + + SubdFace get_subd_face(size_t index) const; + + SubdParams *get_subd_params(); + + size_t get_num_subd_faces() const + { + return num_subd_faces; + } + + void set_num_subd_faces(size_t num_subd_faces_) + { + num_subd_faces = num_subd_faces_; + } + + size_t get_num_subd_verts() + { + return num_subd_verts; + } + + protected: + void clear(bool preserve_shaders, bool preserve_voxel_data); }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/mesh_displace.cpp b/intern/cycles/render/mesh_displace.cpp index 467810f9273..b4fb5dcdea2 100644 --- a/intern/cycles/render/mesh_displace.cpp +++ b/intern/cycles/render/mesh_displace.cpp @@ -58,7 +58,7 @@ bool GeometryManager::displace( size_t object_index = OBJECT_NONE; for (size_t i = 0; i < scene->objects.size(); i++) { - if (scene->objects[i]->geometry == mesh) { + if (scene->objects[i]->get_geometry() == mesh) { object_index = i; break; } @@ -76,10 +76,10 @@ bool GeometryManager::displace( Mesh::Triangle t = mesh->get_triangle(i); int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } @@ -160,10 +160,10 @@ bool GeometryManager::displace( Mesh::Triangle t = mesh->get_triangle(i); int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; - if (!shader->has_displacement || shader->displacement_method == DISPLACE_BUMP) { + if (!shader->has_displacement || shader->get_displacement_method() == DISPLACE_BUMP) { continue; } @@ -227,8 +227,9 @@ bool GeometryManager::displace( bool need_recompute_vertex_normals = false; - foreach (Shader *shader, mesh->used_shaders) { - if (shader->has_displacement && shader->displacement_method == DISPLACE_TRUE) { + foreach (Node *node, mesh->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (shader->has_displacement && shader->get_displacement_method() == DISPLACE_TRUE) { need_recompute_vertex_normals = true; break; } @@ -241,11 +242,11 @@ bool GeometryManager::displace( for (size_t i = 0; i < num_triangles; i++) { int shader_index = mesh->shader[i]; Shader *shader = (shader_index < mesh->used_shaders.size()) ? - mesh->used_shaders[shader_index] : + static_cast<Shader *>(mesh->used_shaders[shader_index]) : scene->default_surface; tri_has_true_disp[i] = shader->has_displacement && - shader->displacement_method == DISPLACE_TRUE; + shader->get_displacement_method() == DISPLACE_TRUE; } /* static vertex normals */ diff --git a/intern/cycles/render/mesh_subdivision.cpp b/intern/cycles/render/mesh_subdivision.cpp index 3d72b2fab91..7408ee2dbdf 100644 --- a/intern/cycles/render/mesh_subdivision.cpp +++ b/intern/cycles/render/mesh_subdivision.cpp @@ -46,13 +46,11 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::resizeComponentTopology(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - setNumBaseVertices(refiner, mesh.verts.size()); - setNumBaseFaces(refiner, mesh.subd_faces.size()); + setNumBaseVertices(refiner, mesh.get_verts().size()); + setNumBaseFaces(refiner, mesh.get_num_subd_faces()); - const ccl::Mesh::SubdFace *face = mesh.subd_faces.data(); - - for (int i = 0; i < mesh.subd_faces.size(); i++, face++) { - setNumBaseFaceVertices(refiner, i, face->num_corners); + for (int i = 0; i < mesh.get_num_subd_faces(); i++) { + setNumBaseFaceVertices(refiner, i, mesh.get_subd_num_corners()[i]); } return true; @@ -62,14 +60,17 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTopology(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - const ccl::Mesh::SubdFace *face = mesh.subd_faces.data(); + const ccl::array<int> &subd_face_corners = mesh.get_subd_face_corners(); + const ccl::array<int> &subd_start_corner = mesh.get_subd_start_corner(); + const ccl::array<int> &subd_num_corners = mesh.get_subd_num_corners(); - for (int i = 0; i < mesh.subd_faces.size(); i++, face++) { + for (int i = 0; i < mesh.get_num_subd_faces(); i++) { IndexArray face_verts = getBaseFaceVertices(refiner, i); - int *corner = &mesh.subd_face_corners[face->start_corner]; + int start_corner = subd_start_corner[i]; + int *corner = &subd_face_corners[start_corner]; - for (int j = 0; j < face->num_corners; j++, corner++) { + for (int j = 0; j < subd_num_corners[i]; j++, corner++) { face_verts[j] = *corner; } } @@ -81,17 +82,18 @@ template<> bool TopologyRefinerFactory<ccl::Mesh>::assignComponentTags(TopologyRefiner &refiner, ccl::Mesh const &mesh) { - const ccl::Mesh::SubdEdgeCrease *crease = mesh.subd_creases.data(); + size_t num_creases = mesh.get_subd_creases_weight().size(); - for (int i = 0; i < mesh.subd_creases.size(); i++, crease++) { - Index edge = findBaseEdge(refiner, crease->v[0], crease->v[1]); + for (int i = 0; i < num_creases; i++) { + ccl::Mesh::SubdEdgeCrease crease = mesh.get_subd_crease(i); + Index edge = findBaseEdge(refiner, crease.v[0], crease.v[1]); if (edge != INDEX_INVALID) { - setBaseEdgeSharpness(refiner, edge, crease->crease * 10.0f); + setBaseEdgeSharpness(refiner, edge, crease.crease * 10.0f); } } - for (int i = 0; i < mesh.verts.size(); i++) { + for (int i = 0; i < mesh.get_verts().size(); i++) { ConstIndexArray vert_edges = getBaseVertexEdges(refiner, i); if (vert_edges.size() == 2) { @@ -203,8 +205,8 @@ class OsdData { int num_local_points = patch_table->GetNumLocalPoints(); verts.resize(num_refiner_verts + num_local_points); - for (int i = 0; i < mesh->verts.size(); i++) { - verts[i].value = mesh->verts[i]; + for (int i = 0; i < mesh->get_verts().size(); i++) { + verts[i].value = mesh->get_verts()[i]; } OsdValue<float3> *src = verts.data(); @@ -278,16 +280,17 @@ class OsdData { { /* loop over all edges to find longest in screen space */ const Far::TopologyLevel &level = refiner->GetLevel(0); - Transform objecttoworld = mesh->subd_params->objecttoworld; - Camera *cam = mesh->subd_params->camera; + const SubdParams *subd_params = mesh->get_subd_params(); + Transform objecttoworld = subd_params->objecttoworld; + Camera *cam = subd_params->camera; float longest_edge = 0.0f; for (size_t i = 0; i < level.GetNumEdges(); i++) { Far::ConstIndexArray verts = level.GetEdgeVertices(i); - float3 a = mesh->verts[verts[0]]; - float3 b = mesh->verts[verts[1]]; + float3 a = mesh->get_verts()[verts[0]]; + float3 b = mesh->get_verts()[verts[1]]; float edge_len; @@ -305,7 +308,7 @@ class OsdData { } /* calculate isolation level */ - int isolation = (int)(log2f(max(longest_edge / mesh->subd_params->dicing_rate, 1.0f)) + 1.0f); + int isolation = (int)(log2f(max(longest_edge / subd_params->dicing_rate, 1.0f)) + 1.0f); return min(isolation, 10); } @@ -368,12 +371,16 @@ struct OsdPatch : Patch { void Mesh::tessellate(DiagSplit *split) { + /* reset the number of subdivision vertices, in case the Mesh was not cleared + * between calls or data updates */ + num_subd_verts = 0; + #ifdef WITH_OPENSUBDIV OsdData osd_data; bool need_packed_patch_table = false; if (subdivision_type == SUBDIVISION_CATMULL_CLARK) { - if (subd_faces.size()) { + if (get_num_subd_faces()) { osd_data.build_from_mesh(this); } } @@ -391,7 +398,7 @@ void Mesh::tessellate(DiagSplit *split) } } - int num_faces = subd_faces.size(); + int num_faces = get_num_subd_faces(); Attribute *attr_vN = subd_attributes.find(ATTR_STD_VERTEX_NORMAL); float3 *vN = (attr_vN) ? attr_vN->data_float3() : NULL; @@ -399,7 +406,7 @@ void Mesh::tessellate(DiagSplit *split) /* count patches */ int num_patches = 0; for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { num_patches++; @@ -416,7 +423,7 @@ void Mesh::tessellate(DiagSplit *split) OsdPatch *patch = osd_patches.data(); for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { patch->patch_index = face.ptex_offset; @@ -444,7 +451,7 @@ void Mesh::tessellate(DiagSplit *split) LinearQuadPatch *patch = linear_patches.data(); for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (face.is_quad()) { float3 *hull = patch->hull; @@ -542,7 +549,7 @@ void Mesh::tessellate(DiagSplit *split) /* keep subdivision for corner attributes disabled for now */ attr.flags &= ~ATTR_SUBDIVIDED; } - else if (subd_faces.size()) { + else if (get_num_subd_faces()) { osd_data.subdivide_attribute(attr); need_packed_patch_table = true; @@ -558,7 +565,7 @@ void Mesh::tessellate(DiagSplit *split) switch (attr.element) { case ATTR_ELEMENT_VERTEX: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { char *center = data + (verts.size() - num_subd_verts + ngons) * stride; @@ -581,7 +588,7 @@ void Mesh::tessellate(DiagSplit *split) } break; case ATTR_ELEMENT_CORNER: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { char *center = data + (subd_face_corners.size() + ngons) * stride; @@ -600,7 +607,7 @@ void Mesh::tessellate(DiagSplit *split) } break; case ATTR_ELEMENT_CORNER_BYTE: { for (int f = 0; f < num_faces; f++) { - SubdFace &face = subd_faces[f]; + SubdFace face = get_subd_face(f); if (!face.is_quad()) { uchar *center = (uchar *)data + (subd_face_corners.size() + ngons) * stride; diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index fa6096ff39b..43dff896db7 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -247,6 +247,9 @@ NODE_DEFINE(ImageTextureNode) SOCKET_FLOAT(projection_blend, "Projection Blend", 0.0f); + SOCKET_INT_ARRAY(tiles, "Tiles", array<int>()); + SOCKET_BOOLEAN(animated, "Animated", false); + SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_UV); SOCKET_OUT_COLOR(color, "Color"); @@ -259,7 +262,7 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(node_type) { colorspace = u_colorspace_raw; animated = false; - tiles.push_back(1001); + tiles.push_back_slow(1001); } ShaderNode *ImageTextureNode::clone(ShaderGraph *graph) const @@ -286,7 +289,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) * 1001 tile, so there's no point in loading any others. */ if (projection == NODE_IMAGE_PROJ_BOX) { tiles.clear(); - tiles.push_back(1001); + tiles.push_back_slow(1001); return; } @@ -308,7 +311,7 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) ShaderNode *node = vector_in->link->parent; if (node->type == UVMapNode::node_type) { UVMapNode *uvmap = (UVMapNode *)node; - attribute = uvmap->attribute; + attribute = uvmap->get_attribute(); } else if (node->type == TextureCoordinateNode::node_type) { if (vector_in->link != node->output("UV")) { @@ -325,20 +328,21 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) * be to have a cache in each mesh that is indexed by attribute. * Additionally, building a graph-to-meshes list once could help. */ foreach (Geometry *geom, scene->geometry) { - foreach (Shader *shader, geom->used_shaders) { + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->graph == graph) { geom->get_uv_tiles(attribute, used_tiles); } } } - ccl::vector<int> new_tiles; + array<int> new_tiles; foreach (int tile, tiles) { if (used_tiles.count(tile)) { - new_tiles.push_back(tile); + new_tiles.push_back_slow(tile); } } - tiles.swap(new_tiles); + tiles.steal_data(new_tiles); } void ImageTextureNode::attributes(Shader *shader, AttributeRequestSet *attributes) @@ -511,6 +515,8 @@ NODE_DEFINE(EnvironmentTextureNode) projection_enum.insert("mirror_ball", NODE_ENVIRONMENT_MIRROR_BALL); SOCKET_ENUM(projection, "Projection", projection_enum, NODE_ENVIRONMENT_EQUIRECTANGULAR); + SOCKET_BOOLEAN(animated, "Animated", false); + SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_POSITION); SOCKET_OUT_COLOR(color, "Color"); @@ -790,7 +796,7 @@ NODE_DEFINE(SkyTextureNode) type_enum.insert("preetham", NODE_SKY_PREETHAM); type_enum.insert("hosek_wilkie", NODE_SKY_HOSEK); type_enum.insert("nishita_improved", NODE_SKY_NISHITA); - SOCKET_ENUM(type, "Type", type_enum, NODE_SKY_NISHITA); + SOCKET_ENUM(sky_type, "Type", type_enum, NODE_SKY_NISHITA); SOCKET_VECTOR(sun_direction, "Sun Direction", make_float3(0.0f, 0.0f, 1.0f)); SOCKET_FLOAT(turbidity, "Turbidity", 2.2f); @@ -823,11 +829,11 @@ void SkyTextureNode::compile(SVMCompiler &compiler) ShaderOutput *color_out = output("Color"); SunSky sunsky; - if (type == NODE_SKY_PREETHAM) + if (sky_type == NODE_SKY_PREETHAM) sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity); - else if (type == NODE_SKY_HOSEK) + else if (sky_type == NODE_SKY_HOSEK) sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo); - else if (type == NODE_SKY_NISHITA) { + else if (sky_type == NODE_SKY_NISHITA) { /* Clamp altitude to reasonable values. * Below 1m causes numerical issues and above 60km is space. */ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f); @@ -860,9 +866,9 @@ void SkyTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.stack_assign(color_out); - compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), type); + compiler.add_node(NODE_TEX_SKY, vector_offset, compiler.stack_assign(color_out), sky_type); /* nishita doesn't need this data */ - if (type != NODE_SKY_NISHITA) { + if (sky_type != NODE_SKY_NISHITA) { compiler.add_node(__float_as_uint(sunsky.phi), __float_as_uint(sunsky.theta), __float_as_uint(sunsky.radiance_x), @@ -919,11 +925,11 @@ void SkyTextureNode::compile(OSLCompiler &compiler) tex_mapping.compile(compiler); SunSky sunsky; - if (type == NODE_SKY_PREETHAM) + if (sky_type == NODE_SKY_PREETHAM) sky_texture_precompute_preetham(&sunsky, sun_direction, turbidity); - else if (type == NODE_SKY_HOSEK) + else if (sky_type == NODE_SKY_HOSEK) sky_texture_precompute_hosek(&sunsky, sun_direction, turbidity, ground_albedo); - else if (type == NODE_SKY_NISHITA) { + else if (sky_type == NODE_SKY_NISHITA) { /* Clamp altitude to reasonable values. * Below 1m causes numerical issues and above 60km is space. */ float clamped_altitude = clamp(altitude, 1.0f, 59999.0f); @@ -963,7 +969,7 @@ void SkyTextureNode::compile(OSLCompiler &compiler) compiler.parameter_array("config_z", sunsky.config_z, 9); compiler.parameter_array("nishita_data", sunsky.nishita_data, 10); /* nishita texture */ - if (type == NODE_SKY_NISHITA) { + if (sky_type == NODE_SKY_NISHITA) { compiler.parameter_texture("filename", handle.svm_slot()); } compiler.add(this, "node_sky_texture"); @@ -985,7 +991,7 @@ NODE_DEFINE(GradientTextureNode) type_enum.insert("radial", NODE_BLEND_RADIAL); type_enum.insert("quadratic_sphere", NODE_BLEND_QUADRATIC_SPHERE); type_enum.insert("spherical", NODE_BLEND_SPHERICAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_BLEND_LINEAR); + SOCKET_ENUM(gradient_type, "Type", type_enum, NODE_BLEND_LINEAR); SOCKET_IN_POINT( vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); @@ -1009,7 +1015,7 @@ void GradientTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_GRADIENT, - compiler.encode_uchar4(type, + compiler.encode_uchar4(gradient_type, vector_offset, compiler.stack_assign_if_linked(fac_out), compiler.stack_assign_if_linked(color_out))); @@ -1369,7 +1375,7 @@ NODE_DEFINE(MusgraveTextureNode) type_enum.insert("hybrid_multifractal", NODE_MUSGRAVE_HYBRID_MULTIFRACTAL); type_enum.insert("ridged_multifractal", NODE_MUSGRAVE_RIDGED_MULTIFRACTAL); type_enum.insert("hetero_terrain", NODE_MUSGRAVE_HETERO_TERRAIN); - SOCKET_ENUM(type, "Type", type_enum, NODE_MUSGRAVE_FBM); + SOCKET_ENUM(musgrave_type, "Type", type_enum, NODE_MUSGRAVE_FBM); SOCKET_IN_POINT( vector, "Vector", make_float3(0.0f, 0.0f, 0.0f), SocketType::LINK_TEXTURE_GENERATED); @@ -1414,7 +1420,7 @@ void MusgraveTextureNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_TEX_MUSGRAVE, - compiler.encode_uchar4(type, dimensions, vector_stack_offset, w_stack_offset), + compiler.encode_uchar4(musgrave_type, dimensions, vector_stack_offset, w_stack_offset), compiler.encode_uchar4(scale_stack_offset, detail_stack_offset, dimension_stack_offset, @@ -1447,7 +1453,7 @@ NODE_DEFINE(WaveTextureNode) static NodeEnum type_enum; type_enum.insert("bands", NODE_WAVE_BANDS); type_enum.insert("rings", NODE_WAVE_RINGS); - SOCKET_ENUM(type, "Type", type_enum, NODE_WAVE_BANDS); + SOCKET_ENUM(wave_type, "Type", type_enum, NODE_WAVE_BANDS); static NodeEnum bands_direction_enum; bands_direction_enum.insert("x", NODE_WAVE_BANDS_DIRECTION_X); @@ -1504,7 +1510,7 @@ void WaveTextureNode::compile(SVMCompiler &compiler) int vector_offset = tex_mapping.compile_begin(compiler, vector_in); compiler.add_node(NODE_TEX_WAVE, - compiler.encode_uchar4(type, bands_direction, rings_direction, profile), + compiler.encode_uchar4(wave_type, bands_direction, rings_direction, profile), compiler.encode_uchar4(vector_offset, compiler.stack_assign_if_linked(scale_in), compiler.stack_assign_if_linked(distortion_in)), @@ -1926,7 +1932,7 @@ NODE_DEFINE(MappingNode) type_enum.insert("texture", NODE_MAPPING_TYPE_TEXTURE); type_enum.insert("vector", NODE_MAPPING_TYPE_VECTOR); type_enum.insert("normal", NODE_MAPPING_TYPE_NORMAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_MAPPING_TYPE_POINT); + SOCKET_ENUM(mapping_type, "Type", type_enum, NODE_MAPPING_TYPE_POINT); SOCKET_IN_POINT(vector, "Vector", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_POINT(location, "Location", make_float3(0.0f, 0.0f, 0.0f)); @@ -1945,11 +1951,11 @@ MappingNode::MappingNode() : ShaderNode(node_type) void MappingNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - float3 result = svm_mapping((NodeMappingType)type, vector, location, rotation, scale); + float3 result = svm_mapping((NodeMappingType)mapping_type, vector, location, rotation, scale); folder.make_constant(result); } else { - folder.fold_mapping((NodeMappingType)type); + folder.fold_mapping((NodeMappingType)mapping_type); } } @@ -1969,7 +1975,7 @@ void MappingNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_MAPPING, - type, + mapping_type, compiler.encode_uchar4( vector_stack_offset, location_stack_offset, rotation_stack_offset, scale_stack_offset), result_stack_offset); @@ -2385,7 +2391,7 @@ void GlossyBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -2478,7 +2484,7 @@ void GlassBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -2571,7 +2577,7 @@ void RefractionBsdfNode::simplify_settings(Scene *scene) } Integrator *integrator = scene->integrator; ShaderInput *roughness_input = input("Roughness"); - if (integrator->filter_glossy == 0.0f) { + if (integrator->get_filter_glossy() == 0.0f) { /* Fallback to Sharp closure for Roughness close to 0. * Note: Keep the epsilon in sync with kernel! */ @@ -3743,7 +3749,7 @@ void GeometryNode::compile(SVMCompiler &compiler) if (!out->links.empty()) { if (compiler.output_type() != SHADER_TYPE_VOLUME) { compiler.add_node( - attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_FLOAT); + attr_node, ATTR_STD_POINTINESS, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); } else { compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); @@ -3753,8 +3759,10 @@ void GeometryNode::compile(SVMCompiler &compiler) out = output("Random Per Island"); if (!out->links.empty()) { if (compiler.output_type() != SHADER_TYPE_VOLUME) { - compiler.add_node( - attr_node, ATTR_STD_RANDOM_PER_ISLAND, compiler.stack_assign(out), NODE_ATTR_FLOAT); + compiler.add_node(attr_node, + ATTR_STD_RANDOM_PER_ISLAND, + compiler.stack_assign(out), + NODE_ATTR_OUTPUT_FLOAT); } else { compiler.add_node(NODE_VALUE_F, __float_as_int(0.0f), compiler.stack_assign(out)); @@ -3872,7 +3880,7 @@ void TextureCoordinateNode::compile(SVMCompiler &compiler) } else { int attr = compiler.attribute(ATTR_STD_GENERATED); - compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3); + compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); } } } @@ -3889,7 +3897,7 @@ void TextureCoordinateNode::compile(SVMCompiler &compiler) } else { int attr = compiler.attribute(ATTR_STD_UV); - compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3); + compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); } } @@ -4007,7 +4015,7 @@ void UVMapNode::compile(SVMCompiler &compiler) else attr = compiler.attribute(ATTR_STD_UV); - compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT3); + compiler.add_node(attr_node, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT3); } } } @@ -4403,7 +4411,7 @@ void HairInfoNode::compile(SVMCompiler &compiler) out = output("Intercept"); if (!out->links.empty()) { int attr = compiler.attribute(ATTR_STD_CURVE_INTERCEPT); - compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT); + compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); } out = output("Thickness"); @@ -4424,7 +4432,7 @@ void HairInfoNode::compile(SVMCompiler &compiler) out = output("Random"); if (!out->links.empty()) { int attr = compiler.attribute(ATTR_STD_CURVE_RANDOM); - compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_FLOAT); + compiler.add_node(NODE_ATTR, attr, compiler.stack_assign(out), NODE_ATTR_OUTPUT_FLOAT); } } @@ -4479,7 +4487,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *color_out = output("Color"); if (!color_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "color"; + attr->set_attribute(ustring("color")); graph->add(attr); graph->relink(color_out, attr->output("Color")); } @@ -4487,7 +4495,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *density_out = output("Density"); if (!density_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "density"; + attr->set_attribute(ustring("density")); graph->add(attr); graph->relink(density_out, attr->output("Fac")); } @@ -4495,7 +4503,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *flame_out = output("Flame"); if (!flame_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "flame"; + attr->set_attribute(ustring("flame")); graph->add(attr); graph->relink(flame_out, attr->output("Fac")); } @@ -4503,7 +4511,7 @@ void VolumeInfoNode::expand(ShaderGraph *graph) ShaderOutput *temperature_out = output("Temperature"); if (!temperature_out->links.empty()) { AttributeNode *attr = graph->create_node<AttributeNode>(); - attr->attribute = "temperature"; + attr->set_attribute(ustring("temperature")); graph->add(attr); graph->relink(temperature_out, attr->output("Fac")); } @@ -4880,7 +4888,7 @@ NODE_DEFINE(MixNode) type_enum.insert("color", NODE_MIX_COLOR); type_enum.insert("soft_light", NODE_MIX_SOFT); type_enum.insert("linear_light", NODE_MIX_LINEAR); - SOCKET_ENUM(type, "Type", type_enum, NODE_MIX_BLEND); + SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -4908,7 +4916,7 @@ void MixNode::compile(SVMCompiler &compiler) compiler.stack_assign(fac_in), compiler.stack_assign(color1_in), compiler.stack_assign(color2_in)); - compiler.add_node(NODE_MIX, type, compiler.stack_assign(color_out)); + compiler.add_node(NODE_MIX, mix_type, compiler.stack_assign(color_out)); if (use_clamp) { compiler.add_node(NODE_MIX, 0, compiler.stack_assign(color_out)); @@ -4926,10 +4934,10 @@ void MixNode::compile(OSLCompiler &compiler) void MixNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - folder.make_constant_clamp(svm_mix(type, fac, color1, color2), use_clamp); + folder.make_constant_clamp(svm_mix(mix_type, fac, color1, color2), use_clamp); } else { - folder.fold_mix(type, use_clamp); + folder.fold_mix(mix_type, use_clamp); } } @@ -5386,6 +5394,7 @@ NODE_DEFINE(AttributeNode) SOCKET_OUT_COLOR(color, "Color"); SOCKET_OUT_VECTOR(vector, "Vector"); SOCKET_OUT_FLOAT(fac, "Fac"); + SOCKET_OUT_FLOAT(alpha, "Alpha"); return type; } @@ -5399,8 +5408,10 @@ void AttributeNode::attributes(Shader *shader, AttributeRequestSet *attributes) ShaderOutput *color_out = output("Color"); ShaderOutput *vector_out = output("Vector"); ShaderOutput *fac_out = output("Fac"); + ShaderOutput *alpha_out = output("Alpha"); - if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty()) { + if (!color_out->links.empty() || !vector_out->links.empty() || !fac_out->links.empty() || + !alpha_out->links.empty()) { attributes->add_standard(attribute); } @@ -5416,6 +5427,7 @@ void AttributeNode::compile(SVMCompiler &compiler) ShaderOutput *color_out = output("Color"); ShaderOutput *vector_out = output("Vector"); ShaderOutput *fac_out = output("Fac"); + ShaderOutput *alpha_out = output("Alpha"); ShaderNodeType attr_node = NODE_ATTR; int attr = compiler.attribute_standard(attribute); @@ -5426,15 +5438,22 @@ void AttributeNode::compile(SVMCompiler &compiler) if (!color_out->links.empty() || !vector_out->links.empty()) { if (!color_out->links.empty()) { - compiler.add_node(attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_FLOAT3); + compiler.add_node( + attr_node, attr, compiler.stack_assign(color_out), NODE_ATTR_OUTPUT_FLOAT3); } if (!vector_out->links.empty()) { - compiler.add_node(attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_FLOAT3); + compiler.add_node( + attr_node, attr, compiler.stack_assign(vector_out), NODE_ATTR_OUTPUT_FLOAT3); } } if (!fac_out->links.empty()) { - compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_FLOAT); + compiler.add_node(attr_node, attr, compiler.stack_assign(fac_out), NODE_ATTR_OUTPUT_FLOAT); + } + + if (!alpha_out->links.empty()) { + compiler.add_node( + attr_node, attr, compiler.stack_assign(alpha_out), NODE_ATTR_OUTPUT_FLOAT_ALPHA); } } @@ -5748,7 +5767,7 @@ NODE_DEFINE(MapRangeNode) type_enum.insert("stepped", NODE_MAP_RANGE_STEPPED); type_enum.insert("smoothstep", NODE_MAP_RANGE_SMOOTHSTEP); type_enum.insert("smootherstep", NODE_MAP_RANGE_SMOOTHERSTEP); - SOCKET_ENUM(type, "Type", type_enum, NODE_MAP_RANGE_LINEAR); + SOCKET_ENUM(range_type, "Type", type_enum, NODE_MAP_RANGE_LINEAR); SOCKET_IN_FLOAT(value, "Value", 1.0f); SOCKET_IN_FLOAT(from_min, "From Min", 0.0f); @@ -5773,7 +5792,7 @@ void MapRangeNode::expand(ShaderGraph *graph) ShaderOutput *result_out = output("Result"); if (!result_out->links.empty()) { ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = NODE_CLAMP_RANGE; + clamp_node->set_clamp_type(NODE_CLAMP_RANGE); graph->add(clamp_node); graph->relink(result_out, clamp_node->output("Result")); graph->connect(result_out, clamp_node->input("Value")); @@ -5781,13 +5800,13 @@ void MapRangeNode::expand(ShaderGraph *graph) graph->connect(input("To Min")->link, clamp_node->input("Min")); } else { - clamp_node->min = to_min; + clamp_node->set_min(to_min); } if (input("To Max")->link) { graph->connect(input("To Max")->link, clamp_node->input("Max")); } else { - clamp_node->max = to_max; + clamp_node->set_max(to_max); } } } @@ -5816,7 +5835,7 @@ void MapRangeNode::compile(SVMCompiler &compiler) value_stack_offset, compiler.encode_uchar4( from_min_stack_offset, from_max_stack_offset, to_min_stack_offset, to_max_stack_offset), - compiler.encode_uchar4(type, steps_stack_offset, result_stack_offset)); + compiler.encode_uchar4(range_type, steps_stack_offset, result_stack_offset)); compiler.add_node(__float_as_int(from_min), __float_as_int(from_max), @@ -5840,7 +5859,7 @@ NODE_DEFINE(ClampNode) static NodeEnum type_enum; type_enum.insert("minmax", NODE_CLAMP_MINMAX); type_enum.insert("range", NODE_CLAMP_RANGE); - SOCKET_ENUM(type, "Type", type_enum, NODE_CLAMP_MINMAX); + SOCKET_ENUM(clamp_type, "Type", type_enum, NODE_CLAMP_MINMAX); SOCKET_IN_FLOAT(value, "Value", 1.0f); SOCKET_IN_FLOAT(min, "Min", 0.0f); @@ -5858,7 +5877,7 @@ ClampNode::ClampNode() : ShaderNode(node_type) void ClampNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - if (type == NODE_CLAMP_RANGE && (min > max)) { + if (clamp_type == NODE_CLAMP_RANGE && (min > max)) { folder.make_constant(clamp(value, max, min)); } else { @@ -5881,7 +5900,7 @@ void ClampNode::compile(SVMCompiler &compiler) compiler.add_node(NODE_CLAMP, value_stack_offset, - compiler.encode_uchar4(min_stack_offset, max_stack_offset, type), + compiler.encode_uchar4(min_stack_offset, max_stack_offset, clamp_type), result_stack_offset); compiler.add_node(__float_as_int(min), __float_as_int(max)); } @@ -5991,7 +6010,7 @@ NODE_DEFINE(MathNode) type_enum.insert("smoothmin", NODE_MATH_SMOOTH_MIN); type_enum.insert("smoothmax", NODE_MATH_SMOOTH_MAX); type_enum.insert("compare", NODE_MATH_COMPARE); - SOCKET_ENUM(type, "Type", type_enum, NODE_MATH_ADD); + SOCKET_ENUM(math_type, "Type", type_enum, NODE_MATH_ADD); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -6014,9 +6033,9 @@ void MathNode::expand(ShaderGraph *graph) ShaderOutput *result_out = output("Value"); if (!result_out->links.empty()) { ClampNode *clamp_node = graph->create_node<ClampNode>(); - clamp_node->type = NODE_CLAMP_MINMAX; - clamp_node->min = 0.0f; - clamp_node->max = 1.0f; + clamp_node->set_clamp_type(NODE_CLAMP_MINMAX); + clamp_node->set_min(0.0f); + clamp_node->set_max(1.0f); graph->add(clamp_node); graph->relink(result_out, clamp_node->output("Result")); graph->connect(result_out, clamp_node->input("Value")); @@ -6027,10 +6046,10 @@ void MathNode::expand(ShaderGraph *graph) void MathNode::constant_fold(const ConstantFolder &folder) { if (folder.all_inputs_constant()) { - folder.make_constant(svm_math(type, value1, value2, value3)); + folder.make_constant(svm_math(math_type, value1, value2, value3)); } else { - folder.fold_math(type); + folder.fold_math(math_type); } } @@ -6048,7 +6067,7 @@ void MathNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_MATH, - type, + math_type, compiler.encode_uchar4(value1_stack_offset, value2_stack_offset, value3_stack_offset), value_stack_offset); } @@ -6094,7 +6113,7 @@ NODE_DEFINE(VectorMathNode) type_enum.insert("sine", NODE_VECTOR_MATH_SINE); type_enum.insert("cosine", NODE_VECTOR_MATH_COSINE); type_enum.insert("tangent", NODE_VECTOR_MATH_TANGENT); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_MATH_ADD); + SOCKET_ENUM(math_type, "Type", type_enum, NODE_VECTOR_MATH_ADD); SOCKET_IN_VECTOR(vector1, "Vector1", make_float3(0.0f, 0.0f, 0.0f)); SOCKET_IN_VECTOR(vector2, "Vector2", make_float3(0.0f, 0.0f, 0.0f)); @@ -6117,7 +6136,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) float3 vector = make_float3(0.0f, 0.0f, 0.0f); if (folder.all_inputs_constant()) { - svm_vector_math(&value, &vector, type, vector1, vector2, vector3, scale); + svm_vector_math(&value, &vector, math_type, vector1, vector2, vector3, scale); if (folder.output == output("Value")) { folder.make_constant(value); } @@ -6126,7 +6145,7 @@ void VectorMathNode::constant_fold(const ConstantFolder &folder) } } else { - folder.fold_vector_math(type); + folder.fold_vector_math(math_type); } } @@ -6145,12 +6164,12 @@ void VectorMathNode::compile(SVMCompiler &compiler) int vector_stack_offset = compiler.stack_assign_if_linked(vector_out); /* 3 Vector Operators */ - if (type == NODE_VECTOR_MATH_WRAP) { + if (math_type == NODE_VECTOR_MATH_WRAP) { ShaderInput *vector3_in = input("Vector3"); int vector3_stack_offset = compiler.stack_assign(vector3_in); compiler.add_node( NODE_VECTOR_MATH, - type, + math_type, compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); compiler.add_node(vector3_stack_offset); @@ -6158,7 +6177,7 @@ void VectorMathNode::compile(SVMCompiler &compiler) else { compiler.add_node( NODE_VECTOR_MATH, - type, + math_type, compiler.encode_uchar4(vector1_stack_offset, vector2_stack_offset, scale_stack_offset), compiler.encode_uchar4(value_stack_offset, vector_stack_offset)); } @@ -6182,7 +6201,7 @@ NODE_DEFINE(VectorRotateNode) type_enum.insert("y_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Y); type_enum.insert("z_axis", NODE_VECTOR_ROTATE_TYPE_AXIS_Z); type_enum.insert("euler_xyz", NODE_VECTOR_ROTATE_TYPE_EULER_XYZ); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS); + SOCKET_ENUM(rotate_type, "Type", type_enum, NODE_VECTOR_ROTATE_TYPE_AXIS); SOCKET_BOOLEAN(invert, "Invert", false); @@ -6209,14 +6228,15 @@ void VectorRotateNode::compile(SVMCompiler &compiler) ShaderInput *angle_in = input("Angle"); ShaderOutput *vector_out = output("Vector"); - compiler.add_node( - NODE_VECTOR_ROTATE, - compiler.encode_uchar4( - type, compiler.stack_assign(vector_in), compiler.stack_assign(rotation_in), invert), - compiler.encode_uchar4(compiler.stack_assign(center_in), - compiler.stack_assign(axis_in), - compiler.stack_assign(angle_in)), - compiler.stack_assign(vector_out)); + compiler.add_node(NODE_VECTOR_ROTATE, + compiler.encode_uchar4(rotate_type, + compiler.stack_assign(vector_in), + compiler.stack_assign(rotation_in), + invert), + compiler.encode_uchar4(compiler.stack_assign(center_in), + compiler.stack_assign(axis_in), + compiler.stack_assign(angle_in)), + compiler.stack_assign(vector_out)); } void VectorRotateNode::compile(OSLCompiler &compiler) @@ -6236,7 +6256,7 @@ NODE_DEFINE(VectorTransformNode) type_enum.insert("vector", NODE_VECTOR_TRANSFORM_TYPE_VECTOR); type_enum.insert("point", NODE_VECTOR_TRANSFORM_TYPE_POINT); type_enum.insert("normal", NODE_VECTOR_TRANSFORM_TYPE_NORMAL); - SOCKET_ENUM(type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR); + SOCKET_ENUM(transform_type, "Type", type_enum, NODE_VECTOR_TRANSFORM_TYPE_VECTOR); static NodeEnum space_enum; space_enum.insert("world", NODE_VECTOR_TRANSFORM_CONVERT_SPACE_WORLD); @@ -6262,7 +6282,7 @@ void VectorTransformNode::compile(SVMCompiler &compiler) compiler.add_node( NODE_VECTOR_TRANSFORM, - compiler.encode_uchar4(type, convert_from, convert_to), + compiler.encode_uchar4(transform_type, convert_from, convert_to), compiler.encode_uchar4(compiler.stack_assign(vector_in), compiler.stack_assign(vector_out))); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index 62dd9d843a8..4d51b4fccaf 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -70,6 +70,17 @@ class TextureNode : public ShaderNode { { } TextureMapping tex_mapping; + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, translation) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, rotation) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, scale) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, min) + NODE_SOCKET_API_STRUCT_MEMBER(float3, tex_mapping, max) + NODE_SOCKET_API_STRUCT_MEMBER(bool, tex_mapping, use_minmax) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Type, tex_mapping, type) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, x_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, y_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Mapping, tex_mapping, z_mapping) + NODE_SOCKET_API_STRUCT_MEMBER(TextureMapping::Projection, tex_mapping, projection) }; /* Any node which uses image manager's slot should be a subclass of this one. */ @@ -108,16 +119,16 @@ class ImageTextureNode : public ImageSlotTextureNode { ImageParams image_params() const; /* Parameters. */ - ustring filename; - ustring colorspace; - ImageAlphaType alpha_type; - NodeImageProjection projection; - InterpolationType interpolation; - ExtensionType extension; - float projection_blend; - bool animated; - float3 vector; - ccl::vector<int> tiles; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, colorspace) + NODE_SOCKET_API(ImageAlphaType, alpha_type) + NODE_SOCKET_API(NodeImageProjection, projection) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(ExtensionType, extension) + NODE_SOCKET_API(float, projection_blend) + NODE_SOCKET_API(bool, animated) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(array<int>, tiles) protected: void cull_tiles(Scene *scene, ShaderGraph *graph); @@ -146,13 +157,13 @@ class EnvironmentTextureNode : public ImageSlotTextureNode { ImageParams image_params() const; /* Parameters. */ - ustring filename; - ustring colorspace; - ImageAlphaType alpha_type; - NodeEnvironmentProjection projection; - InterpolationType interpolation; - bool animated; - float3 vector; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, colorspace) + NODE_SOCKET_API(ImageAlphaType, alpha_type) + NODE_SOCKET_API(NodeEnvironmentProjection, projection) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(bool, animated) + NODE_SOCKET_API(float3, vector) }; class SkyTextureNode : public TextureNode { @@ -164,20 +175,20 @@ class SkyTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeSkyType type; - float3 sun_direction; - float turbidity; - float ground_albedo; - bool sun_disc; - float sun_size; - float sun_intensity; - float sun_elevation; - float sun_rotation; - float altitude; - float air_density; - float dust_density; - float ozone_density; - float3 vector; + NODE_SOCKET_API(NodeSkyType, sky_type) + NODE_SOCKET_API(float3, sun_direction) + NODE_SOCKET_API(float, turbidity) + NODE_SOCKET_API(float, ground_albedo) + NODE_SOCKET_API(bool, sun_disc) + NODE_SOCKET_API(float, sun_size) + NODE_SOCKET_API(float, sun_intensity) + NODE_SOCKET_API(float, sun_elevation) + NODE_SOCKET_API(float, sun_rotation) + NODE_SOCKET_API(float, altitude) + NODE_SOCKET_API(float, air_density) + NODE_SOCKET_API(float, dust_density) + NODE_SOCKET_API(float, ozone_density) + NODE_SOCKET_API(float3, vector) ImageHandle handle; float get_sun_size() @@ -191,10 +202,10 @@ class OutputNode : public ShaderNode { public: SHADER_NODE_CLASS(OutputNode) - void *surface; - void *volume; - float3 displacement; - float3 normal; + NODE_SOCKET_API(Node *, surface) + NODE_SOCKET_API(Node *, volume) + NODE_SOCKET_API(float3, displacement) + NODE_SOCKET_API(float3, normal) /* Don't allow output node de-duplication. */ virtual bool equals(const ShaderNode & /*other*/) @@ -208,10 +219,10 @@ class OutputAOVNode : public ShaderNode { SHADER_NODE_CLASS(OutputAOVNode) virtual void simplify_settings(Scene *scene); - float value; - float3 color; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float3, color) - ustring name; + NODE_SOCKET_API(ustring, name) virtual int get_group() { @@ -237,17 +248,21 @@ class GradientTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeGradientType type; - float3 vector; + NODE_SOCKET_API(NodeGradientType, gradient_type) + NODE_SOCKET_API(float3, vector) }; class NoiseTextureNode : public TextureNode { public: SHADER_NODE_CLASS(NoiseTextureNode) - int dimensions; - float w, scale, detail, roughness, distortion; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, distortion) + NODE_SOCKET_API(float3, vector) }; class VoronoiTextureNode : public TextureNode { @@ -271,11 +286,15 @@ class VoronoiTextureNode : public TextureNode { return result; } - int dimensions; - NodeVoronoiDistanceMetric metric; - NodeVoronoiFeature feature; - float w, scale, exponent, smoothness, randomness; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(NodeVoronoiDistanceMetric, metric) + NODE_SOCKET_API(NodeVoronoiFeature, feature) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, exponent) + NODE_SOCKET_API(float, smoothness) + NODE_SOCKET_API(float, randomness) + NODE_SOCKET_API(float3, vector) }; class MusgraveTextureNode : public TextureNode { @@ -287,10 +306,16 @@ class MusgraveTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - int dimensions; - NodeMusgraveType type; - float w, scale, detail, dimension, lacunarity, offset, gain; - float3 vector; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(NodeMusgraveType, musgrave_type) + NODE_SOCKET_API(float, w) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, dimension) + NODE_SOCKET_API(float, lacunarity) + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, gain) + NODE_SOCKET_API(float3, vector) }; class WaveTextureNode : public TextureNode { @@ -302,13 +327,18 @@ class WaveTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - NodeWaveType type; - NodeWaveBandsDirection bands_direction; - NodeWaveRingsDirection rings_direction; - NodeWaveProfile profile; + NODE_SOCKET_API(NodeWaveType, wave_type) + NODE_SOCKET_API(NodeWaveBandsDirection, bands_direction) + NODE_SOCKET_API(NodeWaveRingsDirection, rings_direction) + NODE_SOCKET_API(NodeWaveProfile, profile) - float scale, distortion, detail, detail_scale, detail_roughness, phase; - float3 vector; + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, distortion) + NODE_SOCKET_API(float, detail) + NODE_SOCKET_API(float, detail_scale) + NODE_SOCKET_API(float, detail_roughness) + NODE_SOCKET_API(float, phase) + NODE_SOCKET_API(float3, vector) }; class MagicTextureNode : public TextureNode { @@ -320,17 +350,20 @@ class MagicTextureNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - int depth; - float3 vector; - float scale, distortion; + NODE_SOCKET_API(int, depth) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, distortion) }; class CheckerTextureNode : public TextureNode { public: SHADER_NODE_CLASS(CheckerTextureNode) - float3 vector, color1, color2; - float scale; + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float, scale) virtual int get_group() { @@ -342,12 +375,21 @@ class BrickTextureNode : public TextureNode { public: SHADER_NODE_CLASS(BrickTextureNode) - float offset, squash; - int offset_frequency, squash_frequency; - - float3 color1, color2, mortar; - float scale, mortar_size, mortar_smooth, bias, brick_width, row_height; - float3 vector; + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, squash) + NODE_SOCKET_API(int, offset_frequency) + NODE_SOCKET_API(int, squash_frequency) + + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float3, mortar) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float, mortar_size) + NODE_SOCKET_API(float, mortar_smooth) + NODE_SOCKET_API(float, bias) + NODE_SOCKET_API(float, brick_width) + NODE_SOCKET_API(float, row_height) + NODE_SOCKET_API(float3, vector) virtual int get_group() { @@ -377,11 +419,11 @@ class PointDensityTextureNode : public ShaderNode { } /* Parameters. */ - ustring filename; - NodeTexVoxelSpace space; - InterpolationType interpolation; - Transform tfm; - float3 vector; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(NodeTexVoxelSpace, space) + NODE_SOCKET_API(InterpolationType, interpolation) + NODE_SOCKET_API(Transform, tfm) + NODE_SOCKET_API(float3, vector) /* Runtime. */ ImageHandle handle; @@ -406,11 +448,11 @@ class IESLightNode : public TextureNode { return NODE_GROUP_LEVEL_2; } - ustring filename; - ustring ies; + NODE_SOCKET_API(ustring, filename) + NODE_SOCKET_API(ustring, ies) - float strength; - float3 vector; + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float3, vector) private: LightManager *light_manager; @@ -427,9 +469,9 @@ class WhiteNoiseTextureNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - int dimensions; - float3 vector; - float w; + NODE_SOCKET_API(int, dimensions) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, w) }; class MappingNode : public ShaderNode { @@ -441,8 +483,11 @@ class MappingNode : public ShaderNode { } void constant_fold(const ConstantFolder &folder); - float3 vector, location, rotation, scale; - NodeMappingType type; + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, location) + NODE_SOCKET_API(float3, rotation) + NODE_SOCKET_API(float3, scale) + NODE_SOCKET_API(NodeMappingType, mapping_type) }; class RGBToBWNode : public ShaderNode { @@ -450,7 +495,7 @@ class RGBToBWNode : public ShaderNode { SHADER_NODE_CLASS(RGBToBWNode) void constant_fold(const ConstantFolder &folder); - float3 color; + NODE_SOCKET_API(float3, color) }; class ConvertNode : public ShaderNode { @@ -460,6 +505,7 @@ class ConvertNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); + private: SocketType::Type from, to; union { @@ -472,7 +518,6 @@ class ConvertNode : public ShaderNode { }; ustring value_string; - private: static const int MAX_TYPE = 12; static bool register_types(); static Node *create(const NodeType *type); @@ -500,6 +545,7 @@ class BsdfBaseNode : public ShaderNode { return false; } + protected: ClosureType closure; }; @@ -514,18 +560,20 @@ class BsdfNode : public BsdfBaseNode { ShaderInput *param3 = NULL, ShaderInput *param4 = NULL); - float3 color; - float3 normal; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, surface_mix_weight) }; class AnisotropicBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(AnisotropicBsdfNode) - float3 tangent; - float roughness, anisotropy, rotation; - ClosureType distribution; + NODE_SOCKET_API(float3, tangent) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, anisotropy) + NODE_SOCKET_API(float, rotation) + NODE_SOCKET_API(ClosureType, distribution) ClosureType get_closure_type() { @@ -542,7 +590,7 @@ class DiffuseBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(DiffuseBsdfNode) - float roughness; + NODE_SOCKET_API(float, roughness) }; /* Disney principled BRDF */ @@ -570,19 +618,37 @@ class PrincipledBsdfNode : public BsdfBaseNode { ShaderInput *anisotropic_rotation, ShaderInput *transmission_roughness); - float3 base_color; - float3 subsurface_color, subsurface_radius; - float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint, - clearcoat, clearcoat_roughness, ior, transmission, anisotropic_rotation, - transmission_roughness; - float3 normal, clearcoat_normal, tangent; - float surface_mix_weight; - ClosureType distribution, distribution_orig; - ClosureType subsurface_method; - float3 emission; - float emission_strength; - float alpha; + NODE_SOCKET_API(float3, base_color) + NODE_SOCKET_API(float3, subsurface_color) + NODE_SOCKET_API(float3, subsurface_radius) + NODE_SOCKET_API(float, metallic) + NODE_SOCKET_API(float, subsurface) + NODE_SOCKET_API(float, specular) + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, specular_tint) + NODE_SOCKET_API(float, anisotropic) + NODE_SOCKET_API(float, sheen) + NODE_SOCKET_API(float, sheen_tint) + NODE_SOCKET_API(float, clearcoat) + NODE_SOCKET_API(float, clearcoat_roughness) + NODE_SOCKET_API(float, ior) + NODE_SOCKET_API(float, transmission) + NODE_SOCKET_API(float, anisotropic_rotation) + NODE_SOCKET_API(float, transmission_roughness) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float3, clearcoat_normal) + NODE_SOCKET_API(float3, tangent) + NODE_SOCKET_API(float, surface_mix_weight) + NODE_SOCKET_API(ClosureType, distribution) + NODE_SOCKET_API(ClosureType, subsurface_method) + NODE_SOCKET_API(float3, emission) + NODE_SOCKET_API(float, emission_strength) + NODE_SOCKET_API(float, alpha) + private: + ClosureType distribution_orig; + + public: bool has_integrator_dependency(); void attributes(Shader *shader, AttributeRequestSet *attributes); bool has_attribute_dependency() @@ -610,7 +676,7 @@ class VelvetBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(VelvetBsdfNode) - float sigma; + NODE_SOCKET_API(float, sigma) }; class GlossyBsdfNode : public BsdfNode { @@ -624,8 +690,12 @@ class GlossyBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class GlassBsdfNode : public BsdfNode { @@ -639,8 +709,13 @@ class GlassBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig, IOR; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, IOR) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class RefractionBsdfNode : public BsdfNode { @@ -654,16 +729,22 @@ class RefractionBsdfNode : public BsdfNode { return distribution; } - float roughness, roughness_orig, IOR; - ClosureType distribution, distribution_orig; + NODE_SOCKET_API(float, roughness) + NODE_SOCKET_API(float, IOR) + NODE_SOCKET_API(ClosureType, distribution) + + private: + float roughness_orig; + ClosureType distribution_orig; }; class ToonBsdfNode : public BsdfNode { public: SHADER_NODE_CLASS(ToonBsdfNode) - float smooth, size; - ClosureType component; + NODE_SOCKET_API(float, smooth) + NODE_SOCKET_API(float, size) + NODE_SOCKET_API(ClosureType, component) }; class SubsurfaceScatteringNode : public BsdfNode { @@ -679,11 +760,11 @@ class SubsurfaceScatteringNode : public BsdfNode { return falloff; } - float scale; - float3 radius; - float sharpness; - float texture_blur; - ClosureType falloff; + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float3, radius) + NODE_SOCKET_API(float, sharpness) + NODE_SOCKET_API(float, texture_blur) + NODE_SOCKET_API(ClosureType, falloff) }; class EmissionNode : public ShaderNode { @@ -700,9 +781,9 @@ class EmissionNode : public ShaderNode { return true; } - float3 color; - float strength; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, surface_mix_weight) }; class BackgroundNode : public ShaderNode { @@ -710,9 +791,9 @@ class BackgroundNode : public ShaderNode { SHADER_NODE_CLASS(BackgroundNode) void constant_fold(const ConstantFolder &folder); - float3 color; - float strength; - float surface_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, surface_mix_weight) }; class HoldoutNode : public ShaderNode { @@ -727,8 +808,8 @@ class HoldoutNode : public ShaderNode { return CLOSURE_HOLDOUT_ID; } - float surface_mix_weight; - float volume_mix_weight; + NODE_SOCKET_API(float, surface_mix_weight) + NODE_SOCKET_API(float, volume_mix_weight) }; class AmbientOcclusionNode : public ShaderNode { @@ -748,13 +829,13 @@ class AmbientOcclusionNode : public ShaderNode { return true; } - float3 color; - float distance; - float3 normal; - int samples; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, distance) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(int, samples) - bool only_local; - bool inside; + NODE_SOCKET_API(bool, only_local) + NODE_SOCKET_API(bool, inside) }; class VolumeNode : public ShaderNode { @@ -780,11 +861,14 @@ class VolumeNode : public ShaderNode { return true; } - float3 color; - float density; - float volume_mix_weight; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, density) + NODE_SOCKET_API(float, volume_mix_weight) + + protected: ClosureType closure; + public: virtual bool equals(const ShaderNode & /*other*/) { /* TODO(sergey): With some care Volume nodes can be de-duplicated. */ @@ -801,7 +885,7 @@ class ScatterVolumeNode : public VolumeNode { public: SHADER_NODE_CLASS(ScatterVolumeNode) - float anisotropy; + NODE_SOCKET_API(float, anisotropy) }; class PrincipledVolumeNode : public VolumeNode { @@ -813,17 +897,17 @@ class PrincipledVolumeNode : public VolumeNode { return true; } - ustring density_attribute; - ustring color_attribute; - ustring temperature_attribute; + NODE_SOCKET_API(ustring, density_attribute) + NODE_SOCKET_API(ustring, color_attribute) + NODE_SOCKET_API(ustring, temperature_attribute) - float anisotropy; - float3 absorption_color; - float emission_strength; - float3 emission_color; - float blackbody_intensity; - float3 blackbody_tint; - float temperature; + NODE_SOCKET_API(float, anisotropy) + NODE_SOCKET_API(float3, absorption_color) + NODE_SOCKET_API(float, emission_strength) + NODE_SOCKET_API(float3, emission_color) + NODE_SOCKET_API(float, blackbody_intensity) + NODE_SOCKET_API(float3, blackbody_tint) + NODE_SOCKET_API(float, temperature) }; /* Interface between the I/O sockets and the SVM/OSL backend. */ @@ -833,36 +917,36 @@ class PrincipledHairBsdfNode : public BsdfBaseNode { void attributes(Shader *shader, AttributeRequestSet *attributes); /* Longitudinal roughness. */ - float roughness; + NODE_SOCKET_API(float, roughness) /* Azimuthal roughness. */ - float radial_roughness; + NODE_SOCKET_API(float, radial_roughness) /* Randomization factor for roughnesses. */ - float random_roughness; + NODE_SOCKET_API(float, random_roughness) /* Longitudinal roughness factor for only the diffuse bounce (shiny undercoat). */ - float coat; + NODE_SOCKET_API(float, coat) /* Index of reflection. */ - float ior; + NODE_SOCKET_API(float, ior) /* Cuticle tilt angle. */ - float offset; + NODE_SOCKET_API(float, offset) /* Direct coloring's color. */ - float3 color; + NODE_SOCKET_API(float3, color) /* Melanin concentration. */ - float melanin; + NODE_SOCKET_API(float, melanin) /* Melanin redness ratio. */ - float melanin_redness; + NODE_SOCKET_API(float, melanin_redness) /* Dye color. */ - float3 tint; + NODE_SOCKET_API(float3, tint) /* Randomization factor for melanin quantities. */ - float random_color; + NODE_SOCKET_API(float, random_color) /* Absorption coefficient (unfiltered). */ - float3 absorption_coefficient; + NODE_SOCKET_API(float3, absorption_coefficient) - float3 normal; - float surface_mix_weight; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, surface_mix_weight) /* If linked, here will be the given random number. */ - float random; + NODE_SOCKET_API(float, random) /* Selected coloring parametrization. */ - NodePrincipledHairParametrization parametrization; + NODE_SOCKET_API(NodePrincipledHairParametrization, parametrization) }; class HairBsdfNode : public BsdfNode { @@ -873,11 +957,11 @@ class HairBsdfNode : public BsdfNode { return component; } - ClosureType component; - float offset; - float roughness_u; - float roughness_v; - float3 tangent; + NODE_SOCKET_API(ClosureType, component) + NODE_SOCKET_API(float, offset) + NODE_SOCKET_API(float, roughness_u) + NODE_SOCKET_API(float, roughness_v) + NODE_SOCKET_API(float3, tangent) }; class GeometryNode : public ShaderNode { @@ -894,7 +978,7 @@ class GeometryNode : public ShaderNode { } int get_group(); - float3 normal_osl; + NODE_SOCKET_API(float3, normal_osl) }; class TextureCoordinateNode : public ShaderNode { @@ -910,10 +994,10 @@ class TextureCoordinateNode : public ShaderNode { return true; } - float3 normal_osl; - bool from_dupli; - bool use_transform; - Transform ob_tfm; + NODE_SOCKET_API(float3, normal_osl) + NODE_SOCKET_API(bool, from_dupli) + NODE_SOCKET_API(bool, use_transform) + NODE_SOCKET_API(Transform, ob_tfm) }; class UVMapNode : public ShaderNode { @@ -933,8 +1017,8 @@ class UVMapNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - ustring attribute; - bool from_dupli; + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(bool, from_dupli) }; class LightPathNode : public ShaderNode { @@ -958,8 +1042,8 @@ class LightFalloffNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - float strength; - float smooth; + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, smooth) }; class ObjectInfoNode : public ShaderNode { @@ -1036,7 +1120,7 @@ class VertexColorNode : public ShaderNode { return true; } - ustring layer_name; + NODE_SOCKET_API(ustring, layer_name) }; class ValueNode : public ShaderNode { @@ -1045,7 +1129,7 @@ class ValueNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); - float value; + NODE_SOCKET_API(float, value) }; class ColorNode : public ShaderNode { @@ -1054,7 +1138,7 @@ class ColorNode : public ShaderNode { void constant_fold(const ConstantFolder &folder); - float3 value; + NODE_SOCKET_API(float3, value) }; class AddClosureNode : public ShaderNode { @@ -1068,15 +1152,15 @@ class MixClosureNode : public ShaderNode { SHADER_NODE_CLASS(MixClosureNode) void constant_fold(const ConstantFolder &folder); - float fac; + NODE_SOCKET_API(float, fac) }; class MixClosureWeightNode : public ShaderNode { public: SHADER_NODE_CLASS(MixClosureWeightNode) - float weight; - float fac; + NODE_SOCKET_API(float, weight) + NODE_SOCKET_API(float, fac) }; class InvertNode : public ShaderNode { @@ -1088,8 +1172,8 @@ class InvertNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float fac; - float3 color; + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, color) }; class MixNode : public ShaderNode { @@ -1102,11 +1186,11 @@ class MixNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeMix type; - bool use_clamp; - float3 color1; - float3 color2; - float fac; + NODE_SOCKET_API(NodeMix, mix_type) + NODE_SOCKET_API(bool, use_clamp) + NODE_SOCKET_API(float3, color1) + NODE_SOCKET_API(float3, color2) + NODE_SOCKET_API(float, fac) }; class CombineRGBNode : public ShaderNode { @@ -1118,7 +1202,9 @@ class CombineRGBNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float r, g, b; + NODE_SOCKET_API(float, r) + NODE_SOCKET_API(float, g) + NODE_SOCKET_API(float, b) }; class CombineHSVNode : public ShaderNode { @@ -1130,7 +1216,9 @@ class CombineHSVNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float h, s, v; + NODE_SOCKET_API(float, h) + NODE_SOCKET_API(float, s) + NODE_SOCKET_API(float, v) }; class CombineXYZNode : public ShaderNode { @@ -1142,7 +1230,9 @@ class CombineXYZNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float x, y, z; + NODE_SOCKET_API(float, x) + NODE_SOCKET_API(float, y) + NODE_SOCKET_API(float, z) }; class GammaNode : public ShaderNode { @@ -1154,8 +1244,8 @@ class GammaNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 color; - float gamma; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, gamma) }; class BrightContrastNode : public ShaderNode { @@ -1167,9 +1257,9 @@ class BrightContrastNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 color; - float bright; - float contrast; + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float, bright) + NODE_SOCKET_API(float, contrast) }; class SeparateRGBNode : public ShaderNode { @@ -1181,7 +1271,7 @@ class SeparateRGBNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 color; + NODE_SOCKET_API(float3, color) }; class SeparateHSVNode : public ShaderNode { @@ -1193,7 +1283,7 @@ class SeparateHSVNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 color; + NODE_SOCKET_API(float3, color) }; class SeparateXYZNode : public ShaderNode { @@ -1205,18 +1295,18 @@ class SeparateXYZNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float3 vector; + NODE_SOCKET_API(float3, vector) }; class HSVNode : public ShaderNode { public: SHADER_NODE_CLASS(HSVNode) - float hue; - float saturation; - float value; - float fac; - float3 color; + NODE_SOCKET_API(float, hue) + NODE_SOCKET_API(float, saturation) + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, color) }; class AttributeNode : public ShaderNode { @@ -1232,7 +1322,7 @@ class AttributeNode : public ShaderNode { return true; } - ustring attribute; + NODE_SOCKET_API(ustring, attribute) }; class CameraNode : public ShaderNode { @@ -1260,8 +1350,8 @@ class FresnelNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 normal; - float IOR; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, IOR) }; class LayerWeightNode : public ShaderNode { @@ -1276,8 +1366,8 @@ class LayerWeightNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - float3 normal; - float blend; + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, blend) }; class WireframeNode : public ShaderNode { @@ -1292,8 +1382,8 @@ class WireframeNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float size; - bool use_pixel_size; + NODE_SOCKET_API(float, size) + NODE_SOCKET_API(bool, use_pixel_size) }; class WavelengthNode : public ShaderNode { @@ -1304,7 +1394,7 @@ class WavelengthNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float wavelength; + NODE_SOCKET_API(float, wavelength) }; class BlackbodyNode : public ShaderNode { @@ -1316,7 +1406,7 @@ class BlackbodyNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - float temperature; + NODE_SOCKET_API(float, temperature) }; class MapRangeNode : public ShaderNode { @@ -1328,9 +1418,14 @@ class MapRangeNode : public ShaderNode { } void expand(ShaderGraph *graph); - float value, from_min, from_max, to_min, to_max, steps; - NodeMapRangeType type; - bool clamp; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, from_min) + NODE_SOCKET_API(float, from_max) + NODE_SOCKET_API(float, to_min) + NODE_SOCKET_API(float, to_max) + NODE_SOCKET_API(float, steps) + NODE_SOCKET_API(NodeMapRangeType, range_type) + NODE_SOCKET_API(bool, clamp) }; class ClampNode : public ShaderNode { @@ -1341,8 +1436,10 @@ class ClampNode : public ShaderNode { { return NODE_GROUP_LEVEL_3; } - float value, min, max; - NodeClampType type; + NODE_SOCKET_API(float, value) + NODE_SOCKET_API(float, min) + NODE_SOCKET_API(float, max) + NODE_SOCKET_API(NodeClampType, clamp_type) }; class MathNode : public ShaderNode { @@ -1355,11 +1452,11 @@ class MathNode : public ShaderNode { void expand(ShaderGraph *graph); void constant_fold(const ConstantFolder &folder); - float value1; - float value2; - float value3; - NodeMathType type; - bool use_clamp; + NODE_SOCKET_API(float, value1) + NODE_SOCKET_API(float, value2) + NODE_SOCKET_API(float, value3) + NODE_SOCKET_API(NodeMathType, math_type) + NODE_SOCKET_API(bool, use_clamp) }; class NormalNode : public ShaderNode { @@ -1370,8 +1467,8 @@ class NormalNode : public ShaderNode { return NODE_GROUP_LEVEL_2; } - float3 direction; - float3 normal; + NODE_SOCKET_API(float3, direction) + NODE_SOCKET_API(float3, normal) }; class VectorMathNode : public ShaderNode { @@ -1383,11 +1480,11 @@ class VectorMathNode : public ShaderNode { } void constant_fold(const ConstantFolder &folder); - float3 vector1; - float3 vector2; - float3 vector3; - float scale; - NodeVectorMathType type; + NODE_SOCKET_API(float3, vector1) + NODE_SOCKET_API(float3, vector2) + NODE_SOCKET_API(float3, vector3) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(NodeVectorMathType, math_type) }; class VectorRotateNode : public ShaderNode { @@ -1398,13 +1495,13 @@ class VectorRotateNode : public ShaderNode { { return NODE_GROUP_LEVEL_3; } - NodeVectorRotateType type; - bool invert; - float3 vector; - float3 center; - float3 axis; - float angle; - float3 rotation; + NODE_SOCKET_API(NodeVectorRotateType, rotate_type) + NODE_SOCKET_API(bool, invert) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float3, center) + NODE_SOCKET_API(float3, axis) + NODE_SOCKET_API(float, angle) + NODE_SOCKET_API(float3, rotation) }; class VectorTransformNode : public ShaderNode { @@ -1416,10 +1513,10 @@ class VectorTransformNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeVectorTransformType type; - NodeVectorTransformConvertSpace convert_from; - NodeVectorTransformConvertSpace convert_to; - float3 vector; + NODE_SOCKET_API(NodeVectorTransformType, transform_type) + NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_from) + NODE_SOCKET_API(NodeVectorTransformConvertSpace, convert_to) + NODE_SOCKET_API(float3, vector) }; class BumpNode : public ShaderNode { @@ -1435,15 +1532,15 @@ class BumpNode : public ShaderNode { return NODE_FEATURE_BUMP; } - bool invert; - bool use_object_space; - float height; - float sample_center; - float sample_x; - float sample_y; - float3 normal; - float strength; - float distance; + NODE_SOCKET_API(bool, invert) + NODE_SOCKET_API(bool, use_object_space) + NODE_SOCKET_API(float, height) + NODE_SOCKET_API(float, sample_center) + NODE_SOCKET_API(float, sample_x) + NODE_SOCKET_API(float, sample_y) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float, distance) }; class CurvesNode : public ShaderNode { @@ -1456,9 +1553,11 @@ class CurvesNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - array<float3> curves; - float min_x, max_x, fac; - float3 value; + NODE_SOCKET_API(array<float3>, curves) + NODE_SOCKET_API(float, min_x) + NODE_SOCKET_API(float, max_x) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(float3, value) protected: using ShaderNode::constant_fold; @@ -1488,16 +1587,16 @@ class RGBRampNode : public ShaderNode { return NODE_GROUP_LEVEL_1; } - array<float3> ramp; - array<float> ramp_alpha; - float fac; - bool interpolate; + NODE_SOCKET_API(array<float3>, ramp) + NODE_SOCKET_API(array<float>, ramp_alpha) + NODE_SOCKET_API(float, fac) + NODE_SOCKET_API(bool, interpolate) }; class SetNormalNode : public ShaderNode { public: SHADER_NODE_CLASS(SetNormalNode) - float3 direction; + NODE_SOCKET_API(float3, direction) }; class OSLNode : public ShaderNode { @@ -1549,11 +1648,11 @@ class NormalMapNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeNormalMapSpace space; - ustring attribute; - float strength; - float3 color; - float3 normal_osl; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float, strength) + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(float3, normal_osl) }; class TangentNode : public ShaderNode { @@ -1573,10 +1672,10 @@ class TangentNode : public ShaderNode { return NODE_GROUP_LEVEL_3; } - NodeTangentDirectionType direction_type; - NodeTangentAxis axis; - ustring attribute; - float3 normal_osl; + NODE_SOCKET_API(NodeTangentDirectionType, direction_type) + NODE_SOCKET_API(NodeTangentAxis, axis) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float3, normal_osl) }; class BevelNode : public ShaderNode { @@ -1595,9 +1694,9 @@ class BevelNode : public ShaderNode { return true; } - float radius; - float3 normal; - int samples; + NODE_SOCKET_API(float, radius) + NODE_SOCKET_API(float3, normal) + NODE_SOCKET_API(int, samples) }; class DisplacementNode : public ShaderNode { @@ -1609,11 +1708,11 @@ class DisplacementNode : public ShaderNode { return NODE_FEATURE_BUMP; } - NodeNormalMapSpace space; - float height; - float midlevel; - float scale; - float3 normal; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(float, height) + NODE_SOCKET_API(float, midlevel) + NODE_SOCKET_API(float, scale) + NODE_SOCKET_API(float3, normal) }; class VectorDisplacementNode : public ShaderNode { @@ -1630,11 +1729,11 @@ class VectorDisplacementNode : public ShaderNode { return NODE_FEATURE_BUMP; } - NodeNormalMapSpace space; - ustring attribute; - float3 vector; - float midlevel; - float scale; + NODE_SOCKET_API(NodeNormalMapSpace, space) + NODE_SOCKET_API(ustring, attribute) + NODE_SOCKET_API(float3, vector) + NODE_SOCKET_API(float, midlevel) + NODE_SOCKET_API(float, scale) }; CCL_NAMESPACE_END diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index bce2e08b390..70ce60252f0 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -104,9 +104,13 @@ NODE_DEFINE(Object) SOCKET_POINT2(dupli_uv, "Dupli UV", make_float2(0.0f, 0.0f)); SOCKET_TRANSFORM_ARRAY(motion, "Motion", array<Transform>()); SOCKET_FLOAT(shadow_terminator_offset, "Terminator Offset", 0.0f); + SOCKET_STRING(asset_name, "Asset Name", ustring()); SOCKET_BOOLEAN(is_shadow_catcher, "Shadow Catcher", false); + SOCKET_NODE(particle_system, "Particle System", &ParticleSystem::node_type); + SOCKET_INT(particle_index, "Particle Index", 0); + return type; } @@ -114,6 +118,7 @@ Object::Object() : Node(node_type) { particle_system = NULL; particle_index = 0; + attr_map_offset = 0; bounds = BoundBox::empty; } @@ -212,10 +217,11 @@ void Object::tag_update(Scene *scene) { if (geometry) { if (geometry->transform_applied) - geometry->need_update = true; + geometry->tag_modified(); - foreach (Shader *shader, geometry->used_shaders) { - if (shader->use_mis && shader->has_surface_emission) + foreach (Node *node, geometry->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (shader->get_use_mis() && shader->has_surface_emission) scene->light_manager->need_update = true; } } @@ -272,7 +278,7 @@ uint Object::visibility_for_tracing() const float Object::compute_volume_step_size() const { - if (geometry->type != Geometry::MESH && geometry->type != Geometry::VOLUME) { + if (geometry->geometry_type != Geometry::MESH && geometry->geometry_type != Geometry::VOLUME) { return FLT_MAX; } @@ -285,11 +291,12 @@ float Object::compute_volume_step_size() const /* Compute step rate from shaders. */ float step_rate = FLT_MAX; - foreach (Shader *shader, mesh->used_shaders) { + foreach (Node *node, mesh->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); if (shader->has_volume) { - if ((shader->heterogeneous_volume && shader->has_volume_spatial_varying) || + if ((shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) || (shader->has_volume_attribute_dependency)) { - step_rate = fminf(shader->volume_step_rate, step_rate); + step_rate = fminf(shader->get_volume_step_rate(), step_rate); } } } @@ -301,7 +308,7 @@ float Object::compute_volume_step_size() const /* Compute step size from voxel grids. */ float step_size = FLT_MAX; - if (geometry->type == Geometry::VOLUME) { + if (geometry->geometry_type == Geometry::VOLUME) { Volume *volume = static_cast<Volume *>(geometry); foreach (Attribute &attr, volume->attributes.attributes) { @@ -313,12 +320,17 @@ float Object::compute_volume_step_size() const } /* User specified step size. */ - float voxel_step_size = volume->step_size; + float voxel_step_size = volume->get_step_size(); if (voxel_step_size == 0.0f) { /* Auto detect step size. */ - float3 size = make_float3( - 1.0f / metadata.width, 1.0f / metadata.height, 1.0f / metadata.depth); + float3 size = make_float3(1.0f, 1.0f, 1.0f); +#ifdef WITH_NANOVDB + /* Dimensions were not applied to image transform with NanOVDB (see image_vdb.cpp) */ + if (metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT && + metadata.type != IMAGE_DATA_TYPE_NANOVDB_FLOAT3) +#endif + size /= make_float3(metadata.width, metadata.height, metadata.depth); /* Step size is transformed from voxel to world space. */ Transform voxel_tfm = tfm; @@ -327,7 +339,7 @@ float Object::compute_volume_step_size() const } voxel_step_size = min3(fabs(transform_direction(&voxel_tfm, size))); } - else if (volume->object_space) { + else if (volume->get_object_space()) { /* User specified step size in object space. */ float3 size = make_float3(voxel_step_size, voxel_step_size, voxel_step_size); voxel_step_size = min3(fabs(transform_direction(&tfm, size))); @@ -371,14 +383,15 @@ static float object_surface_area(UpdateObjectTransformState *state, const Transform &tfm, Geometry *geom) { - if (geom->type != Geometry::MESH && geom->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->type == Geometry::VOLUME) { + if (mesh->has_volume || geom->geometry_type == Geometry::VOLUME) { /* Volume density automatically adjust to object scale. */ - if (geom->type == Geometry::VOLUME && static_cast<Volume *>(geom)->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)); } @@ -410,9 +423,9 @@ static float object_surface_area(UpdateObjectTransformState *state, 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->verts[t.v[0]]; - float3 p2 = mesh->verts[t.v[1]]; - float3 p3 = mesh->verts[t.v[2]]; + 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); } @@ -431,9 +444,9 @@ static float object_surface_area(UpdateObjectTransformState *state, 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->verts[t.v[0]]); - float3 p2 = transform_point(&tfm, mesh->verts[t.v[1]]); - float3 p3 = transform_point(&tfm, mesh->verts[t.v[2]]); + 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); } @@ -472,11 +485,11 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.particle_index = particle_index; kobject.motion_offset = 0; - if (geom->use_motion_blur) { + if (geom->get_use_motion_blur()) { state->have_motion = true; } - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { /* TODO: why only mesh? */ Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) { @@ -527,14 +540,16 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.dupli_generated[0] = ob->dupli_generated[0]; kobject.dupli_generated[1] = ob->dupli_generated[1]; kobject.dupli_generated[2] = ob->dupli_generated[2]; - kobject.numkeys = (geom->type == Geometry::HAIR) ? static_cast<Hair *>(geom)->curve_keys.size() : - 0; + kobject.numkeys = (geom->geometry_type == Geometry::HAIR) ? + static_cast<Hair *>(geom)->get_curve_keys().size() : + 0; kobject.dupli_uv[0] = ob->dupli_uv[0]; kobject.dupli_uv[1] = ob->dupli_uv[1]; - int totalsteps = geom->motion_steps; + int totalsteps = geom->get_motion_steps(); kobject.numsteps = (totalsteps - 1) / 2; - kobject.numverts = (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) ? - static_cast<Mesh *>(geom)->verts.size() : + kobject.numverts = (geom->geometry_type == Geometry::MESH || + geom->geometry_type == Geometry::VOLUME) ? + static_cast<Mesh *>(geom)->get_verts().size() : 0; kobject.patch_map_offset = 0; kobject.attribute_map_offset = 0; @@ -552,7 +567,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s state->object_volume_step[ob->index] = FLT_MAX; /* Have curves. */ - if (geom->type == Geometry::HAIR) { + if (geom->geometry_type == Geometry::HAIR) { state->have_curves = true; } } @@ -687,6 +702,10 @@ void ObjectManager::device_update(Device *device, progress.set_status("Updating Objects", "Applying Static Transformations"); apply_static_transforms(dscene, scene, progress); } + + foreach (Object *object, scene->objects) { + object->clear_modified(); + } } void ObjectManager::device_update_flags( @@ -786,7 +805,7 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc foreach (Object *object, scene->objects) { Geometry *geom = object->geometry; - if (geom->type == Geometry::MESH) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); if (mesh->patch_table) { uint patch_map_offset = 2 * (mesh->patch_table_offset + mesh->patch_table->total_size() - @@ -800,8 +819,15 @@ void ObjectManager::device_update_mesh_offsets(Device *, DeviceScene *dscene, Sc } } - if (kobjects[object->index].attribute_map_offset != geom->attr_map_offset) { - kobjects[object->index].attribute_map_offset = geom->attr_map_offset; + size_t attr_map_offset = object->attr_map_offset; + + /* An object attribute map cannot have a zero offset because mesh maps come first. */ + if (attr_map_offset == 0) { + attr_map_offset = geom->attr_map_offset; + } + + if (kobjects[object->index].attribute_map_offset != attr_map_offset) { + kobjects[object->index].attribute_map_offset = attr_map_offset; update = true; } } @@ -857,11 +883,11 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P bool apply = (geometry_users[geom] == 1) && !geom->has_surface_bssrdf && !geom->has_true_displacement(); - if (geom->type == Geometry::MESH || geom->type == Geometry::VOLUME) { + if (geom->geometry_type == Geometry::MESH) { Mesh *mesh = static_cast<Mesh *>(geom); - apply = apply && mesh->subdivision_type == Mesh::SUBDIVISION_NONE; + apply = apply && mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE; } - else if (geom->type == Geometry::HAIR) { + else if (geom->geometry_type == Geometry::HAIR) { /* Can't apply non-uniform scale to curves, this can't be represented by * control points and radius alone. */ float scale; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index ac9b4c331f5..76c9c30abb0 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -18,6 +18,11 @@ #define __OBJECT_H__ #include "graph/node.h" + +/* included as Object::set_particle_system defined through NODE_SOCKET_API does + * not select the right Node::set overload as it does not know that ParticleSystem + * is a Node */ +#include "render/particles.h" #include "render/scene.h" #include "util/util_array.h" @@ -46,26 +51,26 @@ class Object : public Node { public: NODE_DECLARE - Geometry *geometry; - Transform tfm; + NODE_SOCKET_API(Geometry *, geometry) + NODE_SOCKET_API(Transform, tfm) BoundBox bounds; - uint random_id; - int pass_id; - float3 color; - ustring asset_name; + NODE_SOCKET_API(uint, random_id) + NODE_SOCKET_API(int, pass_id) + NODE_SOCKET_API(float3, color) + NODE_SOCKET_API(ustring, asset_name) vector<ParamValue> attributes; - uint visibility; - array<Transform> motion; - bool hide_on_missing_motion; - bool use_holdout; - bool is_shadow_catcher; - float shadow_terminator_offset; + NODE_SOCKET_API(uint, visibility) + NODE_SOCKET_API_ARRAY(array<Transform>, motion) + NODE_SOCKET_API(bool, hide_on_missing_motion) + NODE_SOCKET_API(bool, use_holdout) + NODE_SOCKET_API(bool, is_shadow_catcher) + NODE_SOCKET_API(float, shadow_terminator_offset) - float3 dupli_generated; - float2 dupli_uv; + NODE_SOCKET_API(float3, dupli_generated) + NODE_SOCKET_API(float2, dupli_uv) - ParticleSystem *particle_system; - int particle_index; + NODE_SOCKET_API(ParticleSystem *, particle_system); + NODE_SOCKET_API(int, particle_index); Object(); ~Object(); @@ -106,7 +111,12 @@ class Object : public Node { * in the device vectors. Gets set in device_update. */ int index; + /* Reference to the attribute map with object attributes, + * or 0 if none. Set in update_svm_attributes. */ + size_t attr_map_offset; + friend class ObjectManager; + friend class GeometryManager; }; /* Object Manager */ diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index 0c2b2cf27e9..bea2c534bd1 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -131,7 +131,7 @@ void OSLShaderManager::device_update(Device *device, compiler.background = (shader == background_shader); compiler.compile(og, shader); - if (shader->use_mis && shader->has_surface_emission) + if (shader->get_use_mis() && shader->has_surface_emission) scene->light_manager->need_update = true; } @@ -145,7 +145,7 @@ void OSLShaderManager::device_update(Device *device, og->use = true; foreach (Shader *shader, scene->shaders) - shader->need_update = false; + shader->clear_modified(); need_update = false; @@ -1120,18 +1120,18 @@ OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph void OSLCompiler::compile(OSLGlobals *og, Shader *shader) { - if (shader->need_update) { + if (shader->is_modified()) { ShaderGraph *graph = shader->graph; ShaderNode *output = (graph) ? graph->output() : NULL; - bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ shader->graph->finalize(scene, has_bump, shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); + shader->get_displacement_method() == DISPLACE_BOTH); current_shader = shader; diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index 3fb6c9620e6..98c256a43b5 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -339,7 +339,7 @@ void Scene::device_update(Device *device_, Progress &progress) Scene::MotionType Scene::need_motion() { - if (integrator->motion_blur) + if (integrator->get_motion_blur()) return MOTION_BLUR; else if (Pass::contains(passes, PASS_MOTION)) return MOTION_PASS; @@ -352,7 +352,7 @@ float Scene::motion_shutter_time() if (need_motion() == Scene::MOTION_PASS) return 2.0f; else - return camera->shuttertime; + return camera->get_shuttertime(); } bool Scene::need_global_attribute(AttributeStandard std) @@ -376,20 +376,21 @@ void Scene::need_global_attributes(AttributeRequestSet &attributes) bool Scene::need_update() { - return (need_reset() || film->need_update); + return (need_reset() || film->is_modified()); } bool Scene::need_data_update() { - return (background->need_update || image_manager->need_update || object_manager->need_update || + return (background->is_modified() || image_manager->need_update || object_manager->need_update || geometry_manager->need_update || light_manager->need_update || - lookup_tables->need_update || integrator->need_update || shader_manager->need_update || - particle_system_manager->need_update || bake_manager->need_update || film->need_update); + lookup_tables->need_update || integrator->is_modified() || shader_manager->need_update || + particle_system_manager->need_update || bake_manager->need_update || + film->is_modified()); } bool Scene::need_reset() { - return need_data_update() || camera->need_update; + return need_data_update() || camera->is_modified(); } void Scene::reset() @@ -398,9 +399,9 @@ void Scene::reset() shader_manager->add_default(this); /* ensure all objects are updated */ - camera->tag_update(); - dicing_camera->tag_update(); - film->tag_update(this); + camera->tag_modified(); + dicing_camera->tag_modified(); + film->tag_modified(); background->tag_update(this); integrator->tag_update(this); object_manager->tag_update(this); @@ -442,24 +443,24 @@ DeviceRequestedFeatures Scene::get_requested_device_features() requested_features.use_object_motion = false; requested_features.use_camera_motion = use_motion && camera->use_motion(); foreach (Object *object, objects) { - Geometry *geom = object->geometry; + Geometry *geom = object->get_geometry(); if (use_motion) { - requested_features.use_object_motion |= object->use_motion() | geom->use_motion_blur; - requested_features.use_camera_motion |= geom->use_motion_blur; + requested_features.use_object_motion |= object->use_motion() | geom->get_use_motion_blur(); + requested_features.use_camera_motion |= geom->get_use_motion_blur(); } - if (object->is_shadow_catcher) { + if (object->get_is_shadow_catcher()) { requested_features.use_shadow_tricks = true; } - if (geom->type == Geometry::MESH) { + if (geom->is_mesh()) { Mesh *mesh = static_cast<Mesh *>(geom); #ifdef WITH_OPENSUBDIV - if (mesh->subdivision_type != Mesh::SUBDIVISION_NONE) { + if (mesh->get_subdivision_type() != Mesh::SUBDIVISION_NONE) { requested_features.use_patch_evaluation = true; } #endif requested_features.use_true_displacement |= mesh->has_true_displacement(); } - else if (geom->type == Geometry::HAIR) { + else if (geom->is_hair()) { requested_features.use_hair = true; } } @@ -467,8 +468,9 @@ DeviceRequestedFeatures Scene::get_requested_device_features() requested_features.use_background_light = light_manager->has_background_light(this); requested_features.use_baking = bake_manager->get_baking(); - requested_features.use_integrator_branched = (integrator->method == Integrator::BRANCHED_PATH); - if (film->denoising_data_pass) { + requested_features.use_integrator_branched = (integrator->get_method() == + Integrator::BRANCHED_PATH); + if (film->get_denoising_data_pass()) { requested_features.use_denoising = true; requested_features.use_shadow_tricks = true; } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index c22e29043d3..a60542259f6 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -61,22 +61,6 @@ Session::Session(const SessionParams ¶ms_) TaskScheduler::init(params.threads); - /* Create CPU/GPU devices. */ - device = Device::create(params.device, stats, profiler, params.background); - - /* Create buffers for interactive rendering. */ - if (params.background && !params.write_render_cb) { - buffers = NULL; - display = NULL; - } - else { - buffers = new RenderBuffers(device); - display = new DisplayBuffer(device, params.display_buffer_linear); - } - - /* Validate denoising parameters. */ - set_denoising(params.denoising); - session_thread = NULL; scene = NULL; @@ -90,6 +74,26 @@ Session::Session(const SessionParams ¶ms_) gpu_draw_ready = false; gpu_need_display_buffer_update = false; pause = false; + + buffers = NULL; + display = NULL; + + /* Validate denoising parameters. */ + set_denoising(params.denoising); + + /* Create CPU/GPU devices. */ + device = Device::create(params.device, stats, profiler, params.background); + + if (!device->error_message().empty()) { + progress.set_error(device->error_message()); + return; + } + + /* Create buffers for interactive rendering. */ + if (!(params.background && !params.write_render_cb)) { + buffers = new RenderBuffers(device); + display = new DisplayBuffer(device, params.display_buffer_linear); + } } Session::~Session() @@ -110,7 +114,7 @@ Session::~Session() wait(); } - if (params.write_render_cb) { + if (buffers && params.write_render_cb) { /* Copy to display buffer and write out image if requested */ delete display; @@ -378,6 +382,62 @@ bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_param return false; } +bool Session::steal_tile(RenderTile &rtile, Device *tile_device, thread_scoped_lock &tile_lock) +{ + /* Devices that can get their tiles stolen don't steal tiles themselves. + * Additionally, if there are no stealable tiles in flight, give up here. */ + if (tile_device->info.type == DEVICE_CPU || stealable_tiles == 0) { + return false; + } + + /* Wait until no other thread is trying to steal a tile. */ + while (tile_stealing_state != NOT_STEALING && stealable_tiles > 0) { + /* Someone else is currently trying to get a tile. + * Wait on the condition variable and try later. */ + tile_steal_cond.wait(tile_lock); + } + /* If another thread stole the last stealable tile in the meantime, give up. */ + if (stealable_tiles == 0) { + return false; + } + + /* There are stealable tiles in flight, so signal that one should be released. */ + tile_stealing_state = WAITING_FOR_TILE; + + /* Wait until a device notices the signal and releases its tile. */ + while (tile_stealing_state != GOT_TILE && stealable_tiles > 0) { + tile_steal_cond.wait(tile_lock); + } + /* If the last stealable tile finished on its own, give up. */ + if (tile_stealing_state != GOT_TILE) { + tile_stealing_state = NOT_STEALING; + return false; + } + + /* Successfully stole a tile, now move it to the new device. */ + rtile = stolen_tile; + rtile.buffers->buffer.move_device(tile_device); + rtile.buffer = rtile.buffers->buffer.device_pointer; + rtile.stealing_state = RenderTile::NO_STEALING; + rtile.num_samples -= (rtile.sample - rtile.start_sample); + rtile.start_sample = rtile.sample; + + tile_stealing_state = NOT_STEALING; + + /* Poke any threads which might be waiting for NOT_STEALING above. */ + tile_steal_cond.notify_one(); + + return true; +} + +bool Session::get_tile_stolen() +{ + /* If tile_stealing_state is WAITING_FOR_TILE, atomically set it to RELEASING_TILE + * and return true. */ + TileStealingState expected = WAITING_FOR_TILE; + return tile_stealing_state.compare_exchange_weak(expected, RELEASING_TILE); +} + bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_types) { if (progress.get_cancel()) { @@ -399,7 +459,8 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ denoising_cond.wait(tile_lock); continue; } - return false; + + return steal_tile(rtile, tile_device, tile_lock); } /* fill render tile */ @@ -415,11 +476,18 @@ bool Session::acquire_tile(RenderTile &rtile, Device *tile_device, uint tile_typ if (tile->state == Tile::DENOISE) { rtile.task = RenderTile::DENOISE; } - else if (read_bake_tile_cb) { - rtile.task = RenderTile::BAKE; - } else { - rtile.task = RenderTile::PATH_TRACE; + if (tile_device->info.type == DEVICE_CPU) { + stealable_tiles++; + rtile.stealing_state = RenderTile::CAN_BE_STOLEN; + } + + if (read_bake_tile_cb) { + rtile.task = RenderTile::BAKE; + } + else { + rtile.task = RenderTile::PATH_TRACE; + } } tile_lock.unlock(); @@ -504,6 +572,26 @@ void Session::release_tile(RenderTile &rtile, const bool need_denoise) { thread_scoped_lock tile_lock(tile_mutex); + if (rtile.stealing_state != RenderTile::NO_STEALING) { + stealable_tiles--; + if (rtile.stealing_state == RenderTile::WAS_STOLEN) { + /* If the tile is being stolen, don't release it here - the new device will pick up where + * the old one left off. */ + + assert(tile_stealing_state == RELEASING_TILE); + assert(rtile.sample < rtile.start_sample + rtile.num_samples); + + tile_stealing_state = GOT_TILE; + stolen_tile = rtile; + tile_steal_cond.notify_all(); + return; + } + else if (stealable_tiles == 0) { + /* If this was the last stealable tile, wake up any threads still waiting for one. */ + tile_steal_cond.notify_all(); + } + } + progress.add_finished_tile(rtile.task == RenderTile::DENOISE); bool delete_tile; @@ -811,6 +899,8 @@ void Session::reset_(BufferParams &buffer_params, int samples) } tile_manager.reset(buffer_params, samples); + stealable_tiles = 0; + tile_stealing_state = NOT_STEALING; progress.reset_sample(); bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX; @@ -918,23 +1008,19 @@ bool Session::update_scene() int height = tile_manager.state.buffer.full_height; int resolution = tile_manager.state.resolution_divider; - if (width != cam->width || height != cam->height || resolution != cam->resolution) { - cam->width = width; - cam->height = height; - cam->resolution = resolution; - cam->tag_update(); - } + cam->set_screen_size_and_resolution(width, height, resolution); /* number of samples is needed by multi jittered * sampling pattern and by baking */ Integrator *integrator = scene->integrator; BakeManager *bake_manager = scene->bake_manager; - if (integrator->sampling_pattern != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) { + if (integrator->get_sampling_pattern() != SAMPLING_PATTERN_SOBOL || bake_manager->get_baking()) { int aa_samples = tile_manager.num_samples; - if (aa_samples != integrator->aa_samples) { - integrator->aa_samples = aa_samples; + integrator->set_aa_samples(aa_samples); + + if (integrator->is_modified()) { integrator->tag_update(scene); } } @@ -1028,7 +1114,7 @@ bool Session::render_need_denoise(bool &delayed) /* Viewport render. */ /* It can happen that denoising was already enabled, but the scene still needs an update. */ - if (scene->film->need_update || !scene->film->denoising_data_offset) { + if (scene->film->is_modified() || !scene->film->get_denoising_data_offset()) { return false; } @@ -1071,10 +1157,12 @@ void Session::render(bool need_denoise) task.get_cancel = function_bind(&Progress::get_cancel, &this->progress); task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2); + task.get_tile_stolen = function_bind(&Session::get_tile_stolen, this); task.need_finish_queue = params.progressive_refine; - task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH; + task.integrator_branched = scene->integrator->get_method() == Integrator::BRANCHED_PATH; - task.adaptive_sampling.use = (scene->integrator->sampling_pattern == SAMPLING_PATTERN_PMJ) && + task.adaptive_sampling.use = (scene->integrator->get_sampling_pattern() == + SAMPLING_PATTERN_PMJ) && scene->dscene.data.film.pass_adaptive_aux_buffer; task.adaptive_sampling.min_samples = scene->dscene.data.integrator.adaptive_min_samples; task.adaptive_sampling.adaptive_step = scene->dscene.data.integrator.adaptive_step; @@ -1085,10 +1173,10 @@ void Session::render(bool need_denoise) if (need_denoise) { task.denoising = params.denoising; - task.pass_stride = scene->film->pass_stride; + task.pass_stride = scene->film->get_pass_stride(); task.target_pass_stride = task.pass_stride; - task.pass_denoising_data = scene->film->denoising_data_offset; - task.pass_denoising_clean = scene->film->denoising_clean_offset; + task.pass_denoising_data = scene->film->get_denoising_data_offset(); + task.pass_denoising_clean = scene->film->get_denoising_clean_offset(); task.denoising_from_render = true; diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index a22bf7731ae..770d3124db7 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -193,6 +193,8 @@ class Session { bool render_need_denoise(bool &delayed); + bool steal_tile(RenderTile &tile, Device *tile_device, thread_scoped_lock &tile_lock); + bool get_tile_stolen(); bool acquire_tile(RenderTile &tile, Device *tile_device, uint tile_types); void update_tile_sample(RenderTile &tile); void release_tile(RenderTile &tile, const bool need_denoise); @@ -217,11 +219,22 @@ class Session { thread_mutex buffers_mutex; thread_mutex display_mutex; thread_condition_variable denoising_cond; + thread_condition_variable tile_steal_cond; double reset_time; double last_update_time; double last_display_time; + RenderTile stolen_tile; + typedef enum { + NOT_STEALING, /* There currently is no tile stealing in progress. */ + WAITING_FOR_TILE, /* A device is waiting for another device to release a tile. */ + RELEASING_TILE, /* A device has releasing a stealable tile. */ + GOT_TILE /* A device has released a stealable tile, which is now stored in stolen_tile. */ + } TileStealingState; + std::atomic<TileStealingState> tile_stealing_state; + int stealable_tiles; + /* progressive refine */ bool update_progressive_refine(bool cancel); }; diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp index 135d0dc962b..cf49dedc426 100644 --- a/intern/cycles/render/shader.cpp +++ b/intern/cycles/render/shader.cpp @@ -187,6 +187,8 @@ NODE_DEFINE(Shader) displacement_method_enum.insert("both", DISPLACE_BOTH); SOCKET_ENUM(displacement_method, "Displacement Method", displacement_method_enum, DISPLACE_BUMP); + SOCKET_INT(pass_id, "Pass ID", 0); + return type; } @@ -216,7 +218,6 @@ Shader::Shader() : Node(node_type) id = -1; used = false; - need_update = true; need_update_geometry = true; } @@ -250,7 +251,7 @@ bool Shader::is_constant_emission(float3 *emission) return false; } - *emission = node->color * node->strength; + *emission = node->get_color() * node->get_strength(); } else if (surf->link->parent->type == BackgroundNode::node_type) { BackgroundNode *node = (BackgroundNode *)surf->link->parent; @@ -262,7 +263,7 @@ bool Shader::is_constant_emission(float3 *emission) return false; } - *emission = node->color * node->strength; + *emission = node->get_color() * node->get_strength(); } else { return false; @@ -306,7 +307,7 @@ void Shader::set_graph(ShaderGraph *graph_) void Shader::tag_update(Scene *scene) { /* update tag */ - need_update = true; + tag_modified(); scene->shader_manager->need_update = true; /* if the shader previously was emissive, update light distribution, @@ -369,7 +370,7 @@ void Shader::tag_used(Scene *scene) /* if an unused shader suddenly gets used somewhere, it needs to be * recompiled because it was skipped for compilation before */ if (!used) { - need_update = true; + tag_modified(); scene->shader_manager->need_update = true; } } @@ -493,16 +494,18 @@ void ShaderManager::update_shaders_used(Scene *scene) scene->default_background->used = true; scene->default_empty->used = true; - if (scene->background->shader) - scene->background->shader->used = true; + if (scene->background->get_shader()) + scene->background->get_shader()->used = true; foreach (Geometry *geom, scene->geometry) - foreach (Shader *shader, geom->used_shaders) + foreach (Node *node, geom->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); shader->used = true; + } foreach (Light *light, scene->lights) - if (light->shader) - light->shader->used = true; + if (light->get_shader()) + const_cast<Shader *>(light->get_shader())->used = true; } void ShaderManager::device_update_common(Device *device, @@ -522,9 +525,9 @@ void ShaderManager::device_update_common(Device *device, foreach (Shader *shader, scene->shaders) { uint flag = 0; - if (shader->use_mis) + if (shader->get_use_mis()) flag |= SD_USE_MIS; - if (shader->has_surface_transparent && shader->use_transparent_shadow) + if (shader->has_surface_transparent && shader->get_use_transparent_shadow()) flag |= SD_HAS_TRANSPARENT_SHADOW; if (shader->has_volume) { flag |= SD_HAS_VOLUME; @@ -539,7 +542,7 @@ void ShaderManager::device_update_common(Device *device, if (shader->has_volume_connected && !shader->has_surface) flag |= SD_HAS_ONLY_VOLUME; if (shader->has_volume) { - if (shader->heterogeneous_volume && shader->has_volume_spatial_varying) + if (shader->get_heterogeneous_volume() && shader->has_volume_spatial_varying) flag |= SD_HETEROGENEOUS_VOLUME; } if (shader->has_volume_attribute_dependency) @@ -547,16 +550,16 @@ void ShaderManager::device_update_common(Device *device, if (shader->has_bssrdf_bump) flag |= SD_HAS_BSSRDF_BUMP; if (device->info.has_volume_decoupled) { - if (shader->volume_sampling_method == VOLUME_SAMPLING_EQUIANGULAR) + if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_EQUIANGULAR) flag |= SD_VOLUME_EQUIANGULAR; - if (shader->volume_sampling_method == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) + if (shader->get_volume_sampling_method() == VOLUME_SAMPLING_MULTIPLE_IMPORTANCE) flag |= SD_VOLUME_MIS; } - if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) + if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) flag |= SD_VOLUME_CUBIC; if (shader->has_bump) flag |= SD_HAS_BUMP; - if (shader->displacement_method != DISPLACE_BUMP) + if (shader->get_displacement_method() != DISPLACE_BUMP) flag |= SD_HAS_DISPLACEMENT; /* constant emission check */ @@ -568,7 +571,7 @@ void ShaderManager::device_update_common(Device *device, /* regular shader */ kshader->flags = flag; - kshader->pass_id = shader->pass_id; + kshader->pass_id = shader->get_pass_id(); kshader->constant_emission[0] = constant_emission.x; kshader->constant_emission[1] = constant_emission.y; kshader->constant_emission[2] = constant_emission.z; @@ -625,7 +628,7 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); DiffuseBsdfNode *diffuse = graph->create_node<DiffuseBsdfNode>(); - diffuse->color = make_float3(0.8f, 0.8f, 0.8f); + diffuse->set_color(make_float3(0.8f, 0.8f, 0.8f)); graph->add(diffuse); graph->connect(diffuse->output("BSDF"), graph->output()->input("Surface")); @@ -658,8 +661,8 @@ void ShaderManager::add_default(Scene *scene) ShaderGraph *graph = new ShaderGraph(); EmissionNode *emission = graph->create_node<EmissionNode>(); - emission->color = make_float3(0.8f, 0.8f, 0.8f); - emission->strength = 0.0f; + emission->set_color(make_float3(0.8f, 0.8f, 0.8f)); + emission->set_strength(0.0f); graph->add(emission); graph->connect(emission->output("Emission"), graph->output()->input("Surface")); @@ -703,10 +706,10 @@ void ShaderManager::get_requested_graph_features(ShaderGraph *graph, requested_features->nodes_features |= node->get_feature(); if (node->special_type == SHADER_SPECIAL_TYPE_CLOSURE) { BsdfBaseNode *bsdf_node = static_cast<BsdfBaseNode *>(node); - if (CLOSURE_IS_VOLUME(bsdf_node->closure)) { + if (CLOSURE_IS_VOLUME(bsdf_node->get_closure_type())) { requested_features->nodes_features |= NODE_FEATURE_VOLUME; } - else if (CLOSURE_IS_PRINCIPLED(bsdf_node->closure)) { + else if (CLOSURE_IS_PRINCIPLED(bsdf_node->get_closure_type())) { requested_features->use_principled = true; } } @@ -738,7 +741,7 @@ void ShaderManager::get_requested_features(Scene *scene, ShaderNode *output_node = shader->graph->output(); if (output_node->input("Displacement")->link != NULL) { requested_features->nodes_features |= NODE_FEATURE_BUMP; - if (shader->displacement_method == DISPLACE_BOTH) { + if (shader->get_displacement_method() == DISPLACE_BOTH) { requested_features->nodes_features |= NODE_FEATURE_BUMP_STATE; requested_features->max_nodes_group = max(requested_features->max_nodes_group, NODE_GROUP_LEVEL_1); diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h index 897b0984a7e..de19048d8e1 100644 --- a/intern/cycles/render/shader.h +++ b/intern/cycles/render/shader.h @@ -81,22 +81,25 @@ class Shader : public Node { public: NODE_DECLARE - int pass_id; - /* shader graph */ ShaderGraph *graph; + NODE_SOCKET_API(int, pass_id) + /* sampling */ - bool use_mis; - bool use_transparent_shadow; - bool heterogeneous_volume; - VolumeSampling volume_sampling_method; - int volume_interpolation_method; - float volume_step_rate; + NODE_SOCKET_API(bool, use_mis) + NODE_SOCKET_API(bool, use_transparent_shadow) + NODE_SOCKET_API(bool, heterogeneous_volume) + NODE_SOCKET_API(VolumeSampling, volume_sampling_method) + NODE_SOCKET_API(int, volume_interpolation_method) + NODE_SOCKET_API(float, volume_step_rate) + + /* displacement */ + NODE_SOCKET_API(DisplacementMethod, displacement_method) + float prev_volume_step_rate; /* synchronization */ - bool need_update; bool need_update_geometry; /* If the shader has only volume components, the surface is assumed to @@ -122,9 +125,6 @@ class Shader : public Node { bool has_volume_attribute_dependency; bool has_integrator_dependency; - /* displacement */ - DisplacementMethod displacement_method; - /* requested mesh attributes */ AttributeRequestSet attributes; diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp index d66744d06be..b2bc17aec19 100644 --- a/intern/cycles/render/svm.cpp +++ b/intern/cycles/render/svm.cpp @@ -123,8 +123,8 @@ void SVMShaderManager::device_update(Device *device, for (int i = 0; i < num_shaders; i++) { Shader *shader = scene->shaders[i]; - shader->need_update = false; - if (shader->use_mis && shader->has_surface_emission) { + shader->clear_modified(); + if (shader->get_use_mis() && shader->has_surface_emission) { scene->light_manager->need_update = true; } @@ -749,7 +749,7 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty /* for the bump shader we need add a node to store the shader state */ bool need_bump_state = (type == SHADER_TYPE_BUMP) && - (shader->displacement_method == DISPLACE_BOTH); + (shader->get_displacement_method() == DISPLACE_BOTH); int bump_state_offset = SVM_STACK_INVALID; if (need_bump_state) { bump_state_offset = stack_find_offset(SVM_BUMP_EVAL_STATE_SIZE); @@ -840,7 +840,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum const double time_start = time_dt(); - bool has_bump = (shader->displacement_method != DISPLACE_TRUE) && + bool has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) && output->input("Surface")->link && output->input("Displacement")->link; /* finalize */ @@ -849,7 +849,7 @@ void SVMCompiler::compile(Shader *shader, array<int4> &svm_nodes, int index, Sum shader->graph->finalize(scene, has_bump, shader->has_integrator_dependency, - shader->displacement_method == DISPLACE_BOTH); + shader->get_displacement_method() == DISPLACE_BOTH); } current_shader = shader; diff --git a/intern/cycles/render/volume.cpp b/intern/cycles/render/volume.cpp index fcf33a5e50a..63261d6a247 100644 --- a/intern/cycles/render/volume.cpp +++ b/intern/cycles/render/volume.cpp @@ -36,11 +36,7 @@ CCL_NAMESPACE_BEGIN NODE_DEFINE(Volume) { - NodeType *type = NodeType::add("volume", create, NodeType::NONE, Geometry::node_base_type); - - SOCKET_INT_ARRAY(triangles, "Triangles", array<int>()); - SOCKET_POINT_ARRAY(verts, "Vertices", array<float3>()); - SOCKET_INT_ARRAY(shader, "Shader", array<int>()); + NodeType *type = NodeType::add("volume", create, NodeType::NONE, Mesh::node_type); SOCKET_FLOAT(clipping, "Clipping", 0.001f); SOCKET_FLOAT(step_size, "Step Size", 0.0f); @@ -56,9 +52,9 @@ Volume::Volume() : Mesh(node_type, Geometry::VOLUME) object_space = false; } -void Volume::clear() +void Volume::clear(bool preserve_shaders) { - Mesh::clear(true); + Mesh::clear(preserve_shaders, true); } struct QuadData { @@ -523,20 +519,20 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) if (image_memory->data_elements == 1) { grid = openvdb_grid_from_device_texture<openvdb::FloatGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } else if (image_memory->data_elements == 3) { grid = openvdb_grid_from_device_texture<openvdb::Vec3fGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } else if (image_memory->data_elements == 4) { grid = openvdb_grid_from_device_texture<openvdb::Vec4fGrid>( - image_memory, volume->clipping, handle.metadata().transform_3d); + image_memory, volume->get_clipping(), handle.metadata().transform_3d); } } if (grid) { - builder.add_grid(grid, do_clipping, volume->clipping); + builder.add_grid(grid, do_clipping, volume->get_clipping()); } } #endif @@ -549,17 +545,19 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) Shader *volume_shader = NULL; int pad_size = 0; - foreach (Shader *shader, volume->used_shaders) { + foreach (Node *node, volume->get_used_shaders()) { + Shader *shader = static_cast<Shader *>(node); + if (!shader->has_volume) { continue; } volume_shader = shader; - if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_LINEAR) { + if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_LINEAR) { pad_size = max(1, pad_size); } - else if (shader->volume_interpolation_method == VOLUME_INTERPOLATION_CUBIC) { + else if (shader->get_volume_interpolation_method() == VOLUME_INTERPOLATION_CUBIC) { pad_size = max(2, pad_size); } @@ -587,8 +585,8 @@ void GeometryManager::create_volume_mesh(Volume *volume, Progress &progress) volume->clear(); volume->reserve_mesh(vertices.size(), indices.size() / 3); - volume->used_shaders.push_back(volume_shader); - volume->need_update = true; + volume->used_shaders.push_back_slow(volume_shader); + volume->tag_modified(); volume->need_update_rebuild = true; for (size_t i = 0; i < vertices.size(); ++i) { diff --git a/intern/cycles/render/volume.h b/intern/cycles/render/volume.h index 05157eb948f..2e9703bf7ed 100644 --- a/intern/cycles/render/volume.h +++ b/intern/cycles/render/volume.h @@ -28,11 +28,11 @@ class Volume : public Mesh { Volume(); - float clipping; - float step_size; - bool object_space; + NODE_SOCKET_API(float, clipping) + NODE_SOCKET_API(float, step_size) + NODE_SOCKET_API(bool, object_space) - virtual void clear() override; + virtual void clear(bool preserve_shaders = false) override; }; CCL_NAMESPACE_END diff --git a/intern/cycles/subd/subd_dice.cpp b/intern/cycles/subd/subd_dice.cpp index 91c7f4bea05..4efdb98aa0f 100644 --- a/intern/cycles/subd/subd_dice.cpp +++ b/intern/cycles/subd/subd_dice.cpp @@ -42,11 +42,11 @@ void EdgeDice::reserve(int num_verts, int num_triangles) { Mesh *mesh = params.mesh; - vert_offset = mesh->verts.size(); + vert_offset = mesh->get_verts().size(); tri_offset = mesh->num_triangles(); - mesh->resize_mesh(mesh->verts.size() + num_verts, mesh->num_triangles()); - mesh->reserve_mesh(mesh->verts.size() + num_verts, mesh->num_triangles() + num_triangles); + mesh->resize_mesh(mesh->get_verts().size() + num_verts, mesh->num_triangles()); + mesh->reserve_mesh(mesh->get_verts().size() + num_verts, mesh->num_triangles() + num_triangles); Attribute *attr_vN = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); diff --git a/intern/cycles/subd/subd_split.cpp b/intern/cycles/subd/subd_split.cpp index 1a8c182510c..928f5bf2ed7 100644 --- a/intern/cycles/subd/subd_split.cpp +++ b/intern/cycles/subd/subd_split.cpp @@ -341,8 +341,8 @@ void DiagSplit::split_patches(Patch *patches, size_t patches_byte_stride) { int patch_index = 0; - for (int f = 0; f < params.mesh->subd_faces.size(); f++) { - Mesh::SubdFace &face = params.mesh->subd_faces[f]; + for (int f = 0; f < params.mesh->get_num_subd_faces(); f++) { + Mesh::SubdFace face = params.mesh->get_subd_face(f); Patch *patch = (Patch *)(((char *)patches) + patch_index * patches_byte_stride); @@ -372,8 +372,8 @@ static Edge *create_edge_from_corner(DiagSplit *split, int v0, int v1) { - int a = mesh->subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]; - int b = mesh->subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]; + int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)]; + int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)]; reversed = !(b < a); @@ -443,8 +443,8 @@ static Edge *create_split_edge_from_corner(DiagSplit *split, { Edge *edge = split->alloc_edge(); - int a = mesh->subd_face_corners[face.start_corner + mod(corner + 0, face.num_corners)]; - int b = mesh->subd_face_corners[face.start_corner + mod(corner + 1, face.num_corners)]; + int a = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 0, face.num_corners)]; + int b = mesh->get_subd_face_corners()[face.start_corner + mod(corner + 1, face.num_corners)]; if (b < a) { edge->stitch_edge_key = {b, a}; diff --git a/intern/cycles/test/render_graph_finalize_test.cpp b/intern/cycles/test/render_graph_finalize_test.cpp index 4639fc6d0dd..3eaec982d09 100644 --- a/intern/cycles/test/render_graph_finalize_test.cpp +++ b/intern/cycles/test/render_graph_finalize_test.cpp @@ -64,9 +64,11 @@ template<typename T> class ShaderNodeBuilder { return *this; } - template<typename T2, typename V> ShaderNodeBuilder &set(V T2::*pfield, V value) + template<typename V> ShaderNodeBuilder &set_param(const string &input_name, V value) { - static_cast<T *>(node_)->*pfield = value; + const SocketType *input_socket = node_->type->find_input(ustring(input_name.c_str())); + EXPECT_NE((void *)NULL, input_socket); + node_->set(*input_socket, value); return *this; } @@ -121,8 +123,8 @@ class ShaderGraphBuilder { /* Common input/output boilerplate. */ ShaderGraphBuilder &add_attribute(const string &name) { - return (*this).add_node(ShaderNodeBuilder<AttributeNode>(*graph_, name) - .set(&AttributeNode::attribute, ustring(name))); + return (*this).add_node( + ShaderNodeBuilder<AttributeNode>(*graph_, name).set_param("attribute", ustring(name))); } ShaderGraphBuilder &output_closure(const string &from) @@ -210,12 +212,12 @@ TEST_F(RenderGraph, deduplicate_deep) builder.add_node(ShaderNodeBuilder<GeometryNode>(graph, "Geometry1")) .add_node(ShaderNodeBuilder<GeometryNode>(graph, "Geometry2")) - .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value1").set(&ValueNode::value, 0.8f)) - .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value2").set(&ValueNode::value, 0.8f)) + .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value1").set_param("value", 0.8f)) + .add_node(ShaderNodeBuilder<ValueNode>(graph, "Value2").set_param("value", 0.8f)) .add_node(ShaderNodeBuilder<NoiseTextureNode>(graph, "Noise1")) .add_node(ShaderNodeBuilder<NoiseTextureNode>(graph, "Noise2")) .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BLEND) + .set_param("mix_type", NODE_MIX_BLEND) .set("Fac", 0.5f)) .add_connection("Geometry1::Parametric", "Noise1::Vector") .add_connection("Value1::Value", "Noise1::Scale") @@ -422,8 +424,8 @@ TEST_F(RenderGraph, constant_fold_mix_add) builder .add_node(ShaderNodeBuilder<MixNode>(graph, "MixAdd") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", false) .set("Fac", 0.8f) .set("Color1", make_float3(0.3f, 0.5f, 0.7f)) .set("Color2", make_float3(0.4f, 0.8f, 0.9f))) @@ -443,8 +445,8 @@ TEST_F(RenderGraph, constant_fold_mix_add_clamp) builder .add_node(ShaderNodeBuilder<MixNode>(graph, "MixAdd") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 0.8f) .set("Color1", make_float3(0.3f, 0.5f, 0.7f)) .set("Color2", make_float3(0.4f, 0.8f, 0.9f))) @@ -465,8 +467,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_dodge_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_DODGE) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_DODGE) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -487,8 +489,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_light_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_LIGHT) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_LIGHT) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -509,8 +511,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_burn_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BURN) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BURN) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -531,8 +533,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend_clamped_no_fac_0) builder.add_attribute("Attribute1") .add_attribute("Attribute2") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", true) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "Mix::Color1") .add_connection("Attribute2::Color", "Mix::Color2") @@ -557,22 +559,22 @@ TEST_F(RenderGraph, constant_fold_part_mix_blend) .add_attribute("Attribute2") /* choose left */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend1") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false) .set("Fac", 0.0f)) .add_connection("Attribute1::Color", "MixBlend1::Color1") .add_connection("Attribute2::Color", "MixBlend1::Color2") /* choose right */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend2") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false) .set("Fac", 1.0f)) .add_connection("Attribute1::Color", "MixBlend2::Color2") .add_connection("Attribute2::Color", "MixBlend2::Color1") /* both inputs folded to Attribute1 */ .add_node(ShaderNodeBuilder<MixNode>(graph, "MixBlend3") - .set(&MixNode::type, NODE_MIX_BLEND) - .set(&MixNode::use_clamp, false)) + .set_param("mix_type", NODE_MIX_BLEND) + .set_param("use_clamp", false)) .add_connection("Attribute1::Fac", "MixBlend3::Fac") .add_connection("MixBlend1::Color", "MixBlend3::Color1") .add_connection("MixBlend2::Color", "MixBlend3::Color2") @@ -592,8 +594,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_bad) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_SUB) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_SUB) + .set_param("use_clamp", true) .set("Fac", 0.5f)) .add_connection("Attribute::Color", "Mix::Color1") .add_connection("Attribute::Color", "Mix::Color2") @@ -613,8 +615,8 @@ TEST_F(RenderGraph, constant_fold_part_mix_sub_same_fac_1) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix") - .set(&MixNode::type, NODE_MIX_SUB) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_SUB) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Attribute::Color", "Mix::Color1") .add_connection("Attribute::Color", "Mix::Color2") @@ -635,12 +637,12 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_Cx_Fx") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color1", constval)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_Cx_F1") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color1", constval) .set("Fac", 1.0f)) .add_connection("Attribute::Fac", "Mix_Cx_Fx::Fac") @@ -648,12 +650,12 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_connection("Attribute::Color", "Mix_Cx_F1::Color2") /* constant on the right */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_xC_Fx") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color2", constval)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Mix_xC_F1") - .set(&MixNode::type, type) - .set(&MixNode::use_clamp, false) + .set_param("mix_type", type) + .set_param("use_clamp", false) .set("Color2", constval) .set("Fac", 1.0f)) .add_connection("Attribute::Fac", "Mix_xC_Fx::Fac") @@ -661,16 +663,16 @@ static void build_mix_partial_test_graph(ShaderGraphBuilder &builder, .add_connection("Attribute::Color", "Mix_xC_F1::Color1") /* results of actual tests simply added up to connect to output */ .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out12") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out34") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_node(ShaderNodeBuilder<MixNode>(builder.graph(), "Out1234") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Mix_Cx_Fx::Color", "Out12::Color1") .add_connection("Mix_Cx_F1::Color", "Out12::Color2") @@ -898,8 +900,8 @@ TEST_F(RenderGraph, constant_fold_gamma_part_0) .add_connection("Attribute::Color", "Gamma_xC::Color") /* output sum */ .add_node(ShaderNodeBuilder<MixNode>(graph, "Out") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Gamma_Cx::Color", "Out::Color1") .add_connection("Gamma_xC::Color", "Out::Color2") @@ -928,8 +930,8 @@ TEST_F(RenderGraph, constant_fold_gamma_part_1) .add_connection("Attribute::Color", "Gamma_xC::Color") /* output sum */ .add_node(ShaderNodeBuilder<MixNode>(graph, "Out") - .set(&MixNode::type, NODE_MIX_ADD) - .set(&MixNode::use_clamp, true) + .set_param("mix_type", NODE_MIX_ADD) + .set_param("use_clamp", true) .set("Fac", 1.0f)) .add_connection("Gamma_Cx::Color", "Out::Color1") .add_connection("Gamma_xC::Color", "Out::Color2") @@ -988,8 +990,8 @@ TEST_F(RenderGraph, constant_fold_math) builder .add_node(ShaderNodeBuilder<MathNode>(graph, "Math") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, false) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", false) .set("Value1", 0.7f) .set("Value2", 0.9f)) .output_value("Math::Value"); @@ -1007,8 +1009,8 @@ TEST_F(RenderGraph, constant_fold_math_clamp) builder .add_node(ShaderNodeBuilder<MathNode>(graph, "Math") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, true) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", true) .set("Value1", 0.7f) .set("Value2", 0.9f)) .output_value("Math::Value"); @@ -1028,20 +1030,20 @@ static void build_math_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Math_Cx") - .set(&MathNode::type, type) - .set(&MathNode::use_clamp, false) + .set_param("math_type", type) + .set_param("use_clamp", false) .set("Value1", constval)) .add_connection("Attribute::Fac", "Math_Cx::Value2") /* constant on the right */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Math_xC") - .set(&MathNode::type, type) - .set(&MathNode::use_clamp, false) + .set_param("math_type", type) + .set_param("use_clamp", false) .set("Value2", constval)) .add_connection("Attribute::Fac", "Math_xC::Value1") /* output sum */ .add_node(ShaderNodeBuilder<MathNode>(builder.graph(), "Out") - .set(&MathNode::type, NODE_MATH_ADD) - .set(&MathNode::use_clamp, true)) + .set_param("math_type", NODE_MATH_ADD) + .set_param("use_clamp", true)) .add_connection("Math_Cx::Value", "Out::Value1") .add_connection("Math_xC::Value", "Out::Value2") .output_value("Out::Value"); @@ -1178,7 +1180,7 @@ TEST_F(RenderGraph, constant_fold_vector_math) builder .add_node(ShaderNodeBuilder<VectorMathNode>(graph, "VectorMath") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_SUBTRACT) + .set_param("math_type", NODE_VECTOR_MATH_SUBTRACT) .set("Vector1", make_float3(1.3f, 0.5f, 0.7f)) .set("Vector2", make_float3(-1.7f, 0.5f, 0.7f))) .output_color("VectorMath::Vector"); @@ -1198,17 +1200,17 @@ static void build_vecmath_partial_test_graph(ShaderGraphBuilder &builder, .add_attribute("Attribute") /* constant on the left */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Math_Cx") - .set(&VectorMathNode::type, type) + .set_param("math_type", type) .set("Vector1", constval)) .add_connection("Attribute::Vector", "Math_Cx::Vector2") /* constant on the right */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Math_xC") - .set(&VectorMathNode::type, type) + .set_param("math_type", type) .set("Vector2", constval)) .add_connection("Attribute::Vector", "Math_xC::Vector1") /* output sum */ .add_node(ShaderNodeBuilder<VectorMathNode>(builder.graph(), "Out") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD)) + .set_param("math_type", NODE_VECTOR_MATH_ADD)) .add_connection("Math_Cx::Vector", "Out::Vector1") .add_connection("Math_xC::Vector", "Out::Vector2") .output_color("Out::Vector"); @@ -1312,9 +1314,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves) builder .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.5f) .set("Color", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Color"); @@ -1336,9 +1338,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f)) .add_connection("Attribute::Color", "Curves::Color") .output_color("Curves::Color"); @@ -1360,9 +1362,9 @@ TEST_F(RenderGraph, constant_fold_rgb_curves_fac_0_const) builder .add_node(ShaderNodeBuilder<RGBCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f) .set("Color", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Color"); @@ -1384,9 +1386,9 @@ TEST_F(RenderGraph, constant_fold_vector_curves) builder .add_node(ShaderNodeBuilder<VectorCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.5f) .set("Vector", make_float3(0.3f, 0.5f, 0.7f))) .output_color("Curves::Vector"); @@ -1408,9 +1410,9 @@ TEST_F(RenderGraph, constant_fold_vector_curves_fac_0) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<VectorCurvesNode>(graph, "Curves") - .set(&CurvesNode::curves, curve) - .set(&CurvesNode::min_x, 0.1f) - .set(&CurvesNode::max_x, 0.9f) + .set_param("curves", curve) + .set_param("min_x", 0.1f) + .set_param("max_x", 0.9f) .set("Fac", 0.0f)) .add_connection("Attribute::Vector", "Curves::Vector") .output_color("Curves::Vector"); @@ -1435,11 +1437,11 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp) builder .add_node(ShaderNodeBuilder<RGBRampNode>(graph, "Ramp") - .set(&RGBRampNode::ramp, curve) - .set(&RGBRampNode::ramp_alpha, alpha) - .set(&RGBRampNode::interpolate, true) + .set_param("ramp", curve) + .set_param("ramp_alpha", alpha) + .set_param("interpolate", true) .set("Fac", 0.56f)) - .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set(&MixNode::type, NODE_MIX_ADD)) + .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set_param("mix_type", NODE_MIX_ADD)) .add_connection("Ramp::Color", "Mix::Color1") .add_connection("Ramp::Alpha", "Mix::Color2") .output_color("Mix::Color"); @@ -1464,11 +1466,11 @@ TEST_F(RenderGraph, constant_fold_rgb_ramp_flat) builder .add_node(ShaderNodeBuilder<RGBRampNode>(graph, "Ramp") - .set(&RGBRampNode::ramp, curve) - .set(&RGBRampNode::ramp_alpha, alpha) - .set(&RGBRampNode::interpolate, false) + .set_param("ramp", curve) + .set_param("ramp_alpha", alpha) + .set_param("interpolate", false) .set("Fac", 0.56f)) - .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set(&MixNode::type, NODE_MIX_ADD)) + .add_node(ShaderNodeBuilder<MixNode>(graph, "Mix").set_param("mix_type", NODE_MIX_ADD)) .add_connection("Ramp::Color", "Mix::Color1") .add_connection("Ramp::Alpha", "Mix::Color2") .output_color("Mix::Color"); @@ -1510,7 +1512,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_vector_color) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<VectorMathNode>(graph, "VecAdd") - .set(&VectorMathNode::type, NODE_VECTOR_MATH_ADD) + .set_param("math_type", NODE_VECTOR_MATH_ADD) .set("Vector2", make_float3(0, 0, 0))) .add_connection("Attribute::Color", "VecAdd::Vector1") .output_color("VecAdd::Vector"); @@ -1531,7 +1533,7 @@ TEST_F(RenderGraph, constant_fold_convert_color_float_color) builder.add_attribute("Attribute") .add_node(ShaderNodeBuilder<MathNode>(graph, "MathAdd") - .set(&MathNode::type, NODE_MATH_ADD) + .set_param("math_type", NODE_MATH_ADD) .set("Value2", 0.0f)) .add_connection("Attribute::Color", "MathAdd::Value1") .output_color("MathAdd::Value"); diff --git a/intern/cycles/util/util_array.h b/intern/cycles/util/util_array.h index db80ab474e0..ea481787018 100644 --- a/intern/cycles/util/util_array.h +++ b/intern/cycles/util/util_array.h @@ -213,6 +213,26 @@ template<typename T, size_t alignment = MIN_ALIGNMENT_CPU_DATA_TYPES> class arra return data_[i]; } + T *begin() + { + return data_; + } + + const T *begin() const + { + return data_; + } + + T *end() + { + return data_ + datasize_; + } + + const T *end() const + { + return data_ + datasize_; + } + void reserve(size_t newcapacity) { if (newcapacity > capacity_) { diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 77e777db872..4a2a12932fe 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -332,7 +332,7 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) elseif(WIN32) # # Warnings as errors, this is too strict! # if(MSVC) - # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /WX") + # string(APPEND CMAKE_CXX_FLAGS " /WX") # endif() list(APPEND INC_SYS diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index 2046b55c97f..64740b68c0c 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -31,8 +31,8 @@ extern "C" { /** * Definition of a callback routine that receives events. - * \param event The event received. - * \param userdata The callback's user data, supplied to GHOST_CreateSystem. + * \param event: The event received. + * \param userdata: The callback's user data, supplied to #GHOST_CreateSystem. */ typedef int (*GHOST_EventCallbackProcPtr)(GHOST_EventHandle event, GHOST_TUserDataPtr userdata); @@ -49,21 +49,20 @@ extern void GHOST_SystemInitDebug(GHOST_SystemHandle systemhandle, int is_debug_ /** * Disposes the one and only system. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. * \return An indication of success. */ extern GHOST_TSuccess GHOST_DisposeSystem(GHOST_SystemHandle systemhandle); /** * Show a system message box to the user - * \param systemhandle The handle to the system - * \param title Title of the message box - * \param message Message of the message box - * \param help_label Text to show on the help button that opens a link - * \param continue_label Text to show on the ok button that continues - * \param link Optional (hyper)link to a webpage to show when pressing help - * \param dialog_options Options to configure the message box. - * \return void. + * \param systemhandle: The handle to the system. + * \param title: Title of the message box. + * \param message: Message of the message box. + * \param help_label: Text to show on the help button that opens a link. + * \param continue_label: Text to show on the ok button that continues. + * \param link: Optional (hyper)link to a webpage to show when pressing help. + * \param dialog_options: Options to configure the message box. */ extern void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle, const char *title, @@ -75,15 +74,15 @@ extern void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle, /** * Creates an event consumer object - * \param eventCallback The event callback routine. - * \param userdata Pointer to user data returned to the callback routine. + * \param eventCallback: The event callback routine. + * \param userdata: Pointer to user data returned to the callback routine. */ extern GHOST_EventConsumerHandle GHOST_CreateEventConsumer( GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata); /** * Disposes an event consumer object - * \param consumerhandle Handle to the event consumer. + * \param consumerhandle: Handle to the event consumer. * \return An indication of success. */ extern GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhandle); @@ -92,7 +91,7 @@ extern GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consu * Returns the system time. * Returns the number of milliseconds since the start of the system process. * Based on ANSI clock() routine. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. * \return The number of milliseconds. */ extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle); @@ -101,11 +100,11 @@ extern GHOST_TUns64 GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle); * Installs a timer. * Note that, on most operating systems, messages need to be processed in order * for the timer callbacks to be invoked. - * \param systemhandle The handle to the system - * \param delay The time to wait for the first call to the timerProc (in milliseconds) - * \param interval The interval between calls to the timerProc (in milliseconds) - * \param timerProc The callback invoked when the interval expires, - * \param userData Placeholder for user data. + * \param systemhandle: The handle to the system. + * \param delay: The time to wait for the first call to the timerProc (in milliseconds). + * \param interval: The interval between calls to the timerProc (in milliseconds). + * \param timerProc: The callback invoked when the interval expires. + * \param userData: Placeholder for user data. * \return A timer task (0 if timer task installation failed). */ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, @@ -116,8 +115,8 @@ extern GHOST_TimerTaskHandle GHOST_InstallTimer(GHOST_SystemHandle systemhandle, /** * Removes a timer. - * \param systemhandle The handle to the system - * \param timertaskhandle Timer task to be removed. + * \param systemhandle: The handle to the system. + * \param timertaskhandle: Timer task to be removed. * \return Indication of success. */ extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, @@ -129,17 +128,16 @@ extern GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle, /** * Returns the number of displays on this system. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. * \return The number of displays. */ extern GHOST_TUns8 GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle); /** * Returns the dimensions of the main display on this system. - * \param systemhandle The handle to the system - * \param width A pointer the width gets put in - * \param height A pointer the height gets put in - * \return void. + * \param systemhandle: The handle to the system. + * \param width: A pointer the width gets put in. + * \param height: A pointer the height gets put in. */ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, GHOST_TUns32 *width, @@ -149,10 +147,9 @@ extern void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, * Returns the dimensions of all displays combine * (the current workspace). * No need to worry about overlapping monitors. - * \param systemhandle The handle to the system - * \param width A pointer the width gets put in - * \param height A pointer the height gets put in - * \return void. + * \param systemhandle: The handle to the system. + * \param width: A pointer the width gets put in. + * \param height: A pointer the height gets put in. */ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, GHOST_TUns32 *width, @@ -162,15 +159,15 @@ extern void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle, * Create a new window. * The new window is added to the list of windows managed. * Never explicitly delete the window, use disposeWindow() instead. - * \param systemhandle The handle to the system - * \param title The name of the window + * \param systemhandle: The handle to the system. + * \param title: The name of the window. * (displayed in the title bar of the window if the OS supports it). - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state of the window when opened. - * \param type The type of drawing context installed in this window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state of the window when opened. + * \param type: The type of drawing context installed in this window. * \param glSettings: Misc OpenGL options. * \return A handle to the new window ( == NULL if creation failed). */ @@ -198,8 +195,8 @@ extern GHOST_WindowHandle GHOST_CreateDialogWindow(GHOST_SystemHandle systemhand /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \param systemhandle The handle to the system - * \param platform_support_callback An optional callback to check platform support + * \param systemhandle: The handle to the system. + * \param platform_support_callback: An optional callback to check platform support. * \return A handle to the new context ( == NULL if creation failed). */ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemhandle, @@ -207,8 +204,8 @@ extern GHOST_ContextHandle GHOST_CreateOpenGLContext(GHOST_SystemHandle systemha /** * Dispose of a context. - * \param systemhandle The handle to the system - * \param contexthandle Handle to the context to be disposed. + * \param systemhandle: The handle to the system. + * \param contexthandle: Handle to the context to be disposed. * \return Indication of success. */ extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle, @@ -216,15 +213,15 @@ extern GHOST_TSuccess GHOST_DisposeOpenGLContext(GHOST_SystemHandle systemhandle /** * Returns the window user data. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The window user data. */ extern GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle); /** * Changes the window user data. - * \param windowhandle The handle to the window - * \param userdata The window user data. + * \param windowhandle: The handle to the window. + * \param userdata: The window user data. */ extern void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr userdata); @@ -232,8 +229,8 @@ extern int GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle); /** * Dispose a window. - * \param systemhandle The handle to the system - * \param windowhandle Handle to the window to be disposed. + * \param systemhandle: The handle to the system. + * \param windowhandle: Handle to the window to be disposed. * \return Indication of success. */ extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle, @@ -241,17 +238,17 @@ extern GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle, /** * Returns whether a window is valid. - * \param systemhandle The handle to the system - * \param windowhandle Handle to the window to be checked. + * \param systemhandle: The handle to the system. + * \param windowhandle: Handle to the window to be checked. * \return Indication of validity. */ extern int GHOST_ValidWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle); /** * Begins full screen mode. - * \param systemhandle The handle to the system - * \param setting The new setting of the display. - * \param stereoVisual Option for stereo display. + * \param systemhandle: The handle to the system. + * \param setting: The new setting of the display. + * \param stereoVisual: Option for stereo display. * \return A handle to the window displayed in full screen. * This window is invalid after full screen has been ended. */ @@ -261,14 +258,14 @@ extern GHOST_WindowHandle GHOST_BeginFullScreen(GHOST_SystemHandle systemhandle, /** * Ends full screen mode. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. * \return Indication of success. */ extern GHOST_TSuccess GHOST_EndFullScreen(GHOST_SystemHandle systemhandle); /** * Returns current full screen mode status. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. * \return The current status. */ extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle); @@ -279,8 +276,8 @@ extern int GHOST_GetFullScreen(GHOST_SystemHandle systemhandle); /** * Retrieves events from the system and stores them in the queue. - * \param systemhandle The handle to the system - * \param waitForEvent Boolean to indicate that ProcessEvents should + * \param systemhandle: The handle to the system. + * \param waitForEvent: Boolean to indicate that #ProcessEvents should. * wait (block) until the next event before returning. * \return Indication of the presence of events. */ @@ -288,14 +285,14 @@ extern int GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, int waitForEvent /** * Retrieves events from the queue and send them to the event consumers. - * \param systemhandle The handle to the system + * \param systemhandle: The handle to the system. */ extern void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle); /** * Adds the given event consumer to our list. - * \param systemhandle The handle to the system - * \param consumerhandle The event consumer to add. + * \param systemhandle: The handle to the system. + * \param consumerhandle: The event consumer to add. * \return Indication of success. */ extern GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, @@ -303,8 +300,8 @@ extern GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, /** * Remove the given event consumer to our list. - * \param systemhandle The handle to the system - * \param consumerhandle The event consumer to remove. + * \param systemhandle: The handle to the system. + * \param consumerhandle: The event consumer to remove. * \return Indication of success. */ extern GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle, @@ -316,14 +313,14 @@ extern GHOST_TSuccess GHOST_RemoveEventConsumer(GHOST_SystemHandle systemhandle, /** * Sets the progress bar value displayed in the window/application icon - * \param windowhandle The handle to the window - * \param progress The progress % (0.0 to 1.0) + * \param windowhandle: The handle to the window. + * \param progress: The progress percentage (0.0 to 1.0). */ extern GHOST_TSuccess GHOST_SetProgressBar(GHOST_WindowHandle windowhandle, float progress); /** * Hides the progress bar in the icon - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. */ extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle); @@ -333,7 +330,7 @@ extern GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle); /** * Returns the current cursor shape. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The current cursor shape. */ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle); @@ -341,8 +338,8 @@ extern GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandl /** * Set the shape of the cursor. If the shape is not supported by the platform, * it will use the default cursor instead. - * \param windowhandle The handle to the window - * \param cursorshape The new cursor shape type id. + * \param windowhandle: The handle to the window. + * \param cursorshape: The new cursor shape type id. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorShape(GHOST_WindowHandle windowhandle, @@ -357,14 +354,14 @@ extern GHOST_TSuccess GHOST_HasCursorShape(GHOST_WindowHandle windowhandle, /** * Set the shape of the cursor to a custom cursor of specified size. - * \param windowhandle The handle to the window - * \param bitmap The bitmap data for the cursor. - * \param mask The mask data for the cursor. - * \param sizex The width of the cursor - * \param sizey The height of the cursor - * \param hotX The X coordinate of the cursor hot-spot. - * \param hotY The Y coordinate of the cursor hot-spot. - * \param canInvertColor Let macOS invert cursor color to match platform convention. + * \param windowhandle: The handle to the window. + * \param bitmap: The bitmap data for the cursor. + * \param mask: The mask data for the cursor. + * \param sizex: The width of the cursor. + * \param sizey: The height of the cursor. + * \param hotX: The X coordinate of the cursor hot-spot. + * \param hotY: The Y coordinate of the cursor hot-spot. + * \param canInvertColor: Let macOS invert cursor color to match platform convention. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle, @@ -378,24 +375,24 @@ extern GHOST_TSuccess GHOST_SetCustomCursorShape(GHOST_WindowHandle windowhandle /** * Returns the visibility state of the cursor. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The visibility state of the cursor. */ extern int GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle); /** * Shows or hides the cursor. - * \param windowhandle The handle to the window - * \param visible The new visibility state of the cursor. + * \param windowhandle: The handle to the window. + * \param visible: The new visibility state of the cursor. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorVisibility(GHOST_WindowHandle windowhandle, int visible); /** * Returns the current location of the cursor (location in screen coordinates) - * \param systemhandle The handle to the system - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. + * \param systemhandle: The handle to the system. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. * \return Indication of success. */ extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, @@ -405,9 +402,9 @@ extern GHOST_TSuccess GHOST_GetCursorPosition(GHOST_SystemHandle systemhandle, /** * Updates the location of the cursor (location in screen coordinates). * Not all operating systems allow the cursor to be moved (without the input device being moved). - * \param systemhandle The handle to the system - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. + * \param systemhandle: The handle to the system. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, @@ -418,10 +415,10 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * Grabs the cursor for a modal operation, to keep receiving * events when the mouse is outside the window. X11 only, others * do this automatically. - * \param windowhandle The handle to the window - * \param mode The new grab state of the cursor. - * \param bounds The grab region (optional) - left,top,right,bottom - * \param mouse_ungrab_xy XY for new mouse location (optional) - x,y + * \param windowhandle: The handle to the window. + * \param mode: The new grab state of the cursor. + * \param bounds: The grab region (optional) - left,top,right,bottom. + * \param mouse_ungrab_xy: XY for new mouse location (optional). * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, @@ -436,9 +433,9 @@ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, /** * Returns the state of a modifier key (outside the message queue). - * \param systemhandle The handle to the system - * \param mask The modifier key state to retrieve. - * \param isDown Pointer to return modifier state in. + * \param systemhandle: The handle to the system. + * \param mask: The modifier key state to retrieve. + * \param isDown: Pointer to return modifier state in. * \return Indication of success. */ extern GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, @@ -447,9 +444,9 @@ extern GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, /** * Returns the state of a mouse button (outside the message queue). - * \param systemhandle The handle to the system - * \param mask The button state to retrieve. - * \param isDown Pointer to return button state in. + * \param systemhandle: The handle to the system. + * \param mask: The button state to retrieve. + * \param isDown: Pointer to return button state in. * \return Indication of success. */ extern GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle, @@ -479,14 +476,14 @@ extern void GHOST_setAcceptDragOperation(GHOST_WindowHandle windowhandle, GHOST_ /** * Returns the event type. - * \param eventhandle The handle to the event + * \param eventhandle: The handle to the event. * \return The event type. */ extern GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle); /** * Returns the time this event was generated. - * \param eventhandle The handle to the event + * \param eventhandle: The handle to the event. * \return The event generation time. */ extern GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle); @@ -494,66 +491,66 @@ extern GHOST_TUns64 GHOST_GetEventTime(GHOST_EventHandle eventhandle); /** * Returns the window this event was generated on, * or NULL if it is a 'system' event. - * \param eventhandle The handle to the event + * \param eventhandle: The handle to the event. * \return The generating window. */ extern GHOST_WindowHandle GHOST_GetEventWindow(GHOST_EventHandle eventhandle); /** * Returns the event data. - * \param eventhandle The handle to the event + * \param eventhandle: The handle to the event. * \return The event data. */ extern GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle); /** * Returns the timer callback. - * \param timertaskhandle The handle to the timer-task. + * \param timertaskhandle: The handle to the timer-task. * \return The timer callback. */ extern GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle); /** * Changes the timer callback. - * \param timertaskhandle The handle to the timertask - * \param timerProc The timer callback. + * \param timertaskhandle: The handle to the timertask. + * \param timerProc: The timer callback. */ extern void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, GHOST_TimerProcPtr timerProc); /** * Returns the timer user data. - * \param timertaskhandle The handle to the timertask + * \param timertaskhandle: The handle to the timertask. * \return The timer user data. */ extern GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle); /** * Changes the time user data. - * \param timertaskhandle The handle to the timertask - * \param userdata The timer user data. + * \param timertaskhandle: The handle to the timertask. + * \param userdata: The timer user data. */ extern void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUserDataPtr userdata); /** * Returns indication as to whether the window is valid. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The validity of the window. */ extern int GHOST_GetValid(GHOST_WindowHandle windowhandle); /** * Returns the type of drawing context used in this window. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The current type of drawing context. */ extern GHOST_TDrawingContextType GHOST_GetDrawingContextType(GHOST_WindowHandle windowhandle); /** * Tries to install a rendering context in this window. - * \param windowhandle The handle to the window - * \param type The type of rendering context installed. + * \param windowhandle: The handle to the window. + * \param type: The type of rendering context installed. * \return Indication as to whether installation has succeeded. */ extern GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandle, @@ -561,8 +558,8 @@ extern GHOST_TSuccess GHOST_SetDrawingContextType(GHOST_WindowHandle windowhandl /** * Sets the title displayed in the title bar. - * \param windowhandle The handle to the window - * \param title The title to display in the title bar. + * \param windowhandle: The handle to the window. + * \param title: The title to display in the title bar. */ extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title); @@ -570,7 +567,7 @@ extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title); * Returns the title displayed in the title bar. The title * should be free'd with free(). * - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The title, free with free(). */ extern char *GHOST_GetTitle(GHOST_WindowHandle windowhandle); @@ -578,7 +575,7 @@ extern char *GHOST_GetTitle(GHOST_WindowHandle windowhandle); /** * Returns the window rectangle dimensions. * These are screen coordinates. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return A handle to the bounding rectangle of the window. */ extern GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle); @@ -586,38 +583,38 @@ extern GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhand /** * Returns the client rectangle dimensions. * The left and top members of the rectangle are always zero. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return A handle to the bounding rectangle of the window. */ extern GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle); /** - * Disposes a rectangle object - * \param rectanglehandle Handle to the rectangle. + * Disposes a rectangle object. + * \param rectanglehandle: Handle to the rectangle. */ void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle); /** * Resizes client rectangle width. - * \param windowhandle The handle to the window - * \param width The new width of the client area of the window. + * \param windowhandle: The handle to the window. + * \param width: The new width of the client area of the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetClientWidth(GHOST_WindowHandle windowhandle, GHOST_TUns32 width); /** * Resizes client rectangle height. - * \param windowhandle The handle to the window - * \param height The new height of the client area of the window. + * \param windowhandle: The handle to the window. + * \param height: The new height of the client area of the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetClientHeight(GHOST_WindowHandle windowhandle, GHOST_TUns32 height); /** * Resizes client rectangle. - * \param windowhandle The handle to the window - * \param width The new width of the client area of the window. - * \param height The new height of the client area of the window. + * \param windowhandle: The handle to the window. + * \param width: The new width of the client area of the window. + * \param height: The new height of the client area of the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, @@ -626,11 +623,11 @@ extern GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, /** * Converts a point in screen coordinates to client rectangle coordinates - * \param windowhandle The handle to the window - * \param inX The x-coordinate on the screen. - * \param inY The y-coordinate on the screen. - * \param outX The x-coordinate in the client rectangle. - * \param outY The y-coordinate in the client rectangle. + * \param windowhandle: The handle to the window. + * \param inX: The x-coordinate on the screen. + * \param inY: The y-coordinate on the screen. + * \param outX: The x-coordinate in the client rectangle. + * \param outY: The y-coordinate in the client rectangle. */ extern void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, GHOST_TInt32 inX, @@ -640,11 +637,11 @@ extern void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, /** * Converts a point in screen coordinates to client rectangle coordinates - * \param windowhandle The handle to the window - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param windowhandle: The handle to the window. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ extern void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle, GHOST_TInt32 inX, @@ -654,24 +651,24 @@ extern void GHOST_ClientToScreen(GHOST_WindowHandle windowhandle, /** * Returns the state of the window (normal, minimized, maximized). - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return The state of the window. */ extern GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle); /** * Sets the state of the window (normal, minimized, maximized). - * \param windowhandle The handle to the window - * \param state The state of the window. + * \param windowhandle: The handle to the window. + * \param state: The state of the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetWindowState(GHOST_WindowHandle windowhandle, GHOST_TWindowState state); /** - * Sets the window "modified" status, indicating unsaved changes - * \param windowhandle The handle to the window - * \param isUnsavedChanges Unsaved changes or not + * Sets the window "modified" status, indicating unsaved changes. + * \param windowhandle: The handle to the window. + * \param isUnsavedChanges: Unsaved changes or not. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhandle, @@ -679,8 +676,8 @@ extern GHOST_TSuccess GHOST_SetWindowModifiedState(GHOST_WindowHandle windowhand /** * Sets the order of the window (bottom, top). - * \param windowhandle The handle to the window - * \param order The order of the window. + * \param windowhandle: The handle to the window. + * \param order: The order of the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, @@ -688,20 +685,20 @@ extern GHOST_TSuccess GHOST_SetWindowOrder(GHOST_WindowHandle windowhandle, /** * Swaps front and back buffers of a window. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return A success indicator. */ extern GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ extern GHOST_TSuccess GHOST_SetSwapInterval(GHOST_WindowHandle windowhandle, int interval); /** - * Gets the current swap interval for swapBuffers. + * Gets the current swap interval for #swapBuffers. * \param windowhandle: The handle to the window * \param intervalOut: pointer to location to return swap interval * (left untouched if there is an error) @@ -711,28 +708,28 @@ extern GHOST_TSuccess GHOST_GetSwapInterval(GHOST_WindowHandle windowhandle, int /** * Activates the drawing context of this window. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return A success indicator. */ extern GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle); /** * Invalidates the contents of this window. - * \param windowhandle The handle to the window + * \param windowhandle: The handle to the window. * \return Indication of success. */ extern GHOST_TSuccess GHOST_InvalidateWindow(GHOST_WindowHandle windowhandle); /** * Activates the drawing context of this context. - * \param contexthandle The handle to the context + * \param contexthandle: The handle to the context. * \return A success indicator. */ extern GHOST_TSuccess GHOST_ActivateOpenGLContext(GHOST_ContextHandle contexthandle); /** * Release the drawing context bound to this thread. - * \param contexthandle The handle to the context + * \param contexthandle: The handle to the context. * \return A success indicator. */ extern GHOST_TSuccess GHOST_ReleaseOpenGLContext(GHOST_ContextHandle contexthandle); @@ -756,32 +753,32 @@ extern unsigned int GHOST_GetDefaultOpenGLFramebuffer(GHOST_WindowHandle windwHa /** * Set which tablet API to use. Only affects Windows, other platforms have a single API. - * \param systemhandle The handle to the system - * \param api Enum indicating which API to use. + * \param systemhandle: The handle to the system. + * \param api: Enum indicating which API to use. */ extern void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api); /** * Access to rectangle width. - * \param rectanglehandle The handle to the rectangle + * \param rectanglehandle: The handle to the rectangle. * \return width of the rectangle */ extern GHOST_TInt32 GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle); /** * Access to rectangle height. - * \param rectanglehandle The handle to the rectangle + * \param rectanglehandle: The handle to the rectangle. * \return height of the rectangle */ extern GHOST_TInt32 GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle); /** * Gets all members of the rectangle. - * \param rectanglehandle The handle to the rectangle - * \param l Pointer to return left coordinate in. - * \param t Pointer to return top coordinate in. - * \param r Pointer to return right coordinate in. - * \param b Pointer to return bottom coordinate in. + * \param rectanglehandle: The handle to the rectangle. + * \param l: Pointer to return left coordinate in. + * \param t: Pointer to return top coordinate in. + * \param r: Pointer to return right coordinate in. + * \param b: Pointer to return bottom coordinate in. */ extern void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 *l, @@ -791,11 +788,11 @@ extern void GHOST_GetRectangle(GHOST_RectangleHandle rectanglehandle, /** * Sets all members of the rectangle. - * \param rectanglehandle The handle to the rectangle - * \param l requested left coordinate of the rectangle - * \param t requested top coordinate of the rectangle - * \param r requested right coordinate of the rectangle - * \param b requested bottom coordinate of the rectangle + * \param rectanglehandle: The handle to the rectangle. + * \param l: requested left coordinate of the rectangle. + * \param t: requested top coordinate of the rectangle. + * \param r: requested right coordinate of the rectangle. + * \param b: requested bottom coordinate of the rectangle. */ extern void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 l, @@ -806,7 +803,7 @@ extern void GHOST_SetRectangle(GHOST_RectangleHandle rectanglehandle, /** * Returns whether this rectangle is empty. * Empty rectangles are rectangles that have width==0 and/or height==0. - * \param rectanglehandle The handle to the rectangle + * \param rectanglehandle: The handle to the rectangle. * \return Success value (true == empty rectangle) */ extern GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehandle); @@ -815,7 +812,7 @@ extern GHOST_TSuccess GHOST_IsEmptyRectangle(GHOST_RectangleHandle rectanglehand * Returns whether this rectangle is valid. * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. * Thus, empty rectangles are valid. - * \param rectanglehandle The handle to the rectangle + * \param rectanglehandle: The handle to the rectangle. * \return Success value (true == valid rectangle) */ extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehandle); @@ -823,25 +820,25 @@ extern GHOST_TSuccess GHOST_IsValidRectangle(GHOST_RectangleHandle rectanglehand /** * Grows (or shrinks the rectangle). * The method avoids negative insets making the rectangle invalid - * \param rectanglehandle The handle to the rectangle - * \param i The amount of offset given to each extreme (negative values shrink the rectangle). + * \param rectanglehandle: The handle to the rectangle. + * \param i: The amount of offset given to each extreme (negative values shrink the rectangle). */ extern void GHOST_InsetRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 i); /** * Does a union of the rectangle given and this rectangle. * The result is stored in this rectangle. - * \param rectanglehandle The handle to the rectangle - * \param anotherrectanglehandle The rectangle that is input for the union operation. + * \param rectanglehandle: The handle to the rectangle. + * \param anotherrectanglehandle: The rectangle that is input for the union operation. */ extern void GHOST_UnionRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_RectangleHandle anotherrectanglehandle); /** * Grows the rectangle to included a point. - * \param rectanglehandle The handle to the rectangle - * \param x The x-coordinate of the point. - * \param y The y-coordinate of the point. + * \param rectanglehandle: The handle to the rectangle. + * \param x: The x-coordinate of the point. + * \param y: The y-coordinate of the point. */ extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 x, @@ -850,9 +847,9 @@ extern void GHOST_UnionPointRectangle(GHOST_RectangleHandle rectanglehandle, /** * Returns whether the point is inside this rectangle. * Point on the boundary is considered inside. - * \param rectanglehandle The handle to the rectangle - * \param x x-coordinate of point to test. - * \param y y-coordinate of point to test. + * \param rectanglehandle: The handle to the rectangle. + * \param x: x-coordinate of point to test. + * \param y: y-coordinate of point to test. * \return Success value (true if point is inside). */ extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehandle, @@ -861,8 +858,8 @@ extern GHOST_TSuccess GHOST_IsInsideRectangle(GHOST_RectangleHandle rectanglehan /** * Returns whether the rectangle is inside this rectangle. - * \param rectanglehandle The handle to the rectangle - * \param anotherrectanglehandle The rectangle to test. + * \param rectanglehandle: The handle to the rectangle. + * \param anotherrectanglehandle: The rectangle to test. * \return visibility (not, partially or fully visible). */ extern GHOST_TVisibility GHOST_GetRectangleVisibility( @@ -871,9 +868,9 @@ extern GHOST_TVisibility GHOST_GetRectangleVisibility( /** * Sets rectangle members. * Sets rectangle members such that it is centered at the given location. - * \param rectanglehandle The handle to the rectangle - * \param cx Requested center x-coordinate of the rectangle - * \param cy Requested center y-coordinate of the rectangle + * \param rectanglehandle: The handle to the rectangle. + * \param cx: Requested center x-coordinate of the rectangle. + * \param cy: Requested center y-coordinate of the rectangle. */ extern void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 cx, @@ -883,11 +880,11 @@ extern void GHOST_SetCenterRectangle(GHOST_RectangleHandle rectanglehandle, * Sets rectangle members. * Sets rectangle members such that it is centered at the given location, * with the width requested. - * \param rectanglehandle The handle to the rectangle - * \param cx requested center x-coordinate of the rectangle - * \param cy requested center y-coordinate of the rectangle - * \param w requested width of the rectangle - * \param h requested height of the rectangle + * \param rectanglehandle: The handle to the rectangle. + * \param cx: requested center x-coordinate of the rectangle. + * \param cy: requested center y-coordinate of the rectangle. + * \param w: requested width of the rectangle. + * \param h: requested height of the rectangle. */ extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle, GHOST_TInt32 cx, @@ -899,8 +896,8 @@ extern void GHOST_SetRectangleCenter(GHOST_RectangleHandle rectanglehandle, * Clips a rectangle. * Updates the rectangle given such that it will fit within this one. * This can result in an empty rectangle. - * \param rectanglehandle The handle to the rectangle - * \param anotherrectanglehandle The rectangle to clip + * \param rectanglehandle: The handle to the rectangle. + * \param anotherrectanglehandle: The rectangle to clip. * \return Whether clipping has occurred */ extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle, @@ -908,21 +905,21 @@ extern GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle, /** * Return the data from the clipboard - * \param selection Boolean to return the selection instead, X11 only feature. + * \param selection: Boolean to return the selection instead, X11 only feature. * \return clipboard data */ extern GHOST_TUns8 *GHOST_getClipboard(int selection); /** * Put data to the Clipboard - * \param buffer the string buffer to set. - * \param selection Set the selection instead, X11 only feature. + * \param buffer: the string buffer to set. + * \param selection: Set the selection instead, X11 only feature. */ extern void GHOST_putClipboard(GHOST_TInt8 *buffer, int selection); /** * Toggles console - * \param action + * \param action: * - 0: Hides * - 1: Shows * - 2: Toggles @@ -955,14 +952,14 @@ extern GHOST_TUns16 GHOST_GetDPIHint(GHOST_WindowHandle windowhandle); /** * Enable IME attached to the given window, i.e. allows user-input * events to be dispatched to the IME. - * \param windowhandle Window handle of the caller - * \param x Requested x-coordinate of the rectangle - * \param y Requested y-coordinate of the rectangle - * \param w Requested width of the rectangle - * \param h Requested height of the rectangle - * \param complete Whether or not to complete the ongoing composition - * true: Start a new composition - * false: Move the IME windows to the given position without finishing it. + * \param windowhandle: Window handle of the caller. + * \param x: Requested x-coordinate of the rectangle. + * \param y: Requested y-coordinate of the rectangle. + * \param w: Requested width of the rectangle. + * \param h: Requested height of the rectangle. + * \param complete: Whether or not to complete the ongoing composition. + * - true: Start a new composition. + * - false: Move the IME windows to the given position without finishing it. */ extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle, GHOST_TInt32 x, @@ -973,7 +970,7 @@ extern void GHOST_BeginIME(GHOST_WindowHandle windowhandle, /** * Disable the IME attached to the given window, i.e. prohibits any user-input * events from being dispatched to the IME. - * \param windowhandle The window handle of the caller + * \param windowhandle: The window handle of the caller. */ extern void GHOST_EndIME(GHOST_WindowHandle windowhandle); @@ -1071,4 +1068,5 @@ GHOST_TSuccess GHOST_XrEventsHandle(GHOST_XrContextHandle xr_context); #ifdef __cplusplus } + #endif diff --git a/intern/ghost/GHOST_IContext.h b/intern/ghost/GHOST_IContext.h index c6316e90ce4..278a9a40bd1 100644 --- a/intern/ghost/GHOST_IContext.h +++ b/intern/ghost/GHOST_IContext.h @@ -44,13 +44,13 @@ class GHOST_IContext { /** * Activates the drawing context. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess activateDrawingContext() = 0; /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess releaseDrawingContext() = 0; diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h index b5975068da0..9096c70904b 100644 --- a/intern/ghost/GHOST_IEventConsumer.h +++ b/intern/ghost/GHOST_IEventConsumer.h @@ -46,8 +46,8 @@ class GHOST_IEventConsumer { /** * This method is called by the system when it has events to dispatch. * \see GHOST_ISystem#dispatchEvents - * \param event The event that can be handled or ignored. - * \return Indication as to whether the event was handled. + * \param event: The event that can be handled or ignored. + * \return Indication as to whether the event was handled. */ virtual bool processEvent(GHOST_IEvent *event) = 0; diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h index 61ddae47292..81b54cf5a0d 100644 --- a/intern/ghost/GHOST_ISystem.h +++ b/intern/ghost/GHOST_ISystem.h @@ -183,10 +183,10 @@ class GHOST_ISystem { * Installs a timer. * Note that, on most operating systems, messages need to be processed in order * for the timer callbacks to be invoked. - * \param delay The time to wait for the first call to the timerProc (in milliseconds) - * \param interval The interval between calls to the timerProc (in milliseconds) - * \param timerProc The callback invoked when the interval expires, - * \param userData Placeholder for user data. + * \param delay: The time to wait for the first call to the timerProc (in milliseconds). + * \param interval: The interval between calls to the timerProc (in milliseconds). + * \param timerProc: The callback invoked when the interval expires. + * \param userData: Placeholder for user data. * \return A timer task (0 if timer task installation failed). */ virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, @@ -196,7 +196,7 @@ class GHOST_ISystem { /** * Removes a timer. - * \param timerTask Timer task to be removed. + * \param timerTask: Timer task to be removed. * \return Indication of success. */ virtual GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask) = 0; @@ -255,38 +255,38 @@ class GHOST_ISystem { /** * Dispose a window. - * \param window Pointer to the window to be disposed. - * \return Indication of success. + * \param window: Pointer to the window to be disposed. + * \return Indication of success. */ virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0; /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0; /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ virtual GHOST_TSuccess disposeContext(GHOST_IContext *context) = 0; /** * Returns whether a window is valid. - * \param window Pointer to the window to be checked. - * \return Indication of validity. + * \param window: Pointer to the window to be checked. + * \return Indication of validity. */ virtual bool validWindow(GHOST_IWindow *window) = 0; /** * Begins full screen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. + * \param setting: The new setting of the display. + * \param window: Window displayed in full screen. * This window is invalid after full screen has been ended. - * \return Indication of success. + * \return Indication of success. */ virtual GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, @@ -295,17 +295,17 @@ class GHOST_ISystem { /** * Updates the resolution while in fullscreen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. + * \param setting: The new setting of the display. + * \param window: Window displayed in full screen. * - * \return Indication of success. + * \return Indication of success. */ virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window) = 0; /** * Ends full screen mode. - * \return Indication of success. + * \return Indication of success. */ virtual GHOST_TSuccess endFullScreen(void) = 0; @@ -331,7 +331,7 @@ class GHOST_ISystem { /** * Retrieves events from the system and stores them in the queue. - * \param waitForEvent Flag to wait for an event (or return immediately). + * \param waitForEvent: Flag to wait for an event (or return immediately). * \return Indication of the presence of events. */ virtual bool processEvents(bool waitForEvent) = 0; @@ -343,14 +343,14 @@ class GHOST_ISystem { /** * Adds the given event consumer to our list. - * \param consumer The event consumer to add. + * \param consumer: The event consumer to add. * \return Indication of success. */ virtual GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer) = 0; /** * Removes the given event consumer to our list. - * \param consumer The event consumer to remove. + * \param consumer: The event consumer to remove. * \return Indication of success. */ virtual GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer) = 0; @@ -361,18 +361,18 @@ class GHOST_ISystem { /** * Returns the current location of the cursor (location in screen coordinates) - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const = 0; /** * Updates the location of the cursor (location in screen coordinates). * Not all operating systems allow the cursor to be moved (without the input device being moved). - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) = 0; @@ -382,23 +382,23 @@ class GHOST_ISystem { /** * Returns the state of a modifier key (outside the message queue). - * \param mask The modifier key state to retrieve. - * \param isDown The state of a modifier key (true == pressed). - * \return Indication of success. + * \param mask: The modifier key state to retrieve. + * \param isDown: The state of a modifier key (true == pressed). + * \return Indication of success. */ virtual GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const = 0; /** * Returns the state of a mouse button (outside the message queue). - * \param mask The button state to retrieve. - * \param isDown Button state. - * \return Indication of success. + * \param mask: The button state to retrieve. + * \param isDown: Button state. + * \return Indication of success. */ virtual GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const = 0; /** * Set which tablet API to use. Only affects Windows, other platforms have a single API. - * \param api Enum indicating which API to use. + * \param api: Enum indicating which API to use. */ virtual void setTabletAPI(GHOST_TTabletAPI api) = 0; @@ -412,8 +412,8 @@ class GHOST_ISystem { /** * Toggles console - * \param action - * - 0: Hides + * \param action: + * - 0: Hides. * - 1: Shows * - 2: Toggles * - 3: Hides if it runs not from command line @@ -445,12 +445,12 @@ class GHOST_ISystem { /** * Show a system message box * - * \param title The title of the message box - * \param message The message to display - * \param help_label Help button label - * \param continue_label Continue button label - * \param link An optional hyperlink - * \param dialog_options Options how to display the message + * \param title: The title of the message box. + * \param message: The message to display. + * \param help_label: Help button label. + * \param continue_label: Continue button label. + * \param link: An optional hyperlink. + * \param dialog_options: Options how to display the message. */ virtual GHOST_TSuccess showMessageBox(const char * /*title*/, const char * /*message*/, diff --git a/intern/ghost/GHOST_ITimerTask.h b/intern/ghost/GHOST_ITimerTask.h index 0f4ac74c466..5d3013ac348 100644 --- a/intern/ghost/GHOST_ITimerTask.h +++ b/intern/ghost/GHOST_ITimerTask.h @@ -55,7 +55,7 @@ class GHOST_ITimerTask { /** * Changes the timer callback. - * \param timerProc The timer callback. + * \param timerProc: The timer callback. */ virtual void setTimerProc(const GHOST_TimerProcPtr timerProc) = 0; diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 6e8b61ae5a1..1650b230812 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -73,62 +73,62 @@ class GHOST_IWindow { /** * Tries to install a rendering context in this window. - * \param type The type of rendering context installed. + * \param type: The type of rendering context installed. * \return Indication as to whether installation has succeeded. */ virtual GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type) = 0; /** * Sets the title displayed in the title bar. - * \param title The title to display in the title bar. + * \param title: The title to display in the title bar. */ virtual void setTitle(const char *title) = 0; /** * Returns the title displayed in the title bar. - * \param title The title displayed in the title bar. + * \param title: The title displayed in the title bar. */ virtual std::string getTitle() const = 0; /** * Returns the window rectangle dimensions. * These are screen coordinates. - * \param bounds The bounding rectangle of the window. + * \param bounds: The bounding rectangle of the window. */ virtual void getWindowBounds(GHOST_Rect &bounds) const = 0; /** * Returns the client rectangle dimensions. * The left and top members of the rectangle are always zero. - * \param bounds The bounding rectangle of the client area of the window. + * \param bounds: The bounding rectangle of the client area of the window. */ virtual void getClientBounds(GHOST_Rect &bounds) const = 0; /** * Resizes client rectangle width. - * \param width The new width of the client area of the window. + * \param width: The new width of the client area of the window. */ virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width) = 0; /** * Resizes client rectangle height. - * \param height The new height of the client area of the window. + * \param height: The new height of the client area of the window. */ virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height) = 0; /** * Resizes client rectangle. - * \param width The new width of the client area of the window. - * \param height The new height of the client area of the window. + * \param width: The new width of the client area of the window. + * \param height: The new height of the client area of the window. */ virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height) = 0; /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate on the screen. - * \param inY The y-coordinate on the screen. - * \param outX The x-coordinate in the client rectangle. - * \param outY The y-coordinate in the client rectangle. + * \param inX: The x-coordinate on the screen. + * \param inY: The y-coordinate on the screen. + * \param outX: The x-coordinate in the client rectangle. + * \param outY: The y-coordinate in the client rectangle. */ virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -137,10 +137,10 @@ class GHOST_IWindow { /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -166,14 +166,14 @@ class GHOST_IWindow { /** * Sets the state of the window (normal, minimized, maximized). - * \param state The state of the window. + * \param state: The state of the window. * \return Indication of success. */ virtual GHOST_TSuccess setState(GHOST_TWindowState state) = 0; /** * Sets the window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not + * \param isUnsavedChanges: Unsaved changes or not. * \return Indication of success. */ virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges) = 0; @@ -186,27 +186,27 @@ class GHOST_IWindow { /** * Sets the order of the window (bottom, top). - * \param order The order of the window. + * \param order: The order of the window. * \return Indication of success. */ virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order) = 0; /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess swapBuffers() = 0; /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ virtual GHOST_TSuccess setSwapInterval(int interval) = 0; /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut pointer to location to return swap interval + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: pointer to location to return swap interval. * (left untouched if there is an error) * \return A boolean success indicator of if swap interval was successfully read. */ @@ -214,13 +214,13 @@ class GHOST_IWindow { /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess activateDrawingContext() = 0; /** - * Gets the OpenGL framebuffer associated with the window's contents. - * \return The name of an OpenGL framebuffer object. + * Gets the OpenGL frame-buffer associated with the window's contents. + * \return The name of an OpenGL frame-buffer object. */ virtual unsigned int getDefaultFramebuffer() = 0; @@ -238,7 +238,7 @@ class GHOST_IWindow { /** * Changes the window user data. - * \param userData The window user data. + * \param userData: The window user data. */ virtual void setUserData(const GHOST_TUserDataPtr userData) = 0; @@ -250,7 +250,7 @@ class GHOST_IWindow { /** * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % + * \param progress: The progress percentage (0.0 to 1.0). */ virtual GHOST_TSuccess setProgressBar(float progress) = 0; @@ -265,13 +265,13 @@ class GHOST_IWindow { /** * Returns the current cursor shape. - * \return The current cursor shape. + * \return The current cursor shape. */ virtual GHOST_TStandardCursor getCursorShape() const = 0; /** * Set the shape of the cursor. - * \param cursorShape: The new cursor shape type id. + * \param cursorShape: The new cursor shape type id. * \return Indication of success. */ virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0; @@ -284,11 +284,11 @@ class GHOST_IWindow { /** * Set the shape of the cursor to a custom cursor. - * \param bitmap The bitmap data for the cursor. - * \param mask The mask data for the cursor. - * \param hotX The X coordinate of the cursor hot-spot. - * \param hotY The Y coordinate of the cursor hot-spot. - * \return Indication of success. + * \param bitmap: The bitmap data for the cursor. + * \param mask: The mask data for the cursor. + * \param hotX: The X coordinate of the cursor hot-spot. + * \param hotY: The Y coordinate of the cursor hot-spot. + * \return Indication of success. */ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, @@ -300,21 +300,21 @@ class GHOST_IWindow { /** * Returns the visibility state of the cursor. - * \return The visibility state of the cursor. + * \return The visibility state of the cursor. */ virtual bool getCursorVisibility() const = 0; /** * Shows or hides the cursor. - * \param visible The new visibility state of the cursor. - * \return Indication of success. + * \param visible: The new visibility state of the cursor. + * \return Indication of success. */ virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0; /** * Grabs the cursor for a modal operation. - * \param grab The new grab state of the cursor. - * \return Indication of success. + * \param grab: The new grab state of the cursor. + * \return Indication of success. */ virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode /*mode*/, GHOST_TAxisFlag /*wrap_axis*/, @@ -340,13 +340,13 @@ class GHOST_IWindow { /** * Enable IME attached to the given window, i.e. allows user-input * events to be dispatched to the IME. - * \param x Requested x-coordinate of the rectangle - * \param y Requested y-coordinate of the rectangle - * \param w Requested width of the rectangle - * \param h Requested height of the rectangle - * \param complete Whether or not to complete the ongoing composition - * true: Start a new composition - * false: Move the IME windows to the given position without finishing it. + * \param x: Requested x-coordinate of the rectangle. + * \param y: Requested y-coordinate of the rectangle. + * \param w: Requested width of the rectangle. + * \param h: Requested height of the rectangle. + * \param complete: Whether or not to complete the ongoing composition. + * - true: Start a new composition + * - false: Move the IME windows to the given position without finishing it. */ virtual void beginIME( GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 w, GHOST_TInt32 h, int completed) = 0; diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h index fcc9da20197..dae2a2a8cbb 100644 --- a/intern/ghost/GHOST_Rect.h +++ b/intern/ghost/GHOST_Rect.h @@ -37,10 +37,10 @@ class GHOST_Rect { public: /** * Constructs a rectangle with the given values. - * \param l requested left coordinate of the rectangle - * \param t requested top coordinate of the rectangle - * \param r requested right coordinate of the rectangle - * \param b requested bottom coordinate of the rectangle + * \param l: requested left coordinate of the rectangle. + * \param t: requested top coordinate of the rectangle. + * \param r: requested right coordinate of the rectangle. + * \param b: requested bottom coordinate of the rectangle. */ GHOST_Rect(GHOST_TInt32 l = 0, GHOST_TInt32 t = 0, GHOST_TInt32 r = 0, GHOST_TInt32 b = 0) : m_l(l), m_t(t), m_r(r), m_b(b) @@ -56,13 +56,13 @@ class GHOST_Rect { /** * Access to rectangle width. - * \return width of the rectangle + * \return width of the rectangle. */ virtual inline GHOST_TInt32 getWidth() const; /** * Access to rectangle height. - * \return height of the rectangle + * \return height of the rectangle. */ virtual inline GHOST_TInt32 getHeight() const; @@ -86,7 +86,7 @@ class GHOST_Rect { * Returns whether this rectangle is valid. * Valid rectangles are rectangles that have m_l <= m_r and m_t <= m_b. * Thus, empty rectangles are valid. - * \return boolean value (true==valid rectangle) + * \return boolean value (true==valid rectangle) */ virtual inline bool isValid() const; @@ -113,8 +113,8 @@ class GHOST_Rect { /** * Grows the rectangle to included a point. - * \param x The x-coordinate of the point. - * \param y The y-coordinate of the point. + * \param x: The x-coordinate of the point. + * \param y: The y-coordinate of the point. */ virtual inline void wrapPoint(GHOST_TInt32 &x, GHOST_TInt32 &y, @@ -124,24 +124,24 @@ class GHOST_Rect { /** * Returns whether the point is inside this rectangle. * Point on the boundary is considered inside. - * \param x x-coordinate of point to test. - * \param y y-coordinate of point to test. + * \param x: x-coordinate of point to test. + * \param y: y-coordinate of point to test. * \return boolean value (true if point is inside). */ virtual inline bool isInside(GHOST_TInt32 x, GHOST_TInt32 y) const; /** * Returns whether the rectangle is inside this rectangle. - * \param r rectangle to test. - * \return visibility (not, partially or fully visible). + * \param r: rectangle to test. + * \return visibility (not, partially or fully visible). */ virtual GHOST_TVisibility getVisibility(GHOST_Rect &r) const; /** * Sets rectangle members. * Sets rectangle members such that it is centered at the given location. - * \param cx requested center x-coordinate of the rectangle - * \param cy requested center y-coordinate of the rectangle + * \param cx: requested center x-coordinate of the rectangle. + * \param cy: requested center y-coordinate of the rectangle. */ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy); @@ -149,10 +149,10 @@ class GHOST_Rect { * Sets rectangle members. * Sets rectangle members such that it is centered at the given location, * with the width requested. - * \param cx requested center x-coordinate of the rectangle - * \param cy requested center y-coordinate of the rectangle - * \param w requested width of the rectangle - * \param h requested height of the rectangle + * \param cx: requested center x-coordinate of the rectangle. + * \param cy: requested center y-coordinate of the rectangle. + * \param w: requested width of the rectangle. + * \param h: requested height of the rectangle. */ virtual void setCenter(GHOST_TInt32 cx, GHOST_TInt32 cy, GHOST_TInt32 w, GHOST_TInt32 h); @@ -160,8 +160,8 @@ class GHOST_Rect { * Clips a rectangle. * Updates the rectangle given such that it will fit within this one. * This can result in an empty rectangle. - * \param r the rectangle to clip - * \return whether clipping has occurred + * \param r: the rectangle to clip. + * \return whether clipping has occurred */ virtual bool clip(GHOST_Rect &r) const; diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 5f0516ae121..547be04ac86 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -162,7 +162,8 @@ typedef enum { } GHOST_TDrawingContextType; typedef enum { - GHOST_kButtonMaskLeft = 0, + GHOST_kButtonMaskNone, + GHOST_kButtonMaskLeft, GHOST_kButtonMaskMiddle, GHOST_kButtonMaskRight, GHOST_kButtonMaskButton4, @@ -584,8 +585,8 @@ typedef int GHOST_TEmbedderWindowID; /** * A timer task callback routine. - * \param task The timer task object. - * \param time The current time. + * \param task: The timer task object. + * \param time: The current time. */ #ifdef __cplusplus class GHOST_ITimerTask; diff --git a/intern/ghost/intern/GHOST_Buttons.h b/intern/ghost/intern/GHOST_Buttons.h index e28fae8870c..e77bab4f2ec 100644 --- a/intern/ghost/intern/GHOST_Buttons.h +++ b/intern/ghost/intern/GHOST_Buttons.h @@ -40,15 +40,15 @@ struct GHOST_Buttons { /** * Returns the state of a single button. - * \param mask Key button to return. + * \param mask: Key button to return. * \return The state of the button (pressed == true). */ bool get(GHOST_TButtonMask mask) const; /** * Updates the state of a single button. - * \param mask Button state to update. - * \param down The new state of the button. + * \param mask: Button state to update. + * \param down: The new state of the button. */ void set(GHOST_TButtonMask mask, bool down); diff --git a/intern/ghost/intern/GHOST_CallbackEventConsumer.h b/intern/ghost/intern/GHOST_CallbackEventConsumer.h index 9a76f4b031f..0d4941907c7 100644 --- a/intern/ghost/intern/GHOST_CallbackEventConsumer.h +++ b/intern/ghost/intern/GHOST_CallbackEventConsumer.h @@ -35,8 +35,8 @@ class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer { public: /** * Constructor. - * \param eventCallback The call-back routine invoked. - * \param userData The data passed back through the call-back routine. + * \param eventCallback: The call-back routine invoked. + * \param userData: The data passed back through the call-back routine. */ GHOST_CallbackEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userData); @@ -50,7 +50,7 @@ class GHOST_CallbackEventConsumer : public GHOST_IEventConsumer { /** * This method is called by an event producer when an event is available. - * \param event The event that can be handled or ignored. + * \param event: The event that can be handled or ignored. * \return Indication as to whether the event was handled. */ bool processEvent(GHOST_IEvent *event); diff --git a/intern/ghost/intern/GHOST_Context.h b/intern/ghost/intern/GHOST_Context.h index 33eeacbb203..d07913b28c4 100644 --- a/intern/ghost/intern/GHOST_Context.h +++ b/intern/ghost/intern/GHOST_Context.h @@ -35,7 +35,7 @@ class GHOST_Context : public GHOST_IContext { public: /** * Constructor. - * \param stereoVisual Stereo visual for quad buffered stereo. + * \param stereoVisual: Stereo visual for quad buffered stereo. */ GHOST_Context(bool stereoVisual) : m_stereoVisual(stereoVisual) { @@ -50,19 +50,19 @@ class GHOST_Context : public GHOST_IContext { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess swapBuffers() = 0; /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess activateDrawingContext() = 0; /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess releaseDrawingContext() = 0; @@ -89,8 +89,8 @@ class GHOST_Context : public GHOST_IContext { virtual GHOST_TSuccess releaseNativeHandles() = 0; /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ virtual GHOST_TSuccess setSwapInterval(int /*interval*/) @@ -99,8 +99,8 @@ class GHOST_Context : public GHOST_IContext { } /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ virtual GHOST_TSuccess getSwapInterval(int &) diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index 7b1e186dede..d499ec987b0 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -50,19 +50,19 @@ class GHOST_ContextCGL : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -82,15 +82,15 @@ class GHOST_ContextCGL : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &); diff --git a/intern/ghost/intern/GHOST_ContextD3D.h b/intern/ghost/intern/GHOST_ContextD3D.h index e85516838fc..18b4a5d1286 100644 --- a/intern/ghost/intern/GHOST_ContextD3D.h +++ b/intern/ghost/intern/GHOST_ContextD3D.h @@ -38,19 +38,19 @@ class GHOST_ContextD3D : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -77,8 +77,8 @@ class GHOST_ContextD3D : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int /*interval*/) @@ -87,8 +87,8 @@ class GHOST_ContextD3D : public GHOST_Context { } /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &) diff --git a/intern/ghost/intern/GHOST_ContextEGL.h b/intern/ghost/intern/GHOST_ContextEGL.h index e5dae0d22a8..f828271d88d 100644 --- a/intern/ghost/intern/GHOST_ContextEGL.h +++ b/intern/ghost/intern/GHOST_ContextEGL.h @@ -57,19 +57,19 @@ class GHOST_ContextEGL : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -87,15 +87,15 @@ class GHOST_ContextEGL : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &intervalOut); diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h index e5654b1aed7..178c750ea99 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.h +++ b/intern/ghost/intern/GHOST_ContextGLX.h @@ -61,19 +61,19 @@ class GHOST_ContextGLX : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -91,15 +91,15 @@ class GHOST_ContextGLX : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &intervalOut); diff --git a/intern/ghost/intern/GHOST_ContextNone.h b/intern/ghost/intern/GHOST_ContextNone.h index b1ac349e4a7..46dde89794a 100644 --- a/intern/ghost/intern/GHOST_ContextNone.h +++ b/intern/ghost/intern/GHOST_ContextNone.h @@ -35,50 +35,50 @@ class GHOST_ContextNone : public GHOST_Context { /** * Dummy function - * \return Always succeeds + * \return Always succeeds */ GHOST_TSuccess swapBuffers(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess activateDrawingContext(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess releaseDrawingContext(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess updateDrawingContext(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess initializeDrawingContext(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess releaseNativeHandles(); /** * Dummy function - * \return Always succeeds + * \return Always succeeds. */ GHOST_TSuccess setSwapInterval(int interval); /** * Dummy function - * \param intervalOut Gets whatever was set by setSwapInterval - * \return Always succeeds + * \param intervalOut: Gets whatever was set by #setSwapInterval. + * \return Always succeeds. */ GHOST_TSuccess getSwapInterval(int &intervalOut); diff --git a/intern/ghost/intern/GHOST_ContextSDL.h b/intern/ghost/intern/GHOST_ContextSDL.h index ead2e91181c..8e8c91b86a3 100644 --- a/intern/ghost/intern/GHOST_ContextSDL.h +++ b/intern/ghost/intern/GHOST_ContextSDL.h @@ -61,19 +61,19 @@ class GHOST_ContextSDL : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -91,15 +91,15 @@ class GHOST_ContextSDL : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &intervalOut); diff --git a/intern/ghost/intern/GHOST_ContextWGL.h b/intern/ghost/intern/GHOST_ContextWGL.h index 087fca100e4..7367bc3baed 100644 --- a/intern/ghost/intern/GHOST_ContextWGL.h +++ b/intern/ghost/intern/GHOST_ContextWGL.h @@ -58,19 +58,19 @@ class GHOST_ContextWGL : public GHOST_Context { /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess activateDrawingContext(); /** * Release the drawing context of the calling thread. - * \return A boolean success indicator. + * \return A boolean success indicator. */ GHOST_TSuccess releaseDrawingContext(); @@ -88,15 +88,15 @@ class GHOST_ContextWGL : public GHOST_Context { GHOST_TSuccess releaseNativeHandles(); /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. - * \param intervalOut Variable to store the swap interval if it can be read. + * Gets the current swap interval for #swapBuffers. + * \param intervalOut: Variable to store the swap interval if it can be read. * \return Whether the swap interval can be read. */ GHOST_TSuccess getSwapInterval(int &intervalOut); diff --git a/intern/ghost/intern/GHOST_DisplayManager.h b/intern/ghost/intern/GHOST_DisplayManager.h index 67b9aada55f..26bc687a179 100644 --- a/intern/ghost/intern/GHOST_DisplayManager.h +++ b/intern/ghost/intern/GHOST_DisplayManager.h @@ -52,15 +52,15 @@ class GHOST_DisplayManager { /** * Returns the number of display devices on this system. - * \param numDisplays The number of displays on this system. + * \param numDisplays: The number of displays on this system. * \return Indication of success. */ virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; /** * Returns the number of display settings for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param numSettings The number of settings of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param numSettings: The number of settings of the display device with this index. * \return Indication of success. */ virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, @@ -68,9 +68,9 @@ class GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param index The setting index to be returned. - * \param setting The setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param index: The setting index to be returned. + * \param setting: The setting of the display device with this index. * \return Indication of success. */ virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, @@ -79,8 +79,8 @@ class GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, @@ -90,8 +90,8 @@ class GHOST_DisplayManager { * Changes the current setting for this display device. * The setting given to this method is matched against the available display settings. * The best match is activated (@see findMatch()). - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The setting of the display device to be matched and activated. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The setting of the display device to be matched and activated. * \return Indication of success. */ virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, @@ -102,9 +102,9 @@ class GHOST_DisplayManager { /** * Finds the best display settings match. - * \param display The index of the display device. - * \param setting The setting to match. - * \param match The optimal display setting. + * \param display: The index of the display device. + * \param setting: The setting to match. + * \param match: The optimal display setting. * \return Indication of success. */ GHOST_TSuccess findMatch(GHOST_TUns8 display, diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h index 5edd555a78b..745ad457796 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h +++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h @@ -43,14 +43,14 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { /** * Returns the number of display devices on this system. - * \param numDisplays The number of displays on this system. + * \param numDisplays: The number of displays on this system. * \return Indication of success. */ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; /** * Returns the number of display settings for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ @@ -58,9 +58,9 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param index The setting index to be returned. - * \param setting The setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param index: The setting index to be returned. + * \param setting: The setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, @@ -69,8 +69,8 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, @@ -78,8 +78,8 @@ class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager { /** * Changes the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, diff --git a/intern/ghost/intern/GHOST_DisplayManagerWin32.h b/intern/ghost/intern/GHOST_DisplayManagerWin32.h index 3392d515c16..2de866b04ec 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerWin32.h +++ b/intern/ghost/intern/GHOST_DisplayManagerWin32.h @@ -42,14 +42,14 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { /** * Returns the number of display devices on this system. - * \param numDisplays The number of displays on this system. + * \param numDisplays: The number of displays on this system. * \return Indication of success. */ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; /** * Returns the number of display settings for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ @@ -57,9 +57,9 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param index The setting index to be returned. - * \param setting The setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param index: The setting index to be returned. + * \param setting: The setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, @@ -68,8 +68,8 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, @@ -77,8 +77,8 @@ class GHOST_DisplayManagerWin32 : public GHOST_DisplayManager { /** * Changes the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.h b/intern/ghost/intern/GHOST_DisplayManagerX11.h index a36ff8d49f1..e0fc1cc1210 100644 --- a/intern/ghost/intern/GHOST_DisplayManagerX11.h +++ b/intern/ghost/intern/GHOST_DisplayManagerX11.h @@ -40,14 +40,14 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { /** * Returns the number of display devices on this system. - * \param numDisplays The number of displays on this system. + * \param numDisplays: The number of displays on this system. * \return Indication of success. */ GHOST_TSuccess getNumDisplays(GHOST_TUns8 &numDisplays) const; /** * Returns the number of display settings for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). * \param numSetting: The number of settings of the display device with this index. * \return Indication of success. */ @@ -55,9 +55,9 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param index The setting index to be returned. - * \param setting The setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param index: The setting index to be returned. + * \param setting: The setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, @@ -66,8 +66,8 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { /** * Returns the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, @@ -75,8 +75,8 @@ class GHOST_DisplayManagerX11 : public GHOST_DisplayManager { /** * Changes the current setting for this display device. - * \param display The index of the display to query with 0 <= display < getNumDisplays(). - * \param setting The current setting of the display device with this index. + * \param display: The index of the display to query with 0 <= display < getNumDisplays(). + * \param setting: The current setting of the display device with this index. * \return Indication of success. */ GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.h b/intern/ghost/intern/GHOST_DropTargetWin32.h index ecce3a68835..08e8ba11b23 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.h +++ b/intern/ghost/intern/GHOST_DropTargetWin32.h @@ -73,8 +73,8 @@ class GHOST_DropTargetWin32 : public IDropTarget { * With the modifier keys, we want to distinguish left and right keys. * Sometimes this is not possible (Windows ME for instance). Then, we want * events generated for both keys. - * \param window The window to register as drop target. - * \param system The associated system. + * \param window: The window to register as drop target. + * \param system: The associated system. */ GHOST_DropTargetWin32(GHOST_WindowWin32 *window, GHOST_SystemWin32 *system); @@ -89,14 +89,14 @@ class GHOST_DropTargetWin32 : public IDropTarget { /** * Base the effect on those allowed by the drop-source. - * \param dwAllowed Drop sources allowed drop effect. + * \param dwAllowed: Drop sources allowed drop effect. * \return The allowed drop effect. */ DWORD allowedDropEffect(DWORD dwAllowed); /** * Query DataObject for the data types it supports. - * \param pDataObject Pointer to the DataObject. + * \param pDataObject: Pointer to the DataObject. * \return GHOST data type. */ GHOST_TDragnDropTypes getGhostType(IDataObject *pDataObject); @@ -104,21 +104,21 @@ class GHOST_DropTargetWin32 : public IDropTarget { /** * Get data to pass in event. * It checks the type and calls specific functions for each type. - * \param pDataObject Pointer to the DataObject. + * \param pDataObject: Pointer to the DataObject. * \return Pointer to data. */ void *getGhostData(IDataObject *pDataObject); /** * Allocate data as file array to pass in event. - * \param pDataObject Pointer to the DataObject. + * \param pDataObject: Pointer to the DataObject. * \return Pointer to data. */ void *getDropDataAsFilenames(IDataObject *pDataObject); /** * Allocate data as string to pass in event. - * \param pDataObject Pointer to the DataObject. + * \param pDataObject: Pointer to the DataObject. * \return Pointer to data. */ void *getDropDataAsString(IDataObject *pDataObject); @@ -127,8 +127,8 @@ class GHOST_DropTargetWin32 : public IDropTarget { * Convert Unicode to ANSI, replacing uncomfortable chars with '?'. * The ANSI codepage is the system default codepage, * and can change from system to system. - * \param in LPCWSTR. - * \param out char *. Is set to NULL on failure. + * \param in: LPCWSTR. + * \param out: char *. Is set to NULL on failure. * \return 0 on failure. Else the size of the string including '\0'. */ int WideCharToANSI(LPCWSTR in, char *&out); diff --git a/intern/ghost/intern/GHOST_DropTargetX11.h b/intern/ghost/intern/GHOST_DropTargetX11.h index a96852da7bb..69f6fec7ac1 100644 --- a/intern/ghost/intern/GHOST_DropTargetX11.h +++ b/intern/ghost/intern/GHOST_DropTargetX11.h @@ -34,8 +34,8 @@ class GHOST_DropTargetX11 { /** * Constructor * - * \param window The window to register as drop target. - * \param system The associated system. + * \param window: The window to register as drop target. + * \param system: The associated system. */ GHOST_DropTargetX11(GHOST_WindowX11 *window, GHOST_SystemX11 *system); @@ -52,9 +52,9 @@ class GHOST_DropTargetX11 { /** * Get data to pass in event. * It checks the type and calls specific functions for each type. - * \param dropType - type of dropped entity. - * \param dropBuffer - buffer returned from source application - * \param dropBufferSize - size of returned buffer + * \param dropType: Type of dropped entity. + * \param dropBuffer: Buffer returned from source application. + * \param dropBufferSize: Size of returned buffer. * \return Pointer to data. */ void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize); @@ -73,25 +73,25 @@ class GHOST_DropTargetX11 { void Uninitialize(void); /** - * Get data to be passed to event from text/uri-list mime type - * \param dropBuffer - buffer returned from source application - * \param dropBufferSize - size of dropped buffer - * \return pointer to newly created GHOST data + * Get data to be passed to event from text/URI-list mime type + * \param dropBuffer: Buffer returned from source application. + * \param dropBufferSize: Size of dropped buffer. + * \return pointer to newly created GHOST data. */ void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize); /** - * Decode URL (i.e. converts "file:///a%20b/test" to "file:///a b/test") - * \param decodedOut - buffer for decoded URL - * \param bufferSize - size of output buffer - * \param encodedIn - input encoded buffer to be decoded + * Decode URL (i.e. converts `file:///a%20b/test` to `file:///a b/test`) + * \param decodedOut: - buffer for decoded URL. + * \param bufferSize: - size of output buffer. + * \param encodedIn: - input encoded buffer to be decoded. */ void UrlDecode(char *decodedOut, int bufferSize, const char *encodedIn); /** - * Fully decode file URL (i.e. converts "file:///a%20b/test" to "/a b/test") - * \param fileUrl - file path URL to be fully decoded - * \return decoded file path (result should be free-d) + * Fully decode file URL (i.e. converts `file:///a%20b/test` to `/a b/test`) + * \param fileUrl: - file path URL to be fully decoded. + * \return decoded file path (result should be free-d). */ char *FileUrlDecode(char *fileUrl); diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h index 845d62fa810..5016ca0e117 100644 --- a/intern/ghost/intern/GHOST_Event.h +++ b/intern/ghost/intern/GHOST_Event.h @@ -33,9 +33,9 @@ class GHOST_Event : public GHOST_IEvent { public: /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of this event. - * \param window The generating window (or NULL if system event). + * \param msec: The time this event was generated. + * \param type: The type of this event. + * \param window: The generating window (or NULL if system event). */ GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window) : m_type(type), m_time(msec), m_window(window), m_data(NULL) diff --git a/intern/ghost/intern/GHOST_EventButton.h b/intern/ghost/intern/GHOST_EventButton.h index 7072e0c5409..02804efdcba 100644 --- a/intern/ghost/intern/GHOST_EventButton.h +++ b/intern/ghost/intern/GHOST_EventButton.h @@ -34,21 +34,19 @@ class GHOST_EventButton : public GHOST_Event { public: /** * Constructor. - * \param time The time this event was generated. - * \param type The type of this event. - * \param window The window of this event. - * \param button The state of the buttons were at the time of the event. - * \param tablet The tablet data associated with this event. + * \param time: The time this event was generated. + * \param type: The type of this event. + * \param window: The window of this event. + * \param button: The state of the buttons were at the time of the event. + * \param tablet: The tablet data associated with this event. */ GHOST_EventButton(GHOST_TUns64 time, GHOST_TEventType type, GHOST_IWindow *window, GHOST_TButtonMask button, const GHOST_TabletData &tablet) - : GHOST_Event(time, type, window) + : GHOST_Event(time, type, window), m_buttonEventData({button, tablet}) { - m_buttonEventData.button = button; - m_buttonEventData.tablet = tablet; m_data = &m_buttonEventData; } diff --git a/intern/ghost/intern/GHOST_EventCursor.h b/intern/ghost/intern/GHOST_EventCursor.h index ba85cd74723..d83ff6af6ce 100644 --- a/intern/ghost/intern/GHOST_EventCursor.h +++ b/intern/ghost/intern/GHOST_EventCursor.h @@ -33,11 +33,11 @@ class GHOST_EventCursor : public GHOST_Event { public: /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of this event. - * \param x The x-coordinate of the location the cursor was at the time of the event. - * \param y The y-coordinate of the location the cursor was at the time of the event. - * \param tablet The tablet data associated with this event. + * \param msec: The time this event was generated. + * \param type: The type of this event. + * \param x: The x-coordinate of the location the cursor was at the time of the event. + * \param y: The y-coordinate of the location the cursor was at the time of the event. + * \param tablet: The tablet data associated with this event. */ GHOST_EventCursor(GHOST_TUns64 msec, GHOST_TEventType type, @@ -45,11 +45,8 @@ class GHOST_EventCursor : public GHOST_Event { GHOST_TInt32 x, GHOST_TInt32 y, const GHOST_TabletData &tablet) - : GHOST_Event(msec, type, window) + : GHOST_Event(msec, type, window), m_cursorEventData({x, y, tablet}) { - m_cursorEventData.x = x; - m_cursorEventData.y = y; - m_cursorEventData.tablet = tablet; m_data = &m_cursorEventData; } diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h index 10975792993..a86b8302bf5 100644 --- a/intern/ghost/intern/GHOST_EventDragnDrop.h +++ b/intern/ghost/intern/GHOST_EventDragnDrop.h @@ -64,13 +64,13 @@ class GHOST_EventDragnDrop : public GHOST_Event { public: /** * Constructor. - * \param time The time this event was generated. - * \param type The type of this event. - * \param dataType The type of the drop candidate object - * \param window The window where the event occurred - * \param x The x-coordinate of the location the cursor was at the time of the event. - * \param y The y-coordinate of the location the cursor was at the time of the event. - * \param data The "content" dropped in the window + * \param time: The time this event was generated. + * \param type: The type of this event. + * \param dataType: The type of the drop candidate object. + * \param window: The window where the event occurred. + * \param x: The x-coordinate of the location the cursor was at the time of the event. + * \param y: The y-coordinate of the location the cursor was at the time of the event. + * \param data: The "content" dropped in the window. */ GHOST_EventDragnDrop(GHOST_TUns64 time, GHOST_TEventType type, diff --git a/intern/ghost/intern/GHOST_EventKey.h b/intern/ghost/intern/GHOST_EventKey.h index cb71b452d80..1e6a3284a51 100644 --- a/intern/ghost/intern/GHOST_EventKey.h +++ b/intern/ghost/intern/GHOST_EventKey.h @@ -35,9 +35,9 @@ class GHOST_EventKey : public GHOST_Event { public: /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of key event. - * \param key The key code of the key. + * \param msec: The time this event was generated. + * \param type: The type of key event. + * \param key: The key code of the key. */ GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, @@ -55,10 +55,10 @@ class GHOST_EventKey : public GHOST_Event { /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of key event. - * \param key The key code of the key. - * \param ascii The ascii code for the key event. + * \param msec: The time this event was generated. + * \param type: The type of key event. + * \param key: The key code of the key. + * \param ascii: The ascii code for the key event. */ GHOST_EventKey(GHOST_TUns64 msec, GHOST_TEventType type, diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h index befbdc72a5c..a372eb96a99 100644 --- a/intern/ghost/intern/GHOST_EventManager.h +++ b/intern/ghost/intern/GHOST_EventManager.h @@ -57,7 +57,7 @@ class GHOST_EventManager { /** * Returns the number of events of a certain type currently on the stack. - * \param type The type of events to be counted. + * \param type: The type of events to be counted. * \return The number of events on the stack of this type. */ GHOST_TUns32 getNumEvents(GHOST_TEventType type); @@ -66,7 +66,7 @@ class GHOST_EventManager { * Pushes an event on the stack. * To dispatch it, call dispatchEvent() or dispatchEvents(). * Do not delete the event! - * \param event The event to push on the stack. + * \param event: The event to push on the stack. */ GHOST_TSuccess pushEvent(GHOST_IEvent *event); @@ -89,30 +89,30 @@ class GHOST_EventManager { /** * Adds a consumer to the list of event consumers. - * \param consumer The consumer added to the list. + * \param consumer: The consumer added to the list. * \return Indication as to whether addition has succeeded. */ GHOST_TSuccess addConsumer(GHOST_IEventConsumer *consumer); /** * Removes a consumer from the list of event consumers. - * \param consumer The consumer removed from the list. + * \param consumer: The consumer removed from the list. * \return Indication as to whether removal has succeeded. */ GHOST_TSuccess removeConsumer(GHOST_IEventConsumer *consumer); /** * Removes all events for a window from the stack. - * \param window The window to remove events for. + * \param window: The window to remove events for. */ void removeWindowEvents(GHOST_IWindow *window); /** * Removes all events of a certain type from the stack. - * The window parameter is optional. If non-null, the routine will remove - * events only associated with that window. - * \param type The type of events to be removed. - * \param window The window to remove the events for. + * The window parameter is optional. + * If non-null, the routine will remove events only associated with that window. + * \param type: The type of events to be removed. + * \param window: The window to remove the events for. */ void removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window = NULL); diff --git a/intern/ghost/intern/GHOST_EventPrinter.h b/intern/ghost/intern/GHOST_EventPrinter.h index 42de4da5ee5..96d0b9acf2d 100644 --- a/intern/ghost/intern/GHOST_EventPrinter.h +++ b/intern/ghost/intern/GHOST_EventPrinter.h @@ -34,7 +34,7 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer { public: /** * Prints all the events received to std out. - * \param event The event that can be handled or not. + * \param event: The event that can be handled or not. * \return Indication as to whether the event was handled. */ bool processEvent(GHOST_IEvent *event); @@ -42,8 +42,8 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer { protected: /** * Converts GHOST key code to a readable string. - * \param key The GHOST key code to convert. - * \param str The GHOST key code converted to a readable string. + * \param key: The GHOST key code to convert. + * \param str: The GHOST key code converted to a readable string. */ void getKeyString(GHOST_TKey key, char str[32]) const; }; diff --git a/intern/ghost/intern/GHOST_EventString.h b/intern/ghost/intern/GHOST_EventString.h index 8cd24a8a78b..6dd2ffb2e86 100644 --- a/intern/ghost/intern/GHOST_EventString.h +++ b/intern/ghost/intern/GHOST_EventString.h @@ -33,10 +33,10 @@ class GHOST_EventString : public GHOST_Event { public: /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of this event. - * \param window The generating window (or NULL if system event). - * \param data_ptr Pointer to the (unformatted) data associated with the event + * \param msec: The time this event was generated. + * \param type: The type of this event. + * \param window: The generating window (or NULL if system event). + * \param data_ptr: Pointer to the (un-formatted) data associated with the event. */ GHOST_EventString(GHOST_TUns64 msec, GHOST_TEventType type, diff --git a/intern/ghost/intern/GHOST_EventTrackpad.h b/intern/ghost/intern/GHOST_EventTrackpad.h index a22f8a34fad..3bbb29821a1 100644 --- a/intern/ghost/intern/GHOST_EventTrackpad.h +++ b/intern/ghost/intern/GHOST_EventTrackpad.h @@ -33,11 +33,11 @@ class GHOST_EventTrackpad : public GHOST_Event { public: /** * Constructor. - * \param msec The time this event was generated. + * \param msec: The time this event was generated. * \param window: The window of this event. - * \param subtype The subtype of the event. - * \param x The x-delta of the pan event. - * \param y The y-delta of the pan event. + * \param subtype: The subtype of the event. + * \param x: The x-delta of the pan event. + * \param y: The y-delta of the pan event. */ GHOST_EventTrackpad(GHOST_TUns64 msec, GHOST_IWindow *window, diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h index 24b42c08e8a..e9e688b76ab 100644 --- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.h +++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.h @@ -44,8 +44,8 @@ class GHOST_IXrGraphicsBinding { * Does __not__ require this object is initialized (can be called prior to * #initFromGhostContext). It's actually meant to be called first. * - * \param r_requirement_info Return argument to retrieve an informal string on the requirements - * to be met. Useful for error/debug messages. + * \param r_requirement_info: Return argument to retrieve an informal string on the requirements. + * to be met. Useful for error/debug messages. */ virtual bool checkVersionRequirements(class GHOST_Context &ghost_ctx, XrInstance instance, diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index 74698d50659..63ecfd96cb8 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -40,9 +40,9 @@ class GHOST_EventIME : public GHOST_Event { public: /** * Constructor. - * \param msec The time this event was generated. - * \param type The type of key event. - * \param key The key code of the key. + * \param msec: The time this event was generated. + * \param type: The type of key event. + * \param key: The key code of the key. */ GHOST_EventIME(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window, void *customdata) : GHOST_Event(msec, type, window) diff --git a/intern/ghost/intern/GHOST_ModifierKeys.h b/intern/ghost/intern/GHOST_ModifierKeys.h index c41ce8b7f39..e94ccef08c0 100644 --- a/intern/ghost/intern/GHOST_ModifierKeys.h +++ b/intern/ghost/intern/GHOST_ModifierKeys.h @@ -40,7 +40,7 @@ struct GHOST_ModifierKeys { /** * Returns the modifier key's key code from a modifier key mask. - * \param mask The mask of the modifier key. + * \param mask: The mask of the modifier key. * \return The modifier key's key code. */ static GHOST_TKey getModifierKeyCode(GHOST_TModifierKeyMask mask); diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h index d5b23d76016..279f90b9641 100644 --- a/intern/ghost/intern/GHOST_System.h +++ b/intern/ghost/intern/GHOST_System.h @@ -79,12 +79,14 @@ class GHOST_System : public GHOST_ISystem { /** * Installs a timer. - * Note that, on most operating systems, messages need to be processed in order + * + * \note On most operating systems, messages need to be processed in order * for the timer callbacks to be invoked. - * \param delay The time to wait for the first call to the timerProc (in milliseconds) - * \param interval The interval between calls to the timerProc - * \param timerProc The callback invoked when the interval expires, - * \param userData Placeholder for user data. + * + * \param delay: The time to wait for the first call to the #timerProc (in milliseconds). + * \param interval: The interval between calls to the #timerProc. + * \param timerProc: The callback invoked when the interval expires. + * \param userData: Placeholder for user data. * \return A timer task (0 if timer task installation failed). */ GHOST_ITimerTask *installTimer(GHOST_TUns64 delay, @@ -94,7 +96,7 @@ class GHOST_System : public GHOST_ISystem { /** * Removes a timer. - * \param timerTask Timer task to be removed. + * \param timerTask: Timer task to be removed. * \return Indication of success. */ GHOST_TSuccess removeTimer(GHOST_ITimerTask *timerTask); @@ -105,32 +107,32 @@ class GHOST_System : public GHOST_ISystem { /** * Dispose a window. - * \param window Pointer to the window to be disposed. - * \return Indication of success. + * \param window: Pointer to the window to be disposed. + * \return Indication of success. */ GHOST_TSuccess disposeWindow(GHOST_IWindow *window); /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ virtual GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings) = 0; /** * Returns whether a window is valid. - * \param window Pointer to the window to be checked. - * \return Indication of validity. + * \param window: Pointer to the window to be checked. + * \return Indication of validity. */ bool validWindow(GHOST_IWindow *window); /** * Begins full screen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. - * \param stereoVisual Stereo visual for quad buffered stereo. + * \param setting: The new setting of the display. + * \param window: Window displayed in full screen. + * \param stereoVisual: Stereo visual for quad buffered stereo. * This window is invalid after full screen has been ended. - * \return Indication of success. + * \return Indication of success. */ GHOST_TSuccess beginFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window, @@ -139,16 +141,16 @@ class GHOST_System : public GHOST_ISystem { /** * Updates the resolution while in fullscreen mode. - * \param setting The new setting of the display. - * \param window Window displayed in full screen. + * \param setting: The new setting of the display. + * \param window: Window displayed in full screen. * - * \return Indication of success. + * \return Indication of success. */ GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting &setting, GHOST_IWindow **window); /** * Ends full screen mode. - * \return Indication of success. + * \return Indication of success. */ GHOST_TSuccess endFullScreen(void); @@ -189,14 +191,14 @@ class GHOST_System : public GHOST_ISystem { /** * Adds the given event consumer to our list. - * \param consumer The event consumer to add. + * \param consumer: The event consumer to add. * \return Indication of success. */ GHOST_TSuccess addEventConsumer(GHOST_IEventConsumer *consumer); /** * Remove the given event consumer to our list. - * \param consumer The event consumer to remove. + * \param consumer: The event consumer to remove. * \return Indication of success. */ GHOST_TSuccess removeEventConsumer(GHOST_IEventConsumer *consumer); @@ -219,25 +221,25 @@ class GHOST_System : public GHOST_ISystem { /** * Returns the state of a modifier key (outside the message queue). - * \param mask The modifier key state to retrieve. - * \param isDown The state of a modifier key (true == pressed). - * \return Indication of success. + * \param mask: The modifier key state to retrieve. + * \param isDown: The state of a modifier key (true == pressed). + * \return Indication of success. */ GHOST_TSuccess getModifierKeyState(GHOST_TModifierKeyMask mask, bool &isDown) const; /** * Returns the state of a mouse button (outside the message queue). - * \param mask The button state to retrieve. - * \param isDown Button state. - * \return Indication of success. + * \param mask: The button state to retrieve. + * \param isDown: Button state. + * \return Indication of success. */ GHOST_TSuccess getButtonState(GHOST_TButtonMask mask, bool &isDown) const; /** * Set which tablet API to use. Only affects Windows, other platforms have a single API. - * \param api Enum indicating which API to use. + * \param api: Enum indicating which API to use. */ - void setTabletAPI(GHOST_TTabletAPI api); + virtual void setTabletAPI(GHOST_TTabletAPI api); GHOST_TTabletAPI getTabletAPI(void); #ifdef WITH_INPUT_NDOF @@ -260,7 +262,7 @@ class GHOST_System : public GHOST_ISystem { * Pushes an event on the stack. * To dispatch it, call dispatchEvent() or dispatchEvents(). * Do not delete the event! - * \param event The event to push on the stack. + * \param event: The event to push on the stack. */ GHOST_TSuccess pushEvent(GHOST_IEvent *event); @@ -288,41 +290,41 @@ class GHOST_System : public GHOST_ISystem { /** * Returns the state of all modifier keys. - * \param keys The state of all modifier keys (true == pressed). - * \return Indication of success. + * \param keys: The state of all modifier keys (true == pressed). + * \return Indication of success. */ virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const = 0; /** * Returns the state of the mouse buttons (outside the message queue). - * \param buttons The state of the buttons. - * \return Indication of success. + * \param buttons: The state of the buttons. + * \return Indication of success. */ virtual GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const = 0; /** * Returns the selection buffer - * \param selection Only used on X11 - * \return Returns the clipboard data + * \param selection: Only used on X11. + * \return Returns the clipboard data * */ virtual GHOST_TUns8 *getClipboard(bool selection) const = 0; /** * Put data to the Clipboard - * \param buffer The buffer to copy to the clipboard - * \param selection The clipboard to copy too only used on X11 + * \param buffer: The buffer to copy to the clipboard. + * \param selection: The clipboard to copy too only used on X11. */ virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const = 0; /** * Show a system message box - * \param title The title of the message box - * \param message The message to display - * \param help_label Help button label - * \param continue_label Continue button label - * \param link An optional hyperlink - * \param dialog_options Options how to display the message + * \param title: The title of the message box. + * \param message: The message to display. + * \param help_label: Help button label. + * \param continue_label: Continue button label. + * \param link: An optional hyperlink. + * \param dialog_options: Options how to display the message. */ virtual GHOST_TSuccess showMessageBox(const char * /*title*/, const char * /*message*/, @@ -363,7 +365,7 @@ class GHOST_System : public GHOST_ISystem { /** * Creates a fullscreen window. - * \param window The window created. + * \param window: The window created. * \return Indication of success. */ GHOST_TSuccess createFullScreenWindow(GHOST_Window **window, diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 22f3c58d297..5637dfb0565 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -85,19 +85,19 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Create a new window. * The new window is added to the list of windows managed. - * Never explicitly delete the window, use disposeWindow() instead. - * \param title The name of the window + * Never explicitly delete the window, use #disposeWindow() instead. + * \param title: The name of the window. * (displayed in the title bar of the window if the OS supports it). - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state of the window when opened. - * \param type The type of drawing context installed in this window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state of the window when opened. + * \param type: The type of drawing context installed in this window. * \param glSettings: Misc OpenGL settings. * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent (embedder) window - * \return The new window (or 0 if creation failed). + * \param parentWindow: Parent (embedder) window. + * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, GHOST_TInt32 left, @@ -114,14 +114,14 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings); /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess disposeContext(GHOST_IContext *context); @@ -131,7 +131,7 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Gets events from the system and stores them in the queue. - * \param waitForEvent Flag to wait for an event (or return immediately). + * \param waitForEvent: Flag to wait for an event (or return immediately). * \return Indication of the presence of events. */ bool processEvents(bool waitForEvent); @@ -150,12 +150,12 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Handles a drag'n'drop destination event. Called by GHOST_WindowCocoa window subclass - * \param eventType The type of drag'n'drop event - * \param draggedObjectType The type object concerned - * (currently array of file names, string, TIFF image) - * \param mouseX x mouse coordinate (in cocoa base window coordinates) - * \param mouseY y mouse coordinate - * \param window The window on which the event occurred + * \param eventType: The type of drag'n'drop event. + * \param draggedObjectType: The type object concerned. + * (currently array of file names, string, TIFF image). + * \param mouseX: x mouse coordinate (in cocoa base window coordinates). + * \param mouseY: y mouse coordinate. + * \param window: The window on which the event occurred. * \return Indication whether the event was handled. */ GHOST_TSuccess handleDraggingEvent(GHOST_TEventType eventType, @@ -171,17 +171,17 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Returns the current location of the cursor (location in screen coordinates) - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; /** * Updates the location of the cursor (location in screen coordinates). - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); @@ -191,36 +191,36 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Returns the state of all modifier keys. - * \param keys The state of all modifier keys (true == pressed). - * \return Indication of success. + * \param keys: The state of all modifier keys (true == pressed). + * \return Indication of success. */ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const; /** * Returns the state of the mouse buttons (outside the message queue). - * \param buttons The state of the buttons. - * \return Indication of success. + * \param buttons: The state of the buttons. + * \return Indication of success. */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; /** * Returns Clipboard data - * \param selection Indicate which buffer to return - * \return Returns the selected buffer + * \param selection: Indicate which buffer to return. + * \return Returns the selected buffer */ GHOST_TUns8 *getClipboard(bool selection) const; /** * Puts buffer to system clipboard - * \param buffer The buffer to be copied - * \param selection Indicates which buffer to copy too, only used on X11 + * \param buffer: The buffer to be copied. + * \param selection: Indicates which buffer to copy too, only used on X11. */ void putClipboard(GHOST_TInt8 *buffer, bool selection) const; /** * Handles a window event. Called by GHOST_WindowCocoa window delegate - * \param eventType The type of window event - * \param window The window on which the event occurred + * \param eventType: The type of window event. + * \param window: The window on which the event occurred. * \return Indication whether the event was handled. */ GHOST_TSuccess handleWindowEvent(GHOST_TEventType eventType, GHOST_WindowCocoa *window); @@ -284,9 +284,9 @@ class GHOST_SystemCocoa : public GHOST_System { /** * Performs the actual cursor position update (location in screen coordinates). - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 152dae48905..19753bca2c7 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -763,7 +763,7 @@ GHOST_IWindow *GHOST_SystemCocoa::createWindow(const char *title, /** * Create a new offscreen context. * Never explicitly delete the context, use #disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSettings) { @@ -778,8 +778,8 @@ GHOST_IContext *GHOST_SystemCocoa::createOffscreenContext(GHOST_GLSettings glSet /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess GHOST_SystemCocoa::disposeContext(GHOST_IContext *context) { diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index b1e2502fa78..8178b9bdf1e 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -234,6 +234,11 @@ GHOST_SystemWin32::~GHOST_SystemWin32() toggleConsole(1); } +GHOST_TUns64 GHOST_SystemWin32::millisSinceStart(__int64 ms) const +{ + return (GHOST_TUns64)(ms - m_start * 1000 / m_freq); +} + GHOST_TUns64 GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const { // Calculate the time passed since system initialization. @@ -417,8 +422,8 @@ finished: /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess GHOST_SystemWin32::disposeContext(GHOST_IContext *context) { @@ -941,23 +946,137 @@ GHOST_EventButton *GHOST_SystemWin32::processButtonEvent(GHOST_TEventType type, window->updateMouseCapture(MouseReleased); } - if (window->m_tabletInRange) { - if (window->useTabletAPI(GHOST_kTabletNative)) { - // Win32 Pointer processing handles input while in-range and in-contact events. - return NULL; - } + /* 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, window->getTabletData()); + system->getMilliSeconds(), type, window, mask, GHOST_TABLET_DATA_NONE); +} + +GHOST_TSuccess GHOST_SystemWin32::processWintabEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TButtonMask mask, + bool mousePressed) +{ + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); + + /* 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; + } + + 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_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)); + 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_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::processPointerEvents( +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; } @@ -982,7 +1101,7 @@ void GHOST_SystemWin32::processPointerEvents( pointerInfo[0].tabletData)); break; case WM_POINTERDOWN: - // Move cursor to point of contact because GHOST_EventButton does not include position. + /* Move cursor to point of contact because GHOST_EventButton does not include position. */ system->pushEvent(new GHOST_EventCursor(pointerInfo[0].time, GHOST_kEventCursorMove, window, @@ -997,8 +1116,8 @@ void GHOST_SystemWin32::processPointerEvents( window->updateMouseCapture(MousePressed); break; case WM_POINTERUPDATE: - // Coalesced pointer events are reverse chronological order, reorder chronologically. - // Only contiguous move events are coalesced. + /* Coalesced pointer events are reverse chronological order, reorder chronologically. + * Only contiguous move events are coalesced. */ for (GHOST_TUns32 i = pointerInfo.size(); i-- > 0;) { system->pushEvent(new GHOST_EventCursor(pointerInfo[i].time, GHOST_kEventCursorMove, @@ -1018,11 +1137,6 @@ void GHOST_SystemWin32::processPointerEvents( break; case WM_POINTERLEAVE: window->m_tabletInRange = false; - system->pushEvent(new GHOST_EventButton(pointerInfo[0].time, - GHOST_kEventCursorMove, - window, - pointerInfo[0].buttonMask, - pointerInfo[0].tabletData)); break; default: break; @@ -1037,13 +1151,21 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind GHOST_TInt32 x_screen, y_screen; GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)getSystem(); - if (window->m_tabletInRange) { - if (window->useTabletAPI(GHOST_kTabletNative)) { - // Tablet input handled in WM_POINTER* events. WM_MOUSEMOVE events in response to tablet - // input aren't normally generated when using WM_POINTER events, but manually moving the - // system cursor as we do in WM_POINTER handling does. + 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; } + + /* If using Wintab but no button event is currently active, + * fall through to default handling. */ } system->getCursorPosition(x_screen, y_screen); @@ -1076,7 +1198,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window, x_screen + x_accum, y_screen + y_accum, - window->getTabletData()); + GHOST_TABLET_DATA_NONE); } } else { @@ -1085,7 +1207,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window, x_screen, y_screen, - window->getTabletData()); + GHOST_TABLET_DATA_NONE); } return NULL; } @@ -1202,7 +1324,6 @@ GHOST_Event *GHOST_SystemWin32::processWindowEvent(GHOST_TEventType type, if (type == GHOST_kEventWindowActivate) { system->getWindowManager()->setActiveWindow(window); - window->bringTabletContextToFront(); } return new GHOST_Event(system->getMilliSeconds(), type, window); @@ -1230,6 +1351,20 @@ GHOST_TSuccess GHOST_SystemWin32::pushDragDropEvent(GHOST_TEventType eventType, system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data)); } +void GHOST_SystemWin32::setTabletAPI(GHOST_TTabletAPI api) +{ + GHOST_System::setTabletAPI(api); + + GHOST_WindowManager *wm = getWindowManager(); + GHOST_WindowWin32 *activeWindow = (GHOST_WindowWin32 *)wm->getActiveWindow(); + + for (GHOST_IWindow *win : wm->getWindows()) { + GHOST_WindowWin32 *windowsWindow = (GHOST_WindowWin32 *)win; + windowsWindow->updateWintab(windowsWindow == activeWindow, + !::IsIconic(windowsWindow->getHWND())); + } +} + void GHOST_SystemWin32::processMinMaxInfo(MINMAXINFO *minmax) { minmax->ptMinTrackSize.x = 320; @@ -1467,14 +1602,19 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, } break; //////////////////////////////////////////////////////////////////////// - // Tablet events, processed + // Wintab events, processed //////////////////////////////////////////////////////////////////////// - case WT_PACKET: - window->processWin32TabletEvent(wParam, lParam); + case WT_INFOCHANGE: { + window->processWintabInfoChangeEvent(lParam); + break; + } + case WT_PROXIMITY: { + bool inRange = LOWORD(lParam); + window->processWintabProximityEvent(inRange); break; - case WT_CSRCHANGE: - case WT_PROXIMITY: - window->processWin32TabletInitEvent(); + } + case WT_PACKET: + window->updatePendingWintabEvents(); break; //////////////////////////////////////////////////////////////////////// // Pointer events, processed @@ -1484,7 +1624,7 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, case WM_POINTERUPDATE: case WM_POINTERUP: case WM_POINTERLEAVE: - processPointerEvents(msg, window, wParam, lParam, eventHandled); + processPointerEvent(msg, window, wParam, lParam, eventHandled); break; //////////////////////////////////////////////////////////////////////// // Mouse events, processed @@ -1614,7 +1754,9 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, * will not be dispatched to OUR active window if we minimize one of OUR windows. */ if (LOWORD(wParam) == WA_INACTIVE) window->lostMouseCapture(); - window->processWin32TabletActivateEvent(GET_WM_ACTIVATE_STATE(wParam, lParam)); + + window->updateWintab(LOWORD(wParam) != WA_INACTIVE, !::IsIconic(window->getHWND())); + lResult = ::DefWindowProc(hwnd, msg, wParam, lParam); break; } @@ -1672,6 +1814,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, 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; case WM_CAPTURECHANGED: window->lostMouseCapture(); @@ -1722,6 +1872,12 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam, SWP_NOZORDER | SWP_NOACTIVATE); } break; + case WM_DISPLAYCHANGE: + for (GHOST_IWindow *iter_win : system->getWindowManager()->getWindows()) { + GHOST_WindowWin32 *iter_win32win = (GHOST_WindowWin32 *)iter_win; + iter_win32win->processWintabDisplayChangeEvent(); + } + break; //////////////////////////////////////////////////////////////////////// // Window events, ignored //////////////////////////////////////////////////////////////////////// @@ -1915,6 +2071,7 @@ void GHOST_SystemWin32::putClipboard(GHOST_TInt8 *buffer, bool selection) const } } +/* -------------------------------------------------------------------- */ /** \name Message Box * \{ */ GHOST_TSuccess GHOST_SystemWin32::showMessageBox(const char *title, diff --git a/intern/ghost/intern/GHOST_SystemWin32.h b/intern/ghost/intern/GHOST_SystemWin32.h index b91a9d7a154..00b626511ab 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.h +++ b/intern/ghost/intern/GHOST_SystemWin32.h @@ -64,6 +64,8 @@ class GHOST_SystemWin32 : public GHOST_System { ** Time(r) functionality ***************************************************************************************/ + GHOST_TUns64 millisSinceStart(__int64 ms) const; + /** * This method converts performance counter measurements into milliseconds since the start of the * system process. @@ -111,19 +113,19 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Create a new window. * The new window is added to the list of windows managed. - * Never explicitly delete the window, use disposeWindow() instead. - * \param title The name of the window + * Never explicitly delete the window, use #disposeWindow() instead. + * \param title: The name of the window. * (displayed in the title bar of the window if the OS supports it). - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state of the window when opened. - * \param type The type of drawing context installed in this window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state of the window when opened. + * \param type: The type of drawing context installed in this window. * \param glSettings: Misc OpenGL settings. * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent window - * \return The new window (or 0 if creation failed). + * \param parentWindow: Parent window. + * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, GHOST_TInt32 left, @@ -140,14 +142,14 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Create a new offscreen context. * Never explicitly delete the window, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings); /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess disposeContext(GHOST_IContext *context); @@ -156,15 +158,15 @@ class GHOST_SystemWin32 : public GHOST_System { * Never explicitly delete the context, use disposeContext() instead. * This is for GHOST internal, Win32 specific use, so it can be called statically. * - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ static GHOST_ContextD3D *createOffscreenContextD3D(); /** * Dispose of a DirectX context. * This is for GHOST internal, Win32 specific use, so it can be called statically. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ static GHOST_TSuccess disposeContextD3D(GHOST_ContextD3D *context); @@ -174,7 +176,7 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Gets events from the system and stores them in the queue. - * \param waitForEvent Flag to wait for an event (or return immediately). + * \param waitForEvent: Flag to wait for an event (or return immediately). * \return Indication of the presence of events. */ bool processEvents(bool waitForEvent); @@ -185,17 +187,17 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Returns the current location of the cursor (location in screen coordinates) - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ GHOST_TSuccess getCursorPosition(GHOST_TInt32 &x, GHOST_TInt32 &y) const; /** * Updates the location of the cursor (location in screen coordinates). - * \param x The x-coordinate of the cursor. - * \param y The y-coordinate of the cursor. - * \return Indication of success. + * \param x: The x-coordinate of the cursor. + * \param y: The y-coordinate of the cursor. + * \return Indication of success. */ GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y); @@ -205,40 +207,40 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Returns the state of all modifier keys. - * \param keys The state of all modifier keys (true == pressed). - * \return Indication of success. + * \param keys: The state of all modifier keys (true == pressed). + * \return Indication of success. */ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const; /** * Returns the state of the mouse buttons (outside the message queue). - * \param buttons The state of the buttons. - * \return Indication of success. + * \param buttons: The state of the buttons. + * \return Indication of success. */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; /** * Returns unsigned char from CUT_BUFFER0 - * \param selection Used by X11 only - * \return Returns the Clipboard + * \param selection: Used by X11 only. + * \return Returns the Clipboard. */ GHOST_TUns8 *getClipboard(bool selection) const; /** - * Puts buffer to system clipboard - * \param selection Used by X11 only - * \return No return + * Puts buffer to system clipboard. + * \param selection: Used by X11 only. + * \return No return. */ void putClipboard(GHOST_TInt8 *buffer, bool selection) const; /** * Show a system message box - * \param title The title of the message box - * \param message The message to display - * \param help_label Help button label - * \param continue_label Continue button label - * \param link An optional hyperlink - * \param dialog_options Options how to display the message + * \param title: The title of the message box. + * \param message: The message to display. + * \param help_label: Help button label. + * \param continue_label: Continue button label. + * \param link: An optional hyperlink. + * \param dialog_options: Options how to display the message. */ GHOST_TSuccess showMessageBox(const char *title, const char *message, @@ -265,6 +267,16 @@ class GHOST_SystemWin32 : public GHOST_System { int mouseY, void *data); + /*************************************************************************************** + ** Modify tablet API + ***************************************************************************************/ + + /** + * Set which tablet API to use. + * \param api: Enum indicating which API to use. + */ + void setTabletAPI(GHOST_TTabletAPI api) override; + protected: /** * Initializes the system. @@ -281,27 +293,27 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Converts raw WIN32 key codes from the wndproc to GHOST keys. - * \param vKey The virtual key from hardKey - * \param ScanCode The ScanCode of pressed key (similar to PS/2 Set 1) - * \param extend Flag if key is not primly (left or right) + * \param vKey: The virtual key from #hardKey. + * \param ScanCode: The ScanCode of pressed key (similar to PS/2 Set 1). + * \param extend: Flag if key is not primly (left or right). * \return The GHOST key (GHOST_kKeyUnknown if no match). */ GHOST_TKey convertKey(short vKey, short ScanCode, short extend) const; /** * Catches raw WIN32 key codes from WM_INPUT in the wndproc. - * \param raw RawInput structure with detailed info about the key event - * \param keyDown Pointer flag that specify if a key is down - * \param vk Pointer to virtual key + * \param raw: RawInput structure with detailed info about the key event. + * \param keyDown: Pointer flag that specify if a key is down. + * \param vk: Pointer to virtual key. * \return The GHOST key (GHOST_kKeyUnknown if no match). */ GHOST_TKey hardKey(RAWINPUT const &raw, bool *r_keyDown, bool *r_is_repeated_modifier); /** * Creates mouse button event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \param mask The button mask of this event. + * \param type: The type of event to create. + * \param window: The window receiving the event (the active window). + * \param mask: The button mask of this event. * \return The event created. */ static GHOST_EventButton *processButtonEvent(GHOST_TEventType type, @@ -310,34 +322,40 @@ 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 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 GHOST_TSuccess processWintabEvents(GHOST_TEventType type, GHOST_WindowWin32 *window); + static GHOST_TSuccess processWintabEvent(GHOST_TEventType type, + GHOST_WindowWin32 *window, + GHOST_TButtonMask mask, + bool mousePressed); /** * Creates tablet events from pointer events. - * \param type The type of pointer event - * \param window The window receiving the event (the active window). - * \param wParam The wParam from the wndproc - * \param lParam The lParam from the wndproc - * \param eventhandled true if the method handled the event + * \param type: The type of pointer event. + * \param window: The window receiving the event (the active window). + * \param wParam: The wParam from the wndproc. + * \param lParam: The lParam from the wndproc. + * \param eventhandled: True if the method handled the event. */ - static void processPointerEvents( + static void processPointerEvent( UINT type, GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam, bool &eventhandled); /** * Creates cursor event. - * \param window The window receiving the event (the active window). + * \param window: The window receiving the event (the active window). * \return The event created. */ static GHOST_EventCursor *processCursorEvent(GHOST_WindowWin32 *window); /** * Handles a mouse wheel event. - * \param window The window receiving the event (the active window). - * \param wParam The wParam from the wndproc - * \param lParam The lParam from the wndproc + * \param window: The window receiving the event (the active window). + * \param wParam: The wParam from the wndproc. + * \param lParam: The lParam from the wndproc. */ static void processWheelEvent(GHOST_WindowWin32 *window, WPARAM wParam, LPARAM lParam); @@ -345,23 +363,23 @@ class GHOST_SystemWin32 : public GHOST_System { * Creates a key event and updates the key data stored locally (m_modifierKeys). * In most cases this is a straightforward conversion of key codes. * For the modifier keys however, we want to distinguish left and right keys. - * \param window The window receiving the event (the active window). - * \param raw RawInput structure with detailed info about the key event + * \param window: The window receiving the event (the active window). + * \param raw: RawInput structure with detailed info about the key event. */ static GHOST_EventKey *processKeyEvent(GHOST_WindowWin32 *window, RAWINPUT const &raw); /** * Process special keys (VK_OEM_*), to see if current key layout * gives us anything special, like ! on french AZERTY. - * \param vKey The virtual key from hardKey - * \param scanCode The ScanCode of pressed key (similar to PS/2 Set 1) + * \param vKey: The virtual key from #hardKey. + * \param scanCode: The ScanCode of pressed key (similar to PS/2 Set 1). */ GHOST_TKey processSpecialKey(short vKey, short scanCode) const; /** * Creates a window event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). + * \param type: The type of event to create. + * \param window: The window receiving the event (the active window). * \return The event created. */ static GHOST_Event *processWindowEvent(GHOST_TEventType type, GHOST_WindowWin32 *window); @@ -369,9 +387,9 @@ class GHOST_SystemWin32 : public GHOST_System { #ifdef WITH_INPUT_IME /** * Creates a IME event. - * \param type The type of event to create. - * \param window The window receiving the event (the active window). - * \param data IME data. + * \param type: The type of event to create. + * \param window: The window receiving the event (the active window). + * \param data: IME data. * \return The event created. */ static GHOST_Event *processImeEvent(GHOST_TEventType type, @@ -381,7 +399,7 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Handles minimum window size. - * \param minmax The MINMAXINFO structure. + * \param minmax: The MINMAXINFO structure. */ static void processMinMaxInfo(MINMAXINFO *minmax); @@ -390,7 +408,7 @@ class GHOST_SystemWin32 : public GHOST_System { * Handles Motion and Button events from a SpaceNavigator or related device. * Instead of returning an event object, this function communicates directly * with the GHOST_NDOFManager. - * \param raw RawInput structure with detailed info about the NDOF event + * \param raw: RawInput structure with detailed info about the NDOF event. * \return Whether an event was generated and sent. */ bool processNDOF(RAWINPUT const &raw); @@ -398,7 +416,7 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Returns the local state of the modifier keys (from the message queue). - * \param keys The state of the keys. + * \param keys: The state of the keys. */ inline void retrieveModifierKeys(GHOST_ModifierKeys &keys) const; @@ -421,7 +439,7 @@ class GHOST_SystemWin32 : public GHOST_System { /** * Toggles console - * \param action + * \param action: * - 0 - Hides * - 1 - Shows * - 2 - Toggles diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 1906ec67c33..ecab61f6964 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -325,19 +325,19 @@ void GHOST_SystemX11::getAllDisplayDimensions(GHOST_TUns32 &width, GHOST_TUns32 /** * Create a new window. * The new window is added to the list of windows managed. - * Never explicitly delete the window, use disposeWindow() instead. - * \param title The name of the window + * Never explicitly delete the window, use #disposeWindow() instead. + * \param title: The name of the window * (displayed in the title bar of the window if the OS supports it). - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state of the window when opened. - * \param type The type of drawing context installed in this window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state of the window when opened. + * \param type: The type of drawing context installed in this window. * \param glSettings: Misc OpenGL settings. - * \param exclusive: Use to show the window ontop and ignore others (used fullscreen). - * \param parentWindow Parent window - * \return The new window (or 0 if creation failed). + * \param exclusive: Use to show the window on top and ignore others (used full-screen). + * \param parentWindow: Parent window. + * \return The new window (or 0 if creation failed). */ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, GHOST_TInt32 left, @@ -393,7 +393,7 @@ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings) { @@ -505,8 +505,8 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess GHOST_SystemX11::disposeContext(GHOST_IContext *context) { @@ -2284,6 +2284,7 @@ void GHOST_SystemX11::putClipboard(GHOST_TInt8 *buffer, bool selection) const } } +/* -------------------------------------------------------------------- */ /** \name Message Box * \{ */ class DialogData { diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index ee29f463fb6..3fab115afff 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -121,20 +121,19 @@ class GHOST_SystemX11 : public GHOST_System { /** * Create a new window. * The new window is added to the list of windows managed. - * Never explicitly delete the window, use disposeWindow() instead. - * \param title The name of the window + * Never explicitly delete the window, use #disposeWindow() instead. + * \param title: The name of the window. * (displayed in the title bar of the window if the OS supports it). - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state of the window when opened. - * \param type The type of drawing context installed in this window. - * \param stereoVisual Create a stereo visual for quad buffered stereo. - * \param exclusive Use to show the window ontop and ignore others - * (used fullscreen). - * \param parentWindow Parent (embedder) window - * \return The new window (or 0 if creation failed). + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state of the window when opened. + * \param type: The type of drawing context installed in this window. + * \param stereoVisual: Create a stereo visual for quad buffered stereo. + * \param exclusive: Use to show the window ontop and ignore others (used full*screen). + * \param parentWindow: Parent (embedder) window. + * \return The new window (or 0 if creation failed). */ GHOST_IWindow *createWindow(const char *title, GHOST_TInt32 left, @@ -151,20 +150,20 @@ class GHOST_SystemX11 : public GHOST_System { /** * Create a new offscreen context. * Never explicitly delete the context, use disposeContext() instead. - * \return The new context (or 0 if creation failed). + * \return The new context (or 0 if creation failed). */ GHOST_IContext *createOffscreenContext(GHOST_GLSettings glSettings); /** * Dispose of a context. - * \param context Pointer to the context to be disposed. - * \return Indication of success. + * \param context: Pointer to the context to be disposed. + * \return Indication of success. */ GHOST_TSuccess disposeContext(GHOST_IContext *context); /** * Retrieves events from the system and stores them in the queue. - * \param waitForEvent Flag to wait for an event (or return immediately). + * \param waitForEvent: Flag to wait for an event (or return immediately). * \return Indication of the presence of events. */ bool processEvents(bool waitForEvent); @@ -175,15 +174,15 @@ class GHOST_SystemX11 : public GHOST_System { /** * Returns the state of all modifier keys. - * \param keys The state of all modifier keys (true == pressed). - * \return Indication of success. + * \param keys: The state of all modifier keys (true == pressed). + * \return Indication of success. */ GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys &keys) const; /** * Returns the state of the mouse buttons (outside the message queue). - * \param buttons The state of the buttons. - * \return Indication of success. + * \param buttons: The state of the buttons. + * \return Indication of success. */ GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const; @@ -220,26 +219,26 @@ class GHOST_SystemX11 : public GHOST_System { /** * Returns unsigned char from CUT_BUFFER0 - * \param selection Get selection, X11 only feature - * \return Returns the Clipboard indicated by Flag + * \param selection: Get selection, X11 only feature. + * \return Returns the Clipboard indicated by Flag. */ GHOST_TUns8 *getClipboard(bool selection) const; /** * Puts buffer to system clipboard - * \param buffer The buffer to copy to the clipboard - * \param selection Set the selection into the clipboard, X11 only feature + * \param buffer: The buffer to copy to the clipboard. + * \param selection: Set the selection into the clipboard, X11 only feature. */ void putClipboard(GHOST_TInt8 *buffer, bool selection) const; /** * Show a system message box - * \param title The title of the message box - * \param message The message to display - * \param help_label Help button label - * \param continue_label Continue button label - * \param link An optional hyperlink - * \param dialog_options Options how to display the message + * \param title: The title of the message box. + * \param message: The message to display. + * \param help_label: Help button label. + * \param continue_label: Continue button label. + * \param link: An optional hyperlink. + * \param dialog_options: Options how to display the message. */ GHOST_TSuccess showMessageBox(const char *title, const char *message, @@ -251,12 +250,12 @@ class GHOST_SystemX11 : public GHOST_System { /** * Creates a drag'n'drop event and pushes it immediately onto the event queue. * Called by GHOST_DropTargetX11 class. - * \param eventType The type of drag'n'drop event - * \param draggedObjectType The type object concerned + * \param eventType: The type of drag'n'drop event. + * \param draggedObjectType: The type object concerned. * (currently array of file names, string, ?bitmap) - * \param mouseX x mouse coordinate (in window coordinates) - * \param mouseY y mouse coordinate - * \param window The window on which the event occurred + * \param mouseX: x mouse coordinate (in window coordinates). + * \param mouseY: y mouse coordinate. + * \param window: The window on which the event occurred. * \return Indication whether the event was handled. */ static GHOST_TSuccess pushDragDropEvent(GHOST_TEventType eventType, diff --git a/intern/ghost/intern/GHOST_TimerManager.h b/intern/ghost/intern/GHOST_TimerManager.h index 2e0f5d42230..3ca62202e5e 100644 --- a/intern/ghost/intern/GHOST_TimerManager.h +++ b/intern/ghost/intern/GHOST_TimerManager.h @@ -62,7 +62,7 @@ class GHOST_TimerManager { /** * Adds a timer task to the list. * It is only added when it not already present in the list. - * \param timer The timer task added to the list. + * \param timer: The timer task added to the list. * \return Indication as to whether addition has succeeded. */ GHOST_TSuccess addTimer(GHOST_TimerTask *timer); @@ -70,7 +70,7 @@ class GHOST_TimerManager { /** * Removes a timer task from the list. * It is only removed when it is found in the list. - * \param timer The timer task to be removed from the list. + * \param timer: The timer task to be removed from the list. * \return Indication as to whether removal has succeeded. */ GHOST_TSuccess removeTimer(GHOST_TimerTask *timer); @@ -84,15 +84,15 @@ class GHOST_TimerManager { /** * Checks all timer tasks to see if they are expired and fires them if needed. - * \param time The current time. + * \param time: The current time. * \return True if any timers were fired. */ bool fireTimers(GHOST_TUns64 time); /** * Checks this timer task to see if they are expired and fires them if needed. - * \param time The current time. - * \param task The timer task to check and optionally fire. + * \param time: The current time. + * \param task: The timer task to check and optionally fire. * \return True if the timer fired. */ bool fireTimer(GHOST_TUns64 time, GHOST_TimerTask *task); diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h index 6dc0728e19b..9c81d3d2637 100644 --- a/intern/ghost/intern/GHOST_TimerTask.h +++ b/intern/ghost/intern/GHOST_TimerTask.h @@ -33,9 +33,9 @@ class GHOST_TimerTask : public GHOST_ITimerTask { public: /** * Constructor. - * \param start The timer start time. - * \param interval The interval between calls to the timerProc - * \param timerProc The callback invoked when the interval expires. + * \param start: The timer start time. + * \param interval: The interval between calls to the #timerProc. + * \param timerProc: The callback invoked when the interval expires. * \param userData: The timer user data. */ GHOST_TimerTask(GHOST_TUns64 start, @@ -62,7 +62,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { /** * Changes the timer start time. - * \param start The timer start time. + * \param start: The timer start time. */ void setStart(GHOST_TUns64 start) { @@ -80,7 +80,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { /** * Changes the timer interval. - * \param interval The timer interval. + * \param interval: The timer interval. */ void setInterval(GHOST_TUns64 interval) { @@ -98,7 +98,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { /** * Changes the time the timerProc will be called. - * \param next The time the timerProc will be called. + * \param next: The time the timerProc will be called. */ void setNext(GHOST_TUns64 next) { @@ -152,7 +152,7 @@ class GHOST_TimerTask : public GHOST_ITimerTask { /** * Changes the auxiliary storage room. - * \param auxData The auxiliary storage room. + * \param auxData: The auxiliary storage room. */ void setAuxData(GHOST_TUns32 auxData) { diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index c8c21b2b08f..d897fafc003 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -41,13 +41,12 @@ class GHOST_Window : public GHOST_IWindow { * Constructor. * Creates a new window and opens it. * To check if the window was created properly, use the getValid() method. - * \param width The width the window. - * \param heigh The height the window. - * \param state The state the window is initially opened with. - * \param type The type of drawing context installed in this window. - * \param stereoVisual Stereo visual for quad buffered stereo. - * \param exclusive Use to show the window ontop and ignore others - * (used fullscreen). + * \param width: The width the window. + * \param heigh: The height the window. + * \param state: The state the window is initially opened with. + * \param type: The type of drawing context installed in this window. + * \param stereoVisual: Stereo visual for quad buffered stereo. + * \param exclusive: Use to show the window ontop and ignore others (used full-screen). */ GHOST_Window(GHOST_TUns32 width, GHOST_TUns32 height, @@ -103,7 +102,7 @@ class GHOST_Window : public GHOST_IWindow { /** * Returns the current cursor shape. - * \return The current cursor shape. + * \return The current cursor shape. */ inline GHOST_TStandardCursor getCursorShape() const; @@ -114,18 +113,18 @@ class GHOST_Window : public GHOST_IWindow { /** * Set the shape of the cursor. - * \param cursorShape: The new cursor shape type id. - * \return Indication of success. + * \param cursorShape: The new cursor shape type id. + * \return Indication of success. */ GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape); /** * Set the shape of the cursor to a custom cursor. - * \param bitmap The bitmap data for the cursor. - * \param mask The mask data for the cursor. - * \param hotX The X coordinate of the cursor hot-spot. - * \param hotY The Y coordinate of the cursor hot-spot. - * \return Indication of success. + * \param bitmap: The bitmap data for the cursor. + * \param mask: The mask data for the cursor. + * \param hotX: The X coordinate of the cursor hot-spot. + * \param hotY: The Y coordinate of the cursor hot-spot. + * \return Indication of success. */ GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, @@ -137,7 +136,7 @@ class GHOST_Window : public GHOST_IWindow { /** * Returns the visibility state of the cursor. - * \return The visibility state of the cursor. + * \return The visibility state of the cursor. */ inline bool getCursorVisibility() const; inline GHOST_TGrabCursorMode getCursorGrabMode() const; @@ -149,15 +148,15 @@ class GHOST_Window : public GHOST_IWindow { /** * Shows or hides the cursor. - * \param visible The new visibility state of the cursor. - * \return Indication of success. + * \param visible: The new visibility state of the cursor. + * \return Indication of success. */ GHOST_TSuccess setCursorVisibility(bool visible); /** * Sets the cursor grab. - * \param mode The new grab state of the cursor. - * \return Indication of success. + * \param mode: The new grab state of the cursor. + * \return Indication of success. */ GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_TAxisFlag wrap_axis, @@ -172,7 +171,7 @@ class GHOST_Window : public GHOST_IWindow { /** * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % (0.0 to 1.0) + * \param progress: The progress percentage (0.0 to 1.0). */ virtual GHOST_TSuccess setProgressBar(float /*progress*/) { @@ -188,14 +187,14 @@ class GHOST_Window : public GHOST_IWindow { } /** - * Sets the swap interval for swapBuffers. - * \param interval The swap interval to use. + * Sets the swap interval for #swapBuffers. + * \param interval: The swap interval to use. * \return A boolean success indicator. */ GHOST_TSuccess setSwapInterval(int interval); /** - * Gets the current swap interval for swapBuffers. + * Gets the current swap interval for #swapBuffers. * \return An integer. */ GHOST_TSuccess getSwapInterval(int &intervalOut); @@ -213,7 +212,7 @@ class GHOST_Window : public GHOST_IWindow { /** * Sets the window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not + * \param isUnsavedChanges: Unsaved changes or not. * \return Indication of success. */ virtual GHOST_TSuccess setModifiedState(bool isUnsavedChanges); @@ -233,21 +232,21 @@ class GHOST_Window : public GHOST_IWindow { /** * Tries to install a rendering context in this window. * Child classes do not need to overload this method, - * They should overload newDrawingContext instead. - * \param type The type of rendering context installed. + * They should overload #newDrawingContext instead. + * \param type: The type of rendering context installed. * \return Indication as to whether installation has succeeded. */ GHOST_TSuccess setDrawingContextType(GHOST_TDrawingContextType type); /** * Swaps front and back buffers of a window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess swapBuffers(); /** * Activates the drawing context of this window. - * \return A boolean success indicator. + * \return A boolean success indicator. */ virtual GHOST_TSuccess activateDrawingContext(); @@ -259,8 +258,8 @@ class GHOST_Window : public GHOST_IWindow { GHOST_TSuccess updateDrawingContext(); /** - * Gets the OpenGL framebuffer associated with the window's contents. - * \return The ID of an OpenGL framebuffer object. + * Gets the OpenGL frame-buffer associated with the window's contents. + * \return The ID of an OpenGL frame-buffer object. */ virtual unsigned int getDefaultFramebuffer(); @@ -314,7 +313,7 @@ class GHOST_Window : public GHOST_IWindow { protected: /** * Tries to install a rendering context in this window. - * \param type The type of rendering context installed. + * \param type: The type of rendering context installed. * \return Indication as to whether installation has succeeded. */ virtual GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) = 0; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h index 97486c9e77a..3cfe46a080b 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.h +++ b/intern/ghost/intern/GHOST_WindowCocoa.h @@ -44,16 +44,16 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Constructor. * Creates a new window and opens it. - * To check if the window was created properly, use the getValid() method. - * \param systemCocoa The associated system class to forward events to - * \param title The text shown in the title bar of the window. - * \param left The coordinate of the left edge of the window. - * \param bottom The coordinate of the bottom edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state the window is initially opened with. - * \param type The type of drawing context installed in this window. - * \param stereoVisual Stereo visual for quad buffered stereo. + * To check if the window was created properly, use the #getValid() method. + * \param systemCocoa: The associated system class to forward events to. + * \param title: The text shown in the title bar of the window. + * \param left: The coordinate of the left edge of the window. + * \param bottom: The coordinate of the bottom edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state the window is initially opened with. + * \param type: The type of drawing context installed in this window. + * \param stereoVisual: Stereo visual for quad buffered stereo. */ GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, const char *title, @@ -88,12 +88,12 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Sets the title displayed in the title bar. - * \param title The title to display in the title bar. + * \param title: The title to display in the title bar. */ void setTitle(const char *title); /** * Returns the title displayed in the title bar. - * \param title The title displayed in the title bar. + * \param title: The title displayed in the title bar. */ std::string getTitle() const; @@ -101,33 +101,33 @@ class GHOST_WindowCocoa : public GHOST_Window { * Returns the window rectangle dimensions. * The dimensions are given in screen coordinates that are * relative to the upper-left corner of the screen. - * \param bounds The bounding rectangle of the window. + * \param bounds: The bounding rectangle of the window. */ void getWindowBounds(GHOST_Rect &bounds) const; /** * Returns the client rectangle dimensions. * The left and top members of the rectangle are always zero. - * \param bounds The bounding rectangle of the client area of the window. + * \param bounds: The bounding rectangle of the client area of the window. */ void getClientBounds(GHOST_Rect &bounds) const; /** * Resizes client rectangle width. - * \param width The new width of the client area of the window. + * \param width: The new width of the client area of the window. */ GHOST_TSuccess setClientWidth(GHOST_TUns32 width); /** * Resizes client rectangle height. - * \param height The new height of the client area of the window. + * \param height: The new height of the client area of the window. */ GHOST_TSuccess setClientHeight(GHOST_TUns32 height); /** * Resizes client rectangle. - * \param width The new width of the client area of the window. - * \param height The new height of the client area of the window. + * \param width: The new width of the client area of the window. + * \param height: The new height of the client area of the window. */ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); @@ -139,17 +139,17 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Sets the window "modified" status, indicating unsaved changes - * \param isUnsavedChanges Unsaved changes or not + * \param isUnsavedChanges: Unsaved changes or not. * \return Indication of success. */ GHOST_TSuccess setModifiedState(bool isUnsavedChanges); /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate on the screen. - * \param inY The y-coordinate on the screen. - * \param outX The x-coordinate in the client rectangle. - * \param outY The y-coordinate in the client rectangle. + * \param inX: The x-coordinate on the screen. + * \param inY: The y-coordinate on the screen. + * \param outX: The x-coordinate in the client rectangle. + * \param outY: The y-coordinate in the client rectangle. */ void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -158,10 +158,10 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -171,10 +171,10 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Converts a point in screen coordinates to client rectangle coordinates * but without the y coordinate conversion needed for ghost compatibility. - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ void clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -184,10 +184,10 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Converts a point in screen coordinates to client rectangle coordinates, * but without the y coordinate conversion needed for ghost compatibility. - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ void screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -202,14 +202,14 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Sets the state of the window (normal, minimized, maximized). - * \param state The state of the window. + * \param state: The state of the window. * \return Indication of success. */ GHOST_TSuccess setState(GHOST_TWindowState state); /** * Sets the order of the window (bottom, top). - * \param order The order of the window. + * \param order: The order of the window. * \return Indication of success. */ GHOST_TSuccess setOrder(GHOST_TWindowOrder order); @@ -226,7 +226,7 @@ class GHOST_WindowCocoa : public GHOST_Window { /** * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % (0.0 to 1.0) + * \param progress: The progress percentage (0.0 to 1.0). */ GHOST_TSuccess setProgressBar(float progress); @@ -265,7 +265,7 @@ class GHOST_WindowCocoa : public GHOST_Window { protected: /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index f8e2f96d111..ebc08fb411c 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -404,7 +404,7 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, [m_window setAcceptsMouseMovedEvents:YES]; NSView *contentview = [m_window contentView]; - [contentview setAcceptsTouchEvents:YES]; + [contentview setAllowedTouchTypes:(NSTouchTypeMaskDirect | NSTouchTypeMaskIndirect)]; [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSStringPboardType, diff --git a/intern/ghost/intern/GHOST_WindowManager.h b/intern/ghost/intern/GHOST_WindowManager.h index 34fdfd30f27..cb0337773c6 100644 --- a/intern/ghost/intern/GHOST_WindowManager.h +++ b/intern/ghost/intern/GHOST_WindowManager.h @@ -47,54 +47,54 @@ class GHOST_WindowManager { /** * Add a window to our list. * It is only added if it is not already in the list. - * \param window Pointer to the window to be added. - * \return Indication of success. + * \param window: Pointer to the window to be added. + * \return Indication of success. */ GHOST_TSuccess addWindow(GHOST_IWindow *window); /** * Remove a window from our list. - * \param window Pointer to the window to be removed. - * \return Indication of success. + * \param window: Pointer to the window to be removed. + * \return Indication of success. */ GHOST_TSuccess removeWindow(const GHOST_IWindow *window); /** * Returns whether the window is in our list. - * \param window Pointer to the window to query. - * \return A boolean indicator. + * \param window: Pointer to the window to query. + * \return A boolean indicator. */ bool getWindowFound(const GHOST_IWindow *window) const; /** - * Returns whether one of the windows is fullscreen. - * \return A boolean indicator. + * Returns whether one of the windows is full-screen. + * \return A boolean indicator. */ bool getFullScreen(void) const; /** * Returns pointer to the full-screen window. - * \return The full-screen window (NULL if not in full-screen). + * \return The full-screen window (NULL if not in full-screen). */ GHOST_IWindow *getFullScreenWindow(void) const; /** - * Activates fullscreen mode for a window. - * \param window The window displayed fullscreen. - * \return Indication of success. + * Activates full-screen mode for a window. + * \param window: The window displayed full-screen. + * \return Indication of success. */ GHOST_TSuccess beginFullScreen(GHOST_IWindow *window, const bool stereoVisual); /** - * Closes fullscreen mode down. - * \return Indication of success. + * Closes full-screen mode down. + * \return Indication of success. */ GHOST_TSuccess endFullScreen(void); /** * Sets new window as active window (the window receiving events). * There can be only one window active which should be in the current window list. - * \param window The new active window. + * \param window: The new active window. */ GHOST_TSuccess setActiveWindow(GHOST_IWindow *window); @@ -107,7 +107,7 @@ class GHOST_WindowManager { /** * Set this window to be inactive (not receiving events). - * \param window The window to deactivate. + * \param window: The window to deactivate. */ void setWindowInactive(const GHOST_IWindow *window); @@ -119,9 +119,9 @@ class GHOST_WindowManager { const std::vector<GHOST_IWindow *> &getWindows() const; /** - * Finds the window associated with an OS window object/handle - * \param osWindow The OS window object/handle - * \return The associated window, null if none corresponds + * Finds the window associated with an OS window object/handle. + * \param osWindow: The OS window object/handle. + * \return The associated window, null if none corresponds. */ GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow); diff --git a/intern/ghost/intern/GHOST_WindowNULL.h b/intern/ghost/intern/GHOST_WindowNULL.h index 0b5a7ee3450..aca06ba75b5 100644 --- a/intern/ghost/intern/GHOST_WindowNULL.h +++ b/intern/ghost/intern/GHOST_WindowNULL.h @@ -168,7 +168,7 @@ class GHOST_WindowNULL : public GHOST_Window { GHOST_SystemNULL *m_system; /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h index 643c54c282e..bfe07af1c70 100644 --- a/intern/ghost/intern/GHOST_WindowSDL.h +++ b/intern/ghost/intern/GHOST_WindowSDL.h @@ -85,7 +85,7 @@ class GHOST_WindowSDL : public GHOST_Window { protected: /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index 1ee41f4d0f6..b62b5c24d60 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -118,7 +118,7 @@ class GHOST_WindowWayland : public GHOST_Window { std::string title; /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type) override; diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index 18a48c9169e..5904a72b186 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -81,6 +81,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_nPressedButtons(0), m_customCursor(0), m_wantAlphaBackground(alphaBackground), + m_wintab(), m_normal_state(GHOST_kWindowStateNormal), m_user32(NULL), m_fpGetPointerInfoHistory(NULL), @@ -89,10 +90,6 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_parentWindowHwnd(parentwindow ? parentwindow->m_hWnd : NULL), m_debug_context(is_debug) { - // Initialize tablet variables - memset(&m_wintab, 0, sizeof(m_wintab)); - m_tabletData = GHOST_TABLET_DATA_NONE; - // Create window if (state != GHOST_kWindowStateFullScreen) { RECT rect; @@ -297,66 +294,25 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_user32, "GetPointerTouchInfoHistory"); } - // Initialize Wintab - m_wintab.handle = ::LoadLibrary("Wintab32.dll"); - if (m_wintab.handle && m_system->getTabletAPI() != GHOST_kTabletNative) { - // Get API functions - m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA"); - m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA"); - m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose"); - m_wintab.packet = (GHOST_WIN32_WTPacket)::GetProcAddress(m_wintab.handle, "WTPacket"); - m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable"); - m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"); - - // Let's see if we can initialize tablet here. - // Check if WinTab available by getting system context info. - LOGCONTEXT lc = {0}; - lc.lcOptions |= CXO_SYSTEM; - if (m_wintab.open && m_wintab.info && m_wintab.info(WTI_DEFSYSCTX, 0, &lc)) { - // Now init the tablet - /* The maximum tablet size, pressure and orientation (tilt) */ - AXIS TabletX, TabletY, Pressure, Orientation[3]; - - // Open a Wintab context - - // Open the context - lc.lcPktData = PACKETDATA; - lc.lcPktMode = PACKETMODE; - lc.lcOptions |= CXO_MESSAGES; - lc.lcMoveMask = PACKETDATA; - - /* Set the entire tablet as active */ - m_wintab.info(WTI_DEVICES, DVC_X, &TabletX); - m_wintab.info(WTI_DEVICES, DVC_Y, &TabletY); - - /* get the max pressure, to divide into a float */ - BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); - if (pressureSupport) - m_wintab.maxPressure = Pressure.axMax; - else - m_wintab.maxPressure = 0; - - /* get the max tilt axes, to divide into floats */ - BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); - if (tiltSupport) { - /* does the tablet support azimuth ([0]) and altitude ([1]) */ - if (Orientation[0].axResolution && Orientation[1].axResolution) { - /* all this assumes the minimum is 0 */ - m_wintab.maxAzimuth = Orientation[0].axMax; - m_wintab.maxAltitude = Orientation[1].axMax; - } - else { /* no so 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.tablet = m_wintab.open(m_hWnd, &lc, FALSE); - if (m_wintab.enable && m_wintab.tablet) { - m_wintab.enable(m_wintab.tablet, TRUE); - } - } + if ((m_wintab.handle = ::LoadLibrary("Wintab32.dll")) && + (m_wintab.info = (GHOST_WIN32_WTInfo)::GetProcAddress(m_wintab.handle, "WTInfoA")) && + (m_wintab.open = (GHOST_WIN32_WTOpen)::GetProcAddress(m_wintab.handle, "WTOpenA")) && + (m_wintab.get = (GHOST_WIN32_WTGet)::GetProcAddress(m_wintab.handle, "WTGetA")) && + (m_wintab.set = (GHOST_WIN32_WTSet)::GetProcAddress(m_wintab.handle, "WTSetA")) && + (m_wintab.close = (GHOST_WIN32_WTClose)::GetProcAddress(m_wintab.handle, "WTClose")) && + (m_wintab.packetsGet = (GHOST_WIN32_WTPacketsGet)::GetProcAddress(m_wintab.handle, + "WTPacketsGet")) && + (m_wintab.queueSizeGet = (GHOST_WIN32_WTQueueSizeGet)::GetProcAddress(m_wintab.handle, + "WTQueueSizeGet")) && + (m_wintab.queueSizeSet = (GHOST_WIN32_WTQueueSizeSet)::GetProcAddress(m_wintab.handle, + "WTQueueSizeSet")) && + (m_wintab.enable = (GHOST_WIN32_WTEnable)::GetProcAddress(m_wintab.handle, "WTEnable")) && + (m_wintab.overlap = (GHOST_WIN32_WTOverlap)::GetProcAddress(m_wintab.handle, "WTOverlap"))) { + initializeWintab(); + // Determine which tablet API to use and enable it. + updateWintab(m_system->m_windowFocus, m_system->m_windowFocus); } + CoCreateInstance( CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList3, (LPVOID *)&m_Bar); } @@ -370,8 +326,9 @@ GHOST_WindowWin32::~GHOST_WindowWin32() } if (m_wintab.handle) { - if (m_wintab.close && m_wintab.tablet) { - m_wintab.close(m_wintab.tablet); + updateWintab(false, false); + if (m_wintab.close && m_wintab.context) { + m_wintab.close(m_wintab.context); } FreeLibrary(m_wintab.handle); @@ -819,6 +776,27 @@ 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 @@ -1022,6 +1000,98 @@ 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. */ + if (!m_wintab.handle || m_wintab.context) { + return; + } + + /* Check if WinTab available by getting system context info. */ + LOGCONTEXT lc = {0}; + 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; + lc.lcOptions |= CXO_CSRMESSAGES | CXO_MESSAGES; + /* Wacom maps y origin to the tablet's bottom. Invert to match Windows y origin mapping to the + * screen top. */ + lc.lcOutExtY = -lc.lcOutExtY; + + m_wintab.info(WTI_INTERFACE, IFC_NDEVICES, &m_wintab.numDevices); + + 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); + + /* Wintab provides no way to determine the maximum queue size aside from checking if attempts + * to change the queue size are successful. */ + const int maxQueue = 500; + int queueSize = m_wintab.queueSizeGet(m_wintab.context); + + while (queueSize < maxQueue) { + int testSize = min(queueSize + 16, maxQueue); + if (m_wintab.queueSizeSet(m_wintab.context, testSize)) { + queueSize = testSize; + } + else { + /* From Windows Wintab Documentation for WTQueueSizeSet: + * "If the return value is zero, the context has no queue because the function deletes the + * original queue before attempting to create a new one. The application must continue + * calling the function with a smaller queue size until the function returns a non - zero + * value." + * + * In our case we start with a known valid queue size and in the event of failure roll + * back to the last valid queue size. The Wintab spec dates back to 16 bit Windows, thus + * assumes memory recently deallocated may not be available, which is no longer a practical + * concern. */ + m_wintab.queueSizeSet(m_wintab.context, queueSize); + break; + } + } + m_wintab.pkts.resize(queueSize); + } +} + GHOST_TSuccess GHOST_WindowWin32::getPointerInfo( std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam) { @@ -1104,28 +1174,20 @@ GHOST_TSuccess GHOST_WindowWin32::getPointerInfo( return GHOST_kSuccess; } -void GHOST_WindowWin32::setTabletData(GHOST_TabletData *pTabletData) +void GHOST_WindowWin32::processWintabDisplayChangeEvent() { - if (pTabletData) { - m_tabletData = *pTabletData; - } - else { - m_tabletData = GHOST_TABLET_DATA_NONE; - } -} + LOGCONTEXT lc_sys = {0}, lc_curr = {0}; -void GHOST_WindowWin32::processWin32TabletActivateEvent(WORD state) -{ - if (!useTabletAPI(GHOST_kTabletWintab)) { - return; - } + if (m_wintab.info && m_wintab.get && m_wintab.set && m_wintab.info(WTI_DEFSYSCTX, 0, &lc_sys)) { - if (m_wintab.enable && m_wintab.tablet) { - m_wintab.enable(m_wintab.tablet, state); + m_wintab.get(m_wintab.context, &lc_curr); - if (m_wintab.overlap && state) { - m_wintab.overlap(m_wintab.tablet, TRUE); - } + lc_curr.lcOutOrgX = lc_sys.lcOutOrgX; + lc_curr.lcOutOrgY = lc_sys.lcOutOrgY; + lc_curr.lcOutExtX = lc_sys.lcOutExtX; + lc_curr.lcOutExtY = -lc_sys.lcOutExtY; + + m_wintab.set(m_wintab.context, &lc_curr); } } @@ -1135,7 +1197,7 @@ bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const return true; } else if (m_system->getTabletAPI() == GHOST_kTabletAutomatic) { - if (m_wintab.tablet) + if (m_wintab.numDevices) return api == GHOST_kTabletWintab; else return api == GHOST_kTabletNative; @@ -1145,114 +1207,232 @@ bool GHOST_WindowWin32::useTabletAPI(GHOST_TTabletAPI api) const } } -void GHOST_WindowWin32::processWin32TabletInitEvent() +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.tablet) { + if (m_wintab.info && m_wintab.context) { AXIS Pressure, Orientation[3]; /* The maximum tablet size */ BOOL pressureSupport = m_wintab.info(WTI_DEVICES, DVC_NPRESSURE, &Pressure); - if (pressureSupport) - m_wintab.maxPressure = Pressure.axMax; - else - m_wintab.maxPressure = 0; + m_wintab.maxPressure = pressureSupport ? Pressure.axMax : 0; BOOL tiltSupport = m_wintab.info(WTI_DEVICES, DVC_ORIENTATION, &Orientation); - if (tiltSupport) { - /* does the tablet support azimuth ([0]) and altitude ([1]) */ - if (Orientation[0].axResolution && Orientation[1].axResolution) { - m_wintab.maxAzimuth = Orientation[0].axMax; - m_wintab.maxAltitude = Orientation[1].axMax; - } - else { /* no so dont do tilt stuff */ - m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; - } + /* 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 { /* no so dont do tilt stuff */ + m_wintab.maxAzimuth = m_wintab.maxAltitude = 0; + } + } + + m_tabletInRange = inRange; +} + +void GHOST_WindowWin32::processWintabInfoChangeEvent(LPARAM lParam) +{ + 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); + updateWintab((GHOST_WindowWin32 *)system->getWindowManager()->getActiveWindow() == this, + !::IsIconic(m_hWnd)); } +} + +GHOST_TSuccess GHOST_WindowWin32::wintabMouseToGhost(UINT cursor, + WORD physicalButton, + GHOST_TButtonMask &ghostButton) +{ + const WORD numButtons = 32; + BYTE logicalButtons[numButtons] = {0}; + BYTE systemButtons[numButtons] = {0}; - m_tabletData.Active = GHOST_kTabletModeNone; + m_wintab.info(WTI_CURSORS + cursor, CSR_BUTTONMAP, &logicalButtons); + m_wintab.info(WTI_CURSORS + cursor, CSR_SYSBTNMAP, &systemButtons); + + if (physicalButton >= numButtons) { + return GHOST_kFailure; + } + BYTE lb = logicalButtons[physicalButton]; + + if (lb >= numButtons) { + return GHOST_kFailure; + } + switch (systemButtons[lb]) { + case SBN_LCLICK: + ghostButton = GHOST_kButtonMaskLeft; + return GHOST_kSuccess; + case SBN_RCLICK: + ghostButton = GHOST_kButtonMaskRight; + return GHOST_kSuccess; + case SBN_MCLICK: + ghostButton = GHOST_kButtonMaskMiddle; + return GHOST_kSuccess; + default: + return GHOST_kFailure; + } } -void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam) +GHOST_TSuccess GHOST_WindowWin32::getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo) { if (!useTabletAPI(GHOST_kTabletWintab)) { - return; + return GHOST_kFailure; } - if (m_wintab.packet && m_wintab.tablet) { - PACKET pkt; - if (m_wintab.packet((HCTX)lParam, wParam, &pkt)) { - switch (pkt.pkCursor % 3) { /* % 3 for multiple devices ("DualTrack") */ - case 0: - m_tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */ - break; - case 1: - m_tabletData.Active = GHOST_kTabletModeStylus; /* stylus */ - break; - case 2: - m_tabletData.Active = GHOST_kTabletModeEraser; /* eraser */ - break; - } + if (!(m_wintab.packetsGet && m_wintab.context)) { + return GHOST_kFailure; + } - if (m_wintab.maxPressure > 0) { - m_tabletData.Pressure = (float)pkt.pkNormalPressure / (float)m_wintab.maxPressure; - } - else { - m_tabletData.Pressure = 1.0f; - } + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem(); - if ((m_wintab.maxAzimuth > 0) && (m_wintab.maxAltitude > 0)) { - ORIENTATION ort = pkt.pkOrientation; - float vecLen; - float altRad, azmRad; /* in radians */ + updatePendingWintabEvents(); - /* - * from the wintab spec: - * orAzimuth Specifies the clockwise rotation of the - * cursor about the z axis through a full circular range. - * - * orAltitude Specifies the angle with the x-y plane - * through a signed, semicircular range. Positive values - * specify an angle upward toward the positive z axis; - * negative values specify an angle downward toward the negative z axis. - * - * wintab.h defines .orAltitude as a UINT but documents .orAltitude - * as positive for upward angles and negative for downward angles. - * WACOM uses negative altitude values to show that the pen is inverted; - * therefore we cast .orAltitude as an (int) and then use the absolute value. - */ - - /* convert raw fixed point data to radians */ - altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0); - azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0); - - /* find length of the stylus' projected vector on the XY plane */ - vecLen = cos(altRad); - - /* from there calculate X and Y components based on azimuth */ - m_tabletData.Xtilt = sin(azmRad) * vecLen; - m_tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen); + auto &pendingEvents = m_wintab.pendingEvents; + size_t pendingEventSize = pendingEvents.size(); + outWintabInfo.resize(pendingEventSize); + + 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: + tabletData.Active = GHOST_kTabletModeNone; /* puck - not yet supported */ + break; + case 1: + tabletData.Active = GHOST_kTabletModeStylus; /* stylus */ + break; + case 2: + tabletData.Active = GHOST_kTabletModeEraser; /* eraser */ + break; + } + + if (m_wintab.maxPressure > 0) { + 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 */ + + /* + * from the wintab spec: + * orAzimuth Specifies the clockwise rotation of the + * cursor about the z axis through a full circular range. + * + * orAltitude Specifies the angle with the x-y plane + * through a signed, semicircular range. Positive values + * specify an angle upward toward the positive z axis; + * negative values specify an angle downward toward the negative z axis. + * + * wintab.h defines .orAltitude as a UINT but documents .orAltitude + * as positive for upward angles and negative for downward angles. + * WACOM uses negative altitude values to show that the pen is inverted; + * therefore we cast .orAltitude as an (int) and then use the absolute value. + */ + + /* convert raw fixed point data to radians */ + altRad = (float)((fabs((float)ort.orAltitude) / (float)m_wintab.maxAltitude) * M_PI / 2.0); + azmRad = (float)(((float)ort.orAzimuth / (float)m_wintab.maxAzimuth) * M_PI * 2.0); + + /* find length of the stylus' projected vector on the XY plane */ + vecLen = cos(altRad); + + /* from there calculate X and Y components based on azimuth */ + tabletData.Xtilt = sin(azmRad) * vecLen; + tabletData.Ytilt = (float)(sin(M_PI / 2.0 - azmRad) * vecLen); + } + + outWintabInfo[i].x = pkt.pkX; + outWintabInfo[i].y = pkt.pkY; + + /* 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; + + /* 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++; + } + + if (buttonsChanged && + wintabMouseToGhost(pkt.pkCursor, physicalButton, outWintabInfo[i].button)) { + if (buttonsChanged & pkt.pkButtons) { + outWintabInfo[i].type = GHOST_kEventButtonDown; } else { - m_tabletData.Xtilt = 0.0f; - m_tabletData.Ytilt = 0.0f; + outWintabInfo[i].type = GHOST_kEventButtonUp; } } + else { + outWintabInfo[i].type = GHOST_kEventCursorMove; + } + + m_wintab.sysButtonsPressed = pkt.pkButtons; + + outWintabInfo[i].time = system->millisSinceStart(pkt.pkTime); + outWintabInfo[i].tabletData = tabletData; } + + return GHOST_kSuccess; } -void GHOST_WindowWin32::bringTabletContextToFront() +/* 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::updatePendingWintabEvents() { - if (!useTabletAPI(GHOST_kTabletWintab)) { + if (!(m_wintab.packetsGet && m_wintab.context)) { return; } + GHOST_SystemWin32 *system = (GHOST_SystemWin32 *)GHOST_System::getSystem(); + + auto &pendingEvents = m_wintab.pendingEvents; + + /* Clear outdated events from queue. */ + GHOST_TUns64 currTime = system->getMilliSeconds(); + GHOST_TUns64 timeout = 300; + while (!pendingEvents.empty()) { + GHOST_TUns64 pktTime = system->millisSinceStart(pendingEvents.front().pkTime); + if (currTime - pktTime > timeout) { + pendingEvents.pop(); + } + else { + break; + } + } - if (m_wintab.overlap && m_wintab.tablet) { - m_wintab.overlap(m_wintab.tablet, TRUE); + /* Get new packets. */ + const int numPackets = m_wintab.packetsGet( + m_wintab.context, m_wintab.pkts.size(), m_wintab.pkts.data()); + + int i = 0; + /* Don't queue outdated packets, such events can include packets that occurred before the current + * window lost and regained focus. */ + for (; i < numPackets; i++) { + GHOST_TUns64 pktTime = system->millisSinceStart(m_wintab.pkts[i].pkTime); + if (currTime - pktTime < timeout) { + break; + } + } + for (; i < numPackets; i++) { + pendingEvents.push(m_wintab.pkts[i]); } } diff --git a/intern/ghost/intern/GHOST_WindowWin32.h b/intern/ghost/intern/GHOST_WindowWin32.h index 224ff53bf7b..a761d7d84dc 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.h +++ b/intern/ghost/intern/GHOST_WindowWin32.h @@ -34,11 +34,14 @@ # include "GHOST_ImeWin32.h" #endif +#include <queue> #include <vector> #include <wintab.h> -#define PACKETDATA (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR) -#define PACKETMODE PK_BUTTONS +// PACKETDATA and PACKETMODE modify structs in pktdef.h, so make sure they come first +#define PACKETDATA \ + (PK_BUTTONS | PK_NORMAL_PRESSURE | PK_ORIENTATION | PK_CURSOR | PK_X | PK_Y | PK_TIME) +#define PACKETMODE 0 #include <pktdef.h> class GHOST_SystemWin32; @@ -46,9 +49,13 @@ class GHOST_DropTargetWin32; // typedefs for WinTab functions to allow dynamic loading typedef UINT(API *GHOST_WIN32_WTInfo)(UINT, UINT, LPVOID); +typedef BOOL(API *GHOST_WIN32_WTGet)(HCTX, LPLOGCONTEXTA); +typedef BOOL(API *GHOST_WIN32_WTSet)(HCTX, LPLOGCONTEXTA); typedef HCTX(API *GHOST_WIN32_WTOpen)(HWND, LPLOGCONTEXTA, BOOL); typedef BOOL(API *GHOST_WIN32_WTClose)(HCTX); -typedef BOOL(API *GHOST_WIN32_WTPacket)(HCTX, UINT, LPVOID); +typedef int(API *GHOST_WIN32_WTPacketsGet)(HCTX, int, LPVOID); +typedef int(API *GHOST_WIN32_WTQueueSizeGet)(HCTX); +typedef BOOL(API *GHOST_WIN32_WTQueueSizeSet)(HCTX, int); typedef BOOL(API *GHOST_WIN32_WTEnable)(HCTX, BOOL); typedef BOOL(API *GHOST_WIN32_WTOverlap)(HCTX, BOOL); @@ -229,7 +236,14 @@ struct GHOST_PointerInfoWin32 { GHOST_TButtonMask buttonMask; POINT pixelLocation; GHOST_TUns64 time; + GHOST_TabletData tabletData; +}; +struct GHOST_WintabInfoWin32 { + GHOST_TInt32 x, y; + GHOST_TEventType type; + GHOST_TButtonMask button; + GHOST_TUns64 time; GHOST_TabletData tabletData; }; @@ -248,16 +262,16 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Constructor. * Creates a new window and opens it. - * To check if the window was created properly, use the getValid() method. - * \param title The text shown in the title bar of the window. - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state the window is initially opened with. - * \param type The type of drawing context installed in this window. - * \param wantStereoVisual Stereo visual for quad buffered stereo. - * \param parentWindowHwnd + * To check if the window was created properly, use the #getValid() method. + * \param title: The text shown in the title bar of the window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state the window is initially opened with. + * \param type: The type of drawing context installed in this window. + * \param wantStereoVisual: Stereo visual for quad buffered stereo. + * \param parentWindowHwnd: TODO. */ GHOST_WindowWin32(GHOST_SystemWin32 *system, const char *title, @@ -293,7 +307,7 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Sets the title displayed in the title bar. - * \param title The title to display in the title bar. + * \param title: The title to display in the title bar. */ void setTitle(const char *title); @@ -307,33 +321,33 @@ class GHOST_WindowWin32 : public GHOST_Window { * Returns the window rectangle dimensions. * The dimensions are given in screen coordinates that are * relative to the upper-left corner of the screen. - * \param bounds The bounding rectangle of the window. + * \param bounds: The bounding rectangle of the window. */ void getWindowBounds(GHOST_Rect &bounds) const; /** * Returns the client rectangle dimensions. * The left and top members of the rectangle are always zero. - * \param bounds The bounding rectangle of the client area of the window. + * \param bounds: The bounding rectangle of the client area of the window. */ void getClientBounds(GHOST_Rect &bounds) const; /** * Resizes client rectangle width. - * \param width The new width of the client area of the window. + * \param width: The new width of the client area of the window. */ GHOST_TSuccess setClientWidth(GHOST_TUns32 width); /** * Resizes client rectangle height. - * \param height The new height of the client area of the window. + * \param height: The new height of the client area of the window. */ GHOST_TSuccess setClientHeight(GHOST_TUns32 height); /** * Resizes client rectangle. - * \param width The new width of the client area of the window. - * \param height The new height of the client area of the window. + * \param width: The new width of the client area of the window. + * \param height: The new height of the client area of the window. */ GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height); @@ -345,10 +359,10 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate on the screen. - * \param inY The y-coordinate on the screen. - * \param outX The x-coordinate in the client rectangle. - * \param outY The y-coordinate in the client rectangle. + * \param inX: The x-coordinate on the screen. + * \param inY: The y-coordinate on the screen. + * \param outX: The x-coordinate in the client rectangle. + * \param outY: The y-coordinate in the client rectangle. */ void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -357,10 +371,10 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Converts a point in screen coordinates to client rectangle coordinates - * \param inX The x-coordinate in the client rectangle. - * \param inY The y-coordinate in the client rectangle. - * \param outX The x-coordinate on the screen. - * \param outY The y-coordinate on the screen. + * \param inX: The x-coordinate in the client rectangle. + * \param inY: The y-coordinate in the client rectangle. + * \param outX: The x-coordinate on the screen. + * \param outY: The y-coordinate on the screen. */ void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, @@ -369,14 +383,14 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Sets the state of the window (normal, minimized, maximized). - * \param state The state of the window. + * \param state: The state of the window. * \return Indication of success. */ GHOST_TSuccess setState(GHOST_TWindowState state); /** * Sets the order of the window (bottom, top). - * \param order The order of the window. + * \param order: The order of the window. * \return Indication of success. */ GHOST_TSuccess setOrder(GHOST_TWindowOrder order); @@ -388,7 +402,7 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Sets the progress bar value displayed in the window/application icon - * \param progress The progress % + * \param progress: The progress percentage (0.0 to 1.0). */ GHOST_TSuccess setProgressBar(float progress); @@ -402,8 +416,8 @@ class GHOST_WindowWin32 : public GHOST_Window { * for any real button press, controls mouse * capturing). * - * \param event Whether mouse was pressed and released, or an operator grabbed or ungrabbed the - * mouse + * \param event: Whether mouse was pressed and released, + * or an operator grabbed or ungrabbed the mouse. */ void updateMouseCapture(GHOST_MouseCaptureEventWin32 event); @@ -417,34 +431,64 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Loads the windows equivalent of a standard GHOST cursor. - * \param visible Flag for cursor visibility. - * \param cursorShape The cursor shape. + * \param visible: Flag for cursor visibility. + * \param cursorShape: The cursor shape. */ HCURSOR getStandardCursor(GHOST_TStandardCursor shape) const; void loadCursor(bool visible, GHOST_TStandardCursor cursorShape) const; - const GHOST_TabletData &getTabletData() - { - return m_tabletData; - } + /** + * 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); - void setTabletData(GHOST_TabletData *tabletData); + /** + * Query whether given tablet API should be used. + * \param api: Tablet API to test. + */ bool useTabletAPI(GHOST_TTabletAPI api) const; /** * Translate WM_POINTER events into GHOST_PointerInfoWin32 structs. - * \param outPointerInfo Storage to return resulting GHOST_PointerInfoWin32 structs - * \param wParam WPARAM of the event - * \param lParam LPARAM of the event + * \param outPointerInfo: Storage to return resulting GHOST_PointerInfoWin32 structs. + * \param wParam: WPARAM of the event. + * \param lParam: LPARAM of the event. + * \return True if #outPointerInfo was updated. */ GHOST_TSuccess getPointerInfo(std::vector<GHOST_PointerInfoWin32> &outPointerInfo, WPARAM wParam, LPARAM lParam); - void processWin32TabletActivateEvent(WORD state); - void processWin32TabletInitEvent(); - void processWin32TabletEvent(WPARAM wParam, LPARAM lParam); - void bringTabletContextToFront(); + /** + * Handle Wintab coordinate changes when DisplayChange events occur. + */ + void processWintabDisplayChangeEvent(); + + /** + * Set tablet details when a cursor enters range. + * \param inRange: Whether the Wintab device is in tracking range. + */ + void processWintabProximityEvent(bool inRange); + + /** + * Handle Wintab info changes such as change in number of connected tablets. + * \param lParam: LPARAM of the event. + */ + void processWintabInfoChangeEvent(LPARAM lParam); + + /** + * Translate Wintab packets into GHOST_WintabInfoWin32 structs. + * \param outWintabInfo: Storage to return resulting GHOST_WintabInfoWin32 structs. + * \return Success if able to read packets, even if there are none. + */ + GHOST_TSuccess getWintabInfo(std::vector<GHOST_WintabInfoWin32> &outWintabInfo); + + /** + * Updates stored pending Wintab events. + */ + void updatePendingWintabEvents(); GHOST_TSuccess beginFullScreen() const { @@ -459,12 +503,25 @@ class GHOST_WindowWin32 : public GHOST_Window { GHOST_TUns16 getDPIHint() override; /** - * Get whether there are currently any mouse buttons pressed - * \return True if there are any currently pressed mouse buttons + * Get whether there are currently any mouse buttons pressed. + * \return True if there are any currently pressed mouse buttons. */ bool getMousePressed() const; - /** Whether a tablet stylus is being tracked */ + /** + * 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; /** if the window currently resizing */ @@ -483,7 +540,7 @@ class GHOST_WindowWin32 : public GHOST_Window { private: /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); @@ -497,7 +554,7 @@ class GHOST_WindowWin32 : public GHOST_Window { /** * Sets the cursor grab on the window using native window system calls. * Using registerMouseClickEvent. - * \param mode GHOST_TGrabCursorMode. + * \param mode: GHOST_TGrabCursorMode. */ GHOST_TSuccess setWindowCursorGrab(GHOST_TGrabCursorMode mode); @@ -547,28 +604,55 @@ class GHOST_WindowWin32 : public GHOST_Window { static const wchar_t *s_windowClassName; static const int s_maxTitleLength; - /** Tablet data for GHOST */ - GHOST_TabletData m_tabletData; - /* Wintab API */ struct { /** WinTab dll handle */ - HMODULE handle; + HMODULE handle = NULL; /** API functions */ - GHOST_WIN32_WTInfo info; - GHOST_WIN32_WTOpen open; - GHOST_WIN32_WTClose close; - GHOST_WIN32_WTPacket packet; - GHOST_WIN32_WTEnable enable; - GHOST_WIN32_WTOverlap overlap; + GHOST_WIN32_WTInfo info = NULL; + GHOST_WIN32_WTGet get = NULL; + GHOST_WIN32_WTSet set = NULL; + GHOST_WIN32_WTOpen open = NULL; + GHOST_WIN32_WTClose close = NULL; + GHOST_WIN32_WTPacketsGet packetsGet = NULL; + GHOST_WIN32_WTQueueSizeGet queueSizeGet = NULL; + GHOST_WIN32_WTQueueSizeSet queueSizeSet = NULL; + GHOST_WIN32_WTEnable enable = NULL; + GHOST_WIN32_WTOverlap overlap = NULL; /** Stores the Tablet context if detected Tablet features using WinTab.dll */ - HCTX tablet; - LONG maxPressure; - LONG maxAzimuth, maxAltitude; + HCTX context = NULL; + /** Number of connected Wintab digitizers */ + UINT numDevices = 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; + 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; + /** + * Wintab setup. + */ + void initializeWintab(); + + /** + * 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. + * \param buttonMask: Return pointer for button found. + * \return Whether an associated button was found. + */ + GHOST_TSuccess wintabMouseToGhost(UINT cursor, + WORD physicalButton, + GHOST_TButtonMask &buttonMask); + GHOST_TWindowState m_normal_state; /** user32 dll handle*/ diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index a4d17d1add3..01699e9d1ce 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -54,16 +54,16 @@ class GHOST_WindowX11 : public GHOST_Window { * Constructor. * Creates a new window and opens it. * To check if the window was created properly, use the getValid() method. - * \param title The text shown in the title bar of the window. - * \param left The coordinate of the left edge of the window. - * \param top The coordinate of the top edge of the window. - * \param width The width the window. - * \param height The height the window. - * \param state The state the window is initially opened with. - * \param parentWindow Parent (embedder) window - * \param type The type of drawing context installed in this window. - * \param stereoVisual Stereo visual for quad buffered stereo. - * \param alphaBackground Enable alpha blending of window with display background + * \param title: The text shown in the title bar of the window. + * \param left: The coordinate of the left edge of the window. + * \param top: The coordinate of the top edge of the window. + * \param width: The width the window. + * \param height: The height the window. + * \param state: The state the window is initially opened with. + * \param parentWindow: Parent (embedder) window. + * \param type: The type of drawing context installed in this window. + * \param stereoVisual: Stereo visual for quad buffered stereo. + * \param alphaBackground: Enable alpha blending of window with display background. */ GHOST_WindowX11(GHOST_SystemX11 *system, Display *display, @@ -186,7 +186,7 @@ class GHOST_WindowX11 : public GHOST_Window { protected: /** - * \param type The type of rendering context create. + * \param type: The type of rendering context create. * \return Indication of success. */ GHOST_Context *newDrawingContext(GHOST_TDrawingContextType type); diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 583bda9731a..2bf67c121f8 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -277,7 +277,7 @@ void GHOST_XrContext::setErrorHandler(GHOST_XrErrorHandlerFn handler_fn, void *c * \{ */ /** - * \param layer_name May be NULL for extensions not belonging to a specific layer. + * \param layer_name: May be NULL for extensions not belonging to a specific layer. */ void GHOST_XrContext::initExtensionsEx(std::vector<XrExtensionProperties> &extensions, const char *layer_name) diff --git a/intern/ghost/intern/GHOST_XrSession.cpp b/intern/ghost/intern/GHOST_XrSession.cpp index e43991853cb..73b73a8f046 100644 --- a/intern/ghost/intern/GHOST_XrSession.cpp +++ b/intern/ghost/intern/GHOST_XrSession.cpp @@ -222,7 +222,7 @@ GHOST_XrSession::LifeExpectancy GHOST_XrSession::handleStateChangeEvent( m_oxr->session_state = lifecycle.state; /* Runtime may send events for apparently destroyed session. Our handle should be NULL then. */ - assert((m_oxr->session == XR_NULL_HANDLE) || (m_oxr->session == lifecycle.session)); + assert(m_oxr->session == XR_NULL_HANDLE || m_oxr->session == lifecycle.session); switch (lifecycle.state) { case XR_SESSION_STATE_READY: { diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt index b6e3c0ecf5f..27a764cd050 100644 --- a/intern/ghost/test/CMakeLists.txt +++ b/intern/ghost/test/CMakeLists.txt @@ -233,8 +233,8 @@ else() set(GLEW_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/extern/glew/include") endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS}") +string(APPEND CMAKE_C_FLAGS " ${PLATFORM_CFLAGS}") +string(APPEND CMAKE_CXX_FLAGS " ${PLATFORM_CFLAGS}") # ----------------------------------------------------------------------------- # Executables diff --git a/intern/libmv/intern/reconstruction.cc b/intern/libmv/intern/reconstruction.cc index 64f00b19df0..0f4e890d4ca 100644 --- a/intern/libmv/intern/reconstruction.cc +++ b/intern/libmv/intern/reconstruction.cc @@ -95,12 +95,23 @@ void libmv_solveRefineIntrinsics( if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) { bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT; } - if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) { - bundle_intrinsics |= libmv::BUNDLE_RADIAL_K1; - } - if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) { - bundle_intrinsics |= libmv::BUNDLE_RADIAL_K2; - } + +#define SET_DISTORTION_FLAG_CHECKED(type, coefficient) \ + do { \ + if (refine_intrinsics & LIBMV_REFINE_ ## type ##_DISTORTION_ ## coefficient) { \ + bundle_intrinsics |= libmv::BUNDLE_ ## type ## _ ## coefficient; \ + } \ + } while (0) + + SET_DISTORTION_FLAG_CHECKED(RADIAL, K1); + SET_DISTORTION_FLAG_CHECKED(RADIAL, K2); + SET_DISTORTION_FLAG_CHECKED(RADIAL, K3); + SET_DISTORTION_FLAG_CHECKED(RADIAL, K4); + + SET_DISTORTION_FLAG_CHECKED(TANGENTIAL, P1); + SET_DISTORTION_FLAG_CHECKED(TANGENTIAL, P2); + +#undef SET_DISTORTION_FLAG_CHECKED progress_update_callback(callback_customdata, 1.0, "Refining solution"); diff --git a/intern/libmv/intern/reconstruction.h b/intern/libmv/intern/reconstruction.h index 727a4943add..408ac884684 100644 --- a/intern/libmv/intern/reconstruction.h +++ b/intern/libmv/intern/reconstruction.h @@ -31,10 +31,22 @@ struct libmv_CameraIntrinsicsOptions; typedef struct libmv_Reconstruction libmv_Reconstruction; enum { - LIBMV_REFINE_FOCAL_LENGTH = (1 << 0), - LIBMV_REFINE_PRINCIPAL_POINT = (1 << 1), - LIBMV_REFINE_RADIAL_DISTORTION_K1 = (1 << 2), - LIBMV_REFINE_RADIAL_DISTORTION_K2 = (1 << 4), + LIBMV_REFINE_FOCAL_LENGTH = (1 << 0), + LIBMV_REFINE_PRINCIPAL_POINT = (1 << 1), + + LIBMV_REFINE_RADIAL_DISTORTION_K1 = (1 << 2), + LIBMV_REFINE_RADIAL_DISTORTION_K2 = (1 << 3), + LIBMV_REFINE_RADIAL_DISTORTION_K3 = (1 << 4), + LIBMV_REFINE_RADIAL_DISTORTION_K4 = (1 << 5), + LIBMV_REFINE_RADIAL_DISTORTION = (LIBMV_REFINE_RADIAL_DISTORTION_K1 | + LIBMV_REFINE_RADIAL_DISTORTION_K2 | + LIBMV_REFINE_RADIAL_DISTORTION_K3 | + LIBMV_REFINE_RADIAL_DISTORTION_K4), + + LIBMV_REFINE_TANGENTIAL_DISTORTION_P1 = (1 << 6), + LIBMV_REFINE_TANGENTIAL_DISTORTION_P2 = (1 << 7), + LIBMV_REFINE_TANGENTIAL_DISTORTION = (LIBMV_REFINE_TANGENTIAL_DISTORTION_P1 | + LIBMV_REFINE_TANGENTIAL_DISTORTION_P2), }; typedef struct libmv_ReconstructionOptions { diff --git a/intern/libmv/libmv/image/array_nd_test.cc b/intern/libmv/libmv/image/array_nd_test.cc index 313f21b60e9..dc7cfacf90d 100644 --- a/intern/libmv/libmv/image/array_nd_test.cc +++ b/intern/libmv/libmv/image/array_nd_test.cc @@ -191,10 +191,10 @@ TEST(ArrayND, CopyFrom) { a(1, 1, 0) = 4; ArrayND<float, 3> b; b.CopyFrom(a); - EXPECT_FLOAT_EQ(1.f, b(0, 0, 0)); - EXPECT_FLOAT_EQ(2.f, b(0, 1, 0)); - EXPECT_FLOAT_EQ(3.f, b(1, 0, 0)); - EXPECT_FLOAT_EQ(4.f, b(1, 1, 0)); + EXPECT_FLOAT_EQ(1.0f, b(0, 0, 0)); + EXPECT_FLOAT_EQ(2.0f, b(0, 1, 0)); + EXPECT_FLOAT_EQ(3.0f, b(1, 0, 0)); + EXPECT_FLOAT_EQ(4.0f, b(1, 1, 0)); } TEST(ArrayND, MultiplyElements) { diff --git a/intern/libmv/libmv/multiview/homography.h b/intern/libmv/libmv/multiview/homography.h index 6d810c845ed..a76aa9405a5 100644 --- a/intern/libmv/libmv/multiview/homography.h +++ b/intern/libmv/libmv/multiview/homography.h @@ -27,21 +27,23 @@ namespace libmv { /** * 2D homography transformation estimation. - * + * * This function estimates the homography transformation from a list of 2D * correspondences which represents either: * * - 3D points on a plane, with a general moving camera. * - 3D points with a rotating camera (pure rotation). * - 3D points + different planar projections - * - * \param x1 The first 2xN or 3xN matrix of euclidean or homogeneous points. - * \param x2 The second 2xN or 3xN matrix of euclidean or homogeneous points. - * \param H The 3x3 homography transformation matrix (8 dof) such that - * x2 = H * x1 with |a b c| - * H = |d e f| - * |g h 1| - * \param expected_precision The expected precision in order for instance + * + * \param x1: The first 2xN or 3xN matrix of euclidean or homogeneous points. + * \param x2: The second 2xN or 3xN matrix of euclidean or homogeneous points. + * \param H: The 3x3 homography transformation matrix (8 dof) such that + * <pre> + * x2 = H * x1 with |a b c| + * H = |d e f| + * |g h 1| + * </pre> + * \param expected_precision: The expected precision in order for instance * to accept almost homography matrices. * * \return True if the transformation estimation has succeeded. @@ -113,16 +115,18 @@ bool EstimateHomography2DFromCorrespondences( * \param[in] x1 The first 4xN matrix of homogeneous points * \param[in] x2 The second 4xN matrix of homogeneous points * \param[out] H The 4x4 homography transformation matrix (15 dof) such that - * x2 = H * x1 with |a b c d| - * H = |e f g h| - * |i j k l| - * |m n o 1| - * \param[in] expected_precision The expected precision in order for instance + * <pre> + * x2 = H * x1 with |a b c d| + * H = |e f g h| + * |i j k l| + * |m n o 1| + * </pre> + * \param[in] expected_precision The expected precision in order for instance * to accept almost homography matrices. * * \return true if the transformation estimation has succeeded * - * \note Need at least 5 non coplanar points + * \note Need at least 5 non coplanar points * \note Points coordinates must be in homogeneous coordinates */ bool Homography3DFromCorrespondencesLinear(const Mat &x1, diff --git a/intern/libmv/libmv/simple_pipeline/bundle.cc b/intern/libmv/libmv/simple_pipeline/bundle.cc index 3df39ab8936..d62f0ebe94f 100644 --- a/intern/libmv/libmv/simple_pipeline/bundle.cc +++ b/intern/libmv/libmv/simple_pipeline/bundle.cc @@ -368,6 +368,8 @@ void BundleIntrinsicsLogMessage(const int bundle_intrinsics) { APPEND_BUNDLING_INTRINSICS("px, py", BUNDLE_PRINCIPAL_POINT); APPEND_BUNDLING_INTRINSICS("k1", BUNDLE_RADIAL_K1); APPEND_BUNDLING_INTRINSICS("k2", BUNDLE_RADIAL_K2); + APPEND_BUNDLING_INTRINSICS("k3", BUNDLE_RADIAL_K3); + APPEND_BUNDLING_INTRINSICS("k4", BUNDLE_RADIAL_K4); APPEND_BUNDLING_INTRINSICS("p1", BUNDLE_TANGENTIAL_P1); APPEND_BUNDLING_INTRINSICS("p2", BUNDLE_TANGENTIAL_P2); @@ -744,7 +746,8 @@ void EuclideanBundleCommonIntrinsics( std::vector<int> constant_intrinsics; #define MAYBE_SET_CONSTANT(bundle_enum, offset) \ - if (!(bundle_intrinsics & bundle_enum)) { \ + if (!(bundle_intrinsics & bundle_enum) || \ + !packed_intrinsics.IsParameterDefined(offset)) { \ constant_intrinsics.push_back(offset); \ } MAYBE_SET_CONSTANT(BUNDLE_FOCAL_LENGTH, @@ -755,22 +758,19 @@ void EuclideanBundleCommonIntrinsics( PackedIntrinsics::OFFSET_PRINCIPAL_POINT_Y); MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K1, PackedIntrinsics::OFFSET_K1); MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K2, PackedIntrinsics::OFFSET_K2); + MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K3, PackedIntrinsics::OFFSET_K3); + MAYBE_SET_CONSTANT(BUNDLE_RADIAL_K4, PackedIntrinsics::OFFSET_K4); MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P1, PackedIntrinsics::OFFSET_P1); MAYBE_SET_CONSTANT(BUNDLE_TANGENTIAL_P2, PackedIntrinsics::OFFSET_P2); #undef MAYBE_SET_CONSTANT - // Always set K3 and K4 constant, it's not used at the moment. - constant_intrinsics.push_back(PackedIntrinsics::OFFSET_K3); - constant_intrinsics.push_back(PackedIntrinsics::OFFSET_K4); + if (!constant_intrinsics.empty()) { + ceres::SubsetParameterization *subset_parameterization = + new ceres::SubsetParameterization(PackedIntrinsics::NUM_PARAMETERS, + constant_intrinsics); - // TODO(sergey): Mark all parameters which are not used by the distortion - // model as constant. - - ceres::SubsetParameterization *subset_parameterization = - new ceres::SubsetParameterization(PackedIntrinsics::NUM_PARAMETERS, - constant_intrinsics); - - problem.SetParameterization(intrinsics_block, subset_parameterization); + problem.SetParameterization(intrinsics_block, subset_parameterization); + } } // Configure the solver. diff --git a/intern/libmv/libmv/simple_pipeline/bundle.h b/intern/libmv/libmv/simple_pipeline/bundle.h index 781bd8476fe..5f420da0045 100644 --- a/intern/libmv/libmv/simple_pipeline/bundle.h +++ b/intern/libmv/libmv/simple_pipeline/bundle.h @@ -101,14 +101,22 @@ void EuclideanBundle(const Tracks &tracks, */ enum BundleIntrinsics { BUNDLE_NO_INTRINSICS = 0, - BUNDLE_FOCAL_LENGTH = 1, - BUNDLE_PRINCIPAL_POINT = 2, - BUNDLE_RADIAL_K1 = 4, - BUNDLE_RADIAL_K2 = 8, - BUNDLE_RADIAL = 12, - BUNDLE_TANGENTIAL_P1 = 16, - BUNDLE_TANGENTIAL_P2 = 32, - BUNDLE_TANGENTIAL = 48, + + BUNDLE_FOCAL_LENGTH = (1 << 0), + BUNDLE_PRINCIPAL_POINT = (1 << 1), + + BUNDLE_RADIAL_K1 = (1 << 2), + BUNDLE_RADIAL_K2 = (1 << 3), + BUNDLE_RADIAL_K3 = (1 << 4), + BUNDLE_RADIAL_K4 = (1 << 5), + BUNDLE_RADIAL = (BUNDLE_RADIAL_K1 | + BUNDLE_RADIAL_K2 | + BUNDLE_RADIAL_K3 | + BUNDLE_RADIAL_K4), + + BUNDLE_TANGENTIAL_P1 = (1 << 6), + BUNDLE_TANGENTIAL_P2 = (1 << 7), + BUNDLE_TANGENTIAL = (BUNDLE_TANGENTIAL_P1 | BUNDLE_TANGENTIAL_P2), }; enum BundleConstraints { BUNDLE_NO_CONSTRAINTS = 0, diff --git a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h index 30b0f1abf7b..ba67ec468dc 100644 --- a/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h +++ b/intern/libmv/libmv/simple_pipeline/camera_intrinsics.h @@ -292,7 +292,7 @@ class PolynomialCameraIntrinsics : public CameraIntrinsics { PolynomialCameraIntrinsics(); PolynomialCameraIntrinsics(const PolynomialCameraIntrinsics &from); - DistortionModelType GetDistortionModelType() const { + DistortionModelType GetDistortionModelType() const override { return DISTORTION_MODEL_POLYNOMIAL; } @@ -316,7 +316,7 @@ class PolynomialCameraIntrinsics : public CameraIntrinsics { void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, - double *image_y) const; + double *image_y) const override; // Invert camera intrinsics on the image point to get normalized coordinates. // @@ -325,7 +325,7 @@ class PolynomialCameraIntrinsics : public CameraIntrinsics { void InvertIntrinsics(double image_x, double image_y, double *normalized_x, - double *normalized_y) const; + double *normalized_y) const override; virtual void Pack(PackedIntrinsics* packed_intrinsics) const override; virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override; @@ -354,7 +354,7 @@ class DivisionCameraIntrinsics : public CameraIntrinsics { DivisionCameraIntrinsics(); DivisionCameraIntrinsics(const DivisionCameraIntrinsics &from); - DistortionModelType GetDistortionModelType() const { + DistortionModelType GetDistortionModelType() const override { return DISTORTION_MODEL_DIVISION; } @@ -372,7 +372,7 @@ class DivisionCameraIntrinsics : public CameraIntrinsics { void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, - double *image_y) const; + double *image_y) const override; // Invert camera intrinsics on the image point to get normalized coordinates. // @@ -381,7 +381,7 @@ class DivisionCameraIntrinsics : public CameraIntrinsics { void InvertIntrinsics(double image_x, double image_y, double *normalized_x, - double *normalized_y) const; + double *normalized_y) const override; virtual void Pack(PackedIntrinsics* packed_intrinsics) const override; virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override; @@ -407,7 +407,7 @@ class NukeCameraIntrinsics : public CameraIntrinsics { NukeCameraIntrinsics(); NukeCameraIntrinsics(const NukeCameraIntrinsics &from); - DistortionModelType GetDistortionModelType() const { + DistortionModelType GetDistortionModelType() const override { return DISTORTION_MODEL_NUKE; } @@ -425,7 +425,7 @@ class NukeCameraIntrinsics : public CameraIntrinsics { void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, - double *image_y) const; + double *image_y) const override; // Invert camera intrinsics on the image point to get normalized coordinates. // @@ -434,7 +434,7 @@ class NukeCameraIntrinsics : public CameraIntrinsics { void InvertIntrinsics(double image_x, double image_y, double *normalized_x, - double *normalized_y) const; + double *normalized_y) const override; virtual void Pack(PackedIntrinsics* packed_intrinsics) const override; virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override; @@ -464,7 +464,7 @@ class BrownCameraIntrinsics : public CameraIntrinsics { BrownCameraIntrinsics(); BrownCameraIntrinsics(const BrownCameraIntrinsics &from); - DistortionModelType GetDistortionModelType() const { + DistortionModelType GetDistortionModelType() const override { return DISTORTION_MODEL_BROWN; } @@ -489,7 +489,7 @@ class BrownCameraIntrinsics : public CameraIntrinsics { void ApplyIntrinsics(double normalized_x, double normalized_y, double *image_x, - double *image_y) const; + double *image_y) const override; // Invert camera intrinsics on the image point to get normalized coordinates. // @@ -498,7 +498,7 @@ class BrownCameraIntrinsics : public CameraIntrinsics { void InvertIntrinsics(double image_x, double image_y, double *normalized_x, - double *normalized_y) const; + double *normalized_y) const override; virtual void Pack(PackedIntrinsics* packed_intrinsics) const override; virtual void Unpack(const PackedIntrinsics& packed_intrinsics) override; diff --git a/intern/libmv/libmv/simple_pipeline/keyframe_selection.h b/intern/libmv/libmv/simple_pipeline/keyframe_selection.h index aa3eeaf193d..25253af32fe 100644 --- a/intern/libmv/libmv/simple_pipeline/keyframe_selection.h +++ b/intern/libmv/libmv/simple_pipeline/keyframe_selection.h @@ -38,11 +38,11 @@ namespace libmv { // and if expected error estimation is too large, keyframe candidate // is rejecting. // -// \param tracks contains all tracked correspondences between frames -// expected to be undistorted and normalized -// \param intrinsics is camera intrinsics -// \param keyframes will contain all images number which are considered -// good to be used for reconstruction +// \param tracks: contains all tracked correspondences between frames +// expected to be undistorted and normalized. +// \param intrinsics: is camera intrinsics. +// \param keyframes: will contain all images number which are considered +// good to be used for reconstruction. void SelectKeyframesBasedOnGRICAndVariance( const Tracks &tracks, const CameraIntrinsics &intrinsics, diff --git a/intern/libmv/libmv/simple_pipeline/packed_intrinsics.cc b/intern/libmv/libmv/simple_pipeline/packed_intrinsics.cc index e9d7c2e78be..73ad4faed9c 100644 --- a/intern/libmv/libmv/simple_pipeline/packed_intrinsics.cc +++ b/intern/libmv/libmv/simple_pipeline/packed_intrinsics.cc @@ -47,7 +47,7 @@ double PackedIntrinsics::GetPrincipalPointY() const { void PackedIntrinsics::SetParameter(int index, double value) { parameters_.at(index) = value; - known_parameters_.at(index) = value; + known_parameters_.at(index) = true; } double PackedIntrinsics::GetParameter(int index) const { // TODO(sergey): Consider adding a check for whether the parameter is known. @@ -55,4 +55,8 @@ double PackedIntrinsics::GetParameter(int index) const { return parameters_.at(index); } +bool PackedIntrinsics::IsParameterDefined(int offset) { + return known_parameters_.at(offset); +} + } // namespace libmv diff --git a/intern/libmv/libmv/simple_pipeline/packed_intrinsics.h b/intern/libmv/libmv/simple_pipeline/packed_intrinsics.h index e551fe74800..cbea599fccd 100644 --- a/intern/libmv/libmv/simple_pipeline/packed_intrinsics.h +++ b/intern/libmv/libmv/simple_pipeline/packed_intrinsics.h @@ -86,6 +86,8 @@ class PackedIntrinsics { double* GetParametersBlock() { return parameters_.data(); } const double* GetParametersBlock() const { return parameters_.data(); } + bool IsParameterDefined(int offset); + private: void SetParameter(int index, double value); double GetParameter(int index) const; diff --git a/intern/mantaflow/intern/MANTA_main.cpp b/intern/mantaflow/intern/MANTA_main.cpp index dec05831e61..0dbbd1ee9d0 100644 --- a/intern/mantaflow/intern/MANTA_main.cpp +++ b/intern/mantaflow/intern/MANTA_main.cpp @@ -697,12 +697,6 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd) if ((fds->border_collisions & FLUID_DOMAIN_BORDER_TOP) == 0) borderCollisions += "Z"; - string simulationMethod = ""; - if (fds->simulation_method & FLUID_DOMAIN_METHOD_FLIP) - simulationMethod += "'FLIP'"; - else if (fds->simulation_method & FLUID_DOMAIN_METHOD_APIC) - simulationMethod += "'APIC'"; - string particleTypesStr = ""; if (fds->particle_type & FLUID_DOMAIN_PARTICLE_SPRAY) particleTypesStr += "PtypeSpray"; @@ -837,7 +831,7 @@ void MANTA::initializeRNAMap(FluidModifierData *fmd) mRNAMap["CACHE_MESH_FORMAT"] = getCacheFileEnding(fds->cache_mesh_format); mRNAMap["CACHE_NOISE_FORMAT"] = getCacheFileEnding(fds->cache_noise_format); mRNAMap["CACHE_PARTICLE_FORMAT"] = getCacheFileEnding(fds->cache_particle_format); - mRNAMap["SIMULATION_METHOD"] = simulationMethod; + mRNAMap["USING_APIC"] = getBooleanString(fds->simulation_method == FLUID_DOMAIN_METHOD_APIC); mRNAMap["FLIP_RATIO"] = to_string(fds->flip_ratio); mRNAMap["PARTICLE_RANDOMNESS"] = to_string(fds->particle_randomness); mRNAMap["PARTICLE_NUMBER"] = to_string(fds->particle_number); diff --git a/intern/mantaflow/intern/strings/fluid_script.h b/intern/mantaflow/intern/strings/fluid_script.h index dfc751e45db..0df9e0e8df0 100644 --- a/intern/mantaflow/intern/strings/fluid_script.h +++ b/intern/mantaflow/intern/strings/fluid_script.h @@ -39,11 +39,7 @@ isWindows = platform.system() != 'Darwin' and platform.system() != 'Linux'\n\ #try:\n\ # multiprocessing.set_start_method('spawn')\n\ #except:\n\ -# pass\n\ -\n\ -bpy = sys.modules.get('bpy')\n\ -if bpy is not None:\n\ - sys.executable = bpy.app.binary_path_python\n"; +# pass\n"; ////////////////////////////////////////////////////////////////////// // DEBUG diff --git a/intern/mantaflow/intern/strings/liquid_script.h b/intern/mantaflow/intern/strings/liquid_script.h index 7622fc5a602..8e0d113d680 100644 --- a/intern/mantaflow/intern/strings/liquid_script.h +++ b/intern/mantaflow/intern/strings/liquid_script.h @@ -50,7 +50,8 @@ smoothenPos_s$ID$ = $MESH_SMOOTHEN_POS$\n\ 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"; +maxSysParticles_s$ID$ = $PP_PARTICLE_MAXIMUM$\n\ +using_apic_s$ID$ = $USING_APIC$\n"; const std::string liquid_variables_particles = "\n\ @@ -91,6 +92,14 @@ curvature_s$ID$ = None\n\ pp_s$ID$ = s$ID$.create(BasicParticleSystem, name='$NAME_PARTS$')\n\ pVel_pp$ID$ = pp_s$ID$.create(PdataVec3, name='$NAME_PARTSVELOCITY$')\n\ \n\ +pCx_pp$ID$ = None\n\ +pCy_pp$ID$ = None\n\ +pCz_pp$ID$ = None\n\ +if using_apic_s$ID$:\n\ + pCx_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\ + pCy_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\ + pCz_pp$ID$ = pp_s$ID$.create(PdataVec3)\n\ +\n\ # Acceleration data for particle nbs\n\ pindex_s$ID$ = s$ID$.create(ParticleIndexSystem, name='$NAME_PINDEX$')\n\ gpi_s$ID$ = s$ID$.create(IntGrid, name='$NAME_GPI$')\n\ @@ -275,8 +284,12 @@ def liquid_step_$ID$():\n\ resetOutflow(flags=flags_s$ID$, phi=phi_s$ID$, parts=pp_s$ID$, index=gpi_s$ID$, indexSys=pindex_s$ID$)\n\ flags_s$ID$.updateFromLevelset(phi_s$ID$)\n\ \n\ - # combine particles velocities with advected grid velocities\n\ - mapPartsToMAC(vel=velParts_s$ID$, flags=flags_s$ID$, velOld=velOld_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, weight=mapWeights_s$ID$)\n\ + # combine particle velocities with advected grid velocities\n\ + if using_apic_s$ID$:\n\ + apicMapPartsToMAC(flags=flags_s$ID$, vel=vel_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, cpx=pCx_pp$ID$, cpy=pCy_pp$ID$, cpz=pCz_pp$ID$)\n\ + else:\n\ + mapPartsToMAC(vel=velParts_s$ID$, flags=flags_s$ID$, velOld=velOld_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, weight=mapWeights_s$ID$)\n\ + \n\ extrapolateMACFromWeight(vel=velParts_s$ID$, distance=2, weight=mapWeights_s$ID$)\n\ combineGridVel(vel=velParts_s$ID$, weight=mapWeights_s$ID$, combineVel=vel_s$ID$, phi=phi_s$ID$, narrowBand=combineBandWidth_s$ID$, thresh=0)\n\ velOld_s$ID$.copyFrom(vel_s$ID$)\n\ @@ -319,7 +332,11 @@ def liquid_step_$ID$():\n\ # set source grids for resampling, used in adjustNumber!\n\ pVel_pp$ID$.setSource(grid=vel_s$ID$, isMAC=True)\n\ adjustNumber(parts=pp_s$ID$, vel=vel_s$ID$, flags=flags_s$ID$, minParticles=minParticles_s$ID$, maxParticles=maxParticles_s$ID$, phi=phi_s$ID$, exclude=phiObs_s$ID$, radiusFactor=radiusFactor_s$ID$, narrowBand=adjustedNarrowBandWidth_s$ID$)\n\ - flipVelocityUpdate(vel=vel_s$ID$, velOld=velOld_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, flipRatio=flipRatio_s$ID$)\n"; + \n\ + if using_apic_s$ID$:\n\ + apicMapMACGridToParts(partVel=pVel_pp$ID$, cpx=pCx_pp$ID$, cpy=pCy_pp$ID$, cpz=pCz_pp$ID$, parts=pp_s$ID$, vel=vel_s$ID$, flags=flags_s$ID$)\n\ + else:\n\ + flipVelocityUpdate(vel=vel_s$ID$, velOld=velOld_s$ID$, flags=flags_s$ID$, parts=pp_s$ID$, partVel=pVel_pp$ID$, flipRatio=flipRatio_s$ID$)\n"; const std::string liquid_step_mesh = "\n\ diff --git a/release/datafiles/alert_icons.png b/release/datafiles/alert_icons.png Binary files differindex c73277af99b..e1cb671713f 100644 --- a/release/datafiles/alert_icons.png +++ b/release/datafiles/alert_icons.png diff --git a/release/datafiles/alert_icons.svg b/release/datafiles/alert_icons.svg index 1e4aefd8b4e..530071ecddc 100644 --- a/release/datafiles/alert_icons.svg +++ b/release/datafiles/alert_icons.svg @@ -10,9 +10,9 @@ <rect x="6" y="6" width="52" height="52" style="fill:#fff;"/> </g> <g id="WARNING"> - <path d="M35.462,10.006c-0.714,-1.241 -2.036,-2.006 -3.468,-2.006c-1.432,-0 -2.754,0.765 -3.468,2.006l-23,40c-0.711,1.238 -0.709,2.761 0.006,3.997c0.715,1.236 2.034,1.997 3.462,1.997l46,0c1.428,0 2.747,-0.761 3.462,-1.997c0.715,-1.236 0.717,-2.759 0.006,-3.997l-23,-40Zm-2.601,1.496l23,40c0.178,0.309 0.177,0.69 -0.001,0.999c-0.179,0.309 -0.509,0.499 -0.866,0.499l-46,0c-0.357,-0 -0.687,-0.19 -0.866,-0.499c-0.178,-0.309 -0.179,-0.69 -0.001,-0.999c0,-0 23,-40 23,-40c0.179,-0.311 0.509,-0.502 0.867,-0.502c0.358,0 0.689,0.191 0.867,0.502Z" style="fill:#fff;"/> - <circle cx="32" cy="46.5" r="2.5" style="fill:#fff;"/> - <path d="M32,24c1.38,0 2.5,1.12 2.5,2.5l-1.5,14.5l-2,0l-1.5,-14.5c0,-1.38 1.12,-2.5 2.5,-2.5Z" style="fill:#fff;"/> + <path d="M37.212,10.038c-1.066,-1.878 -3.059,-3.038 -5.218,-3.038c-2.159,-0 -4.152,1.16 -5.218,3.038l-21,37c-1.054,1.858 -1.042,4.135 0.033,5.981c1.075,1.846 3.049,2.981 5.185,2.981l42,-0c2.136,0 4.11,-1.135 5.185,-2.981c1.075,-1.846 1.087,-4.123 0.033,-5.981l-21,-37Zm-2.609,1.481l21,37c0.527,0.929 0.521,2.068 -0.016,2.991c-0.538,0.922 -1.525,1.49 -2.593,1.49l-42,-0c-1.068,0 -2.055,-0.568 -2.593,-1.49c-0.537,-0.923 -0.543,-2.062 -0.016,-2.991c-0,0 21,-37 21,-37c0.533,-0.939 1.529,-1.519 2.609,-1.519c1.08,0 2.076,0.58 2.609,1.519Z" style="fill:#fff;"/> + <circle cx="32" cy="45.5" r="2.5" style="fill:#fff;"/> + <path d="M32,23c1.38,0 2.5,1.12 2.5,2.5l-1.5,14.5l-2,0l-1.5,-14.5c0,-1.38 1.12,-2.5 2.5,-2.5Z" style="fill:#fff;"/> </g> <g id="QUESTION"> <path d="M96,6c14.35,-0 26,11.65 26,26c-0,14.35 -11.65,26 -26,26c-14.35,-0 -26,-11.65 -26,-26c-0,-14.35 11.65,-26 26,-26Zm-0,3c12.694,-0 23,10.306 23,23c-0,12.694 -10.306,23 -23,23c-12.694,-0 -23,-10.306 -23,-23c-0,-12.694 10.306,-23 23,-23Z" style="fill:#fff;"/> diff --git a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat Binary files differindex cfd1e186f61..6ce7f1948c0 100644 --- a/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat +++ b/release/datafiles/icons/ops.gpencil.sculpt_randomize.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat Binary files differindex 7fced673192..a280ad7ab3e 100644 --- a/release/datafiles/icons/ops.gpencil.sculpt_strength.dat +++ b/release/datafiles/icons/ops.gpencil.sculpt_strength.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat Binary files differindex 1e558806888..7204343c08a 100644 --- a/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat +++ b/release/datafiles/icons/ops.gpencil.sculpt_thickness.dat diff --git a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat Binary files differindex 01c9587ec2e..e66af3555c5 100644 --- a/release/datafiles/icons/ops.gpencil.sculpt_weight.dat +++ b/release/datafiles/icons/ops.gpencil.sculpt_weight.dat diff --git a/release/datafiles/icons/ops.sculpt.border_mask.dat b/release/datafiles/icons/ops.sculpt.border_mask.dat Binary files differindex 701b96e31d9..0c616d5dc42 100644 --- a/release/datafiles/icons/ops.sculpt.border_mask.dat +++ b/release/datafiles/icons/ops.sculpt.border_mask.dat diff --git a/release/datafiles/icons/ops.sculpt.box_trim.dat b/release/datafiles/icons/ops.sculpt.box_trim.dat Binary files differindex c4cd2282a2a..9a2e691a621 100644 --- a/release/datafiles/icons/ops.sculpt.box_trim.dat +++ b/release/datafiles/icons/ops.sculpt.box_trim.dat diff --git a/release/datafiles/icons/ops.sculpt.lasso_mask.dat b/release/datafiles/icons/ops.sculpt.lasso_mask.dat Binary files differindex 109ce3991ce..5406def96a7 100644 --- a/release/datafiles/icons/ops.sculpt.lasso_mask.dat +++ b/release/datafiles/icons/ops.sculpt.lasso_mask.dat diff --git a/release/datafiles/icons/ops.sculpt.lasso_trim.dat b/release/datafiles/icons/ops.sculpt.lasso_trim.dat Binary files differindex 31e7919d3c5..e87cdb97fec 100644 --- a/release/datafiles/icons/ops.sculpt.lasso_trim.dat +++ b/release/datafiles/icons/ops.sculpt.lasso_trim.dat diff --git a/release/datafiles/icons/ops.sculpt.line_project.dat b/release/datafiles/icons/ops.sculpt.line_project.dat Binary files differindex 816048d26c2..44cdf70a0df 100644 --- a/release/datafiles/icons/ops.sculpt.line_project.dat +++ b/release/datafiles/icons/ops.sculpt.line_project.dat diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 9f6078722ee..babb3e30c6d 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/datafiles/studiolights/studio/paint.sl b/release/datafiles/studiolights/studio/paint.sl new file mode 100644 index 00000000000..2442004e00c --- /dev/null +++ b/release/datafiles/studiolights/studio/paint.sl @@ -0,0 +1,48 @@ +version 1 +light_ambient.x 0.000000 +light_ambient.y 0.000000 +light_ambient.z 0.000000 +light[0].flag 1 +light[0].smooth 0.374078 +light[0].col.x 1.000000 +light[0].col.y 1.000000 +light[0].col.z 1.000000 +light[0].spec.x 0.281010 +light[0].spec.y 0.281010 +light[0].spec.z 0.281010 +light[0].vec.x 0.033898 +light[0].vec.y 0.406780 +light[0].vec.z 0.912897 +light[1].flag 1 +light[1].smooth 0.135593 +light[1].col.x 0.342384 +light[1].col.y 0.342384 +light[1].col.z 0.342384 +light[1].spec.x 0.000000 +light[1].spec.y 0.000000 +light[1].spec.z 0.000000 +light[1].vec.x 0.000000 +light[1].vec.y 0.372881 +light[1].vec.z 0.927879 +light[2].flag 1 +light[2].smooth 0.630803 +light[2].col.x 0.201899 +light[2].col.y 0.156801 +light[2].col.z 0.147954 +light[2].spec.x 0.066807 +light[2].spec.y 0.058182 +light[2].spec.z 0.063403 +light[2].vec.x 0.079643 +light[2].vec.y -0.681392 +light[2].vec.z -0.727573 +light[3].flag 1 +light[3].smooth 0.200000 +light[3].col.x 0.220250 +light[3].col.y 0.037944 +light[3].col.z 0.047254 +light[3].spec.x 0.106531 +light[3].spec.y 0.080187 +light[3].spec.z 0.063969 +light[3].vec.x -0.081162 +light[3].vec.y -0.173044 +light[3].vec.z -0.981564 diff --git a/release/scripts/modules/bl_keymap_utils/io.py b/release/scripts/modules/bl_keymap_utils/io.py index 433bd955029..091cdbc2642 100644 --- a/release/scripts/modules/bl_keymap_utils/io.py +++ b/release/scripts/modules/bl_keymap_utils/io.py @@ -73,6 +73,11 @@ def kmi_args_as_data(kmi): if kmi.key_modifier and kmi.key_modifier != 'NONE': s.append(f"\"key_modifier\": '{kmi.key_modifier}'") + if kmi.repeat: + if kmi.map_type == 'KEYBOARD': + if kmi.value in {'PRESS', 'ANY'}: + s.append("\"repeat\": True") + return "{" + ", ".join(s) + "}" @@ -161,6 +166,13 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False): with open(filepath, "w", encoding="utf-8") as fh: fw = fh.write + + # Use the file version since it includes the sub-version + # which we can bump multiple times between releases. + from bpy.app import version_file + fw(f"keyconfig_version = {version_file!r}\n") + del version_file + fw("keyconfig_data = \\\n[") for km, _kc_x in export_keymaps: @@ -212,7 +224,11 @@ def keyconfig_export_as_data(wm, kc, filepath, *, all_keymaps=False): fw("if __name__ == \"__main__\":\n") fw(" import os\n") fw(" from bl_keymap_utils.io import keyconfig_import_from_data\n") - fw(" keyconfig_import_from_data(os.path.splitext(os.path.basename(__file__))[0], keyconfig_data)\n") + fw(" keyconfig_import_from_data(\n") + fw(" os.path.splitext(os.path.basename(__file__))[0],\n") + fw(" keyconfig_data,\n") + fw(" keyconfig_version=keyconfig_version,\n") + fw(" )\n") # ----------------------------------------------------------------------------- @@ -264,7 +280,7 @@ def keyconfig_init_from_data(kc, keyconfig_data): keymap_init_from_data(km, km_items, is_modal=km_args.get("modal", False)) -def keyconfig_import_from_data(name, keyconfig_data): +def keyconfig_import_from_data(name, keyconfig_data, *, keyconfig_version=(0, 0, 0)): # Load data in the format defined above. # # Runs at load time, keep this fast! @@ -272,6 +288,9 @@ def keyconfig_import_from_data(name, keyconfig_data): import bpy wm = bpy.context.window_manager kc = wm.keyconfigs.new(name) + if keyconfig_version is not None: + from .versioning import keyconfig_update + keyconfig_data = keyconfig_update(keyconfig_data, keyconfig_version) keyconfig_init_from_data(kc, keyconfig_data) return kc diff --git a/release/scripts/modules/bl_keymap_utils/versioning.py b/release/scripts/modules/bl_keymap_utils/versioning.py new file mode 100644 index 00000000000..4c2e8ed7f54 --- /dev/null +++ b/release/scripts/modules/bl_keymap_utils/versioning.py @@ -0,0 +1,49 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +# Update Blender version this key-map was written in: +# +# When the version is ``(0, 0, 0)``, the key-map being loaded didn't contain any versioning information. +# This will older than ``(2, 92, 0)``. + +def keyconfig_update(keyconfig_data, keyconfig_version): + from bpy.app import version_file as blender_version + if keyconfig_version >= blender_version: + return keyconfig_data + + # Version the key-map. + import copy + has_copy = False + + # Default repeat to false. + if keyconfig_version <= (2, 92, 0): + # Only copy once. + if not has_copy: + keyconfig_data = copy.deepcopy(keyconfig_data) + has_copy = True + + for _km_name, _km_parms, km_items_data in keyconfig_data: + for (_item_op, item_event, _item_prop) in km_items_data["items"]: + if item_event.get("value") == 'PRESS': + # Unfortunately we don't know the 'map_type' at this point. + # Setting repeat true on other kinds of events is harmless. + item_event["repeat"] = True + + return keyconfig_data diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 98722ea322b..8fdd66dff9f 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -282,10 +282,10 @@ def draw(layout, context, context_member, property_type, use_edit=True): if use_edit: split = box.split(factor=0.75) - row = split.row(align=True) + row = split.row() else: split = box.split(factor=1.00) - row = split.row(align=True) + row = split.row() row.alignment = 'RIGHT' diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 03c5e6b18c0..174ab6fd28b 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -394,7 +394,7 @@ def km_window(params): ("wm.window_new", {"type": 'W', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("wm.window_fullscreen_toggle", {"type": 'F11', "value": 'PRESS', "alt": True}, None), ("wm.doc_view_manual_ui_context", {"type": 'F1', "value": 'PRESS', "alt": True}, None), - ("wm.search_menu", {"type": 'SPACE', "value": 'PRESS', "repeat": False}, None), + ("wm.search_menu", {"type": 'SPACE', "value": 'PRESS'}, None), ("wm.redraw_timer", {"type": 'T', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("wm.debug_menu", {"type": 'D', "value": 'PRESS', "ctrl": True, "alt": True}, None), ]) @@ -470,11 +470,11 @@ def km_window(params): ) elif params.spacebar_action == 'PLAY': items.append( - ("wm.toolbar", {"type": 'SPACE', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("wm.toolbar", {"type": 'SPACE', "value": 'PRESS', "shift": True}, None), ) elif params.spacebar_action == 'SEARCH': items.append( - ("wm.search_menu", {"type": 'SPACE', "value": 'PRESS', "repeat": False}, None), + ("wm.search_menu", {"type": 'SPACE', "value": 'PRESS'}, None), ) else: assert False @@ -506,14 +506,14 @@ def km_screen(params): # Quad view ("screen.region_quadview", {"type": 'Q', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Repeat last - ("screen.repeat_last", {"type": 'R', "value": 'PRESS', "shift": True}, None), + ("screen.repeat_last", {"type": 'R', "value": 'PRESS', "shift": True, "repeat": True}, None), # Files ("file.execute", {"type": 'RET', "value": 'PRESS'}, None), ("file.execute", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), ("file.cancel", {"type": 'ESC', "value": 'PRESS'}, None), # Undo - ("ed.undo", {"type": 'Z', "value": 'PRESS', "ctrl": True}, None), - ("ed.redo", {"type": 'Z', "value": 'PRESS', "shift": True, "ctrl": True}, None), + ("ed.undo", {"type": 'Z', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("ed.redo", {"type": 'Z', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, None), # Render ("render.render", {"type": 'F12', "value": 'PRESS'}, {"properties": [("use_viewport", True)]}), @@ -526,8 +526,8 @@ def km_screen(params): if not params.legacy: items.extend([ - ("screen.screen_full_area", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "repeat": False}, None), - ("screen.screen_full_area", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, + ("screen.screen_full_area", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, None), + ("screen.screen_full_area", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "alt": True}, {"properties": [("use_hide_panels", True)]}), ("screen.redo_last", {"type": 'F9', "value": 'PRESS'}, None), ]) @@ -633,8 +633,8 @@ def km_view2d(_params): # Zoom with single step ("view2d.zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, None), ("view2d.zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, None), - ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), - ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), + ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), + ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), ("view2d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), ("view2d.smoothview", {"type": 'TIMER1', "value": 'ANY', "any": True}, None), # Scroll up/down, only when zoom is not available. @@ -668,16 +668,16 @@ def km_view2d_buttons_list(_params): ("view2d.pan", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("view2d.scroll_down", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("view2d.scroll_up", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), - ("view2d.scroll_down", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("view2d.scroll_down", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("page", True)]}), - ("view2d.scroll_up", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("view2d.scroll_up", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("page", True)]}), # Zoom ("view2d.zoom", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "ctrl": True}, None), ("view2d.zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("view2d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), - ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), - ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), + ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), + ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), ("view2d.reset", {"type": 'HOME', "value": 'PRESS'}, None), ]) @@ -789,17 +789,21 @@ def km_outliner(params): {"properties": [("tweak", True), ("mode", "ADD")]}), ("outliner.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True}, {"properties": [("tweak", True), ("mode", "SUB")]}), - ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'UP')]}), - ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'UP')]}), + ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'UP'), ("extend", True)]}), - ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'DOWN')]}), - ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'DOWN')]}), + ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'DOWN'), ("extend", True)]}), - ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'LEFT')]}), - ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'LEFT')]}), + ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'LEFT'), ("toggle_all", True)]}), - ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'RIGHT')]}), - ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'RIGHT')]}), + ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'RIGHT'), ("toggle_all", True)]}), ("outliner.item_openclose", {"type": 'LEFTMOUSE', "value": 'CLICK'}, {"properties": [("all", False)]}), @@ -815,9 +819,9 @@ def km_outliner(params): ("outliner.show_hierarchy", {"type": 'HOME', "value": 'PRESS'}, None), ("outliner.show_active", {"type": 'PERIOD', "value": 'PRESS'}, None), ("outliner.show_active", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), - ("outliner.scroll_page", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("outliner.scroll_page", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("up", False)]}), - ("outliner.scroll_page", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("outliner.scroll_page", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("up", True)]}), ("outliner.show_one_level", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), ("outliner.show_one_level", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, @@ -890,8 +894,8 @@ def km_uv_editor(params): {"properties": [("extend", True), ("deselect", False)]}), ("uv.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, {"properties": [("extend", False), ("deselect", True)]}), - ("uv.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("uv.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("uv.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("uv.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), *_template_items_select_actions(params, "uv.select_all"), ("uv.select_pinned", {"type": 'P', "value": 'PRESS', "shift": True}, None), op_menu("IMAGE_MT_uvs_merge", {"type": 'M', "value": 'PRESS'}), @@ -912,12 +916,12 @@ def km_uv_editor(params): op_menu_pie("IMAGE_MT_uvs_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), op_menu("IMAGE_MT_uvs_select_mode", {"type": 'TAB', "value": 'PRESS', "ctrl": True}), *_template_items_proportional_editing(connected=False), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), ("wm.context_toggle", {"type": 'TAB', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.use_snap')]}), ("wm.context_menu_enum", {"type": 'TAB', "value": 'PRESS', "shift": True, "ctrl": True}, @@ -1031,25 +1035,25 @@ def km_view3d(params): ("view3d.smoothview", {"type": 'TIMER1', "value": 'ANY', "any": True}, None), ("view3d.zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("view3d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), - ("view3d.zoom", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("view3d.zoom", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.zoom", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("view3d.zoom", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("delta", -1)]}), - ("view3d.zoom", {"type": 'EQUAL', "value": 'PRESS', "ctrl": True}, + ("view3d.zoom", {"type": 'EQUAL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.zoom", {"type": 'MINUS', "value": 'PRESS', "ctrl": True}, + ("view3d.zoom", {"type": 'MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("delta", -1)]}), ("view3d.zoom", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, {"properties": [("delta", 1)]}), ("view3d.zoom", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, {"properties": [("delta", -1)]}), - ("view3d.dolly", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("view3d.dolly", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.dolly", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("view3d.dolly", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("view3d.dolly", {"type": 'EQUAL', "value": 'PRESS', "shift": True, "ctrl": True}, + ("view3d.dolly", {"type": 'EQUAL', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.dolly", {"type": 'MINUS', "value": 'PRESS', "shift": True, "ctrl": True}, + ("view3d.dolly", {"type": 'MINUS', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("delta", -1)]}), ("view3d.view_center_camera", {"type": 'HOME', "value": 'PRESS'}, None), ("view3d.view_center_lock", {"type": 'HOME', "value": 'PRESS'}, None), @@ -1070,18 +1074,18 @@ def km_view3d(params): ("view3d.view_camera", {"type": 'NUMPAD_0', "value": 'PRESS'}, None), ("view3d.view_axis", {"type": 'NUMPAD_1', "value": 'PRESS'}, {"properties": [("type", 'FRONT')]}), - ("view3d.view_orbit", {"type": 'NUMPAD_2', "value": 'PRESS'}, + ("view3d.view_orbit", {"type": 'NUMPAD_2', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'ORBITDOWN')]}), ("view3d.view_axis", {"type": 'NUMPAD_3', "value": 'PRESS'}, {"properties": [("type", 'RIGHT')]}), - ("view3d.view_orbit", {"type": 'NUMPAD_4', "value": 'PRESS'}, + ("view3d.view_orbit", {"type": 'NUMPAD_4', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'ORBITLEFT')]}), ("view3d.view_persportho", {"type": 'NUMPAD_5', "value": 'PRESS'}, None), - ("view3d.view_orbit", {"type": 'NUMPAD_6', "value": 'PRESS'}, + ("view3d.view_orbit", {"type": 'NUMPAD_6', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'ORBITRIGHT')]}), ("view3d.view_axis", {"type": 'NUMPAD_7', "value": 'PRESS'}, {"properties": [("type", 'TOP')]}), - ("view3d.view_orbit", {"type": 'NUMPAD_8', "value": 'PRESS'}, + ("view3d.view_orbit", {"type": 'NUMPAD_8', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'ORBITUP')]}), ("view3d.view_axis", {"type": 'NUMPAD_1', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'BACK')]}), @@ -1089,17 +1093,17 @@ def km_view3d(params): {"properties": [("type", 'LEFT')]}), ("view3d.view_axis", {"type": 'NUMPAD_7', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'BOTTOM')]}), - ("view3d.view_pan", {"type": 'NUMPAD_2', "value": 'PRESS', "ctrl": True}, + ("view3d.view_pan", {"type": 'NUMPAD_2', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PANDOWN')]}), - ("view3d.view_pan", {"type": 'NUMPAD_4', "value": 'PRESS', "ctrl": True}, + ("view3d.view_pan", {"type": 'NUMPAD_4', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PANLEFT')]}), - ("view3d.view_pan", {"type": 'NUMPAD_6', "value": 'PRESS', "ctrl": True}, + ("view3d.view_pan", {"type": 'NUMPAD_6', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PANRIGHT')]}), - ("view3d.view_pan", {"type": 'NUMPAD_8', "value": 'PRESS', "ctrl": True}, + ("view3d.view_pan", {"type": 'NUMPAD_8', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PANUP')]}), - ("view3d.view_roll", {"type": 'NUMPAD_4', "value": 'PRESS', "shift": True}, + ("view3d.view_roll", {"type": 'NUMPAD_4', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'LEFT')]}), - ("view3d.view_roll", {"type": 'NUMPAD_6', "value": 'PRESS', "shift": True}, + ("view3d.view_roll", {"type": 'NUMPAD_6', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'RIGHT')]}), ("view3d.view_orbit", {"type": 'NUMPAD_9', "value": 'PRESS'}, {"properties": [("angle", 3.1415927), ("type", 'ORBITRIGHT')]}), @@ -1201,19 +1205,19 @@ def km_view3d(params): ("view3d.copybuffer", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("view3d.pastebuffer", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), # Transform. - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True, "repeat": False}, None), - ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True}, None), + ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), ("wm.context_toggle", {"type": 'TAB', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.use_snap')]}), op_panel("VIEW3D_PT_snapping", {"type": 'TAB', "value": 'PRESS', "shift": True, "ctrl": True}, [("keep_open", False)]), ("object.transform_axis_target", {"type": 'T', "value": 'PRESS', "shift": True}, None), - ("transform.skin_resize", {"type": 'A', "value": 'PRESS', "ctrl": True, "repeat": False}, None), + ("transform.skin_resize", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ]) if not params.legacy: @@ -1267,11 +1271,11 @@ def km_view3d(params): {"properties": [("type", 'LEFT')]}), ("view3d.view_roll", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'RIGHT')]}), - ("transform.create_orientation", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, + ("transform.create_orientation", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "alt": True}, {"properties": [("use", True)]}), - ("transform.translate", {"type": 'T', "value": 'PRESS', "shift": True, "repeat": False}, + ("transform.translate", {"type": 'T', "value": 'PRESS', "shift": True}, {"properties": [("texture_space", True)]}), - ("transform.resize", {"type": 'T', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, + ("transform.resize", {"type": 'T', "value": 'PRESS', "shift": True, "alt": True}, {"properties": [("texture_space", True)]}), # Old pivot. ("wm.context_set_enum", {"type": 'COMMA', "value": 'PRESS'}, @@ -1280,7 +1284,7 @@ def km_view3d(params): {"properties": [("data_path", 'tool_settings.transform_pivot_point'), ("value", 'MEDIAN_POINT')]}), ("wm.context_toggle", {"type": 'COMMA', "value": 'PRESS', "alt": True}, {"properties": [("data_path", 'tool_settings.use_transform_pivot_point_align')]}), - ("wm.context_toggle", {"type": 'SPACE', "value": 'PRESS', "ctrl": True, "repeat": False}, + ("wm.context_toggle", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.show_gizmo_context')]}), ("wm.context_set_enum", {"type": 'PERIOD', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.transform_pivot_point'), ("value", 'CURSOR')]}), @@ -1350,8 +1354,8 @@ def km_mask_editing(params): {"properties": [("mode", 'ADD')]}), ("mask.select_lasso", {"type": params.action_tweak, "value": 'ANY', "shift": True, "ctrl": True, "alt": True}, {"properties": [("mode", 'SUB')]}), - ("mask.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("mask.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("mask.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("mask.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("mask.hide_view_clear", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("mask.hide_view_set", {"type": 'H', "value": 'PRESS'}, {"properties": [("unselected", False)]}), @@ -1371,13 +1375,13 @@ def km_mask_editing(params): ("mask.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True}, None), ("mask.copy_splines", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("mask.paste_splines", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'MASK_SHRINKFATTEN')]}), ]) @@ -1544,8 +1548,8 @@ def km_graph_editor(params): {"properties": [("mode", 'MARKERS_COLUMN')]}), ("graph.select_column", {"type": 'K', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'MARKERS_BETWEEN')]}), - ("graph.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("graph.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("graph.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("graph.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("graph.select_linked", {"type": 'L', "value": 'PRESS'}, None), ("graph.frame_jump", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), op_menu_pie("GRAPH_MT_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), @@ -1576,12 +1580,12 @@ def km_graph_editor(params): ("graph.fmodifier_add", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("only_active", False)]}), ("anim.channels_editable_toggle", {"type": 'TAB', "value": 'PRESS'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'E', "value": 'PRESS'}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), ("wm.context_toggle", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_fcurve')]}), op_menu_pie("VIEW3D_MT_proportional_editing_falloff_pie", {"type": 'O', "value": 'PRESS', "shift": True}), @@ -1622,8 +1626,8 @@ def km_image_generic(_params): ("image.read_viewlayers", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("image.save", {"type": 'S', "value": 'PRESS', "alt": True}, None), ("image.save_as", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), - ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS'}, None), - ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS', "alt": True}, + ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS', "repeat": True}, None), + ("image.cycle_render_slot", {"type": 'J', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("reverse", True)]}), ]) @@ -1650,8 +1654,8 @@ def km_image(params): ("image.view_ndof", {"type": 'NDOF_MOTION', "value": 'ANY'}, None), ("image.view_zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, None), ("image.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, None), - ("image.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), - ("image.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), + ("image.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), + ("image.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), ("image.view_zoom", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "ctrl": True}, None), ("image.view_zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("image.view_zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), @@ -1775,9 +1779,9 @@ def km_node_editor(params): ("node.links_cut", {"type": 'EVT_TWEAK_R', "value": 'ANY', "ctrl": True}, None), ("node.select_link_viewer", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("node.backimage_move", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "alt": True}, None), - ("node.backimage_zoom", {"type": 'V', "value": 'PRESS'}, + ("node.backimage_zoom", {"type": 'V', "value": 'PRESS', "repeat": True}, {"properties": [("factor", 1.0 / 1.2)]}), - ("node.backimage_zoom", {"type": 'V', "value": 'PRESS', "alt": True}, + ("node.backimage_zoom", {"type": 'V', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("factor", 1.2)]}), ("node.backimage_fit", {"type": 'HOME', "value": 'PRESS', "alt": True}, None), ("node.backimage_sample", {"type": params.action_mouse, "value": 'PRESS', "alt": True}, None), @@ -1832,13 +1836,13 @@ def km_node_editor(params): ("node.translate_attach", {"type": 'G', "value": 'PRESS'}, None), ("node.translate_attach", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None), ("node.translate_attach", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, {"properties": [("release_confirm", True)]}), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("release_confirm", True)]}), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), ("node.move_detach_links", {"type": 'D', "value": 'PRESS', "alt": True}, None), ("node.move_detach_links_release", {"type": params.action_tweak, "value": 'ANY', "alt": True}, None), ("node.move_detach_links", {"type": params.select_tweak, "value": 'ANY', "alt": True}, None), @@ -1909,17 +1913,17 @@ def km_file_browser(params): ("file.smoothscroll", {"type": 'TIMER1', "value": 'ANY', "any": True}, None), ("file.bookmark_add", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), ("file.start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", 1)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", 10)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", 100)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", -1)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", -10)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), *_template_items_context_menu("FILEBROWSER_MT_context_menu", params.context_menu_event), ]) @@ -1951,29 +1955,29 @@ def km_file_browser_main(params): {"properties": [("extend", True), ("open", False)]}), ("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True}, {"properties": [("extend", True), ("fill", True), ("open", False)]}), - ("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'UP')]}), ("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'UP'), ("extend", True)]}), - ("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'UP'), ("extend", True), ("fill", True)]}), - ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'DOWN')]}), - ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'DOWN'), ("extend", True)]}), - ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("file.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'DOWN'), ("extend", True), ("fill", True)]}), - ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'LEFT')]}), - ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'LEFT'), ("extend", True)]}), - ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("file.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'LEFT'), ("extend", True), ("fill", True)]}), - ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'RIGHT')]}), - ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'RIGHT'), ("extend", True)]}), - ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("file.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'RIGHT'), ("extend", True), ("fill", True)]}), ("file.previous", {"type": 'BUTTON4MOUSE', "value": 'CLICK'}, None), ("file.next", {"type": 'BUTTON5MOUSE', "value": 'CLICK'}, None), @@ -2000,17 +2004,17 @@ def km_file_browser_buttons(_params): ) items.extend([ - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", 1)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", 10)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", 100)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", -1)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", -10)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), ]) @@ -2094,8 +2098,8 @@ def km_dopesheet(params): {"properties": [("mode", 'MARKERS_COLUMN')]}), ("action.select_column", {"type": 'K', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'MARKERS_BETWEEN')]}), - ("action.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("action.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("action.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("action.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("action.select_linked", {"type": 'L', "value": 'PRESS'}, None), ("action.frame_jump", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), op_menu_pie("DOPESHEET_MT_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), @@ -2121,15 +2125,15 @@ def km_dopesheet(params): ("action.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None), ("anim.channels_editable_toggle", {"type": 'TAB', "value": 'PRESS'}, None), ("anim.channels_find", {"type": 'F', "value": 'PRESS', "ctrl": True}, None), - ("transform.transform", {"type": 'G', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'G', "value": 'PRESS'}, {"properties": [("mode", 'TIME_TRANSLATE')]}), ("transform.transform", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("mode", 'TIME_TRANSLATE')]}), - ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'E', "value": 'PRESS'}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.transform", {"type": 'S', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'S', "value": 'PRESS'}, {"properties": [("mode", 'TIME_SCALE')]}), - ("transform.transform", {"type": 'T', "value": 'PRESS', "shift": True, "repeat": False}, + ("transform.transform", {"type": 'T', "value": 'PRESS', "shift": True}, {"properties": [("mode", 'TIME_SLIDE')]}), ("wm.context_toggle", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_action')]}), @@ -2247,19 +2251,19 @@ def km_nla_editor(params): ("nla.split", {"type": 'Y', "value": 'PRESS'}, None), ("nla.mute_toggle", {"type": 'H', "value": 'PRESS'}, None), ("nla.swap", {"type": 'F', "value": 'PRESS', "alt": True}, None), - ("nla.move_up", {"type": 'PAGE_UP', "value": 'PRESS'}, None), - ("nla.move_down", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), + ("nla.move_up", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), + ("nla.move_down", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), ("nla.apply_scale", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("nla.clear_scale", {"type": 'S', "value": 'PRESS', "alt": True}, None), op_menu_pie("NLA_MT_snap_pie", {"type": 'S', "value": 'PRESS', "shift": True}), ("nla.fmodifier_add", {"type": 'M', "value": 'PRESS', "shift": True, "ctrl": True}, None), - ("transform.transform", {"type": 'G', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'G', "value": 'PRESS'}, {"properties": [("mode", 'TRANSLATION')]}), ("transform.transform", {"type": params.select_tweak, "value": 'ANY'}, {"properties": [("mode", 'TRANSLATION')]}), - ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'E', "value": 'PRESS'}, {"properties": [("mode", 'TIME_EXTEND')]}), - ("transform.transform", {"type": 'S', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'S', "value": 'PRESS'}, {"properties": [("mode", 'TIME_SCALE')]}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), @@ -2304,9 +2308,9 @@ def km_text(params): {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), ("wm.context_cycle_int", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), ]) @@ -2318,9 +2322,9 @@ def km_text(params): items.extend([ ("text.new", {"type": 'N', "value": 'PRESS', "ctrl": True}, None), - ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), ]) @@ -2332,20 +2336,20 @@ def km_text(params): ("text.run_script", {"type": 'P', "value": 'PRESS', "alt": True}, None), ("text.cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), ("text.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), - ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("text.cut", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), ("text.copy", {"type": 'INSERT', "value": 'PRESS', "ctrl": True}, None), - ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True}, None), - ("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), + ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("text.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("text.select_line", {"type": 'A', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("text.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), - ("text.move_lines", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_lines", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'UP')]}), - ("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'DOWN')]}), - ("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None), - ("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), + ("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS', "repeat": True}, None), + ("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": True}, None), ("text.comment_toggle", {"type": 'SLASH', "value": 'PRESS', "ctrl": True}, None), ("text.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), @@ -2355,21 +2359,21 @@ def km_text(params): {"properties": [("type", 'LINE_END')]}), ("text.move", {"type": 'E', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'LINE_END')]}), - ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("text.move", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("text.move", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("text.move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("text.move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("text.move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("text.move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("text.move", {"type": 'HOME', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'FILE_TOP')]}), @@ -2379,33 +2383,33 @@ def km_text(params): {"properties": [("type", 'LINE_BEGIN')]}), ("text.move_select", {"type": 'END', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_END')]}), - ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("text.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("text.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("text.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("text.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("text.move_select", {"type": 'HOME', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'FILE_TOP')]}), ("text.move_select", {"type": 'END', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'FILE_BOTTOM')]}), - ("text.delete", {"type": 'DEL', "value": 'PRESS'}, + ("text.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, + ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("text.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), @@ -2421,11 +2425,11 @@ def km_text(params): {"properties": [("lines", -1)]}), ("text.scroll", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, {"properties": [("lines", 1)]}), - ("text.line_break", {"type": 'RET', "value": 'PRESS'}, None), - ("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), - ("text.line_number", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), + ("text.line_break", {"type": 'RET', "value": 'PRESS', "repeat": True}, None), + ("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "repeat": True}, None), + ("text.line_number", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), op_menu("TEXT_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), - ("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), + ("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), ]) return keymap @@ -2503,17 +2507,17 @@ def km_sequencer(params): ("sequencer.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("sequencer.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), ("sequencer.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None), - ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("next", True), ("center", False)]}), - ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("next", False), ("center", False)]}), - ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "alt": True}, + ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("next", True), ("center", True)]}), - ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "alt": True}, + ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("next", False), ("center", True)]}), - ("sequencer.swap", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("sequencer.swap", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("side", 'LEFT')]}), - ("sequencer.swap", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("sequencer.swap", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("side", 'RIGHT')]}), ("sequencer.gap_remove", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("all", False)]}), @@ -2543,8 +2547,8 @@ def km_sequencer(params): ("sequencer.select", {"type": params.select_mouse, "value": 'PRESS' if params.legacy else 'CLICK', "ctrl": True, "shift": True}, {"properties": [("side_of_frame", True), ("linked_time", True), ("extend", True)]}), - ("sequencer.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("sequencer.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("sequencer.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("sequencer.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("sequencer.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("extend", False)]}), ("sequencer.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, @@ -2565,9 +2569,9 @@ def km_sequencer(params): ("sequencer.slip", {"type": 'S', "value": 'PRESS'}, None), ("wm.context_set_int", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'scene.sequence_editor.overlay_frame'), ("value", 0)]}), - ("transform.seq_slide", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.seq_slide", {"type": 'G', "value": 'PRESS'}, None), ("transform.seq_slide", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.transform", {"type": 'E', "value": 'PRESS', "repeat": False}, + ("transform.transform", {"type": 'E', "value": 'PRESS'}, {"properties": [("mode", 'TIME_EXTEND')]}), ("marker.add", {"type": 'M', "value": 'PRESS'}, None), ("marker.rename", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), @@ -2623,9 +2627,9 @@ def km_console(_params): ) items.extend([ - ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), ("console.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), @@ -2635,27 +2639,27 @@ def km_console(_params): {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), ("wm.context_cycle_int", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("console.history_cycle", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("console.history_cycle", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("reverse", True)]}), - ("console.history_cycle", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("console.history_cycle", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("reverse", False)]}), - ("console.delete", {"type": 'DEL', "value": 'PRESS'}, + ("console.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, - {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, + {"properties": [("type", 'PREVIOUS_CHARACTER')], "repeat": True}), + ("console.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), ("console.clear_line", {"type": 'RET', "value": 'PRESS', "shift": True}, None), ("console.clear_line", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "shift": True}, None), @@ -2665,15 +2669,15 @@ def km_console(_params): {"properties": [("interactive", True)]}), ("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), - ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("console.select_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), - ("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, + ("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("text", '\t')]}), - ("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None), - ("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), + ("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS', "repeat": True}, None), + ("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": True}, None), *_template_items_context_menu("CONSOLE_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), - ("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), + ("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), ]) return keymap @@ -2693,9 +2697,9 @@ def km_clip(_params): sidebar_key={"type": 'N', "value": 'PRESS'}, ), ("clip.open", {"type": 'O', "value": 'PRESS', "alt": True}, None), - ("clip.track_markers", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("clip.track_markers", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("backwards", True), ("sequence", False)]}), - ("clip.track_markers", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("clip.track_markers", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("backwards", False), ("sequence", False)]}), ("clip.track_markers", {"type": 'T', "value": 'PRESS', "ctrl": True}, {"properties": [("backwards", False), ("sequence", True)]}), @@ -2730,8 +2734,8 @@ def km_clip_editor(params): ("clip.view_zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), ("clip.view_zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, None), ("clip.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, None), - ("clip.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), - ("clip.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), + ("clip.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), + ("clip.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), ("clip.view_zoom_ratio", {"type": 'NUMPAD_8', "value": 'PRESS', "ctrl": True}, {"properties": [("ratio", 8.0)]}), ("clip.view_zoom_ratio", {"type": 'NUMPAD_4', "value": 'PRESS', "ctrl": True}, @@ -2758,13 +2762,13 @@ def km_clip_editor(params): ("clip.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None), ("clip.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("clip.view_ndof", {"type": 'NDOF_MOTION', "value": 'ANY'}, None), - ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("position", 'PATHSTART')]}), - ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("position", 'PATHEND')]}), - ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True}, + ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True}, {"properties": [("position", 'FAILEDPREV')]}), - ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True}, + ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True}, {"properties": [("position", 'PATHSTART')]}), ("clip.change_frame", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("clip.select", {"type": params.select_mouse, "value": 'PRESS'}, @@ -2807,10 +2811,10 @@ def km_clip_editor(params): {"properties": [("data_path", 'space_data.show_marker_search')]}), ("wm.context_toggle", {"type": 'M', "value": 'PRESS'}, {"properties": [("data_path", 'space_data.use_mute_footage')]}), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), ("clip.clear_track_path", {"type": 'T', "value": 'PRESS', "alt": True}, {"properties": [("action", 'REMAINED'), ("clear_active", False)]}), ("clip.clear_track_path", {"type": 'T', "value": 'PRESS', "shift": True}, @@ -2864,10 +2868,10 @@ def km_clip_graph_editor(params): {"properties": [("action", 'ALL'), ("clear_active", True)]}), ("clip.graph_disable_markers", {"type": 'D', "value": 'PRESS', "shift": True}, {"properties": [("action", 'TOGGLE')]}), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), ]) if params.select_mouse == 'LEFTMOUSE' and not params.legacy: @@ -2914,17 +2918,17 @@ def km_frames(params): items.extend([ # Frame offsets - ("screen.frame_offset", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("screen.frame_offset", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("delta", -1)]}), - ("screen.frame_offset", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("screen.frame_offset", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("delta", 1)]}), - ("screen.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("screen.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("end", True)]}), - ("screen.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("screen.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("end", False)]}), - ("screen.keyframe_jump", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("screen.keyframe_jump", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("next", True)]}), - ("screen.keyframe_jump", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("screen.keyframe_jump", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("next", False)]}), ("screen.keyframe_jump", {"type": 'MEDIA_LAST', "value": 'PRESS'}, {"properties": [("next", True)]}), @@ -2940,29 +2944,29 @@ def km_frames(params): # New playback if params.spacebar_action in {'TOOL', 'SEARCH'}: items.append( - ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "shift": True}, None), ) elif params.spacebar_action == 'PLAY': items.append( - ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "repeat": False}, None), + ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS'}, None), ) else: assert False items.extend([ - ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": False}, + ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("reverse", True)]}), ]) else: # Old playback items.extend([ - ("screen.frame_offset", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("screen.frame_offset", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", 10)]}), - ("screen.frame_offset", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("screen.frame_offset", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", -10)]}), - ("screen.frame_jump", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("screen.frame_jump", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("end", True)]}), - ("screen.frame_jump", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("screen.frame_jump", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("end", False)]}), ("screen.animation_play", {"type": 'A', "value": 'PRESS', "alt": True}, None), ("screen.animation_play", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True}, @@ -3048,9 +3052,9 @@ def km_animation_channels(params): ("anim.channels_collapse", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, {"properties": [("all", False)]}), # Move. - ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'UP')]}), - ("anim.channels_move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("anim.channels_move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'DOWN')]}), ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'TOP')]}), @@ -3135,8 +3139,8 @@ def _grease_pencil_selection(params): # Select grouped ("gpencil.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), # Select more/less - ("gpencil.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("gpencil.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("gpencil.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("gpencil.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ] @@ -3208,17 +3212,17 @@ def km_grease_pencil_stroke_edit_mode(params): # Move to layer op_menu("GPENCIL_MT_move_to_layer", {"type": 'M', "value": 'PRESS'}), # Transform tools - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True, "repeat": False}, None), - ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True, "repeat": False}, None), - ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True, "repeat": False}, None), - ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True, "repeat": False}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), + ("transform.mirror", {"type": 'M', "value": 'PRESS', "ctrl": True}, None), + ("transform.bend", {"type": 'W', "value": 'PRESS', "shift": True}, None), + ("transform.tosphere", {"type": 'S', "value": 'PRESS', "shift": True, "alt": True}, None), + ("transform.shear", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'GPENCIL_SHRINKFATTEN')]}), - ("transform.transform", {"type": 'F', "value": 'PRESS', "shift": True, "repeat": False}, + ("transform.transform", {"type": 'F', "value": 'PRESS', "shift": True}, {"properties": [("mode", 'GPENCIL_OPACITY')]}), # Proportional editing. *_template_items_proportional_editing(connected=True), @@ -3912,13 +3916,13 @@ def km_pose(params): {"properties": [("flipped", True)]}), *_template_items_select_actions(params, "pose.select_all"), ("pose.select_parent", {"type": 'P', "value": 'PRESS', "shift": True}, None), - ("pose.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("pose.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", False)]}), - ("pose.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True}, + ("pose.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", True)]}), - ("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", False)]}), - ("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, + ("pose.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), ("pose.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("pose.select_linked_pick", {"type": 'L', "value": 'PRESS'}, None), @@ -3935,7 +3939,7 @@ def km_pose(params): ("armature.layers_show_all", {"type": 'ACCENT_GRAVE', "value": 'PRESS', "ctrl": True}, None), ("armature.armature_layers", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("pose.bone_layers", {"type": 'M', "value": 'PRESS'}, None), - ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, None), + ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, None), ("anim.keyframe_insert_menu", {"type": 'I', "value": 'PRESS'}, None), ("anim.keyframe_delete_v3d", {"type": 'I', "value": 'PRESS', "alt": True}, None), ("anim.keying_set_active_set", {"type": 'I', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None), @@ -3973,17 +3977,17 @@ def km_object_mode(params): ("wm.context_toggle", {"type": 'O', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.use_proportional_edit_objects')]}), *_template_items_select_actions(params, "object.select_all"), - ("object.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("object.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("object.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("object.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("object.select_linked", {"type": 'L', "value": 'PRESS', "shift": True}, None), ("object.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), - ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", False)]}), - ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True}, + ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", True)]}), - ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", False)]}), - ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, + ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), ("object.parent_set", {"type": 'P', "value": 'PRESS', "ctrl": True}, None), ("object.parent_clear", {"type": 'P', "value": 'PRESS', "alt": True}, None), @@ -4081,10 +4085,10 @@ def km_paint_curve(params): ("paintcurve.delete_point", {"type": 'DEL', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'RET', "value": 'PRESS'}, None), ("paintcurve.draw", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), - ("transform.translate", {"type": 'G', "value": 'PRESS', "repeat": False}, None), + ("transform.translate", {"type": 'G', "value": 'PRESS'}, None), ("transform.translate", {"type": params.select_tweak, "value": 'ANY'}, None), - ("transform.rotate", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("transform.resize", {"type": 'S', "value": 'PRESS', "repeat": False}, None), + ("transform.rotate", {"type": 'R', "value": 'PRESS'}, None), + ("transform.resize", {"type": 'S', "value": 'PRESS'}, None), ]) return keymap @@ -4104,8 +4108,8 @@ def km_curve(params): ("curve.vertex_add", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, None), *_template_items_select_actions(params, "curve.select_all"), ("curve.select_row", {"type": 'R', "value": 'PRESS', "shift": True}, None), - ("curve.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("curve.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("curve.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("curve.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("curve.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("curve.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), ("curve.select_linked_pick", {"type": 'L', "value": 'PRESS'}, @@ -4124,8 +4128,8 @@ def km_curve(params): ("curve.dissolve_verts", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), ("curve.dissolve_verts", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, None), ("curve.tilt_clear", {"type": 'T', "value": 'PRESS', "alt": True}, None), - ("transform.tilt", {"type": 'T', "value": 'PRESS', "ctrl": True, "repeat": False}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, + ("transform.tilt", {"type": 'T', "value": 'PRESS', "ctrl": True}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'CURVE_SHRINKFATTEN')]}), ("curve.reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("curve.hide", {"type": 'H', "value": 'PRESS'}, @@ -4208,9 +4212,9 @@ def km_image_paint(params): ("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None), ("paint.grab_clone", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, None), ("paint.sample_color", {"type": 'S', "value": 'PRESS'}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("image_paint", color=True, zoom=True, rotation=True, secondary_rotation=True), ("brush.stencil_control", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, @@ -4257,9 +4261,9 @@ def km_vertex_paint(params): ("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None), ("paint.sample_color", {"type": 'S', "value": 'PRESS'}, None), ("paint.vertex_color_set", {"type": 'K', "value": 'PRESS', "shift": True}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("vertex_paint", color=True, rotation=True), ("brush.stencil_control", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, @@ -4312,9 +4316,9 @@ def km_weight_paint(params): ("paint.weight_gradient", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "alt": True}, {"properties": [("type", 'RADIAL')]}), ("paint.weight_set", {"type": 'K', "value": 'PRESS', "shift": True}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("weight_paint"), ("wm.radial_control", {"type": 'F', "value": 'PRESS', "ctrl": True}, @@ -4376,9 +4380,9 @@ def km_sculpt(params): {"properties": [("mode", "SHRINK")]}), # Subdivision levels *_template_items_object_subdivision_set(), - ("object.subdivision_set", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("object.subdivision_set", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("level", 1), ("relative", True)]}), - ("object.subdivision_set", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("object.subdivision_set", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("level", -1), ("relative", True)]}), # Mask ("paint.mask_flood_fill", {"type": 'M', "value": 'PRESS', "alt": True}, @@ -4396,7 +4400,7 @@ def km_sculpt(params): {"properties": [("use_normals", True), ("keep_previous_mask", True), ("invert", False), ("smooth_iterations", 0), ("create_face_set", False)]}), # Dynamic topology ("sculpt.dynamic_topology_toggle", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), - ("sculpt.set_detail_size", {"type": 'D', "value": 'PRESS', "shift": True}, None), + ("sculpt.dyntopo_detail_size_edit", {"type": 'D', "value": 'PRESS', "shift": True}, None), # Remesh ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), @@ -4404,9 +4408,9 @@ def km_sculpt(params): # Color ("sculpt.sample_color", {"type": 'S', "value": 'PRESS'}, None), # Brush properties - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("sculpt", rotation=True), # Stencil @@ -4452,6 +4456,7 @@ def km_sculpt(params): {"properties": [("data_path", 'tool_settings.sculpt.brush.use_smooth_stroke')]}), op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_mask_edit_pie", {"type": 'A', "value": 'PRESS'}), + op_menu_pie("VIEW3D_MT_sculpt_automasking_pie", {"type": 'A', "alt": True,"value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_face_sets_edit_pie", {"type": 'W', "value": 'PRESS'}), *_template_items_context_panel("VIEW3D_PT_sculpt_context_menu", params.context_menu_event), ]) @@ -4501,10 +4506,10 @@ def km_mesh(params): ("mesh.shortest_path_pick", {"type": params.select_mouse, "value": params.select_mouse_value, "shift": True, "ctrl": True}, {"properties": [("use_fill", True)]}), *_template_items_select_actions(params, "mesh.select_all"), - ("mesh.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("mesh.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), - ("mesh.select_next_item", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "ctrl": True}, None), - ("mesh.select_prev_item", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "ctrl": True}, None), + ("mesh.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("mesh.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("mesh.select_next_item", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, None), + ("mesh.select_prev_item", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, None), ("mesh.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None), ("mesh.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), @@ -4525,7 +4530,7 @@ def km_mesh(params): {"properties": [("inside", True)]}), ("view3d.edit_mesh_extrude_move_normal", {"type": 'E', "value": 'PRESS'}, None), op_menu("VIEW3D_MT_edit_mesh_extrude", {"type": 'E', "value": 'PRESS', "alt": True}), - ("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("transform.edge_crease", {"type": 'E', "value": 'PRESS', "shift": True}, None), ("mesh.fill", {"type": 'F', "value": 'PRESS', "alt": True}, None), ("mesh.quads_convert_to_tris", {"type": 'T', "value": 'PRESS', "ctrl": True}, {"properties": [("quad_method", 'BEAUTY'), ("ngon_method", 'BEAUTY')]}), @@ -4539,7 +4544,7 @@ def km_mesh(params): ("mesh.rip_edge_move", {"type": 'D', "value": 'PRESS', "alt": True}, None), 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, "repeat": False}, None), + ("transform.shrink_fatten", {"type": 'S', "value": 'PRESS', "alt": 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}), @@ -4547,7 +4552,7 @@ def km_mesh(params): ("mesh.split", {"type": 'Y', "value": 'PRESS'}, None), ("mesh.vert_connect_path", {"type": 'J', "value": 'PRESS'}, None), ("mesh.point_normals", {"type": 'L', "value": 'PRESS', "alt": True}, None), - ("transform.vert_slide", {"type": 'V', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("transform.vert_slide", {"type": 'V', "value": 'PRESS', "shift": True}, None), ("mesh.dupli_extrude_cursor", {"type": params.action_mouse, "value": 'CLICK', "ctrl": True}, {"properties": [("rotate_source", True)]}), ("mesh.dupli_extrude_cursor", {"type": params.action_mouse, "value": 'CLICK', "shift": True, "ctrl": True}, @@ -4639,8 +4644,8 @@ def km_armature(params): {"properties": [("direction", 'CHILD'), ("extend", False)]}), ("armature.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), - ("armature.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("armature.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("armature.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("armature.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), ("armature.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), @@ -4669,10 +4674,10 @@ def km_armature(params): ("armature.armature_layers", {"type": 'M', "value": 'PRESS', "shift": True}, None), ("armature.bone_layers", {"type": 'M', "value": 'PRESS'}, None), # Special transforms. - ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True, "repeat": False}, None), - ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True, "repeat": False}, + ("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "ctrl": True, "alt": True}, None), + ("transform.transform", {"type": 'S', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'BONE_ENVELOPE')]}), - ("transform.transform", {"type": 'R', "value": 'PRESS', "ctrl": True, "repeat": False}, + ("transform.transform", {"type": 'R', "value": 'PRESS', "ctrl": True}, {"properties": [("mode", 'BONE_ROLL')]}), # Menus. *_template_items_context_menu("VIEW3D_MT_armature_context_menu", params.context_menu_event), @@ -4720,8 +4725,8 @@ def km_lattice(params): items.extend([ *_template_items_select_actions(params, "lattice.select_all"), - ("lattice.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("lattice.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("lattice.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("lattice.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("object.vertex_parent_set", {"type": 'P', "value": 'PRESS', "ctrl": True}, None), ("lattice.flip", {"type": 'F', "value": 'PRESS', "alt": True}, None), op_menu("VIEW3D_MT_hook", {"type": 'H', "value": 'PRESS', "ctrl": True}), @@ -4743,8 +4748,8 @@ def km_particle(params): items.extend([ *_template_items_select_actions(params, "particle.select_all"), - ("particle.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, None), - ("particle.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, None), + ("particle.select_more", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("particle.select_less", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("particle.select_linked_pick", {"type": 'L', "value": 'PRESS'}, {"properties": [("deselect", False)]}), ("particle.select_linked_pick", {"type": 'L', "value": 'PRESS', "shift": True}, @@ -4796,71 +4801,71 @@ def km_font(params): {"properties": [("style", 'UNDERLINE')]}), ("font.style_toggle", {"type": 'P', "value": 'PRESS', "ctrl": True}, {"properties": [("style", 'SMALL_CAPS')]}), - ("font.delete", {"type": 'DEL', "value": 'PRESS'}, + ("font.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_OR_SELECTION')]}), - ("font.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("font.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_OR_SELECTION')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_OR_SELECTION')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), ("font.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), ("font.move", {"type": 'END', "value": 'PRESS'}, {"properties": [("type", 'LINE_END')]}), - ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.move", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("font.move", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("font.move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("font.move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("font.move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("font.move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("font.move_select", {"type": 'HOME', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_BEGIN')]}), ("font.move_select", {"type": 'END', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_END')]}), - ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("font.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("font.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), - ("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), - ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), - ("font.line_break", {"type": 'RET', "value": 'PRESS'}, None), - ("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), - ("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True}, + ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("font.line_break", {"type": 'RET', "value": 'PRESS', "repeat": True}, None), + ("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), + ("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("accent", True)]}), *_template_items_context_menu("VIEW3D_MT_edit_font_context_menu", params.context_menu_event), ]) @@ -4977,28 +4982,28 @@ def km_transform_modal_map(_params): ("CONFIRM", {"type": 'SPACE', "value": 'PRESS', "any": True}, None), ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}, None), ("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None), - ("AXIS_X", {"type": 'X', "value": 'PRESS', "repeat": False}, None), - ("AXIS_Y", {"type": 'Y', "value": 'PRESS', "repeat": False}, None), - ("AXIS_Z", {"type": 'Z', "value": 'PRESS', "repeat": False}, None), - ("PLANE_X", {"type": 'X', "value": 'PRESS', "shift": True, "repeat": False}, None), - ("PLANE_Y", {"type": 'Y', "value": 'PRESS', "shift": True, "repeat": False}, None), - ("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True, "repeat": False}, None), - ("CONS_OFF", {"type": 'C', "value": 'PRESS', "repeat": False}, None), - ("TRANSLATE", {"type": 'G', "value": 'PRESS', "repeat": False}, None), - ("ROTATE", {"type": 'R', "value": 'PRESS', "repeat": False}, None), - ("RESIZE", {"type": 'S', "value": 'PRESS', "repeat": False}, None), - ("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": False}, None), + ("AXIS_X", {"type": 'X', "value": 'PRESS'}, None), + ("AXIS_Y", {"type": 'Y', "value": 'PRESS'}, None), + ("AXIS_Z", {"type": 'Z', "value": 'PRESS'}, None), + ("PLANE_X", {"type": 'X', "value": 'PRESS', "shift": True}, None), + ("PLANE_Y", {"type": 'Y', "value": 'PRESS', "shift": True}, None), + ("PLANE_Z", {"type": 'Z', "value": 'PRESS', "shift": True}, None), + ("CONS_OFF", {"type": 'C', "value": 'PRESS'}, None), + ("TRANSLATE", {"type": 'G', "value": 'PRESS'}, None), + ("ROTATE", {"type": 'R', "value": 'PRESS'}, None), + ("RESIZE", {"type": 'S', "value": 'PRESS'}, None), + ("SNAP_TOGGLE", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), ("SNAP_INV_ON", {"type": 'LEFT_CTRL', "value": 'PRESS', "any": True}, None), ("SNAP_INV_OFF", {"type": 'LEFT_CTRL', "value": 'RELEASE', "any": True}, None), ("SNAP_INV_ON", {"type": 'RIGHT_CTRL', "value": 'PRESS', "any": True}, None), ("SNAP_INV_OFF", {"type": 'RIGHT_CTRL', "value": 'RELEASE', "any": True}, None), - ("ADD_SNAP", {"type": 'A', "value": 'PRESS', "repeat": False}, None), - ("ADD_SNAP", {"type": 'A', "value": 'PRESS', "ctrl": True, "repeat": False}, None), - ("REMOVE_SNAP", {"type": 'A', "value": 'PRESS', "alt": True, "repeat": False}, None), - ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS'}, None), - ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), - ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, None), - ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, None), + ("ADD_SNAP", {"type": 'A', "value": 'PRESS'}, None), + ("ADD_SNAP", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), + ("REMOVE_SNAP", {"type": 'A', "value": 'PRESS', "alt": True}, None), + ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), + ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), + ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), @@ -5006,17 +5011,17 @@ def km_transform_modal_map(_params): ("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("EDGESLIDE_EDGE_NEXT", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": True}, None), ("EDGESLIDE_PREV_NEXT", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": True}, None), - ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS'}, None), - ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), - ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, None), - ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, None), + ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), - ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS', "repeat": False}, None), - ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "repeat": False}, None), - ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "repeat": False, "shift": True}, None), + ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), + ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), + ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "shift": True}, None), ]) return keymap @@ -5069,9 +5074,9 @@ def km_view3d_gesture_circle(_params): ("DESELECT", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), ("NOP", {"type": 'MIDDLEMOUSE', "value": 'RELEASE', "any": True}, None), ("SUBTRACT", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), - ("SUBTRACT", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), + ("SUBTRACT", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), ("ADD", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), - ("ADD", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), + ("ADD", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), ("SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ]) @@ -5096,7 +5101,7 @@ def km_gesture_border(_params): ("SELECT", {"type": 'LEFTMOUSE', "value": 'RELEASE', "any": True}, None), ("BEGIN", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), ("DESELECT", {"type": 'MIDDLEMOUSE', "value": 'RELEASE'}, None), - ("MOVE", {"type": 'SPACE', "value": 'ANY', "repeat": False, "any": True}, None), + ("MOVE", {"type": 'SPACE', "value": 'ANY', "any": True}, None), ]) return keymap @@ -5135,9 +5140,9 @@ def km_gesture_straight_line(_params): ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'ANY', "any": True}, None), ("BEGIN", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("SELECT", {"type": 'LEFTMOUSE', "value": 'RELEASE', "any": True}, None), - ("MOVE", {"type": 'SPACE', "value": 'ANY', "repeat": False, "any": True}, None), - ("SNAP", {"type": 'LEFT_CTRL', "value": 'ANY', "any": True, "repeat": False}, None), - ("FLIP", {"type": 'F', "value": 'PRESS', "any": True, "repeat": False}, None), + ("MOVE", {"type": 'SPACE', "value": 'ANY', "any": True}, None), + ("SNAP", {"type": 'LEFT_CTRL', "value": 'ANY', "any": True}, None), + ("FLIP", {"type": 'F', "value": 'PRESS', "any": True}, None), ]) return keymap @@ -5152,7 +5157,7 @@ def km_gesture_lasso(_params): ) items.extend([ - ("MOVE", {"type": 'SPACE', "value": 'ANY', "repeat": False, "any": True}, None), + ("MOVE", {"type": 'SPACE', "value": 'ANY', "any": True}, None), ]) return keymap @@ -5290,25 +5295,25 @@ def km_view3d_fly_modal(_params): ("CONFIRM", {"type": 'RET', "value": 'PRESS', "any": True}, None), ("CONFIRM", {"type": 'SPACE', "value": 'PRESS', "any": True}, None), ("CONFIRM", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "any": True}, None), - ("ACCELERATE", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "any": True}, None), - ("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True}, None), + ("ACCELERATE", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "any": True, "repeat": True}, None), + ("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True, "repeat": True}, None), ("ACCELERATE", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "any": True}, None), ("DECELERATE", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "any": True}, None), ("CONFIRM", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("PAN_ENABLE", {"type": 'MIDDLEMOUSE', "value": 'PRESS', "any": True}, None), ("PAN_DISABLE", {"type": 'MIDDLEMOUSE', "value": 'RELEASE', "any": True}, None), - ("FORWARD", {"type": 'W', "value": 'PRESS'}, None), - ("BACKWARD", {"type": 'S', "value": 'PRESS'}, None), - ("LEFT", {"type": 'A', "value": 'PRESS'}, None), - ("RIGHT", {"type": 'D', "value": 'PRESS'}, None), - ("UP", {"type": 'E', "value": 'PRESS'}, None), - ("DOWN", {"type": 'Q', "value": 'PRESS'}, None), - ("UP", {"type": 'R', "value": 'PRESS'}, None), - ("DOWN", {"type": 'F', "value": 'PRESS'}, None), - ("FORWARD", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("BACKWARD", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), - ("LEFT", {"type": 'LEFT_ARROW', "value": 'PRESS'}, None), - ("RIGHT", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, None), + ("FORWARD", {"type": 'W', "value": 'PRESS', "repeat": True}, None), + ("BACKWARD", {"type": 'S', "value": 'PRESS', "repeat": True}, None), + ("LEFT", {"type": 'A', "value": 'PRESS', "repeat": True}, None), + ("RIGHT", {"type": 'D', "value": 'PRESS', "repeat": True}, None), + ("UP", {"type": 'E', "value": 'PRESS', "repeat": True}, None), + ("DOWN", {"type": 'Q', "value": 'PRESS', "repeat": True}, None), + ("UP", {"type": 'R', "value": 'PRESS', "repeat": True}, None), + ("DOWN", {"type": 'F', "value": 'PRESS', "repeat": True}, None), + ("FORWARD", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("BACKWARD", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), + ("LEFT", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, None), + ("RIGHT", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, None), ("AXIS_LOCK_X", {"type": 'X', "value": 'PRESS'}, None), ("AXIS_LOCK_Z", {"type": 'Z', "value": 'PRESS'}, None), ("PRECISION_ENABLE", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), @@ -5366,8 +5371,8 @@ def km_view3d_walk_modal(_params): ("JUMP_STOP", {"type": 'V', "value": 'RELEASE', "any": True}, None), ("TELEPORT", {"type": 'SPACE', "value": 'PRESS', "any": True}, None), ("TELEPORT", {"type": 'MIDDLEMOUSE', "value": 'ANY', "any": True}, None), - ("ACCELERATE", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "any": True}, None), - ("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True}, None), + ("ACCELERATE", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "any": True, "repeat": True}, None), + ("DECELERATE", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "any": True, "repeat": True}, None), ("ACCELERATE", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "any": True}, None), ("DECELERATE", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "any": True}, None), ]) @@ -5687,9 +5692,9 @@ def km_image_editor_tool_uv_sculpt_stroke(params): {"properties": [("mode", 'INVERT')]}), ("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, {"properties": [("mode", 'RELAX')]}), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("uv_sculpt"), ]}, @@ -6486,10 +6491,8 @@ def km_3d_view_tool_sculpt_face_set_edit(params): "3D View Tool: Sculpt, Face Set Edit", {"space_type": 'VIEW_3D', "region_type": 'WINDOW'}, {"items": [ - ("sculpt.face_set_edit", {"type": params.tool_mouse, "value": 'ANY'}, + ("sculpt.face_set_edit", {"type": params.tool_mouse, "value": 'PRESS'}, None), - ("sculpt.face_set_edit", {"type": params.tool_tweak, "value": 'ANY'}, - None) ]}, ) diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index e4ff0177ceb..c79a59145cf 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -237,7 +237,7 @@ def km_screen(params): ) items.extend([ - ("screen.repeat_last", {"type": 'G', "value": 'PRESS'}, None), + ("screen.repeat_last", {"type": 'G', "value": 'PRESS', "repeat": True}, None), # Animation ("screen.userpref_show", {"type": 'COMMA', "value": 'PRESS', "ctrl": True}, None), ("screen.animation_step", {"type": 'TIMER0', "value": 'ANY', "any": True}, None), @@ -256,8 +256,8 @@ def km_screen(params): ("file.execute", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), ("file.cancel", {"type": 'ESC', "value": 'PRESS'}, None), # Undo - ("ed.undo", {"type": 'Z', "value": 'PRESS', "ctrl": True}, None), - ("ed.redo", {"type": 'Z', "value": 'PRESS', "shift": True, "ctrl": True}, None), + ("ed.undo", {"type": 'Z', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("ed.redo", {"type": 'Z', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, None), ("ed.undo_history", {"type": 'Z', "value": 'PRESS', "alt": True, "ctrl": True}, None), # Render ("render.view_cancel", {"type": 'ESC', "value": 'PRESS'}, None), @@ -344,8 +344,8 @@ def km_view2d(params): ("view2d.zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, None), ("view2d.zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS', "alt": True}, None), ("view2d.zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS', "alt": True}, None), - ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), - ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), + ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), + ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), ("view2d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), ("view2d.smoothview", {"type": 'TIMER1', "value": 'ANY', "any": True}, None), # Scroll up/down, only when zoom is not available. @@ -379,16 +379,16 @@ def km_view2d_buttons_list(params): ("view2d.pan", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("view2d.scroll_down", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("view2d.scroll_up", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), - ("view2d.scroll_down", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("view2d.scroll_down", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("page", True)]}), - ("view2d.scroll_up", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("view2d.scroll_up", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("page", True)]}), # Zoom ("view2d.zoom", {"type": 'RIGHTMOUSE', "value": 'PRESS', "alt": True}, None), ("view2d.zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("view2d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), - ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), - ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), + ("view2d.zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), + ("view2d.zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), ("view2d.reset", {"type": 'A', "value": 'PRESS'}, None), ]) @@ -479,17 +479,21 @@ def km_outliner(params): {"properties": [("tweak", True), ("mode", "ADD")]}), ("outliner.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True}, {"properties": [("tweak", True), ("mode", "SUB")]}), - ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'UP')]}), - ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'UP')]}), + ("outliner.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'UP'), ("extend", True)]}), - ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'DOWN')]}), - ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'DOWN')]}), + ("outliner.select_walk", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'DOWN'), ("extend", True)]}), - ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'LEFT')]}), - ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'LEFT')]}), + ("outliner.select_walk", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'LEFT'), ("toggle_all", True)]}), - ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, {"properties": [("direction", 'RIGHT')]}), - ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, + {"properties": [("direction", 'RIGHT')]}), + ("outliner.select_walk", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'RIGHT'), ("toggle_all", True)]}), ("outliner.item_openclose", {"type": 'LEFTMOUSE', "value": 'CLICK'}, {"properties": [("all", False)]}), @@ -505,9 +509,9 @@ def km_outliner(params): ("outliner.show_hierarchy", {"type": 'A', "value": 'PRESS'}, None), ("outliner.show_active", {"type": 'PERIOD', "value": 'PRESS'}, None), ("outliner.show_active", {"type": 'F', "value": 'PRESS'}, None), - ("outliner.scroll_page", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("outliner.scroll_page", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("up", False)]}), - ("outliner.scroll_page", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("outliner.scroll_page", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("up", True)]}), ("outliner.show_one_level", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), ("outliner.show_one_level", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, @@ -570,8 +574,8 @@ def km_uv_editor(params): ("uv.select_loop", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, {"properties": [("extend", False)]}), ("uv.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), - ("uv.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("uv.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("uv.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("uv.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("uv.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("uv.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("uv.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), @@ -649,9 +653,9 @@ def km_view3d(params): ("view3d.zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("view3d.zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), # Numpad - ("view3d.zoom", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("view3d.zoom", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.zoom", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("view3d.zoom", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("delta", -1)]}), ("view3d.zoom", {"type": 'WHEELINMOUSE', "value": 'PRESS'}, {"properties": [("delta", 1)]}), @@ -661,9 +665,9 @@ def km_view3d(params): {"properties": [("delta", 1)]}), ("view3d.zoom", {"type": 'WHEELOUTMOUSE', "value": 'PRESS', "alt": True}, {"properties": [("delta", -1)]}), - ("view3d.dolly", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("view3d.dolly", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("view3d.dolly", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("view3d.dolly", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("delta", -1)]}), ("view3d.view_all", {"type": 'A', "value": 'PRESS'}, {"properties": [("center", False)]}), @@ -777,8 +781,8 @@ def km_mask_editing(params): {"properties": [("mode", 'ADD')]}), ("mask.select_lasso", {"type": params.action_tweak, "value": 'ANY', "shift": True, "ctrl": True, "alt": True}, {"properties": [("mode", 'SUB')]}), - ("mask.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("mask.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("mask.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("mask.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("mask.hide_view_clear", {"type": 'H', "value": 'PRESS', "alt": True}, None), ("mask.hide_view_set", {"type": 'H', "value": 'PRESS', "ctrl": True}, {"properties": [("unselected", False)]}), @@ -903,8 +907,8 @@ def km_graph_editor(params): {"properties":[("tweak", True), ("axis_range", False), ("mode", 'ADD')]}), ("graph.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True}, {"properties":[("tweak", True), ("axis_range", False), ("mode", 'SUB')]}), - ("graph.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("graph.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("graph.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("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'}), op_menu("GRAPH_MT_delete", {"type": 'DEL', "value": 'PRESS'}), @@ -982,8 +986,8 @@ def km_image(params): ("image.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, None), ("image.view_zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS', "alt": True}, None), ("image.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS', "alt": True}, None), - ("image.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), - ("image.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), + ("image.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), + ("image.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), ("image.view_zoom", {"type": 'RIGHTMOUSE', "value": 'PRESS', "alt": True}, None), ("image.view_zoom", {"type": 'TRACKPADZOOM', "value": 'ANY'}, None), ("image.view_zoom", {"type": 'TRACKPADPAN', "value": 'ANY', "ctrl": True}, None), @@ -1213,17 +1217,17 @@ def km_file_browser(params): ("wm.context_toggle", {"type": 'T', "value": 'PRESS'}, {"properties": [("data_path", 'space_data.show_region_toolbar')]}), ("file.bookmark_add", {"type": 'B', "value": 'PRESS', "ctrl": True}, None), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", 1)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", 10)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", 100)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", -1)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", -10)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), *_template_items_context_menu("FILEBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ]) @@ -1301,17 +1305,17 @@ def km_file_browser_buttons(params): ) items.extend([ - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", 1)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", 10)]}), - ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", 100)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, {"properties": [("increment", -1)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("increment", -10)]}), - ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("file.filenum", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("increment", -100)]}), ]) @@ -1385,8 +1389,8 @@ def km_dopesheet(params): {"properties": [("mode", 'MARKERS_COLUMN')]}), ("action.select_column", {"type": 'K', "value": 'PRESS', "alt": True}, {"properties": [("mode", 'MARKERS_BETWEEN')]}), - ("action.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "ctrl": True}, None), - ("action.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "ctrl": True}, None), + ("action.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, None), + ("action.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("action.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), ("action.frame_jump", {"type": 'G', "value": 'PRESS', "ctrl": True}, None), ("wm.context_menu_enum", {"type": 'X', "value": 'PRESS'}, @@ -1584,9 +1588,9 @@ def km_text(params): {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), ("wm.context_cycle_int", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), ("text.new", {"type": 'N', "value": 'PRESS', "ctrl": True}, None), ]) @@ -1599,20 +1603,20 @@ def km_text(params): ("text.run_script", {"type": 'P', "value": 'PRESS', "alt": True}, None), ("text.cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), ("text.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), - ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("text.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("text.cut", {"type": 'DEL', "value": 'PRESS', "shift": True}, None), ("text.copy", {"type": 'INSERT', "value": 'PRESS', "ctrl": True}, None), - ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True}, None), - ("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), + ("text.paste", {"type": 'INSERT', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("text.duplicate_line", {"type": 'D', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("text.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("text.select_line", {"type": 'A', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("text.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), - ("text.move_lines", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_lines", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'UP')]}), - ("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("direction", 'DOWN')]}), - ("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None), - ("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), + ("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS', "repeat": True}, None), + ("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": True}, None), ("text.uncomment", {"type": 'D', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("text.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), @@ -1622,21 +1626,21 @@ def km_text(params): {"properties": [("type", 'LINE_END')]}), ("text.move", {"type": 'E', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'LINE_END')]}), - ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("text.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("text.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("text.move", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("text.move", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("text.move", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("text.move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("text.move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("text.move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("text.move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("text.move", {"type": 'HOME', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'FILE_TOP')]}), @@ -1646,33 +1650,33 @@ def km_text(params): {"properties": [("type", 'LINE_BEGIN')]}), ("text.move_select", {"type": 'END', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_END')]}), - ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("text.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("text.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("text.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("text.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("text.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, + ("text.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("text.move_select", {"type": 'HOME', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'FILE_TOP')]}), ("text.move_select", {"type": 'END', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("type", 'FILE_BOTTOM')]}), - ("text.delete", {"type": 'DEL', "value": 'PRESS'}, + ("text.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, + ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("text.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("text.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), ("text.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), @@ -1688,11 +1692,11 @@ def km_text(params): {"properties": [("lines", -1)]}), ("text.scroll", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, {"properties": [("lines", 1)]}), - ("text.line_break", {"type": 'RET', "value": 'PRESS'}, None), - ("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None), + ("text.line_break", {"type": 'RET', "value": 'PRESS', "repeat": True}, None), + ("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "repeat": True}, None), *_template_items_context_menu("TEXT_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}), ("text.line_number", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), - ("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), + ("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), ]) return keymap @@ -1759,17 +1763,17 @@ def km_sequencer(params): ("sequencer.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("sequencer.view_selected", {"type": 'F', "value": 'PRESS'}, None), ("sequencer.view_frame", {"type": 'NUMPAD_0', "value": 'PRESS'}, None), - ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("next", True), ("center", False)]}), - ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("next", False), ("center", False)]}), - ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "alt": True}, + ("sequencer.strip_jump", {"type": 'PAGE_UP', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("next", True), ("center", True)]}), - ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "alt": True}, + ("sequencer.strip_jump", {"type": 'PAGE_DOWN', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("next", False), ("center", True)]}), - ("sequencer.swap", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("sequencer.swap", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("side", 'LEFT')]}), - ("sequencer.swap", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("sequencer.swap", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("side", 'RIGHT')]}), ("sequencer.gap_remove", {"type": 'BACK_SPACE', "value": 'PRESS'}, {"properties": [("all", False)]}), @@ -1797,8 +1801,8 @@ def km_sequencer(params): {"properties": [("side_of_frame", True), ("linked_time", True)]}), ("sequencer.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "ctrl": True}, {"properties": [("extend", True), ("side_of_frame", True), ("linked_time", True)]}), - ("sequencer.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("sequencer.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("sequencer.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("sequencer.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("sequencer.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("extend", False)]}), ("sequencer.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, @@ -1860,9 +1864,9 @@ def km_console(params): ) items.extend([ - ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), ("console.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), @@ -1872,27 +1876,27 @@ def km_console(params): {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), ("wm.context_cycle_int", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", False)]}), - ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, + ("wm.context_cycle_int", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("data_path", 'space_data.font_size'), ("reverse", True)]}), - ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("console.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("console.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("console.history_cycle", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("console.history_cycle", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("reverse", True)]}), - ("console.history_cycle", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("console.history_cycle", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("reverse", False)]}), - ("console.delete", {"type": 'DEL', "value": 'PRESS'}, + ("console.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, - {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("console.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, + {"properties": [("type", 'PREVIOUS_CHARACTER')], "repeat": True}), + ("console.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, + ("console.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), ("console.clear_line", {"type": 'RET', "value": 'PRESS', "shift": True}, None), ("console.clear_line", {"type": 'NUMPAD_ENTER', "value": 'PRESS', "shift": True}, None), @@ -1902,15 +1906,15 @@ def km_console(params): {"properties": [("interactive", True)]}), ("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None), ("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), - ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("console.select_set", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None), - ("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True}, + ("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("text", '\t')]}), - ("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None), - ("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None), + ("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS', "repeat": True}, None), + ("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True, "repeat": True}, None), *_template_items_context_menu("CONSOLE_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), - ("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), + ("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True, "repeat": True}, None), ]) return keymap @@ -1928,9 +1932,9 @@ def km_clip(params): op_panel("TOPBAR_PT_name", {"type": 'RET', "value": 'PRESS'}, [("keep_open", False)]), ("wm.search_menu", {"type": 'TAB', "value": 'PRESS'}, None), ("clip.open", {"type": 'O', "value": 'PRESS', "alt": True}, None), - ("clip.track_markers", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("clip.track_markers", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("backwards", True), ("sequence", False)]}), - ("clip.track_markers", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("clip.track_markers", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("backwards", False), ("sequence", False)]}), ("clip.track_markers", {"type": 'T', "value": 'PRESS', "ctrl": True}, {"properties": [("backwards", False), ("sequence", True)]}), @@ -1965,8 +1969,8 @@ def km_clip_editor(params): ("clip.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS'}, None), ("clip.view_zoom_in", {"type": 'WHEELINMOUSE', "value": 'PRESS', "alt": True}, None), ("clip.view_zoom_out", {"type": 'WHEELOUTMOUSE', "value": 'PRESS', "alt": True}, None), - ("clip.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS'}, None), - ("clip.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS'}, None), + ("clip.view_zoom_in", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "repeat": True}, None), + ("clip.view_zoom_out", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "repeat": True}, None), ("clip.view_zoom_ratio", {"type": 'NUMPAD_8', "value": 'PRESS', "ctrl": True}, {"properties": [("ratio", 8.0)]}), ("clip.view_zoom_ratio", {"type": 'NUMPAD_4', "value": 'PRESS', "ctrl": True}, @@ -1991,13 +1995,13 @@ def km_clip_editor(params): ("clip.view_selected", {"type": 'F', "value": 'PRESS'}, None), ("clip.view_all", {"type": 'NDOF_BUTTON_FIT', "value": 'PRESS'}, None), ("clip.view_ndof", {"type": 'NDOF_MOTION', "value": 'ANY'}, None), - ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("position", 'PATHSTART')]}), - ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("position", 'PATHEND')]}), - ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True}, + ("clip.frame_jump", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True}, {"properties": [("position", 'FAILEDPREV')]}), - ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True}, + ("clip.frame_jump", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "alt": True, "repeat": True}, {"properties": [("position", 'PATHSTART')]}), ("clip.change_frame", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("clip.select", {"type": 'LEFTMOUSE', "value": 'PRESS'}, @@ -2139,7 +2143,7 @@ def km_frames(params): {"properties": [("end", True)]}), ("screen.frame_jump", {"type": 'MEDIA_FIRST', "value": 'PRESS'}, {"properties": [("end", False)]}), - ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS', "repeat": False}, None), + ("screen.animation_play", {"type": 'SPACE', "value": 'PRESS'}, None), ("screen.animation_cancel", {"type": 'ESC', "value": 'PRESS'}, None), ("screen.animation_play", {"type": 'MEDIA_PLAY', "value": 'PRESS'}, None), ("screen.animation_cancel", {"type": 'MEDIA_STOP', "value": 'PRESS'}, None), @@ -2214,9 +2218,9 @@ def km_animation_channels(params): ("anim.channels_collapse", {"type": 'NUMPAD_MINUS', "value": 'PRESS', "ctrl": True}, {"properties": [("all", False)]}), # Move. - ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'UP')]}), - ("anim.channels_move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("anim.channels_move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'DOWN')]}), ("anim.channels_move", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'TOP')]}), @@ -2268,8 +2272,8 @@ def _grease_pencil_selection(params): # Select grouped ("gpencil.select_grouped", {"type": 'G', "value": 'PRESS', "shift": True}, None), # Select more/less - ("gpencil.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("gpencil.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("gpencil.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("gpencil.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ] @@ -2957,13 +2961,13 @@ def km_pose(params): ("pose.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("pose.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("pose.select_parent", {"type": 'UP_ARROW', "value": 'PRESS', "ctrl": True}, None), - ("pose.select_hierarchy", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("pose.select_hierarchy", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", False)]}), - ("pose.select_hierarchy", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("pose.select_hierarchy", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", True)]}), - ("pose.select_hierarchy", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("pose.select_hierarchy", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", False)]}), - ("pose.select_hierarchy", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("pose.select_hierarchy", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), ("pose.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), ("pose.bone_layers", {"type": 'G', "value": 'PRESS'}, None), @@ -3007,16 +3011,16 @@ def km_object_mode(params): ("object.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("object.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("object.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("object.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("object.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("object.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("object.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("object.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), - ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", False)]}), - ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True}, + ("object.select_hierarchy", {"type": 'LEFT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'PARENT'), ("extend", True)]}), - ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", False)]}), - ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, + ("object.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), ("object.parent_set", {"type": 'P', "value": 'PRESS'}, None), @@ -3113,8 +3117,8 @@ def km_curve(params): ("curve.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("curve.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), ("curve.select_row", {"type": 'R', "value": 'PRESS', "shift": True}, None), - ("curve.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("curve.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("curve.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("curve.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("curve.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), ("curve.shortest_path_pick", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True, "shift": True}, None), ("curve.duplicate_move", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), @@ -3208,9 +3212,9 @@ def km_image_paint(params): ("paint.sample_color", {"type": 'I', "value": 'PRESS'}, None), ("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None), ("paint.grab_clone", {"type": 'MIDDLEMOUSE', "value": 'PRESS'}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("image_paint", color=True, zoom=True, rotation=True, secondary_rotation=True), ("brush.stencil_control", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, @@ -3258,9 +3262,9 @@ def km_vertex_paint(params): ("paint.vertex_paint", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, {"properties": [("mode", 'INVERT')]}), ("paint.brush_colors_flip", {"type": 'X', "value": 'PRESS'}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("vertex_paint", color=True, rotation=True), ("brush.stencil_control", {"type": 'RIGHTMOUSE', "value": 'PRESS'}, @@ -3303,9 +3307,9 @@ def km_weight_paint(params): items.extend([ ("paint.weight_paint", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), ("paint.weight_sample_group", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True}, None), - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("weight_paint"), ("wm.context_toggle", {"type": 'M', "value": 'PRESS'}, @@ -3354,9 +3358,9 @@ def km_sculpt(params): {"properties": [("action", 'SHOW'), ("area", 'ALL')]}), # Subdivision levels *_template_items_object_subdivision_set(), - ("object.subdivision_set", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("object.subdivision_set", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("level", 1), ("relative", True)]}), - ("object.subdivision_set", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("object.subdivision_set", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("level", -1), ("relative", True)]}), # Mask ("paint.mask_flood_fill", {"type": 'A', "value": 'PRESS', "ctrl": True}, @@ -3381,9 +3385,9 @@ def km_sculpt(params): ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Brush properties - ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 0.9)]}), - ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, + ("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True}, {"properties": [("scalar", 1.0 / 0.9)]}), *_template_paint_radial_control("sculpt", rotation=True), # Stencil @@ -3469,8 +3473,8 @@ def km_mesh(params): ("mesh.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("mesh.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("mesh.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("mesh.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("mesh.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("mesh.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("mesh.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("mesh.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None), *_template_items_editmode_mesh_select_mode(params), @@ -3537,8 +3541,8 @@ def km_armature(params): ("armature.select_hierarchy", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, {"properties": [("direction", 'CHILD'), ("extend", True)]}), - ("armature.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("armature.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("armature.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("armature.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("armature.select_similar", {"type": 'G', "value": 'PRESS', "shift": True}, None), ("armature.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, @@ -3610,8 +3614,8 @@ def km_lattice(params): ("lattice.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("lattice.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("lattice.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("lattice.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("lattice.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("lattice.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("lattice.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("object.vertex_parent_set", {"type": 'P', "value": 'PRESS', "ctrl": True}, None), *_template_items_context_menu("VIEW3D_MT_edit_lattice_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), ("wm.context_toggle", {"type": 'B', "value": 'PRESS'}, @@ -3641,8 +3645,8 @@ def km_particle(params): ("particle.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'SELECT')]}), ("particle.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}), ("particle.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}), - ("particle.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None), - ("particle.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None), + ("particle.select_more", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, None), + ("particle.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, None), ("particle.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, {"properties": [("deselect", False)]}), ("particle.select_linked_pick", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "shift": True}, @@ -3687,68 +3691,68 @@ def km_font(params): {"properties": [("style", 'UNDERLINE')]}), ("font.style_toggle", {"type": 'P', "value": 'PRESS', "ctrl": True}, {"properties": [("style", 'SMALL_CAPS')]}), - ("font.delete", {"type": 'DEL', "value": 'PRESS'}, + ("font.delete", {"type": 'DEL', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_OR_SELECTION')]}), - ("font.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True}, + ("font.delete", {"type": 'DEL', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS'}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_OR_SELECTION')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_OR_SELECTION')]}), - ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True}, + ("font.delete", {"type": 'BACK_SPACE', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), ("font.move", {"type": 'HOME', "value": 'PRESS'}, {"properties": [("type", 'LINE_BEGIN')]}), ("font.move", {"type": 'END', "value": 'PRESS'}, {"properties": [("type", 'LINE_END')]}), - ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True}, + ("font.move", {"type": 'LEFT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True}, + ("font.move", {"type": 'RIGHT_ARROW', "value": 'PRESS', "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.move", {"type": 'UP_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'UP_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("font.move", {"type": 'DOWN_ARROW', "value": 'PRESS'}, + ("font.move", {"type": 'DOWN_ARROW', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("font.move", {"type": 'PAGE_UP', "value": 'PRESS'}, + ("font.move", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("font.move", {"type": 'PAGE_DOWN', "value": 'PRESS'}, + ("font.move", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), ("font.move_select", {"type": 'HOME', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_BEGIN')]}), ("font.move_select", {"type": 'END', "value": 'PRESS', "shift": True}, {"properties": [("type", 'LINE_END')]}), - ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_CHARACTER')]}), - ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_CHARACTER')]}), - ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("font.move_select", {"type": 'LEFT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_WORD')]}), - ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True}, + ("font.move_select", {"type": 'RIGHT_ARROW', "value": 'PRESS', "shift": True, "ctrl": True, "repeat": True}, {"properties": [("type", 'NEXT_WORD')]}), - ("font.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_LINE')]}), - ("font.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_LINE')]}), - ("font.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'PREVIOUS_PAGE')]}), - ("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, + ("font.move_select", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, {"properties": [("type", 'NEXT_PAGE')]}), - ("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_spacing", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), - ("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_spacing", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_character", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", 1)]}), - ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True}, + ("font.change_character", {"type": 'DOWN_ARROW', "value": 'PRESS', "alt": True, "repeat": True}, {"properties": [("delta", -1)]}), ("font.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("font.text_copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None), ("font.text_cut", {"type": 'X', "value": 'PRESS', "ctrl": True}, None), - ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None), + ("font.text_paste", {"type": 'V', "value": 'PRESS', "ctrl": True, "repeat": True}, None), ("font.line_break", {"type": 'RET', "value": 'PRESS'}, None), ("font.text_insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None), ("font.text_insert", {"type": 'BACK_SPACE', "value": 'PRESS', "alt": True}, @@ -3918,10 +3922,10 @@ def km_transform_modal_map(_params): ("ADD_SNAP", {"type": 'A', "value": 'PRESS'}, None), ("ADD_SNAP", {"type": 'A', "value": 'PRESS', "ctrl": True}, None), ("REMOVE_SNAP", {"type": 'A', "value": 'PRESS', "alt": True}, None), - ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS'}, None), - ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), - ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, None), - ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, None), + ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), + ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), + ("PROPORTIONAL_SIZE_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("PROPORTIONAL_SIZE_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), ("PROPORTIONAL_SIZE_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), @@ -3929,10 +3933,10 @@ def km_transform_modal_map(_params): ("PROPORTIONAL_SIZE", {"type": 'TRACKPADPAN', "value": 'ANY'}, None), ("EDGESLIDE_EDGE_NEXT", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "alt": True}, None), ("EDGESLIDE_PREV_NEXT", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "alt": True}, None), - ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS'}, None), - ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS'}, None), - ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True}, None), - ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True}, None), + ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_UP", {"type": 'PAGE_UP', "value": 'PRESS', "shift": True, "repeat": True}, None), + ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'PAGE_DOWN', "value": 'PRESS', "shift": True, "repeat": True}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS'}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS'}, None), ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py index c927cc184a3..eff88c835e7 100644 --- a/release/scripts/startup/bl_operators/__init__.py +++ b/release/scripts/startup/bl_operators/__init__.py @@ -48,7 +48,6 @@ _modules = [ "uvcalc_lightmap", "vertexpaint_dirt", "view3d", - "gpencil_mesh_bake", "wm", ] diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py index d0b4b485d82..8334557d1f6 100644 --- a/release/scripts/startup/bl_operators/anim.py +++ b/release/scripts/startup/bl_operators/anim.py @@ -348,7 +348,7 @@ class UpdateAnimatedTransformConstraint(Operator): bl_options = {'REGISTER', 'UNDO'} use_convert_to_radians: BoolProperty( - name="Convert To Radians", + name="Convert to Radians", description="Convert fcurves/drivers affecting rotations to radians (Warning: use this only once!)", default=True, ) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index b4795168a19..a3c54a7b069 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -1011,7 +1011,7 @@ class CLIP_OT_track_settings_as_default(Operator): """Copy tracking settings from active track to default settings""" bl_idname = "clip.track_settings_as_default" - bl_label = "Track Settings As Default" + bl_label = "Track Settings as Default" bl_options = {'UNDO', 'REGISTER'} @classmethod diff --git a/release/scripts/startup/bl_operators/console.py b/release/scripts/startup/bl_operators/console.py index b62b9310224..bffac4eef55 100644 --- a/release/scripts/startup/bl_operators/console.py +++ b/release/scripts/startup/bl_operators/console.py @@ -85,7 +85,7 @@ class ConsoleAutocomplete(Operator): class ConsoleCopyAsScript(Operator): """Copy the console contents for use in a script""" bl_idname = "console.copy_as_script" - bl_label = "Copy to Clipboard (as script)" + bl_label = "Copy to Clipboard (as Script)" @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_operators/file.py b/release/scripts/startup/bl_operators/file.py index 43fbd381cb2..78a7ead71ca 100644 --- a/release/scripts/startup/bl_operators/file.py +++ b/release/scripts/startup/bl_operators/file.py @@ -77,7 +77,7 @@ class WM_OT_previews_batch_generate(Operator): ) use_intern_data: BoolProperty( default=True, - name="Mat/Tex/...", + name="Materials & Textures", description="Generate 'internal' previews (materials, textures, images, etc.)", ) @@ -187,7 +187,7 @@ class WM_OT_previews_batch_clear(Operator): ) use_intern_data: BoolProperty( default=True, - name="Mat/Tex/...", + name="Materials & Textures", description="Clear 'internal' previews (materials, textures, images, etc.)", ) diff --git a/release/scripts/startup/bl_operators/gpencil_mesh_bake.py b/release/scripts/startup/bl_operators/gpencil_mesh_bake.py deleted file mode 100644 index d4b1b11ed69..00000000000 --- a/release/scripts/startup/bl_operators/gpencil_mesh_bake.py +++ /dev/null @@ -1,157 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### - -# <pep8-80 compliant> - -import bpy -from bpy.types import Operator -from bpy.props import ( - IntProperty, - FloatProperty, - BoolProperty, - EnumProperty, -) - -gp_object_items = [] - - -def my_objlist_callback(scene, context): - gp_object_items.clear() - gp_object_items.append(('*NEW', "New Object", "")) - for o in context.scene.objects: - if o.type == 'GPENCIL': - gp_object_items.append((o.name, o.name, "")) - - return gp_object_items - - -class GPENCIL_OT_mesh_bake(Operator): - """Bake all mesh animation into grease pencil strokes""" - bl_idname = "gpencil.mesh_bake" - bl_label = "Bake Mesh to Grease Pencil" - bl_options = {'REGISTER', 'UNDO'} - - frame_start: IntProperty( - name="Start Frame", - description="Start frame for baking", - min=0, max=300000, - default=1, - ) - frame_end: IntProperty( - name="End Frame", - description="End frame for baking", - min=1, max=300000, - default=250, - ) - step: IntProperty( - name="Frame Step", - description="Frame Step", - min=1, max=120, - default=1, - ) - thickness: IntProperty( - name="Thickness", - description="Thickness of the stroke lines", - min=1, max=100, - default=1, - ) - angle: FloatProperty( - name="Threshold Angle", - description="Threshold to determine ends of the strokes", - min=0, - max=+3.141592, - default=+1.22173, # 70 Degress - subtype='ANGLE', - ) - offset: FloatProperty( - name="Stroke Offset", - description="Offset strokes from fill", - soft_min=0.0, soft_max=100.0, - min=0.0, max=100.0, - default=0.001, - precision=3, - step=1, - subtype='DISTANCE', - unit='LENGTH', - ) - seams: BoolProperty( - name="Only Seam Edges", - description="Convert only seam edges", - default=False, - ) - faces: BoolProperty( - name="Export Faces", - description="Export faces as filled strokes", - default=True, - ) - target: EnumProperty( - name="Target Object", - description="Grease Pencil Object", - items=my_objlist_callback - ) - frame_target: IntProperty( - name="Target Frame", - description="Destination frame for the baked animation", - min=1, max=300000, - default=1, - ) - project_type: EnumProperty( - name="Reproject Type", - description="Type of projection", - items=( - ("KEEP", "No Reproject", ""), - ("FRONT", "Front", "Reproject the strokes using the X-Z plane"), - ("SIDE", "Side", "Reproject the strokes using the Y-Z plane"), - ("TOP", "Top", "Reproject the strokes using the X-Y plane"), - ("VIEW", "View", "Reproject the strokes to current viewpoint"), - ("CURSOR", "Cursor", "Reproject the strokes using the orientation of 3D cursor") - ) - ) - - @classmethod - def poll(self, context): - ob = context.active_object - return ((ob is not None) and - (ob.type in {'EMPTY', 'MESH'}) and - (context.mode == 'OBJECT')) - - def execute(self, context): - bpy.ops.gpencil.bake_mesh_animation( - frame_start=self.frame_start, - frame_end=self.frame_end, - step=self.step, - angle=self.angle, - thickness=self.thickness, - seams=self.seams, - faces=self.faces, - offset=self.offset, - target=self.target, - frame_target=self.frame_target, - project_type=self.project_type - ) - - return {'FINISHED'} - - def invoke(self, context, _event): - wm = context.window_manager - return wm.invoke_props_dialog(self) - - -classes = ( - GPENCIL_OT_mesh_bake, -) diff --git a/release/scripts/startup/bl_operators/object_randomize_transform.py b/release/scripts/startup/bl_operators/object_randomize_transform.py index a9a6819cb13..97c477d3704 100644 --- a/release/scripts/startup/bl_operators/object_randomize_transform.py +++ b/release/scripts/startup/bl_operators/object_randomize_transform.py @@ -97,7 +97,7 @@ from bpy.props import ( class RandomizeLocRotSize(Operator): - """Randomize objects loc/rot/scale""" + """Randomize objects location, rotation, and scale""" bl_idname = "object.randomize_transform" bl_label = "Randomize Transform" bl_options = {'REGISTER', 'UNDO'} diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index ca8999e9588..5da7a3270d9 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -676,6 +676,7 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): "gpcolor.pixel_size", "gpcolor.mix_stroke_factor", "gpcolor.alignment_mode", + "gpcolor.alignment_rotation", "gpcolor.fill_style", "gpcolor.fill_color", "gpcolor.fill_image", diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py index 6b420d20e14..df1098bdd3f 100644 --- a/release/scripts/startup/bl_operators/sequencer.py +++ b/release/scripts/startup/bl_operators/sequencer.py @@ -32,7 +32,7 @@ class SequencerCrossfadeSounds(Operator): """Do cross-fading volume animation of two selected sound strips""" bl_idname = "sequencer.crossfade_sounds" - bl_label = "Crossfade sounds" + bl_label = "Crossfade Sounds" bl_options = {'REGISTER', 'UNDO'} @classmethod @@ -83,7 +83,7 @@ class SequencerSplitMulticam(Operator): """Split multi-cam strip and select camera""" bl_idname = "sequencer.split_multicam" - bl_label = "Split multicam" + bl_label = "Split Multicam" bl_options = {'REGISTER', 'UNDO'} camera: IntProperty( diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index 31d601debba..07dba491dbd 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -1112,9 +1112,9 @@ class PREFERENCES_OT_studiolight_uninstall(Operator): class PREFERENCES_OT_studiolight_copy_settings(Operator): - """Copy Studio Light settings to the Studio light editor""" + """Copy Studio Light settings to the Studio Light editor""" bl_idname = "preferences.studiolight_copy_settings" - bl_label = "Copy Studio Light settings" + bl_label = "Copy Studio Light Settings" index: IntProperty() def execute(self, context): diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index e9a658bdc10..aa4e4e77993 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1660,7 +1660,7 @@ class WM_OT_owner_disable(Operator): class WM_OT_tool_set_by_id(Operator): """Set the tool by name (for keymaps)""" bl_idname = "wm.tool_set_by_id" - bl_label = "Set Tool By Name" + bl_label = "Set Tool by Name" name: StringProperty( name="Identifier", @@ -1718,7 +1718,7 @@ class WM_OT_tool_set_by_id(Operator): class WM_OT_tool_set_by_index(Operator): """Set the tool by index (for keymaps)""" bl_idname = "wm.tool_set_by_index" - bl_label = "Set Tool By Index" + bl_label = "Set Tool by Index" index: IntProperty( name="Index in toolbar", default=0, diff --git a/release/scripts/startup/bl_ui/properties_data_empty.py b/release/scripts/startup/bl_ui/properties_data_empty.py index c8a1d9e238c..7ded4c775a7 100644 --- a/release/scripts/startup/bl_ui/properties_data_empty.py +++ b/release/scripts/startup/bl_ui/properties_data_empty.py @@ -54,7 +54,7 @@ class DATA_PT_empty(DataButtonsPanel, Panel): depth_row.prop(ob, "empty_image_depth", text="Depth", expand=True) col.row().prop(ob, "empty_image_side", text="Side", expand=True) - col = layout.column(heading="Show in", align=True) + col = layout.column(heading="Show In", align=True) col.prop(ob, "show_empty_image_orthographic", text="Orthographic") col.prop(ob, "show_empty_image_perspective", text="Perspective") col.prop(ob, "show_empty_image_only_axis_aligned", text="Only Axis Aligned") diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py index 946578937bb..affdba6f693 100644 --- a/release/scripts/startup/bl_ui/properties_data_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py @@ -101,7 +101,7 @@ class GPENCIL_MT_layer_context_menu(Menu): layout.separator() layout.operator("gpencil.lock_all", icon='LOCKED', text="Lock All") - layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="UnLock All") + layout.operator("gpencil.unlock_all", icon='UNLOCKED', text="Unlock All") layout.prop(gpd, "use_autolock_layers", text="Autolock Inactive Layers") layout.separator() @@ -263,7 +263,7 @@ class DATA_PT_gpencil_onion_skinning_display(DataButtonsPanel, Panel): layout.use_property_split = True layout.enabled = gpd.users <= 1 - layout.prop(gpd, "use_ghosts_always", text="View In Render") + layout.prop(gpd, "use_ghosts_always", text="View in Render") col = layout.column(align=True) col.prop(gpd, "use_onion_fade", text="Fade") diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 2ea439a7e89..924a89755f8 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -57,7 +57,7 @@ class MESH_MT_vertex_group_context_menu(Menu): layout.separator() props = layout.operator("object.vertex_group_lock", icon='LOCKED', text="Lock All") props.action, props.mask = 'LOCK', 'ALL' - props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="UnLock All") + props = layout.operator("object.vertex_group_lock", icon='UNLOCKED', text="Unlock All") props.action, props.mask = 'UNLOCK', 'ALL' props = layout.operator("object.vertex_group_lock", text="Lock Invert All") props.action, props.mask = 'INVERT', 'ALL' diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index bdf63a5d95e..fd12747e2fa 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -162,7 +162,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): if freestyle.mode == 'SCRIPT': row = layout.row() - row.label(text="Style modules:") + row.label(text="Style Modules:") row.operator("scene.freestyle_module_add", text="Add") for module in freestyle.modules: box = layout.box() diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 910d6b64b74..e41858587bf 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -404,20 +404,21 @@ class GPENCIL_MT_cleanup(Menu): layout = self.layout + layout.operator("gpencil.frame_clean_fill", text="Boundary Strokes").mode = 'ACTIVE' + layout.operator("gpencil.frame_clean_fill", text="Boundary Strokes all Frames").mode = 'ALL' + + layout.separator() + layout.operator("gpencil.frame_clean_loose", text="Delete Loose Points") - layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicated Frames") if ob.mode != 'PAINT_GPENCIL': layout.operator("gpencil.stroke_merge_by_distance", text="Merge by Distance") layout.separator() - layout.operator("gpencil.frame_clean_fill", text="Boundary Strokes").mode = 'ACTIVE' - layout.operator("gpencil.frame_clean_fill", text="Boundary Strokes all Frames").mode = 'ALL' - + layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicated Frames") + layout.operator("gpencil.recalc_geometry", text="Recalculate Geometry") if ob.mode != 'PAINT_GPENCIL': - layout.separator() - layout.operator("gpencil.reproject") @@ -880,11 +881,11 @@ class GreasePencilLayerDisplayPanel: gpd = ob.data gpl = gpd.layers.active - col = layout.row(align=True) - col.prop(gpl, "channel_color") + row = layout.row(align=True) + row.prop(gpl, "channel_color") - col = layout.row(align=True) - col.prop(gpl, "use_solo_mode", text="Show Only On Keyframed") + row = layout.row(align=True) + row.prop(gpl, "use_solo_mode", text="Show Only on Keyframed") class GreasePencilFlipTintColors(Operator): diff --git a/release/scripts/startup/bl_ui/properties_mask_common.py b/release/scripts/startup/bl_ui/properties_mask_common.py index 6ee755722f3..4d25b8ca309 100644 --- a/release/scripts/startup/bl_ui/properties_mask_common.py +++ b/release/scripts/startup/bl_ui/properties_mask_common.py @@ -37,7 +37,7 @@ def draw_mask_context_menu(layout, context): layout.separator() - layout.operator("mask.shape_key_rekey", text="Re-key Shape Points") + layout.operator("mask.shape_key_rekey", text="Re-Key Shape Points") layout.operator("mask.feather_weight_clear") layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation") diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index 4ed7b1ac7b9..7c8f6b2309a 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -39,7 +39,7 @@ class GPENCIL_MT_material_context_menu(Menu): layout.separator() layout.operator("gpencil.material_lock_all", icon='LOCKED', text="Lock All") - layout.operator("gpencil.material_unlock_all", icon='UNLOCKED', text="UnLock All") + layout.operator("gpencil.material_unlock_all", icon='UNLOCKED', text="Unlock All") layout.operator("gpencil.material_lock_unused", text="Lock Unselected") layout.operator("gpencil.lock_layer", text="Lock Unused") @@ -165,6 +165,7 @@ class MATERIAL_PT_gpencil_strokecolor(GPMaterialButtonsPanel, Panel): if gpcolor.mode in {'DOTS', 'BOX'}: col.prop(gpcolor, "alignment_mode") + col.prop(gpcolor, "alignment_rotation") if gpcolor.mode == 'LINE': col.prop(gpcolor, "use_overlap_strokes") diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index b142f6085fa..7101a78e18f 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -141,6 +141,7 @@ class OBJECT_PT_relations(ObjectButtonsPanel, Panel): if parent and ob.parent_type == 'BONE' and parent.type == 'ARMATURE': sub.prop_search(ob, "parent_bone", parent.data, "bones") sub.active = (parent is not None) + sub.prop(ob, "use_camera_lock_parent") col.separator() @@ -364,7 +365,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): layout.prop(ob, "hide_select", text="Selectable", toggle=False, invert_checkbox=True) - col = layout.column(heading="Show in") + col = layout.column(heading="Show In") col.prop(ob, "hide_viewport", text="Viewports", toggle=False, invert_checkbox=True) col.prop(ob, "hide_render", text="Renders", toggle=False, invert_checkbox=True) diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 2b26ad92a02..63ccbd2ae05 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -330,7 +330,7 @@ class StrokePanel(BrushPanel): col.separator() if brush.use_anchor: - col.prop(brush, "use_edge_to_edge", text="Edge To Edge") + col.prop(brush, "use_edge_to_edge", text="Edge to Edge") if brush.use_airbrush: col.prop(brush, "rate", text="Rate", slider=True) @@ -698,6 +698,7 @@ def brush_settings(layout, context, brush, popover=False): elif sculpt_tool == 'GRAB': layout.prop(brush, "use_grab_active_vertex") + layout.prop(brush, "use_grab_silhouette") elif sculpt_tool == 'PAINT': row = layout.row(align=True) @@ -1023,10 +1024,7 @@ def brush_texture_settings(layout, brush, sculpt): layout.use_property_decorate = False # map_mode - if sculpt: - layout.prop(tex_slot, "map_mode", text="Mapping") - else: - layout.prop(tex_slot, "tex_paint_map_mode", text="Mapping") + layout.prop(tex_slot, "map_mode", text="Mapping") layout.separator() diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index abc75ceed2c..b8c0035ee6b 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -228,7 +228,7 @@ def point_cache_ui(self, cache, enabled, cachetype): sub = col.row() sub.enabled = enabled - sub.operator("ptcache.bake", text="Calculate To Frame").bake = False + sub.operator("ptcache.bake", text="Calculate to Frame").bake = False sub = col.column() sub.enabled = enabled @@ -237,7 +237,7 @@ def point_cache_ui(self, cache, enabled, cachetype): col = flow.column() col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True col.operator("ptcache.free_bake_all", text="Delete All Bakes") - col.operator("ptcache.bake_all", text="Update All To Frame").bake = False + col.operator("ptcache.bake_all", text="Update All to Frame").bake = False def effector_weights_ui(self, weights, weight_type): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index d1ff1dc9f5e..c8c49ee02b0 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -102,7 +102,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): col.separator() col = flow.column() - col.prop(field, "guide_clump_amount", text="Clumping amount") + col.prop(field, "guide_clump_amount", text="Clumping Amount") col.prop(field, "guide_clump_shape") col.prop(field, "use_max_distance") @@ -378,7 +378,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): - bl_label = "Softbody And Cloth" + bl_label = "Softbody & Cloth" bl_parent_id = "PHYSICS_PT_collision" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 779bdb5cd11..3afe7a47028 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -196,7 +196,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): col = flow.column() if PhysicButtonsPanel.poll_gas_domain(context): col.prop(domain, "clipping", text="Empty Space") - col.prop(domain, "delete_in_obstacle", text="Delete In Obstacle") + col.prop(domain, "delete_in_obstacle", text="Delete in Obstacle") if domain.cache_type == 'MODULAR': col.separator() @@ -486,7 +486,8 @@ class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): col = flow.column() col.prop(domain, "simulation_method", expand=False) - col.prop(domain, "flip_ratio", text="FLIP Ratio") + if domain.simulation_method == 'FLIP': + col.prop(domain, "flip_ratio", text="FLIP Ratio") col.prop(domain, "sys_particle_maximum", text="System Maximum") col = col.column(align=True) col.prop(domain, "particle_radius", text="Particle Radius") diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index a23dfae55b7..a0cf22877d5 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -532,6 +532,7 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): tracking = clip.tracking settings = tracking.settings tracking_object = tracking.objects.active + camera = clip.tracking.camera col = layout.column() col.prop(settings, "use_tripod_solver", text="Tripod") @@ -545,9 +546,16 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): col.prop(tracking_object, "keyframe_a") col.prop(tracking_object, "keyframe_b") - col = layout.column() + col = layout.column(heading="Refine", align=True) col.active = tracking_object.is_camera - col.prop(settings, "refine_intrinsics", text="Refine") + col.prop(settings, "refine_intrinsics_focal_length", text="Focal Length") + col.prop(settings, "refine_intrinsics_principal_point", text="Optical Center") + + col.prop(settings, "refine_intrinsics_radial_distortion", text="Radial Distortion") + + row = col.row() + row.active = (camera.distortion_model == 'BROWN') + row.prop(settings, "refine_intrinsics_tangential_distortion", text="Tangential Distortion") col = layout.column(align=True) col.scale_y = 2.0 @@ -560,7 +568,7 @@ class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel): class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel): bl_space_type = 'CLIP_EDITOR' bl_region_type = 'TOOLS' - bl_label = "Clean up" + bl_label = "Clean Up" bl_options = {'DEFAULT_CLOSED'} bl_category = "Solve" @@ -869,10 +877,6 @@ class CLIP_PT_tracking_camera(Panel): col.prop(clip.tracking.camera, "sensor_width", text="Sensor Width") col.prop(clip.tracking.camera, "pixel_aspect", text="Pixel Aspect") - col = layout.column() - col.prop(clip.tracking.camera, "principal", text="Optical Center") - col.operator("clip.set_center_principal", text="Set Center") - class CLIP_PT_tracking_lens(Panel): bl_space_type = 'CLIP_EDITOR' @@ -909,6 +913,10 @@ class CLIP_PT_tracking_lens(Panel): col.prop(camera, "units", text="Units") col = layout.column() + col.prop(clip.tracking.camera, "principal", text="Optical Center") + col.operator("clip.set_center_principal", text="Set Center") + + col = layout.column() col.prop(camera, "distortion_model", text="Lens Distortion") if camera.distortion_model == 'POLYNOMIAL': col = layout.column(align=True) @@ -1000,9 +1008,9 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel): row.prop(stab, "show_tracks_expanded", text="", emboss=False) if not stab.show_tracks_expanded: - row.label(text="Tracks For Stabilization") + row.label(text="Tracks for Stabilization") else: - row.label(text="Tracks For Location") + row.label(text="Tracks for Location") row = box.row() row.template_list("UI_UL_list", "stabilization_tracks", stab, "tracks", stab, "active_track_index", rows=2) @@ -1018,7 +1026,7 @@ class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel): # Usually we don't hide things from interface, but here every pixel of # vertical space is precious. if stab.use_stabilize_rotation: - box.label(text="Tracks For Rotation / Scale") + box.label(text="Tracks for Rotation/Scale") row = box.row() row.template_list("UI_UL_list", "stabilization_rotation_tracks", stab, "rotation_tracks", diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index aa88fceaef7..9a716621b08 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -336,7 +336,7 @@ class DOPESHEET_MT_view(Menu): layout.separator() - layout.prop(st.dopesheet, "use_multi_word_filter", text="Multi-word Match Search") + layout.prop(st.dopesheet, "use_multi_word_filter", text="Multi-Word Match Search") layout.separator() diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index 1bf7465e54c..3fee0ae9d47 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -301,6 +301,7 @@ class GRAPH_MT_key(Menu): layout.operator("graph.smooth") layout.operator("graph.sample") layout.operator("graph.bake") + layout.operator("graph.unbake") layout.separator() layout.operator("graph.euler_filter", text="Discontinuity (Euler) Filter") diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 72395e1de5e..0171fa902db 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -949,54 +949,28 @@ class SEQUENCER_PT_strip(SequencerButtonsPanel, Panel): row.prop(strip, "mute", toggle=True, icon_only=True, emboss=False) -class SEQUENCER_PT_adjust_transform_offset(SequencerButtonsPanel, Panel): - bl_label = "Offset" - bl_parent_id = "SEQUENCER_PT_adjust_transform" +class SEQUENCER_PT_adjust_crop(SequencerButtonsPanel, Panel): + bl_label = "Crop" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @classmethod def poll(cls, context): - strip = act_strip(context) - return strip.type != 'SOUND' - - def draw_header(self, context): - strip = act_strip(context) - self.layout.prop(strip, "use_translation", text="") + if not cls.has_sequencer(context): + return False - def draw(self, context): strip = act_strip(context) - layout = self.layout - layout.use_property_split = True - - layout.active = strip.use_translation and (not strip.mute) - - col = layout.column(align=True) - col.prop(strip.transform, "offset_x", text="Position X") - col.prop(strip.transform, "offset_y", text="Y") - - -class SEQUENCER_PT_adjust_transform_crop(SequencerButtonsPanel, Panel): - bl_label = "Crop" - bl_parent_id = "SEQUENCER_PT_adjust_transform" - bl_options = {'DEFAULT_CLOSED'} - bl_category = "Strip" + if not strip: + return False - @classmethod - def poll(cls, context): strip = act_strip(context) return strip.type != 'SOUND' - def draw_header(self, context): - strip = act_strip(context) - self.layout.prop(strip, "use_crop", text="") - def draw(self, context): strip = act_strip(context) layout = self.layout layout.use_property_split = True - - layout.active = strip.use_crop and (not strip.mute) + layout.active = not strip.mute col = layout.column(align=True) col.prop(strip.crop, "min_x") @@ -1071,7 +1045,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): flow.prop(strip, "use_only_boost") elif strip_type == 'SPEED': - layout.prop(strip, "use_default_fade", text="Stretch to input strip length") + layout.prop(strip, "use_default_fade", text="Stretch to Input Strip Length") if not strip.use_default_fade: layout.prop(strip, "use_as_speed") if strip.use_as_speed: @@ -1113,7 +1087,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): # The multicam strip needs at least 2 strips to be useful if strip_channel > 2: BT_ROW = 4 - col.label(text=" Cut to") + col.label(text="Cut To") row = col.row() for i in range(1, strip_channel): @@ -1153,7 +1127,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): col.prop(strip, "use_frame_interpolate") elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}: - col.prop(strip, "use_default_fade", text="Default fade") + col.prop(strip, "use_default_fade", text="Default Fade") if not strip.use_default_fade: col.prop(strip, "effect_fader", text="Effect Fader") elif strip_type == 'GAUSSIAN_BLUR': @@ -1590,21 +1564,19 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel): split.label(text="%d-%d (%d)" % (sta, end, end - sta + 1), translate=False) -class SEQUENCER_PT_adjust(SequencerButtonsPanel, Panel): - bl_label = "Adjust" - bl_category = "Strip" - - def draw(self, context): - pass - - class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel): bl_label = "Sound" - bl_parent_id = "SEQUENCER_PT_adjust" bl_category = "Strip" @classmethod def poll(cls, context): + if not cls.has_sequencer(context): + return False + + strip = act_strip(context) + if not strip: + return False + strip = act_strip(context) return strip.type == 'SOUND' @@ -1636,11 +1608,17 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel): class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel): bl_label = "Compositing" - bl_parent_id = "SEQUENCER_PT_adjust" bl_category = "Strip" @classmethod def poll(cls, context): + if not cls.has_sequencer(context): + return False + + strip = act_strip(context) + if not strip: + return False + strip = act_strip(context) return strip.type != 'SOUND' @@ -1659,8 +1637,8 @@ class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel): class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): bl_label = "Transform" - bl_parent_id = "SEQUENCER_PT_adjust" bl_category = "Strip" + bl_options = {'DEFAULT_CLOSED'} @classmethod def poll(cls, context): @@ -1671,23 +1649,26 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): if not strip: return False - return strip.type in { - 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK', - 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'TEXT', - 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', - 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', - 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX' - } + strip = act_strip(context) + return strip.type != 'SOUND' def draw(self, context): - layout = self.layout strip = act_strip(context) - + layout = self.layout layout.use_property_split = True - layout.use_property_decorate = False - layout.active = not strip.mute + col = layout.column(align=True) + col.prop(strip.transform, "offset_x", text="Position X") + col.prop(strip.transform, "offset_y", text="Y") + + col = layout.column(align=True) + col.prop(strip.transform, "scale_x", text="Scale X") + col.prop(strip.transform, "scale_y", text="Y") + + col = layout.column(align=True) + col.prop(strip.transform, "rotation", text="Rotation") + row = layout.row(heading="Mirror") sub = row.row(align=True) sub.prop(strip, "use_flip_x", text="X", toggle=True) @@ -1696,7 +1677,6 @@ class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel): class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): bl_label = "Video" - bl_parent_id = "SEQUENCER_PT_adjust" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @@ -1745,7 +1725,6 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel): bl_label = "Color" - bl_parent_id = "SEQUENCER_PT_adjust" bl_options = {'DEFAULT_CLOSED'} bl_category = "Strip" @@ -2234,11 +2213,9 @@ classes = ( SEQUENCER_PT_effect_text_style, SEQUENCER_PT_effect_text_layout, - SEQUENCER_PT_adjust, SEQUENCER_PT_adjust_comp, SEQUENCER_PT_adjust_transform, - SEQUENCER_PT_adjust_transform_offset, - SEQUENCER_PT_adjust_transform_crop, + SEQUENCER_PT_adjust_crop, SEQUENCER_PT_adjust_video, SEQUENCER_PT_adjust_color, SEQUENCER_PT_adjust_sound, diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index 8a45069470b..c937882bd6e 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -35,12 +35,12 @@ class TEXT_HT_header(Header): TEXT_MT_editor_menus.draw_collapsible(context, layout) + layout.separator_spacer() + if text and text.is_modified: row = layout.row(align=True) row.alert = True - row.operator("text.resolve_conflict", text="", icon='HELP') - - layout.separator_spacer() + row.operator("text.resolve_conflict", text="", icon='QUESTION') row = layout.row(align=True) row.template_ID(st, "text", new="text.new", @@ -177,7 +177,7 @@ class TEXT_PT_find(Panel): row = col.row(align=True) row.operator("text.replace") - row.operator("text.replace", text="Replace all").all = True + row.operator("text.replace", text="Replace All").all = True layout.separator() diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 290bbdb1ab6..16b02db9377 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -241,8 +241,8 @@ class TIME_PT_playback(TimelinePanelButtons, Panel): screen = context.screen scene = context.scene - col = layout.column() - col.prop(scene, "sync_mode", text="Audio") + layout.prop(scene, "sync_mode", text="Sync") + col = layout.column(heading="Audio") col.prop(scene, "use_audio_scrub", text="Scrubbing") col.prop(scene, "use_audio", text="Mute") diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index b0704d60378..9e86ea19432 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1259,6 +1259,7 @@ class _defs_sculpt: def draw_settings(_context, layout, tool): props = tool.operator_properties("paint.mask_line_gesture") layout.prop(props, "use_front_faces_only", expand=False) + layout.prop(props, "use_limit_to_segment", expand=False) return dict( idname="builtin.line_mask", @@ -1319,6 +1320,7 @@ class _defs_sculpt: def draw_settings(_context, layout, tool): props = tool.operator_properties("sculpt.trim_lasso_gesture") layout.prop(props, "trim_mode", expand=False) + layout.prop(props, "trim_orientation", expand=False) layout.prop(props, "use_cursor_depth", expand=False) return dict( idname="builtin.lasso_trim", @@ -1331,12 +1333,17 @@ class _defs_sculpt: @ToolDef.from_fn def project_line(): + def draw_settings(_context, layout, tool): + props = tool.operator_properties("sculpt.project_line_gesture") + layout.prop(props, "use_limit_to_segment", expand=False) + return dict( idname="builtin.line_project", label="Line Project", icon="ops.sculpt.line_project", widget=None, keymap=(), + draw_settings=draw_settings, ) @ToolDef.from_fn @@ -1814,6 +1821,11 @@ class _defs_gpencil_paint: @ToolDef.from_fn def cutter(): + def draw_settings(context, layout, tool): + props = tool.operator_properties("gpencil.stroke_cutter") + row = layout.row() + row.use_property_split = False + row.prop(props, "flat_caps") return dict( idname="builtin.cutter", label="Cutter", @@ -1821,6 +1833,7 @@ class _defs_gpencil_paint: cursor='KNIFE', widget=None, keymap=(), + draw_settings=draw_settings, ) @ToolDef.from_fn @@ -2558,8 +2571,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): 'OBJECT': [ *_tools_default, - # None, - # _tools_view3d_add, + None, + _tools_view3d_add, ], 'POSE': [ *_tools_default, @@ -2587,8 +2600,8 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ], 'EDIT_MESH': [ *_tools_default, - # None, - # _tools_view3d_add, + None, + _tools_view3d_add, None, ( _defs_edit_mesh.extrude, diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 6fc29119cdc..a7e28c38b9e 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -248,7 +248,7 @@ class TOPBAR_MT_file_cleanup(Menu): layout = self.layout layout.separator() - layout.operator("outliner.orphans_purge") + layout.operator("outliner.orphans_purge", text="Unused Data-Blocks") class TOPBAR_MT_file(Menu): diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index b96e317e2e9..8c1409f00ac 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -271,7 +271,7 @@ class USERPREF_PT_interface_editors(InterfacePanel, CenterAlignMixIn, Panel): class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, Panel): - bl_label = "Temporary Windows" + bl_label = "Temporary Editors" bl_parent_id = "USERPREF_PT_interface_editors" bl_options = {'DEFAULT_CLOSED'} @@ -280,7 +280,7 @@ class USERPREF_PT_interface_temporary_windows(InterfacePanel, CenterAlignMixIn, view = prefs.view col = layout.column() - col.prop(view, "render_display_type", text="Render in") + col.prop(view, "render_display_type", text="Render In") col.prop(view, "filebrowser_display_type", text="File Browser") @@ -374,8 +374,8 @@ class USERPREF_PT_edit_objects_new(EditingPanel, CenterAlignMixIn, Panel): flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - flow.prop(edit, "material_link", text="Link Materials to") - flow.prop(edit, "object_align", text="Align to") + flow.prop(edit, "material_link", text="Link Materials To") + flow.prop(edit, "object_align", text="Align To") flow.prop(edit, "use_enter_edit_mode", text="Enter Edit Mode") flow.prop(edit, "collection_instance_empty_size", text="Instance Empty Size") @@ -480,7 +480,7 @@ class USERPREF_PT_edit_misc(EditingPanel, CenterAlignMixIn, Panel): col = layout.column() col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color") - col.prop(edit, "node_margin", text="Node Auto-offset Margin") + col.prop(edit, "node_margin", text="Node Auto-Offset Margin") # ----------------------------------------------------------------------------- @@ -1349,7 +1349,7 @@ class USERPREF_PT_saveload_blend(SaveLoadPanel, CenterAlignMixIn, Panel): col.prop(view, "use_save_prompt") col.prop(paths, "use_save_preview_images") - col = layout.column(heading="Default to") + col = layout.column(heading="Default To") col.prop(paths, "use_relative_paths") col.prop(paths, "use_file_compression") col.prop(paths, "use_load_ui") @@ -1378,7 +1378,7 @@ class USERPREF_PT_saveload_blend_autosave(SaveLoadPanel, CenterAlignMixIn, Panel col = layout.column() col.active = paths.use_auto_save_temporary_files - col.prop(paths, "auto_save_time", text="Timer (mins)") + col.prop(paths, "auto_save_time", text="Timer (Minutes)") class USERPREF_PT_saveload_file_browser(SaveLoadPanel, CenterAlignMixIn, Panel): @@ -1548,9 +1548,6 @@ class USERPREF_PT_navigation_fly_walk(NavigationPanel, CenterAlignMixIn, Panel): layout.row().prop(inputs, "navigation_mode", expand=True) - flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False) - flow.prop(inputs, "use_camera_lock_parent") - class USERPREF_PT_navigation_fly_walk_navigation(NavigationPanel, CenterAlignMixIn, Panel): bl_label = "Walk" diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 07ccdfa8416..94acab20e66 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -693,7 +693,7 @@ class VIEW3D_HT_header(Header): text="Multiframe", ) - if gpd.use_stroke_edit_mode: + if gpd.use_stroke_edit_mode or gpd.is_stroke_paint_mode: row = layout.row(align=True) row.popover( panel="VIEW3D_PT_tools_grease_pencil_interpolate", @@ -815,10 +815,12 @@ class VIEW3D_MT_editor_menus(Menu): # Select Menu if gp_edit: if mode_string not in {'PAINT_GPENCIL', 'WEIGHT_GPENCIL'}: - if mode_string == 'SCULPT_GPENCIL' and \ - (ts.use_gpencil_select_mask_point or - ts.use_gpencil_select_mask_stroke or - ts.use_gpencil_select_mask_segment): + if ( + mode_string == 'SCULPT_GPENCIL' and + (ts.use_gpencil_select_mask_point or + ts.use_gpencil_select_mask_stroke or + ts.use_gpencil_select_mask_segment) + ): layout.menu("VIEW3D_MT_select_gpencil") elif mode_string == 'EDIT_GPENCIL': layout.menu("VIEW3D_MT_select_gpencil") @@ -2257,7 +2259,7 @@ class VIEW3D_MT_object(Menu): ob = context.active_object if ob and ob.type == 'GPENCIL' and context.gpencil_data: - layout.operator_menu_enum("gpencil.convert", "type", text="Convert to") + layout.operator_menu_enum("gpencil.convert", "type", text="Convert To") else: layout.operator_menu_enum("object.convert", "target") @@ -2292,7 +2294,7 @@ class VIEW3D_MT_object_animation(Menu): layout.separator() layout.operator("nla.bake", text="Bake Action...") - layout.operator("gpencil.mesh_bake", text="Bake Mesh to Grease Pencil...") + layout.operator("gpencil.bake_mesh_animation", text="Bake Mesh to Grease Pencil...") class VIEW3D_MT_object_rigid_body(Menu): @@ -3035,14 +3037,14 @@ class VIEW3D_MT_mask(Menu): layout.separator() - props = layout.operator("sculpt.mask_expand", text="Expand Mask By Topology") + props = layout.operator("sculpt.mask_expand", text="Expand Mask by Topology") props.use_normals = False props.keep_previous_mask = False props.invert = True props.smooth_iterations = 2 props.create_face_set = False - props = layout.operator("sculpt.mask_expand", text="Expand Mask By Curvature") + props = layout.operator("sculpt.mask_expand", text="Expand Mask by Curvature") props.use_normals = True props.keep_previous_mask = True props.invert = False @@ -3428,7 +3430,7 @@ class VIEW3D_MT_pose_constraints(Menu): def draw(self, _context): layout = self.layout - layout.operator("pose.constraint_add_with_targets", text="Add (With Targets)...") + layout.operator("pose.constraint_add_with_targets", text="Add (with Targets)...") layout.operator("pose.constraints_copy") layout.operator("pose.constraints_clear") @@ -3440,9 +3442,9 @@ class VIEW3D_MT_pose_names(Menu): layout = self.layout layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("pose.autoside_names", text="AutoName Left/Right").axis = 'XAXIS' - layout.operator("pose.autoside_names", text="AutoName Front/Back").axis = 'YAXIS' - layout.operator("pose.autoside_names", text="AutoName Top/Bottom").axis = 'ZAXIS' + layout.operator("pose.autoside_names", text="Auto-Name Left/Right").axis = 'XAXIS' + layout.operator("pose.autoside_names", text="Auto-Name Front/Back").axis = 'YAXIS' + layout.operator("pose.autoside_names", text="Auto-Name Top/Bottom").axis = 'ZAXIS' layout.operator("pose.flip_names") @@ -4769,9 +4771,9 @@ class VIEW3D_MT_edit_armature_names(Menu): layout = self.layout layout.operator_context = 'EXEC_REGION_WIN' - layout.operator("armature.autoside_names", text="AutoName Left/Right").type = 'XAXIS' - layout.operator("armature.autoside_names", text="AutoName Front/Back").type = 'YAXIS' - layout.operator("armature.autoside_names", text="AutoName Top/Bottom").type = 'ZAXIS' + layout.operator("armature.autoside_names", text="Auto-Name Left/Right").type = 'XAXIS' + layout.operator("armature.autoside_names", text="Auto-Name Front/Back").type = 'YAXIS' + layout.operator("armature.autoside_names", text="Auto-Name Top/Bottom").type = 'ZAXIS' layout.operator("armature.flip_names", text="Flip Names") @@ -5074,7 +5076,7 @@ class VIEW3D_MT_edit_gpencil_transform(Menu): class VIEW3D_MT_edit_gpencil_showhide(Menu): - bl_label = "Show/hide" + bl_label = "Show/Hide" def draw(self, _context): layout = self.layout @@ -5285,6 +5287,21 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu): op.filter_type = 'CONTRAST_DECREASE' op.auto_iteration_count = False +class VIEW3D_MT_sculpt_automasking_pie(Menu): + bl_label = "Automasking" + + def draw(self, context): + layout = self.layout + pie = layout.menu_pie() + + tool_settings = context.tool_settings + sculpt = tool_settings.sculpt + + pie.prop(sculpt, "use_automasking_topology", text="Topology") + pie.prop(sculpt, "use_automasking_face_sets", text="Face Sets") + pie.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") + pie.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary") + class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): @@ -5862,7 +5879,7 @@ class VIEW3D_PT_shading_options(Panel): row = col.row() row.active = not xray_active - row.prop(shading, "use_dof", text="Depth Of Field") + row.prop(shading, "use_dof", text="Depth of Field") if shading.type in {'WIREFRAME', 'SOLID'}: row = layout.split() @@ -6111,18 +6128,21 @@ class VIEW3D_PT_overlay_geometry(Panel): sub.active = overlay.show_wireframes or is_wireframes sub.prop(overlay, "wireframe_threshold", text="Wireframe") - col = layout.column(align=True) - col.active = display_all - - col.prop(overlay, "show_face_orientation") row = col.row(align=True) - if context.mode not in {'EDIT_ARMATURE', 'POSE', 'OBJECT', 'PAINT_GPENCIL',\ - 'VERTEX_GPENCIL', 'WEIGHT_GPENCIL', 'SCULPT_GPENCIL', 'EDIT_GPENCIL'}: + if context.mode not in { + 'EDIT_ARMATURE', 'POSE', 'OBJECT', + 'PAINT_GPENCIL', 'VERTEX_GPENCIL', 'WEIGHT_GPENCIL', 'SCULPT_GPENCIL', 'EDIT_GPENCIL', + }: row.prop(overlay, "show_fade_inactive", text="") sub = row.row() sub.active = overlay.show_fade_inactive sub.prop(overlay, "fade_inactive_alpha", text="Fade Inactive Geometry") + col = layout.column(align=True) + col.active = display_all + + col.prop(overlay, "show_face_orientation") + # sub.prop(overlay, "show_onion_skins") @@ -6553,7 +6573,7 @@ class VIEW3D_PT_snapping(Panel): layout = self.layout col = layout.column() - col.label(text="Snap to") + col.label(text="Snap To") col.prop(tool_settings, "snap_elements", expand=True) col.separator() @@ -6561,7 +6581,7 @@ class VIEW3D_PT_snapping(Panel): col.prop(tool_settings, "use_snap_grid_absolute") if snap_elements != {'INCREMENT'}: - col.label(text="Snap with") + col.label(text="Snap With") row = col.row(align=True) row.prop(tool_settings, "snap_target", expand=True) @@ -7572,6 +7592,7 @@ classes = ( VIEW3D_MT_orientations_pie, VIEW3D_MT_proportional_editing_falloff_pie, VIEW3D_MT_sculpt_mask_edit_pie, + VIEW3D_MT_sculpt_automasking_pie, VIEW3D_MT_wpaint_vgroup_lock_pie, VIEW3D_MT_sculpt_face_sets_edit_pie, VIEW3D_PT_active_tool, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index e9118a8be91..8c0103d10e6 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -124,11 +124,7 @@ class View3DPanel: # Used by vertex & weight paint def draw_vpaint_symmetry(layout, vpaint, mesh): - col = layout.column() - col.use_property_split = True - col.use_property_decorate = False - row = col.row(heading="Mirror", align=True) row.prop(mesh, "use_mirror_x", text="X", toggle=True) row.prop(mesh, "use_mirror_y", text="Y", toggle=True) @@ -681,7 +677,7 @@ class VIEW3D_PT_tools_brush_falloff(Panel, View3DPaintPanel, FalloffPanel): class VIEW3D_PT_tools_brush_falloff_frontface(View3DPaintPanel, Panel): bl_context = ".imagepaint" # dot on purpose (access from topbar) - bl_label = "Front-face Falloff" + bl_label = "Front-Face Falloff" bl_parent_id = "VIEW3D_PT_tools_brush_falloff" bl_options = {'DEFAULT_CLOSED'} @@ -955,14 +951,20 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + tool_settings = context.tool_settings wpaint = tool_settings.weight_paint - draw_vpaint_symmetry(layout, wpaint, context.object.data) + mesh = context.object.data - col = layout.column() - row = col.row(align=True) - row.prop(context.object.data, 'use_mirror_vertex_group_x') + draw_vpaint_symmetry(layout, wpaint, mesh) + col = layout.column(align=True) + col.prop(mesh, 'use_mirror_vertex_group_x', text="Vertex Group X") + row = col.row() + row.active = mesh.use_mirror_vertex_group_x + row.prop(mesh, "use_mirror_topology") class VIEW3D_PT_tools_weightpaint_symmetry_for_topbar(Panel): bl_space_type = 'TOPBAR' @@ -995,14 +997,6 @@ class VIEW3D_PT_tools_weightpaint_options(Panel, View3DPaintPanel): col.prop(wpaint, "use_group_restrict") - obj = context.weight_paint_object - if obj.type == 'MESH': - mesh = obj.data - col.prop(mesh, "use_mirror_x") - row = col.row() - row.active = mesh.use_mirror_x - row.prop(mesh, "use_mirror_topology") - # ********** default tools for vertex-paint **************** @@ -1037,8 +1031,12 @@ class VIEW3D_PT_tools_vertexpaint_symmetry(Panel, View3DPaintPanel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + tool_settings = context.tool_settings vpaint = tool_settings.vertex_paint + draw_vpaint_symmetry(layout, vpaint, context.object.data) @@ -1685,7 +1683,8 @@ class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): return False gpd = context.gpencil_data - return bool(context.editable_gpencil_strokes) and bool(gpd.use_stroke_edit_mode) + valid_mode = bool(gpd.use_stroke_edit_mode or gpd.is_stroke_paint_mode) + return bool(context.editable_gpencil_strokes) and valid_mode def draw(self, context): layout = self.layout @@ -1700,7 +1699,10 @@ class VIEW3D_PT_tools_grease_pencil_interpolate(Panel): col = layout.column(align=True) col.label(text="Options:") col.prop(settings, "interpolate_all_layers") - col.prop(settings, "interpolate_selected_only") + + gpd = context.gpencil_data + if gpd.use_stroke_edit_mode: + col.prop(settings, "interpolate_selected_only") col = layout.column(align=True) col.label(text="Sequence Options:") diff --git a/source/blender/blendthumb/CMakeLists.txt b/source/blender/blendthumb/CMakeLists.txt index 0b1ce5149da..cb121cb9c8d 100644 --- a/source/blender/blendthumb/CMakeLists.txt +++ b/source/blender/blendthumb/CMakeLists.txt @@ -28,7 +28,7 @@ set(SRC src/Dll.cpp ) -set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /nodefaultlib:MSVCRT.lib") +string(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG " /nodefaultlib:MSVCRT.lib") add_library(BlendThumb SHARED ${SRC}) target_link_libraries(BlendThumb ${ZLIB_LIBRARIES}) diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index bf84f5c57b3..1f39257a4c2 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -40,9 +40,6 @@ struct rcti; int BLF_init(void); void BLF_exit(void); -void BLF_default_dpi(int dpi); -void BLF_default_set(int fontid); -int BLF_default(void); /* get default font ID so we can pass it to other functions */ void BLF_cache_clear(void); @@ -77,7 +74,7 @@ void BLF_color4f(int fontid, float r, float g, float b, float a); void BLF_color4fv(int fontid, const float rgba[4]); void BLF_color3f(int fontid, float r, float g, float b); void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha); -/* also available: UI_FontThemeColor(fontid, colorid) */ +/* Also available: `UI_FontThemeColor(fontid, colorid)`. */ /* Set a 4x4 matrix to be multiplied before draw the text. * Remember that you need call BLF_enable(BLF_MATRIX) @@ -92,19 +89,12 @@ void BLF_color3fv_alpha(int fontid, const float rgb[3], float alpha); */ void BLF_matrix(int fontid, const float m[16]); -/* Batch drawcalls together as long as - * the modelview matrix and the font remain unchanged. */ +/* Batch draw-calls together as long as + * the model-view matrix and the font remain unchanged. */ void BLF_batch_draw_begin(void); void BLF_batch_draw_flush(void); void BLF_batch_draw_end(void); -/* Draw the string using the default font, size and dpi. */ -void BLF_draw_default(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); -void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); - -/* Set size and DPI, and return default font ID. */ -int BLF_set_default(void); - /* Draw the string using the current font. */ void BLF_draw_ex(int fontid, const char *str, size_t len, struct ResultBLF *r_info) ATTR_NONNULL(2); @@ -257,6 +247,16 @@ void BLF_thumb_preview(const char *filename, int h, int channels) ATTR_NONNULL(); +/* blf_default.c */ +void BLF_default_dpi(int dpi); +void BLF_default_set(int fontid); +int BLF_default(void); /* get default font ID so we can pass it to other functions */ +/* Draw the string using the default font, size and dpi. */ +void BLF_draw_default(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); +void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) ATTR_NONNULL(); +/* Set size and DPI, and return default font ID. */ +int BLF_set_default(void); + /* blf_font_default.c */ int BLF_load_default(const bool unique); int BLF_load_mono_default(const bool unique); diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index 3fd0dd95ef8..59a9072de57 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -38,6 +38,7 @@ set(INC_SYS set(SRC intern/blf.c + intern/blf_default.c intern/blf_dir.c intern/blf_font.c intern/blf_font_default.c diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index c8940add738..48f283e67b9 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -37,10 +37,6 @@ #include "MEM_guardedalloc.h" -#include "DNA_listBase.h" -#include "DNA_userdef_types.h" -#include "DNA_vec_types.h" - #include "BLI_math.h" #include "BLI_threads.h" @@ -48,9 +44,6 @@ #include "IMB_colormanagement.h" -#include "UI_interface.h" - -#include "GPU_immediate.h" #include "GPU_matrix.h" #include "GPU_shader.h" @@ -64,9 +57,6 @@ */ #define BLF_MAX_FONT 16 -/* call BLF_default_set first! */ -#define ASSERT_DEFAULT_SET BLI_assert(global_font_default != -1) - #define BLF_RESULT_CHECK_INIT(r_info) \ if (r_info) { \ memset(r_info, 0, sizeof(*(r_info))); \ @@ -76,10 +66,6 @@ /* Font array. */ static FontBLF *global_font[BLF_MAX_FONT] = {NULL}; -/* Default size and dpi, for BLF_draw_default. */ -static int global_font_default = -1; -static int global_font_dpi = 72; - /* XXX, should these be made into global_font_'s too? */ int blf_mono_font = -1; int blf_mono_font_render = -1; @@ -98,16 +84,11 @@ int BLF_init(void) global_font[i] = NULL; } - global_font_dpi = 72; + BLF_default_dpi(72); return blf_font_init(); } -void BLF_default_dpi(int dpi) -{ - global_font_dpi = dpi; -} - void BLF_exit(void) { for (int i = 0; i < BLF_MAX_FONT; i++) { @@ -132,6 +113,11 @@ void BLF_cache_clear(void) } } +bool blf_font_id_is_valid(int fontid) +{ + return blf_get(fontid) != NULL; +} + static int blf_search(const char *name) { for (int i = 0; i < BLF_MAX_FONT; i++) { @@ -155,20 +141,6 @@ static int blf_search_available(void) return -1; } -void BLF_default_set(int fontid) -{ - FontBLF *font = blf_get(fontid); - if (font || fontid == -1) { - global_font_default = fontid; - } -} - -int BLF_default(void) -{ - ASSERT_DEFAULT_SET; - return global_font_default; -} - bool BLF_has_glyph(int fontid, unsigned int unicode) { FontBLF *font = blf_get(fontid); @@ -515,37 +487,6 @@ void BLF_batch_draw_end(void) g_batch.enabled = false; } -void BLF_draw_default(float x, float y, float z, const char *str, size_t len) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - BLF_position(global_font_default, x, y, z); - BLF_draw(global_font_default, str, len); -} - -/* same as above but call 'BLF_draw_ascii' */ -void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - BLF_position(global_font_default, x, y, z); - BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */ -} - -int BLF_set_default(void) -{ - ASSERT_DEFAULT_SET; - - const uiStyle *style = UI_style_get(); - BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); - - return global_font_default; -} - static void blf_draw_gl__start(FontBLF *font) { /* diff --git a/source/blender/blenfont/intern/blf_default.c b/source/blender/blenfont/intern/blf_default.c new file mode 100644 index 00000000000..7bbc865128d --- /dev/null +++ b/source/blender/blenfont/intern/blf_default.c @@ -0,0 +1,90 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2009 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup blf + * + * Default API, that uses Blender's user preferences for the default size. + */ + +#include "DNA_userdef_types.h" + +#include "BLI_assert.h" + +#include "BLF_api.h" + +#include "UI_interface.h" + +#include "blf_internal.h" + +/* call BLF_default_set first! */ +#define ASSERT_DEFAULT_SET BLI_assert(global_font_default != -1) + +/* Default size and dpi, for BLF_draw_default. */ +static int global_font_default = -1; +static int global_font_dpi = 72; + +void BLF_default_dpi(int dpi) +{ + global_font_dpi = dpi; +} + +void BLF_default_set(int fontid) +{ + if ((fontid == -1) || blf_font_id_is_valid(fontid)) { + global_font_default = fontid; + } +} + +int BLF_default(void) +{ + ASSERT_DEFAULT_SET; + return global_font_default; +} + +int BLF_set_default(void) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + + return global_font_default; +} + +void BLF_draw_default(float x, float y, float z, const char *str, size_t len) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + BLF_position(global_font_default, x, y, z); + BLF_draw(global_font_default, str, len); +} + +/* same as above but call 'BLF_draw_ascii' */ +void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t len) +{ + ASSERT_DEFAULT_SET; + + const uiStyle *style = UI_style_get(); + BLF_size(global_font_default, style->widgetlabel.points, global_font_dpi); + BLF_position(global_font_default, x, y, z); + BLF_draw_ascii(global_font_default, str, len); /* XXX, use real length */ +} diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c index 1501ee07b66..189cbaf152d 100644 --- a/source/blender/blenfont/intern/blf_font.c +++ b/source/blender/blenfont/intern/blf_font.c @@ -75,9 +75,9 @@ static SpinLock blf_glyph_cache_mutex; * \{ */ /** - * Drawcalls are precious! make them count! - * Since most of the Text elems are not covered by other UI elements, we can - * group some strings together and render them in one drawcall. This behavior + * Draw-calls are precious! make them count! + * Since most of the Text elements are not covered by other UI elements, we can + * group some strings together and render them in one draw-call. This behavior * is on demand only, between #BLF_batch_draw_begin() and #BLF_batch_draw_end(). */ static void blf_batch_draw_init(void) diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index b616f47a897..ada772c53d2 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -43,6 +43,8 @@ char *blf_dir_metrics_search(const char *filename); int blf_font_init(void); void blf_font_exit(void); +bool blf_font_id_is_valid(int fontid); + void blf_draw_buffer__start(struct FontBLF *font); void blf_draw_buffer__end(void); diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index b517ecfa599..092eec578c9 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -364,6 +364,7 @@ struct Mesh *editbmesh_get_eval_cage_and_final(struct Depsgraph *depsgraph, float (*editbmesh_vert_coords_alloc(struct BMEditMesh *em, int *r_vert_len))[3]; bool editbmesh_modifier_is_enabled(struct Scene *scene, + const struct Object *ob, struct ModifierData *md, bool has_prev_mesh); void makeDerivedMesh(struct Depsgraph *depsgraph, diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 741abb50453..5a64140b917 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,15 +31,15 @@ extern "C" { */ /* Blender major and minor version. */ -#define BLENDER_VERSION 291 +#define BLENDER_VERSION 292 /* Blender patch version for bugfix releases. */ #define BLENDER_VERSION_PATCH 0 /** Blender release cycle stage: alpha/beta/rc/release. */ -#define BLENDER_VERSION_CYCLE beta +#define BLENDER_VERSION_CYCLE alpha /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 9 +#define BLENDER_FILE_SUBVERSION 3 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_collection.h b/source/blender/blenkernel/BKE_collection.h index f4393742dff..f35dafa15a8 100644 --- a/source/blender/blenkernel/BKE_collection.h +++ b/source/blender/blenkernel/BKE_collection.h @@ -35,10 +35,16 @@ extern "C" { struct BLI_Iterator; struct Base; +struct BlendDataReader; +struct BlendExpander; +struct BlendLibReader; +struct BlendWriter; struct Collection; +struct Library; struct Main; struct Object; struct Scene; +struct SceneCollection; struct ViewLayer; typedef struct CollectionParent { @@ -160,6 +166,22 @@ bool BKE_collection_has_collection(struct Collection *parent, struct Collection void BKE_collection_parent_relations_rebuild(struct Collection *collection); void BKE_main_collections_parent_relations_rebuild(struct Main *bmain); +/* .blend file I/O */ + +void BKE_collection_blend_write_nolib(struct BlendWriter *writer, struct Collection *collection); +void BKE_collection_blend_read_data(struct BlendDataReader *reader, struct Collection *collection); +void BKE_collection_blend_read_lib(struct BlendLibReader *reader, struct Collection *collection); +void BKE_collection_blend_read_expand(struct BlendExpander *expander, + struct Collection *collection); + +void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader, + struct SceneCollection *sc); +void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader, + struct Library *lib, + struct SceneCollection *sc); +void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander, + struct SceneCollection *sc); + /* Iteration callbacks. */ typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data); diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index ecb891760b7..5ff0e7597e9 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -183,6 +183,8 @@ bool BKE_constraint_remove_ex(ListBase *list, bool clear_dep); bool BKE_constraint_remove(ListBase *list, struct bConstraint *con); +void BKE_constraint_panel_expand(struct bConstraint *con); + /* Constraints + Proxies function prototypes */ void BKE_constraints_proxylocal_extract(struct ListBase *dst, struct ListBase *src); bool BKE_constraints_proxylocked_owner(struct Object *ob, struct bPoseChannel *pchan); diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index c9bc5e83a1f..f527f40d0d7 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -325,6 +325,9 @@ float fcurve_samplingcb_evalcurve(struct FCurve *fcu, void *data, float evaltime void fcurve_store_samples( struct FCurve *fcu, void *data, int start, int end, FcuSampleFunc sample_cb); +/* Convert baked/sampled fcurves into bezt/regular fcurves. */ +void fcurve_samples_to_keyframes(struct FCurve *fcu, const int start, const int end); + /* ************* F-Curve .blend file API ******************** */ void BKE_fmodifiers_blend_write(struct BlendWriter *writer, struct ListBase *fmodifiers); diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h index e003144047b..78a17e3568d 100644 --- a/source/blender/blenkernel/BKE_gpencil_modifier.h +++ b/source/blender/blenkernel/BKE_gpencil_modifier.h @@ -249,6 +249,7 @@ typedef struct GpencilModifierTypeInfo { void BKE_gpencil_modifier_init(void); void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname); +void BKE_gpencil_modifier_panel_expand(struct GpencilModifierData *md); const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType type); struct GpencilModifierData *BKE_gpencil_modifier_new(int type); void BKE_gpencil_modifier_free_ex(struct GpencilModifierData *md, const int flag); diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 37a83a94079..9c250240e5e 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -147,8 +147,6 @@ void IDP_FreeProperty(struct IDProperty *prop); void IDP_ClearProperty(IDProperty *prop); -void IDP_RelinkProperty(struct IDProperty *prop); - void IDP_Reset(IDProperty *prop, const IDProperty *reference); #define IDP_Int(prop) ((prop)->data.val) diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h index 3caf15d1b50..1298e3c2bbf 100644 --- a/source/blender/blenkernel/BKE_idtype.h +++ b/source/blender/blenkernel/BKE_idtype.h @@ -102,6 +102,10 @@ typedef void (*IDTypeBlendReadDataFunction)(struct BlendDataReader *reader, stru typedef void (*IDTypeBlendReadLibFunction)(struct BlendLibReader *reader, struct ID *id); typedef void (*IDTypeBlendReadExpandFunction)(struct BlendExpander *expander, struct ID *id); +typedef void (*IDTypeBlendReadUndoPreserve)(struct BlendLibReader *reader, + struct ID *id_new, + struct ID *id_old); + typedef struct IDTypeInfo { /* ********** General IDType data. ********** */ @@ -196,6 +200,13 @@ typedef struct IDTypeInfo { * Specify which other id data blocks should be loaded when the current one is loaded. */ IDTypeBlendReadExpandFunction blend_read_expand; + + /** + * Allow an ID type to preserve some of its data across (memfile) undo steps. + * + * \note Called from #setup_app_data when undoing or redoing a memfile step. + */ + IDTypeBlendReadUndoPreserve blend_read_undo_preserve; } IDTypeInfo; /* ********** Declaration of each IDTypeInfo. ********** */ diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h index 024d58174e8..3d5062eada0 100644 --- a/source/blender/blenkernel/BKE_layer.h +++ b/source/blender/blenkernel/BKE_layer.h @@ -34,6 +34,8 @@ extern "C" { #define TODO_LAYER /* generic todo */ struct Base; +struct BlendDataReader; +struct BlendLibReader; struct Collection; struct Depsgraph; struct LayerCollection; @@ -147,6 +149,13 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph, struct Scene *scene, int view_layer_index); +/* .blend file I/O */ + +void BKE_view_layer_blend_read_data(struct BlendDataReader *reader, struct ViewLayer *view_layer); +void BKE_view_layer_blend_read_lib(struct BlendLibReader *reader, + struct Library *lib, + struct ViewLayer *view_layer); + /* iterators */ typedef struct ObjectsVisibleIteratorData { diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 0275f4dd587..253b0480b3a 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -177,7 +177,7 @@ void BKE_mesh_to_pointcloud(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); -void BKE_mesh_from_pointcloud(struct PointCloud *pointcloud, struct Mesh *me); +void BKE_mesh_from_pointcloud(const struct PointCloud *pointcloud, struct Mesh *me); void BKE_pointcloud_to_mesh(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index b2015c4e6d7..4909fe012b5 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -396,6 +396,7 @@ const ModifierTypeInfo *BKE_modifier_get_info(ModifierType type); /* For modifier UI panels. */ void BKE_modifier_type_panel_id(ModifierType type, char *r_idname); +void BKE_modifier_panel_expand(struct ModifierData *md); /* Modifier utility calls, do call through type pointer and return * default values if pointer is optional. @@ -427,8 +428,10 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md); bool BKE_modifier_is_enabled(const struct Scene *scene, struct ModifierData *md, int required_mode); -void BKE_modifier_set_error(struct ModifierData *md, const char *format, ...) - ATTR_PRINTF_FORMAT(2, 3); +void BKE_modifier_set_error(const struct Object *ob, + struct ModifierData *md, + const char *format, + ...) ATTR_PRINTF_FORMAT(3, 4); bool BKE_modifier_is_preview(struct ModifierData *md); void BKE_modifiers_foreach_ID_link(struct Object *ob, IDWalkFunc walk, void *userData); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index fbdfc5b76a7..5a668532033 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -36,7 +36,6 @@ struct DerivedMesh; struct MDisps; struct Mesh; struct ModifierData; -struct Multires; struct MultiresModifierData; struct Object; struct Scene; @@ -114,22 +113,12 @@ int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph, struct MultiresModifierData *mmd, int rebuild_limit, bool switch_view_to_lower_level); -void multiresModifier_subdivide_legacy(struct MultiresModifierData *mmd, - struct Scene *scene, - struct Object *ob, - int updateblock, - int simple); void multiresModifier_sync_levels_ex(struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst); void multires_stitch_grids(struct Object *); -/* Related to the old multires */ -void multires_free(struct Multires *mr); -void multires_load_old(struct Object *ob, struct Mesh *me); -void multires_load_old_250(struct Mesh *); - void multiresModifier_scale_disp(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); @@ -229,6 +218,13 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3] const float dPdv[3], const int corner); +/* Versioning. */ + +/* Convert displacement which is stored for simply-subdivided mesh to a Catmull-Clark + * subdivided mesh. */ +void multires_do_versions_simple_to_catmull_clark(struct Object *object, + struct MultiresModifierData *mmd); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 38045e22def..e3591b8fcd1 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -880,8 +880,7 @@ void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree); * } FOREACH_NODETREE_END; * \endcode * - * \{ - */ + * \{ */ /* should be an opaque type, only for internal use by BKE_node_tree_iter_*** */ struct NodeTreeIterStore { @@ -1337,8 +1336,8 @@ int ntreeTexExecTree(struct bNodeTree *ntree, /** \} */ -void init_nodesystem(void); -void free_nodesystem(void); +void BKE_node_system_init(void); +void BKE_node_system_exit(void); /* -------------------------------------------------------------------- */ /* evaluation support, */ diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 0a992f2cb58..b7015942cb4 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -191,6 +191,8 @@ struct Base **BKE_object_pose_base_array_get(struct ViewLayer *view_layer, unsigned int *r_bases_len); void BKE_object_get_parent_matrix(struct Object *ob, struct Object *par, float r_parentmat[4][4]); + +/* Compute object world transform and store it in ob->obmat. */ void BKE_object_where_is_calc(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); void BKE_object_where_is_calc_ex(struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 150d0d9b011..bb1d1781e31 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -505,6 +505,9 @@ typedef struct SculptSession { int active_face_index; int active_grid_index; + /* When active, the cursor draws with faded colors, indicating that there is an action enabled. + */ + bool draw_faded_cursor; float cursor_radius; float cursor_location[3]; float cursor_normal[3]; @@ -514,6 +517,7 @@ typedef struct SculptSession { /* For Sculpt trimming gesture tools, initial raycast data from the position of the mouse when * the gesture starts (intersection with the surface and if they ray hit the surface or not). */ float gesture_initial_location[3]; + float gesture_initial_normal[3]; bool gesture_initial_hit; /* TODO(jbakker): Replace rv3d adn v3d with ViewContext */ diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 6ed3b94b8e5..5df42e4ccd6 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -45,6 +45,8 @@ struct ParticleSystemModifierData; struct BVHTreeRay; struct BVHTreeRayHit; +struct BlendDataReader; +struct BlendLibReader; struct CustomData_MeshMasks; struct Depsgraph; struct EdgeHash; @@ -261,7 +263,7 @@ extern unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT]; extern unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT]; extern float PSYS_FRAND_BASE[PSYS_FRAND_COUNT]; -void psys_init_rng(void); +void BKE_particle_init_rng(void); BLI_INLINE float psys_frand(ParticleSystem *psys, unsigned int seed) { @@ -625,6 +627,13 @@ void BKE_particle_batch_cache_free(struct ParticleSystem *psys); extern void (*BKE_particle_batch_cache_dirty_tag_cb)(struct ParticleSystem *psys, int mode); extern void (*BKE_particle_batch_cache_free_cb)(struct ParticleSystem *psys); +/* .blend file I/O */ +void BKE_particle_partdeflect_blend_read_data(struct BlendDataReader *reader, + struct PartDeflect *pd); +void BKE_particle_partdeflect_blend_read_lib(struct BlendLibReader *reader, + struct ID *id, + struct PartDeflect *pd); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index f8e04b75b3d..a45b134f825 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -167,7 +167,7 @@ typedef struct PTCacheID { * (the cfra parameter is just for using same function pointer with totwrite). */ int (*totpoint)(void *calldata, int cfra); /* report error if number of points does not match */ - void (*error)(void *calldata, const char *message); + void (*error)(const struct ID *owner_id, void *calldata, const char *message); /* number of points written for current cache frame */ int (*totwrite)(void *calldata, int cfra); diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 35a3d0415a8..fd7f20d8839 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -33,6 +33,9 @@ extern "C" { #endif struct ARegion; +struct BlendDataReader; +struct BlendLibReader; +struct BlendWriter; struct Header; struct ID; struct LibraryForeachIDData; @@ -362,8 +365,8 @@ typedef struct Menu { /* spacetypes */ struct SpaceType *BKE_spacetype_from_id(int spaceid); -struct ARegionType *BKE_regiontype_from_id_or_first(struct SpaceType *st, int regionid); -struct ARegionType *BKE_regiontype_from_id(struct SpaceType *st, int regionid); +struct ARegionType *BKE_regiontype_from_id_or_first(const struct SpaceType *st, int regionid); +struct ARegionType *BKE_regiontype_from_id(const struct SpaceType *st, int regionid); const struct ListBase *BKE_spacetypes_list(void); void BKE_spacetype_register(struct SpaceType *st); bool BKE_spacetype_exists(int spaceid); @@ -384,7 +387,7 @@ void BKE_spacedata_callback_id_remap_set(void (*func)( void BKE_spacedata_id_unref(struct ScrArea *area, struct SpaceLink *sl, struct ID *id); /* area/regions */ -struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *region); +struct ARegion *BKE_area_region_copy(const struct SpaceType *st, const struct ARegion *region); void BKE_area_region_free(struct SpaceType *st, struct ARegion *region); void BKE_area_region_panels_free(struct ListBase *panels); void BKE_screen_area_free(struct ScrArea *area); @@ -449,6 +452,20 @@ void BKE_screen_remove_unused_scrverts(struct bScreen *screen); void BKE_screen_header_alignment_reset(struct bScreen *screen); +/* .blend file I/O */ +void BKE_screen_view3d_shading_blend_write(struct BlendWriter *writer, + struct View3DShading *shading); +void BKE_screen_view3d_shading_blend_read_data(struct BlendDataReader *reader, + struct View3DShading *shading); + +void BKE_screen_area_map_blend_write(struct BlendWriter *writer, struct ScrAreaMap *area_map); +bool BKE_screen_area_map_blend_read_data(struct BlendDataReader *reader, + struct ScrAreaMap *area_map); +void BKE_screen_view3d_do_versions_250(struct View3D *v3d, ListBase *regions); +void BKE_screen_area_blend_read_lib(struct BlendLibReader *reader, + struct ID *parent_id, + struct ScrArea *area); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_sequencer_offscreen.h b/source/blender/blenkernel/BKE_sequencer_offscreen.h index 90d3f80320a..f5f6067b06e 100644 --- a/source/blender/blenkernel/BKE_sequencer_offscreen.h +++ b/source/blender/blenkernel/BKE_sequencer_offscreen.h @@ -33,6 +33,8 @@ extern "C" { #endif +struct GPUOffScreen; + typedef struct ImBuf *(*SequencerDrawView)(struct Depsgraph *depsgraph, struct Scene *scene, struct View3DShading *shading_override, diff --git a/source/blender/blenkernel/BKE_shader_fx.h b/source/blender/blenkernel/BKE_shader_fx.h index da14487c1f4..4b9688f9515 100644 --- a/source/blender/blenkernel/BKE_shader_fx.h +++ b/source/blender/blenkernel/BKE_shader_fx.h @@ -151,6 +151,7 @@ typedef struct ShaderFxTypeInfo { void BKE_shaderfx_init(void); void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname); +void BKE_shaderfx_panel_expand(struct ShaderFxData *fx); const ShaderFxTypeInfo *BKE_shaderfx_get_info(ShaderFxType type); struct ShaderFxData *BKE_shaderfx_new(int type); void BKE_shaderfx_free_ex(struct ShaderFxData *fx, const int flag); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index f6df3f1bb62..97281dbccf0 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -189,6 +189,7 @@ set(SRC intern/multires_reshape_vertcos.c intern/multires_subdiv.c intern/multires_unsubdivide.c + intern/multires_versioning.c intern/nla.c intern/node.c intern/object.c @@ -705,7 +706,7 @@ endif() # # Warnings as errors, this is too strict! # if(MSVC) -# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX") +# string(APPEND CMAKE_C_FLAGS " /WX") # endif() blender_add_lib(bf_blenkernel "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index d63c5fe12ab..67e7b890548 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -736,7 +736,7 @@ CCGError ccgSubSurf_syncFace( } } else { - if (ss->syncState == eSyncState_Vert || ss->syncState == eSyncState_Edge) { + if (ELEM(ss->syncState, eSyncState_Vert, eSyncState_Edge)) { ss->syncState = eSyncState_Face; } else if (ss->syncState != eSyncState_Face) { diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index d551eaf04e4..eeff04788f9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1021,7 +1021,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && have_non_onlydeform_modifiers_appled) { - BKE_modifier_set_error(md, "Modifier requires original data, bad stack position"); + BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position"); continue; } @@ -1047,10 +1047,10 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, if (unsupported) { if (sculpt_dyntopo) { - BKE_modifier_set_error(md, "Not supported in dyntopo"); + BKE_modifier_set_error(ob, md, "Not supported in dyntopo"); } else { - BKE_modifier_set_error(md, "Not supported in sculpt mode"); + BKE_modifier_set_error(ob, md, "Not supported in sculpt mode"); } continue; } @@ -1378,7 +1378,10 @@ float (*editbmesh_vert_coords_alloc(BMEditMesh *em, int *r_vert_len))[3] return cos; } -bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev_mesh) +bool editbmesh_modifier_is_enabled(Scene *scene, + const Object *ob, + ModifierData *md, + bool has_prev_mesh) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); const int required_mode = eModifierMode_Realtime | eModifierMode_Editmode; @@ -1388,7 +1391,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, bool has_prev } if ((mti->flags & eModifierTypeFlag_RequiresOriginalData) && has_prev_mesh) { - BKE_modifier_set_error(md, "Modifier requires original data, bad stack position"); + BKE_modifier_set_error(ob, md, "Modifier requires original data, bad stack position"); return false; } @@ -1522,7 +1525,7 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, for (int i = 0; md; i++, md = md->next, md_datamask = md_datamask->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); - if (!editbmesh_modifier_is_enabled(scene, md, mesh_final != NULL)) { + if (!editbmesh_modifier_is_enabled(scene, ob, md, mesh_final != NULL)) { continue; } @@ -2187,7 +2190,7 @@ static void mesh_init_origspace(Mesh *mesh) for (i = 0; i < numpoly; i++, mp++) { OrigSpaceLoop *lof = lof_array + mp->loopstart; - if (mp->totloop == 3 || mp->totloop == 4) { + if (ELEM(mp->totloop, 3, 4)) { for (j = 0; j < mp->totloop; j++, lof++) { copy_v2_v2(lof->uv, default_osf[j]); } diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index cbecc91b4ec..c77153960ea 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -295,6 +295,8 @@ IDTypeInfo IDType_ID_AC = { .blend_read_data = action_blend_read_data, .blend_read_lib = action_blend_read_lib, .blend_read_expand = action_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /* ***************** Library data level operations on action ************** */ diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index bad2ed53436..fb885527cce 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -329,6 +329,8 @@ IDTypeInfo IDType_ID_AR = { .blend_read_data = armature_blend_read_data, .blend_read_lib = armature_blend_read_lib, .blend_read_expand = armature_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /** \} */ @@ -576,7 +578,7 @@ void BKE_armature_transform(bArmature *arm, const float mat[4][4], const bool do /* -------------------------------------------------------------------- */ /** \name Armature Bone Find by Name * - * Using fast #GHash look-ups when available. + * Using fast #GHash lookups when available. * \{ */ static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name) @@ -799,7 +801,7 @@ bool bone_autoside_name( while (changed) { /* remove extensions */ changed = false; if (len > 2 && basename[len - 2] == '.') { - if (basename[len - 1] == 'L' || basename[len - 1] == 'R') { /* L R */ + if (ELEM(basename[len - 1], 'L', 'R')) { /* L R */ basename[len - 2] = '\0'; len -= 2; changed = true; diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 1ad1a821129..71c859e1514 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -53,7 +53,6 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_studiolight.h" #include "DEG_depsgraph.h" @@ -61,6 +60,8 @@ #include "RE_pipeline.h" #include "RE_render_ext.h" +#include "SEQ_sequencer.h" + #include "BLF_api.h" Global G; @@ -99,7 +100,7 @@ void BKE_blender_free(void) IMB_moviecache_destruct(); - free_nodesystem(); + BKE_node_system_exit(); } /** \} */ diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 78ce70a8448..96bf9fbe8d2 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -899,7 +899,7 @@ static Object *boid_find_ground(BoidBrainData *bbd, for (coll = bbd->sim->colliders->first; coll; coll = coll->next) { col.current = coll->ob; col.md = coll->collmd; - col.fac1 = col.fac2 = 0.f; + col.fac1 = col.fac2 = 0.0f; if (col.md && col.md->bvhtree) { BLI_bvhtree_ray_cast_ex(col.md->bvhtree, diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 4ea9a26f0f8..f624d0ae057 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -73,12 +73,13 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_report.h" -#include "BKE_sequencer.h" #include "BKE_bpath.h" /* own include */ #include "CLG_log.h" +#include "SEQ_sequencer.h" + #ifndef _MSC_VER # include "BLI_strict_flags.h" #endif diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 17243b328e8..806b9ca1416 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -355,6 +355,37 @@ static void brush_blend_read_expand(BlendExpander *expander, ID *id) } } +static int brush_undo_preserve_cb(LibraryIDLinkCallbackData *cb_data) +{ + BlendLibReader *reader = cb_data->user_data; + ID *id_old = *cb_data->id_pointer; + /* Old data has not been remapped to new values of the pointers, if we want to keep the old + * pointer here we need its new address. */ + ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) : + NULL; + BLI_assert(id_old_new == NULL || ELEM(id_old, id_old_new, id_old_new->orig_id)); + if (cb_data->cb_flag & IDWALK_CB_USER) { + id_us_plus_no_lib(id_old_new); + id_us_min(id_old); + } + *cb_data->id_pointer = id_old_new; + return IDWALK_RET_NOP; +} + +static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) +{ + /* Whole Brush is preserved accross undo's. */ + BKE_lib_id_swap(NULL, id_new, id_old); + + /* `id_new` now has content from `id_old`, we need to ensure those old ID pointers are valid. + * Note: Since we want to re-use all old pointers here, code is much simpler than for Scene. */ + BKE_library_foreach_ID_link(NULL, id_new, brush_undo_preserve_cb, reader, IDWALK_NOP); + + /* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be + * fairly delicate. */ + SWAP(IDProperty *, id_new->properties, id_old->properties); +} + IDTypeInfo IDType_ID_BR = { .id_code = ID_BR, .id_filter = FILTER_ID_BR, @@ -376,6 +407,8 @@ IDTypeInfo IDType_ID_BR = { .blend_read_data = brush_blend_read_data, .blend_read_lib = brush_blend_read_lib, .blend_read_expand = brush_blend_read_expand, + + .blend_read_undo_preserve = brush_undo_preserve, }; static RNG *brush_rng; diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 0ee0242866f..d6c31809a2e 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -140,6 +140,8 @@ IDTypeInfo IDType_ID_CF = { .blend_read_data = cache_file_blend_read_data, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /* TODO: make this per cache file to avoid global locks. */ diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 3980a552855..0ca22e34973 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -201,6 +201,8 @@ IDTypeInfo IDType_ID_CA = { .blend_read_data = camera_blend_read_data, .blend_read_lib = camera_blend_read_lib, .blend_read_expand = camera_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /** \} */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 403722b80cf..e9df562a15f 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -55,7 +55,7 @@ /* Prototypes for internal functions. */ static void cloth_to_object(Object *ob, ClothModifierData *clmd, float (*vertexCos)[3]); -static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh); +static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh); static bool cloth_from_object( Object *ob, ClothModifierData *clmd, Mesh *mesh, float framenr, int first); static void cloth_update_springs(ClothModifierData *clmd); @@ -234,13 +234,13 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int if (clmd->clothObject == NULL) { if (!cloth_from_object(ob, clmd, result, framenr, 1)) { BKE_ptcache_invalidate(cache); - BKE_modifier_set_error(&(clmd->modifier), "Can't initialize cloth"); + BKE_modifier_set_error(ob, &(clmd->modifier), "Can't initialize cloth"); return false; } if (clmd->clothObject == NULL) { BKE_ptcache_invalidate(cache); - BKE_modifier_set_error(&(clmd->modifier), "Null cloth object"); + BKE_modifier_set_error(ob, &(clmd->modifier), "Null cloth object"); return false; } @@ -742,7 +742,7 @@ static bool cloth_from_object( clmd->clothObject->edgeset = NULL; } else { - BKE_modifier_set_error(&(clmd->modifier), "Out of memory on allocating clmd->clothObject"); + BKE_modifier_set_error(ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject"); return false; } @@ -751,7 +751,7 @@ static bool cloth_from_object( return false; } - cloth_from_mesh(clmd, mesh); + cloth_from_mesh(clmd, ob, mesh); /* create springs */ clmd->clothObject->springs = NULL; @@ -814,7 +814,7 @@ static bool cloth_from_object( if (!cloth_build_springs(clmd, mesh)) { cloth_free_modifier(clmd); - BKE_modifier_set_error(&(clmd->modifier), "Cannot build springs"); + BKE_modifier_set_error(ob, &(clmd->modifier), "Cannot build springs"); return false; } @@ -831,7 +831,7 @@ static bool cloth_from_object( return true; } -static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh) +static void cloth_from_mesh(ClothModifierData *clmd, const Object *ob, Mesh *mesh) { const MLoop *mloop = mesh->mloop; const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh); @@ -844,8 +844,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh) "clothVertex"); if (clmd->clothObject->verts == NULL) { cloth_free_modifier(clmd); - BKE_modifier_set_error(&(clmd->modifier), - "Out of memory on allocating clmd->clothObject->verts"); + BKE_modifier_set_error( + ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->verts"); printf("cloth_free_modifier clmd->clothObject->verts\n"); return; } @@ -861,8 +861,8 @@ static void cloth_from_mesh(ClothModifierData *clmd, Mesh *mesh) clmd->clothObject->tri = MEM_mallocN(sizeof(MVertTri) * looptri_num, "clothLoopTris"); if (clmd->clothObject->tri == NULL) { cloth_free_modifier(clmd); - BKE_modifier_set_error(&(clmd->modifier), - "Out of memory on allocating clmd->clothObject->looptri"); + BKE_modifier_set_error( + ob, &(clmd->modifier), "Out of memory on allocating clmd->clothObject->looptri"); printf("cloth_free_modifier clmd->clothObject->looptri\n"); return; } diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 0ed6f94ce79..7ab63810719 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -18,6 +18,9 @@ * \ingroup bke */ +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #include <string.h> #include "BLI_blenlib.h" @@ -55,6 +58,8 @@ #include "MEM_guardedalloc.h" +#include "BLO_read_write.h" + /* -------------------------------------------------------------------- */ /** \name Prototypes * \{ */ @@ -167,6 +172,173 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) } } +void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection) +{ + BKE_id_blend_write(writer, &collection->id); + + /* Shared function for collection data-blocks and scene master collection. */ + BKE_previewimg_blend_write(writer, collection->preview); + + LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { + BLO_write_struct(writer, CollectionObject, cob); + } + + LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { + BLO_write_struct(writer, CollectionChild, child); + } +} + +static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + Collection *collection = (Collection *)id; + if (collection->id.us > 0 || BLO_write_is_undo(writer)) { + /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ + collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; + collection->tag = 0; + BLI_listbase_clear(&collection->object_cache); + BLI_listbase_clear(&collection->parents); + + /* write LibData */ + BLO_write_id_struct(writer, Collection, id_address, &collection->id); + + BKE_collection_blend_write_nolib(writer, collection); + } +} + +#ifdef USE_COLLECTION_COMPAT_28 +void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollection *sc) +{ + BLO_read_list(reader, &sc->objects); + BLO_read_list(reader, &sc->scene_collections); + + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { + BKE_collection_compat_blend_read_data(reader, nsc); + } +} +#endif + +void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection) +{ + BLO_read_list(reader, &collection->gobject); + BLO_read_list(reader, &collection->children); + + BLO_read_data_address(reader, &collection->preview); + BKE_previewimg_blend_read(reader, collection->preview); + + collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; + collection->tag = 0; + BLI_listbase_clear(&collection->object_cache); + BLI_listbase_clear(&collection->parents); + +#ifdef USE_COLLECTION_COMPAT_28 + /* This runs before the very first doversion. */ + BLO_read_data_address(reader, &collection->collection); + if (collection->collection != NULL) { + BKE_collection_compat_blend_read_data(reader, collection->collection); + } + + BLO_read_data_address(reader, &collection->view_layer); + if (collection->view_layer != NULL) { + BKE_view_layer_blend_read_data(reader, collection->view_layer); + } +#endif +} + +static void collection_blend_read_data(BlendDataReader *reader, ID *id) +{ + Collection *collection = (Collection *)id; + BKE_collection_blend_read_data(reader, collection); +} + +static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection) +{ + LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) { + BLO_read_id_address(reader, lib, &cob->ob); + + if (cob->ob == NULL) { + BLI_freelinkN(&collection->gobject, cob); + } + } + + LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { + BLO_read_id_address(reader, lib, &child->collection); + } +} + +#ifdef USE_COLLECTION_COMPAT_28 +void BKE_collection_compat_blend_read_lib(BlendLibReader *reader, + Library *lib, + SceneCollection *sc) +{ + LISTBASE_FOREACH (LinkData *, link, &sc->objects) { + BLO_read_id_address(reader, lib, &link->data); + BLI_assert(link->data); + } + + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { + BKE_collection_compat_blend_read_lib(reader, lib, nsc); + } +} +#endif + +void BKE_collection_blend_read_lib(BlendLibReader *reader, Collection *collection) +{ +#ifdef USE_COLLECTION_COMPAT_28 + if (collection->collection) { + BKE_collection_compat_blend_read_lib(reader, collection->id.lib, collection->collection); + } + + if (collection->view_layer) { + BKE_view_layer_blend_read_lib(reader, collection->id.lib, collection->view_layer); + } +#endif + + lib_link_collection_data(reader, collection->id.lib, collection); +} + +static void collection_blend_read_lib(BlendLibReader *reader, ID *id) +{ + Collection *collection = (Collection *)id; + BKE_collection_blend_read_lib(reader, collection); +} + +#ifdef USE_COLLECTION_COMPAT_28 +void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander, + struct SceneCollection *sc) +{ + LISTBASE_FOREACH (LinkData *, link, &sc->objects) { + BLO_expand(expander, link->data); + } + + LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { + BKE_collection_compat_blend_read_expand(expander, nsc); + } +} +#endif + +void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *collection) +{ + LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { + BLO_expand(expander, cob->ob); + } + + LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { + BLO_expand(expander, child->collection); + } + +#ifdef USE_COLLECTION_COMPAT_28 + if (collection->collection != NULL) { + BKE_collection_compat_blend_read_expand(expander, collection->collection); + } +#endif +} + +static void collection_blend_read_expand(BlendExpander *expander, ID *id) +{ + Collection *collection = (Collection *)id; + BKE_collection_blend_read_expand(expander, collection); +} + IDTypeInfo IDType_ID_GR = { .id_code = ID_GR, .id_filter = FILTER_ID_GR, @@ -184,10 +356,12 @@ IDTypeInfo IDType_ID_GR = { .foreach_id = collection_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = collection_blend_write, + .blend_read_data = collection_blend_read_data, + .blend_read_lib = collection_blend_read_lib, + .blend_read_expand = collection_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /** \} */ @@ -301,6 +475,7 @@ void BKE_collection_add_from_collection(Main *bmain, /** Free (or release) any data used by this collection (does not free the collection itself). */ void BKE_collection_free(Collection *collection) { + BKE_libblock_free_data(&collection->id, false); collection_free_data(&collection->id); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 34e8e8bc6fb..8723cd13e35 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -1257,7 +1257,7 @@ void BKE_curvemapping_blend_read(BlendDataReader *reader, CurveMapping *cumap) /* ***************** Histogram **************** */ -#define INV_255 (1.f / 255.f) +#define INV_255 (1.0f / 255.0f) BLI_INLINE int get_bin_float(float f) { @@ -1570,8 +1570,8 @@ void BKE_scopes_update(Scopes *scopes, return; } - if (scopes->hist.ymax == 0.f) { - scopes->hist.ymax = 1.f; + if (scopes->hist.ymax == 0.0f) { + scopes->hist.ymax = 1.0f; } /* hmmmm */ diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 274546132fb..d21529467a1 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -45,6 +45,7 @@ #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" +#include "DNA_screen_types.h" #include "DNA_lattice_types.h" #include "DNA_movieclip_types.h" @@ -5406,6 +5407,11 @@ bool BKE_constraint_remove_ex(ListBase *list, Object *ob, bConstraint *con, bool return false; } +void BKE_constraint_panel_expand(bConstraint *con) +{ + con->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT; +} + /* ......... */ /* Creates a new constraint, initializes its data, and returns it */ @@ -5421,10 +5427,10 @@ static bConstraint *add_new_constraint_internal(const char *name, short type) con->enforce = 1.0f; /* Only open the main panel when constraints are created, not the sub-panels. */ - con->ui_expand_flag = (1 << 0); + con->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; if (ELEM(type, CONSTRAINT_TYPE_ACTION, CONSTRAINT_TYPE_SPLINEIK)) { /* Expand the two sub-panels in the cases where the main panel barely has any properties. */ - con->ui_expand_flag |= (1 << 1) | (1 << 2); + con->ui_expand_flag |= UI_SUBPANEL_DATA_EXPAND_1 | UI_SUBPANEL_DATA_EXPAND_2; } /* Determine a basic name, and info */ diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 01c05c62b70..4e1ec9ba35e 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -273,7 +273,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra for (i = 0; md && i <= cageIndex; i++, md = md->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); - if (!editbmesh_modifier_is_enabled(scene, md, me != NULL)) { + if (!editbmesh_modifier_is_enabled(scene, ob, md, me != NULL)) { continue; } @@ -302,7 +302,7 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgra } for (; md && i <= cageIndex; md = md->next, i++) { - if (editbmesh_modifier_is_enabled(scene, md, me != NULL) && + if (editbmesh_modifier_is_enabled(scene, ob, md, me != NULL) && BKE_modifier_is_correctable_deformed(md)) { numleft++; } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index bc4cb231153..091d542c43d 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -325,6 +325,8 @@ IDTypeInfo IDType_ID_CU = { .blend_read_data = curve_blend_read_data, .blend_read_lib = curve_blend_read_lib, .blend_read_expand = curve_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static int cu_isectLL(const float v1[3], @@ -438,7 +440,6 @@ ListBase *BKE_curve_editNurbs_get(Curve *cu) short BKE_curve_type_get(const Curve *cu) { - Nurb *nu; int type = cu->type; if (cu->vfont) { @@ -448,7 +449,7 @@ short BKE_curve_type_get(const Curve *cu) if (!cu->type) { type = OB_CURVE; - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->pntsv > 1) { type = OB_SURF; } @@ -461,15 +462,14 @@ short BKE_curve_type_get(const Curve *cu) void BKE_curve_curve_dimension_update(Curve *cu) { ListBase *nurbs = BKE_curve_nurbs_get(cu); - Nurb *nu = nurbs->first; if (cu->flag & CU_3D) { - for (; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { nu->flag &= ~CU_2D; } } else { - for (; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { nu->flag |= CU_2D; BKE_nurb_test_2d(nu); @@ -569,10 +569,9 @@ void BKE_curve_texspace_get(Curve *cu, float r_loc[3], float r_size[3]) bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3]) { - Nurb *nu; int tot = 0; - for (nu = nurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { int tot_nu; if (nu->type == CU_BEZIER) { tot_nu = nu->pntsu; @@ -596,39 +595,33 @@ bool BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3]) int BKE_nurbList_verts_count(ListBase *nurb) { - Nurb *nu; int tot = 0; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { tot += 3 * nu->pntsu; } else if (nu->bp) { tot += nu->pntsu * nu->pntsv; } - - nu = nu->next; } + return tot; } int BKE_nurbList_verts_count_without_handles(ListBase *nurb) { - Nurb *nu; int tot = 0; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { tot += nu->pntsu; } else if (nu->bp) { tot += nu->pntsu * nu->pntsv; } - - nu = nu->next; } + return tot; } @@ -636,7 +629,6 @@ int BKE_nurbList_verts_count_without_handles(ListBase *nurb) void BKE_nurb_free(Nurb *nu) { - if (nu == NULL) { return; } @@ -664,17 +656,12 @@ void BKE_nurb_free(Nurb *nu) void BKE_nurbList_free(ListBase *lb) { - Nurb *nu, *next; - if (lb == NULL) { return; } - nu = lb->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, lb) { BKE_nurb_free(nu); - nu = next; } BLI_listbase_clear(lb); } @@ -747,16 +734,11 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv) void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2) { - Nurb *nu, *nun; - BKE_nurbList_free(lb1); - nu = lb2->first; - while (nu) { - nun = BKE_nurb_duplicate(nu); - BLI_addtail(lb1, nun); - - nu = nu->next; + LISTBASE_FOREACH (const Nurb *, nu, lb2) { + Nurb *nurb_new = BKE_nurb_duplicate(nu); + BLI_addtail(lb1, nurb_new); } } @@ -2641,9 +2623,7 @@ static void bevlist_firstlast_direction_calc_from_bpoint(Nurb *nu, BevList *bl) void BKE_curve_bevelList_free(ListBase *bev) { - BevList *bl, *blnext; - for (bl = bev->first; bl != NULL; bl = blnext) { - blnext = bl->next; + LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) { if (bl->seglen != NULL) { MEM_freeN(bl->seglen); } @@ -2670,12 +2650,11 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* this function needs an object, because of tflag and upflag */ Curve *cu = ob->data; - Nurb *nu; BezTriple *bezt, *prevbezt; BPoint *bp; - BevList *bl, *blnew, *blnext; + BevList *blnew; BevPoint *bevp2, *bevp1 = NULL, *bevp0; - const float treshold = 0.00001f; + const float threshold = 0.00001f; float min, inp; float *seglen = NULL; struct BevelSort *sortdata, *sd, *sd1; @@ -2701,16 +2680,26 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* STEP 1: MAKE POLYS */ BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); - nu = nurbs->first; if (cu->editnurb && ob->type != OB_FONT) { is_editmode = 1; } - for (; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { if (nu->hide && is_editmode) { continue; } + /* check we are a single point? also check we are not a surface and that the orderu is sane, + * enforced in the UI but can go wrong possibly */ + if (!BKE_nurb_check_valid_u(nu)) { + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList1"); + bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1"); + BLI_addtail(bev, bl); + bl->nr = 0; + bl->charidx = nu->charidx; + continue; + } + /* check if we will calculate tilt data */ do_tilt = CU_DO_TILT(cu, nu); @@ -2719,89 +2708,231 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) do_weight = true; - /* check we are a single point? also check we are not a surface and that the orderu is sane, - * enforced in the UI but can go wrong possibly */ - if (!BKE_nurb_check_valid_u(nu)) { - bl = MEM_callocN(sizeof(BevList), "makeBevelList1"); - bl->bevpoints = MEM_calloc_arrayN(1, sizeof(BevPoint), "makeBevelPoints1"); + BevPoint *bevp; + + if (for_render && cu->resolu_ren != 0) { + resolu = cu->resolu_ren; + } + else { + resolu = nu->resolu; + } + + segcount = SEGMENTSU(nu); + + if (nu->type == CU_POLY) { + len = nu->pntsu; + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList2"); + bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2"); + if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { + bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen"); + bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount"); + } BLI_addtail(bev, bl); - bl->nr = 0; + + bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; + bl->nr = len; + bl->dupe_nr = 0; bl->charidx = nu->charidx; + bevp = bl->bevpoints; + bevp->offset = 0; + bp = nu->bp; + seglen = bl->seglen; + segbevcount = bl->segbevcount; + + while (len--) { + copy_v3_v3(bevp->vec, bp->vec); + bevp->tilt = bp->tilt; + bevp->radius = bp->radius; + bevp->weight = bp->weight; + bevp->split_tag = true; + bp++; + if (seglen != NULL && len != 0) { + *seglen = len_v3v3(bevp->vec, bp->vec); + bevp++; + bevp->offset = *seglen; + if (*seglen > threshold) { + *segbevcount = 1; + } + else { + *segbevcount = 0; + } + seglen++; + segbevcount++; + } + else { + bevp++; + } + } + + if ((nu->flagu & CU_NURB_CYCLIC) == 0) { + bevlist_firstlast_direction_calc_from_bpoint(nu, bl); + } } - else { - BevPoint *bevp; + else if (nu->type == CU_BEZIER) { + /* in case last point is not cyclic */ + len = segcount * resolu + 1; - if (for_render && cu->resolu_ren != 0) { - resolu = cu->resolu_ren; + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints"); + bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints"); + if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { + bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen"); + bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelBPoints_segbevcount"); + } + BLI_addtail(bev, bl); + + bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; + bl->charidx = nu->charidx; + + bevp = bl->bevpoints; + seglen = bl->seglen; + segbevcount = bl->segbevcount; + + bevp->offset = 0; + if (seglen != NULL) { + *seglen = 0; + *segbevcount = 0; + } + + a = nu->pntsu - 1; + bezt = nu->bezt; + if (nu->flagu & CU_NURB_CYCLIC) { + a++; + prevbezt = nu->bezt + (nu->pntsu - 1); } else { - resolu = nu->resolu; + prevbezt = bezt; + bezt++; } - segcount = SEGMENTSU(nu); + sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]); + normalize_v3(bevp->dir); - if (nu->type == CU_POLY) { - len = nu->pntsu; - bl = MEM_callocN(sizeof(BevList), "makeBevelList2"); - bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints2"); - if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { - bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList2_seglen"); - bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList2_segbevcount"); - } - BLI_addtail(bev, bl); + BLI_assert(segcount >= a); - bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; - bl->nr = len; - bl->dupe_nr = 0; - bl->charidx = nu->charidx; - bevp = bl->bevpoints; - bevp->offset = 0; - bp = nu->bp; - seglen = bl->seglen; - segbevcount = bl->segbevcount; + while (a--) { + if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { - while (len--) { - copy_v3_v3(bevp->vec, bp->vec); - bevp->tilt = bp->tilt; - bevp->radius = bp->radius; - bevp->weight = bp->weight; + copy_v3_v3(bevp->vec, prevbezt->vec[1]); + bevp->tilt = prevbezt->tilt; + bevp->radius = prevbezt->radius; + bevp->weight = prevbezt->weight; bevp->split_tag = true; - bp++; - if (seglen != NULL && len != 0) { - *seglen = len_v3v3(bevp->vec, bp->vec); - bevp++; + bevp->dupe_tag = false; + bevp++; + bl->nr++; + bl->dupe_nr = 1; + if (seglen != NULL) { + *seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]); bevp->offset = *seglen; - if (*seglen > treshold) { + seglen++; + /* match segbevcount to the cleaned up bevel lists (see STEP 2) */ + if (bevp->offset > threshold) { *segbevcount = 1; } - else { - *segbevcount = 0; + segbevcount++; + } + } + else { + /* always do all three, to prevent data hanging around */ + int j; + + /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */ + for (j = 0; j < 3; j++) { + BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], + prevbezt->vec[2][j], + bezt->vec[0][j], + bezt->vec[1][j], + &(bevp->vec[j]), + resolu, + sizeof(BevPoint)); + } + + /* if both arrays are NULL do nothiong */ + tilt_bezpart(prevbezt, + bezt, + nu, + do_tilt ? &bevp->tilt : NULL, + do_radius ? &bevp->radius : NULL, + do_weight ? &bevp->weight : NULL, + resolu, + sizeof(BevPoint)); + + if (cu->twist_mode == CU_TWIST_TANGENT) { + forward_diff_bezier_cotangent(prevbezt->vec[1], + prevbezt->vec[2], + bezt->vec[0], + bezt->vec[1], + bevp->tan, + resolu, + sizeof(BevPoint)); + } + + /* indicate with handlecodes double points */ + if (prevbezt->h1 == prevbezt->h2) { + if (ELEM(prevbezt->h1, 0, HD_VECT)) { + bevp->split_tag = true; + } + } + else { + if (ELEM(prevbezt->h1, 0, HD_VECT)) { + bevp->split_tag = true; + } + else if (ELEM(prevbezt->h2, 0, HD_VECT)) { + bevp->split_tag = true; + } + } + + /* seglen */ + if (seglen != NULL) { + *seglen = 0; + *segbevcount = 0; + for (j = 0; j < resolu; j++) { + bevp0 = bevp; + bevp++; + bevp->offset = len_v3v3(bevp0->vec, bevp->vec); + /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */ + if (bevp->offset > threshold) { + *seglen += bevp->offset; + *segbevcount += 1; + } } seglen++; segbevcount++; } else { - bevp++; + bevp += resolu; } + bl->nr += resolu; } + prevbezt = bezt; + bezt++; + } - if ((nu->flagu & CU_NURB_CYCLIC) == 0) { - bevlist_firstlast_direction_calc_from_bpoint(nu, bl); - } + if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */ + copy_v3_v3(bevp->vec, prevbezt->vec[1]); + bevp->tilt = prevbezt->tilt; + bevp->radius = prevbezt->radius; + bevp->weight = prevbezt->weight; + + sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]); + normalize_v3(bevp->dir); + + bl->nr++; } - else if (nu->type == CU_BEZIER) { - /* in case last point is not cyclic */ - len = segcount * resolu + 1; + } + else if (nu->type == CU_NURBS) { + if (nu->pntsv == 1) { + len = (resolu * segcount); - bl = MEM_callocN(sizeof(BevList), "makeBevelBPoints"); - bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelBPointsPoints"); + BevList *bl = MEM_callocN(sizeof(BevList), "makeBevelList3"); + bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3"); if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { - bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelBPoints_seglen"); - bl->segbevcount = MEM_malloc_arrayN( - segcount, sizeof(int), "makeBevelBPoints_segbevcount"); + bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen"); + bl->segbevcount = MEM_malloc_arrayN(segcount, sizeof(int), "makeBevelList3_segbevcount"); } BLI_addtail(bev, bl); - + bl->nr = len; + bl->dupe_nr = 0; bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; bl->charidx = nu->charidx; @@ -2809,292 +2940,134 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) seglen = bl->seglen; segbevcount = bl->segbevcount; - bevp->offset = 0; - if (seglen != NULL) { - *seglen = 0; - *segbevcount = 0; - } - - a = nu->pntsu - 1; - bezt = nu->bezt; - if (nu->flagu & CU_NURB_CYCLIC) { - a++; - prevbezt = nu->bezt + (nu->pntsu - 1); - } - else { - prevbezt = bezt; - bezt++; - } + BKE_nurb_makeCurve(nu, + &bevp->vec[0], + do_tilt ? &bevp->tilt : NULL, + do_radius ? &bevp->radius : NULL, + do_weight ? &bevp->weight : NULL, + resolu, + sizeof(BevPoint)); - sub_v3_v3v3(bevp->dir, prevbezt->vec[2], prevbezt->vec[1]); - normalize_v3(bevp->dir); - - BLI_assert(segcount >= a); - - while (a--) { - if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { - - copy_v3_v3(bevp->vec, prevbezt->vec[1]); - bevp->tilt = prevbezt->tilt; - bevp->radius = prevbezt->radius; - bevp->weight = prevbezt->weight; - bevp->split_tag = true; - bevp->dupe_tag = false; - bevp++; - bl->nr++; - bl->dupe_nr = 1; - if (seglen != NULL) { - *seglen = len_v3v3(prevbezt->vec[1], bezt->vec[1]); - bevp->offset = *seglen; - seglen++; - /* match segbevcount to the cleaned up bevel lists (see STEP 2) */ - if (bevp->offset > treshold) { - *segbevcount = 1; - } - segbevcount++; - } - } - else { - /* always do all three, to prevent data hanging around */ + /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */ + if (seglen != NULL) { + nr = segcount; + bevp0 = bevp; + bevp++; + while (nr) { int j; - - /* BevPoint must stay aligned to 4 so sizeof(BevPoint)/sizeof(float) works */ - for (j = 0; j < 3; j++) { - BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], - prevbezt->vec[2][j], - bezt->vec[0][j], - bezt->vec[1][j], - &(bevp->vec[j]), - resolu, - sizeof(BevPoint)); - } - - /* if both arrays are NULL do nothiong */ - tilt_bezpart(prevbezt, - bezt, - nu, - do_tilt ? &bevp->tilt : NULL, - do_radius ? &bevp->radius : NULL, - do_weight ? &bevp->weight : NULL, - resolu, - sizeof(BevPoint)); - - if (cu->twist_mode == CU_TWIST_TANGENT) { - forward_diff_bezier_cotangent(prevbezt->vec[1], - prevbezt->vec[2], - bezt->vec[0], - bezt->vec[1], - bevp->tan, - resolu, - sizeof(BevPoint)); - } - - /* indicate with handlecodes double points */ - if (prevbezt->h1 == prevbezt->h2) { - if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) { - bevp->split_tag = true; + *seglen = 0; + *segbevcount = 0; + /* We keep last bevel segment zero-length. */ + for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) { + bevp->offset = len_v3v3(bevp0->vec, bevp->vec); + if (bevp->offset > threshold) { + *seglen += bevp->offset; + *segbevcount += 1; } + bevp0 = bevp; + bevp++; } - else { - if (prevbezt->h1 == 0 || prevbezt->h1 == HD_VECT) { - bevp->split_tag = true; - } - else if (prevbezt->h2 == 0 || prevbezt->h2 == HD_VECT) { - bevp->split_tag = true; - } - } - - /* seglen */ - if (seglen != NULL) { - *seglen = 0; - *segbevcount = 0; - for (j = 0; j < resolu; j++) { - bevp0 = bevp; - bevp++; - bevp->offset = len_v3v3(bevp0->vec, bevp->vec); - /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */ - if (bevp->offset > treshold) { - *seglen += bevp->offset; - *segbevcount += 1; - } - } - seglen++; - segbevcount++; - } - else { - bevp += resolu; - } - bl->nr += resolu; + seglen++; + segbevcount++; + nr--; } - prevbezt = bezt; - bezt++; } - if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic: endpoint */ - copy_v3_v3(bevp->vec, prevbezt->vec[1]); - bevp->tilt = prevbezt->tilt; - bevp->radius = prevbezt->radius; - bevp->weight = prevbezt->weight; - - sub_v3_v3v3(bevp->dir, prevbezt->vec[1], prevbezt->vec[0]); - normalize_v3(bevp->dir); - - bl->nr++; - } - } - else if (nu->type == CU_NURBS) { - if (nu->pntsv == 1) { - len = (resolu * segcount); - - bl = MEM_callocN(sizeof(BevList), "makeBevelList3"); - bl->bevpoints = MEM_calloc_arrayN(len, sizeof(BevPoint), "makeBevelPoints3"); - if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) { - bl->seglen = MEM_malloc_arrayN(segcount, sizeof(float), "makeBevelList3_seglen"); - bl->segbevcount = MEM_malloc_arrayN( - segcount, sizeof(int), "makeBevelList3_segbevcount"); - } - BLI_addtail(bev, bl); - bl->nr = len; - bl->dupe_nr = 0; - bl->poly = (nu->flagu & CU_NURB_CYCLIC) ? 0 : -1; - bl->charidx = nu->charidx; - - bevp = bl->bevpoints; - seglen = bl->seglen; - segbevcount = bl->segbevcount; - - BKE_nurb_makeCurve(nu, - &bevp->vec[0], - do_tilt ? &bevp->tilt : NULL, - do_radius ? &bevp->radius : NULL, - do_weight ? &bevp->weight : NULL, - resolu, - sizeof(BevPoint)); - - /* match seglen and segbevcount to the cleaned up bevel lists (see STEP 2) */ - if (seglen != NULL) { - nr = segcount; - bevp0 = bevp; - bevp++; - while (nr) { - int j; - *seglen = 0; - *segbevcount = 0; - /* We keep last bevel segment zero-length. */ - for (j = 0; j < ((nr == 1) ? (resolu - 1) : resolu); j++) { - bevp->offset = len_v3v3(bevp0->vec, bevp->vec); - if (bevp->offset > treshold) { - *seglen += bevp->offset; - *segbevcount += 1; - } - bevp0 = bevp; - bevp++; - } - seglen++; - segbevcount++; - nr--; - } - } - - if ((nu->flagu & CU_NURB_CYCLIC) == 0) { - bevlist_firstlast_direction_calc_from_bpoint(nu, bl); - } + if ((nu->flagu & CU_NURB_CYCLIC) == 0) { + bevlist_firstlast_direction_calc_from_bpoint(nu, bl); } } } } /* STEP 2: DOUBLE POINTS AND AUTOMATIC RESOLUTION, REDUCE DATABLOCKS */ - bl = bev->first; - while (bl) { - if (bl->nr) { /* null bevel items come from single points */ - /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */ - const float threshold_resolu = 0.00001f / resolu; - bool is_cyclic = bl->poly != -1; - nr = bl->nr; - if (is_cyclic) { - bevp1 = bl->bevpoints; - bevp0 = bevp1 + (nr - 1); + LISTBASE_FOREACH (BevList *, bl, bev) { + if (bl->nr == 0) { /* null bevel items come from single points */ + continue; + } + + /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */ + const float threshold_resolu = 0.00001f / resolu; + bool is_cyclic = bl->poly != -1; + nr = bl->nr; + if (is_cyclic) { + bevp1 = bl->bevpoints; + bevp0 = bevp1 + (nr - 1); + } + else { + bevp0 = bl->bevpoints; + bevp0->offset = 0; + bevp1 = bevp0 + 1; + } + nr--; + while (nr--) { + if (seglen != NULL) { + if (fabsf(bevp1->offset) < threshold) { + bevp0->dupe_tag = true; + bl->dupe_nr++; + } } else { - bevp0 = bl->bevpoints; - bevp0->offset = 0; - bevp1 = bevp0 + 1; - } - nr--; - while (nr--) { - if (seglen != NULL) { - if (fabsf(bevp1->offset) < treshold) { - bevp0->dupe_tag = true; - bl->dupe_nr++; - } + if (compare_v3v3(bevp0->vec, bevp1->vec, threshold_resolu)) { + bevp0->dupe_tag = true; + bl->dupe_nr++; } - else { - if (compare_v3v3(bevp0->vec, bevp1->vec, threshold_resolu)) { - bevp0->dupe_tag = true; - bl->dupe_nr++; - } - } - bevp0 = bevp1; - bevp1++; } + bevp0 = bevp1; + bevp1++; } - bl = bl->next; } - bl = bev->first; - while (bl) { - blnext = bl->next; - if (bl->nr && bl->dupe_nr) { - nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */ - blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4"); - memcpy(blnew, bl, sizeof(BevList)); - blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4"); - if (!blnew->bevpoints) { - MEM_freeN(blnew); - break; - } - blnew->segbevcount = bl->segbevcount; - blnew->seglen = bl->seglen; - blnew->nr = 0; - BLI_remlink(bev, bl); - BLI_insertlinkbefore(bev, blnext, blnew); /* to make sure bevlijst is tuned with nurblist */ - bevp0 = bl->bevpoints; - bevp1 = blnew->bevpoints; - nr = bl->nr; - while (nr--) { - if (bevp0->dupe_tag == 0) { - memcpy(bevp1, bevp0, sizeof(BevPoint)); - bevp1++; - blnew->nr++; - } - bevp0++; - } - if (bl->bevpoints != NULL) { - MEM_freeN(bl->bevpoints); + + LISTBASE_FOREACH_MUTABLE (BevList *, bl, bev) { + if (bl->nr == 0 || bl->dupe_nr == 0) { + continue; + } + + nr = bl->nr - bl->dupe_nr + 1; /* +1 because vectorbezier sets flag too */ + blnew = MEM_mallocN(sizeof(BevList), "makeBevelList4"); + memcpy(blnew, bl, sizeof(BevList)); + blnew->bevpoints = MEM_calloc_arrayN(nr, sizeof(BevPoint), "makeBevelPoints4"); + if (!blnew->bevpoints) { + MEM_freeN(blnew); + break; + } + blnew->segbevcount = bl->segbevcount; + blnew->seglen = bl->seglen; + blnew->nr = 0; + BLI_remlink(bev, bl); + BLI_insertlinkbefore(bev, bl->next, blnew); /* to make sure bevlist is tuned with nurblist */ + bevp0 = bl->bevpoints; + bevp1 = blnew->bevpoints; + nr = bl->nr; + while (nr--) { + if (bevp0->dupe_tag == 0) { + memcpy(bevp1, bevp0, sizeof(BevPoint)); + bevp1++; + blnew->nr++; } - MEM_freeN(bl); - blnew->dupe_nr = 0; + bevp0++; } - bl = blnext; + if (bl->bevpoints != NULL) { + MEM_freeN(bl->bevpoints); + } + MEM_freeN(bl); + blnew->dupe_nr = 0; } /* STEP 3: POLYS COUNT AND AUTOHOLE */ - bl = bev->first; poly = 0; - while (bl) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr && bl->poly >= 0) { poly++; bl->poly = poly; bl->hole = 0; } - bl = bl->next; } /* find extreme left points, also test (turning) direction */ if (poly > 0) { sd = sortdata = MEM_malloc_arrayN(poly, sizeof(struct BevelSort), "makeBevelList5"); - bl = bev->first; - while (bl) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->poly > 0) { BevPoint *bevp; @@ -3139,14 +3112,12 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) sd++; } - - bl = bl->next; } qsort(sortdata, poly, sizeof(struct BevelSort), vergxcobev); sd = sortdata + 1; for (a = 1; a < poly; a++, sd++) { - bl = sd->bl; /* is bl a hole? */ + BevList *bl = sd->bl; /* is bl a hole? */ sd1 = sortdata + (a - 1); for (b = a - 1; b >= 0; b--, sd1--) { /* all polys to the left */ if (sd1->bl->charidx == bl->charidx) { /* for text, only check matching char */ @@ -3163,7 +3134,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) sd = sortdata; for (a = 0; a < poly; a++, sd++) { if (sd->bl->hole == sd->dir) { - bl = sd->bl; + BevList *bl = sd->bl; bevp1 = bl->bevpoints; bevp2 = bevp1 + (bl->nr - 1); nr = bl->nr / 2; @@ -3181,7 +3152,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) /* STEP 4: 2D-COSINES or 3D ORIENTATION */ if ((cu->flag & CU_3D) == 0) { /* 2D Curves */ - for (bl = bev->first; bl; bl = bl->next) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr < 2) { BevPoint *bevp = bl->bevpoints; unit_qt(bevp->quat); @@ -3196,7 +3167,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render) } else { /* 3D Curves */ - for (bl = bev->first; bl; bl = bl->next) { + LISTBASE_FOREACH (BevList *, bl, bev) { if (bl->nr < 2) { BevPoint *bevp = bl->bevpoints; unit_qt(bevp->quat); @@ -3690,7 +3661,7 @@ static bool tridiagonal_solve_with_limits(float *a, * is affected by all other points of the curve segment, in practice the influence * decreases exponentially with distance. * - * Note: this algorithm assumes that the handle horizontal size if always 1/3 of the + * Note: this algorithm assumes that the handle horizontal size is always 1/3 of the * of the interval to the next point. This rule ensures linear interpolation of time. * * ^ height (co 1) @@ -4330,12 +4301,8 @@ void BKE_nurb_handles_autocalc(Nurb *nu, uint8_t flag) void BKE_nurbList_handles_autocalc(ListBase *editnurb, uint8_t flag) { - Nurb *nu; - - nu = editnurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { BKE_nurb_handles_autocalc(nu, flag); - nu = nu->next; } } @@ -4347,13 +4314,11 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) /* code==4: sets icu flag to become IPO_AUTO_HORIZ, horizontal extremes on auto-handles */ /* code==5: Set align, like 3 but no toggle */ /* code==6: Clear align, like 3 but no toggle */ - Nurb *nu; BezTriple *bezt; int a; if (ELEM(code, HD_AUTO, HD_VECT)) { - nu = editnurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4380,7 +4345,6 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) /* like BKE_nurb_handles_calc but moves selected */ nurb_handles_calc__align_selected(nu); } - nu = nu->next; } } else { @@ -4395,7 +4359,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) } else { /* Toggle */ - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4411,7 +4375,7 @@ void BKE_nurbList_handles_set(ListBase *editnurb, const char code) } h_new = (h_new == HD_FREE) ? HD_ALIGN : HD_FREE; } - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -4437,66 +4401,66 @@ void BKE_nurbList_handles_recalculate(ListBase *editnurb, const bool calc_length, const uint8_t flag) { - Nurb *nu; BezTriple *bezt; int a; - for (nu = editnurb->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - bool changed = false; + LISTBASE_FOREACH (Nurb *, nu, editnurb) { + if (nu->type != CU_BEZIER) { + continue; + } - for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) { + bool changed = false; - const bool h1_select = (bezt->f1 & flag) == flag; - const bool h2_select = (bezt->f3 & flag) == flag; + for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) { - if (h1_select || h2_select) { + const bool h1_select = (bezt->f1 & flag) == flag; + const bool h2_select = (bezt->f3 & flag) == flag; - float co1_back[3], co2_back[3]; + if (h1_select || h2_select) { - copy_v3_v3(co1_back, bezt->vec[0]); - copy_v3_v3(co2_back, bezt->vec[2]); + float co1_back[3], co2_back[3]; - BKE_nurb_handle_calc_simple_auto(nu, bezt); + copy_v3_v3(co1_back, bezt->vec[0]); + copy_v3_v3(co2_back, bezt->vec[2]); - if (h1_select) { - if (!calc_length) { - dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1])); - } - } - else { - copy_v3_v3(bezt->vec[0], co1_back); - } + BKE_nurb_handle_calc_simple_auto(nu, bezt); - if (h2_select) { - if (!calc_length) { - dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1])); - } - } - else { - copy_v3_v3(bezt->vec[2], co2_back); + if (h1_select) { + if (!calc_length) { + dist_ensure_v3_v3fl(bezt->vec[0], bezt->vec[1], len_v3v3(co1_back, bezt->vec[1])); } + } + else { + copy_v3_v3(bezt->vec[0], co1_back); + } - changed = true; + if (h2_select) { + if (!calc_length) { + dist_ensure_v3_v3fl(bezt->vec[2], bezt->vec[1], len_v3v3(co2_back, bezt->vec[1])); + } + } + else { + copy_v3_v3(bezt->vec[2], co2_back); } - } - if (changed) { - /* Recalculate the whole curve */ - BKE_nurb_handles_calc(nu); + changed = true; } } + + if (changed) { + /* Recalculate the whole curve */ + BKE_nurb_handles_calc(nu); + } } } void BKE_nurbList_flag_set(ListBase *editnurb, uint8_t flag, bool set) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { a = nu->pntsu; bezt = nu->bezt; @@ -4532,7 +4496,7 @@ bool BKE_nurbList_flag_set_from_flag(ListBase *editnurb, uint8_t from_flag, uint { bool changed = false; - for (Nurb *nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { for (int i = 0; i < nu->pntsu; i++) { BezTriple *bezt = &nu->bezt[i]; @@ -4997,7 +4961,7 @@ bool BKE_nurb_type_convert(Nurb *nu, } } else if (nu->type == CU_BEZIER) { /* Bezier */ - if (type == CU_POLY || type == CU_NURBS) { + if (ELEM(type, CU_POLY, CU_NURBS)) { nr = use_handles ? (3 * nu->pntsu) : nu->pntsu; nu->bp = MEM_calloc_arrayN(nr, sizeof(BPoint), "setsplinetype"); a = nu->pntsu; @@ -5246,12 +5210,11 @@ bool BKE_curve_minmax(Curve *cu, bool use_radius, float min[3], float max[3]) bool BKE_curve_center_median(Curve *cu, float cent[3]) { ListBase *nurb_lb = BKE_curve_nurbs_get(cu); - Nurb *nu; int total = 0; zero_v3(cent); - for (nu = nurb_lb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurb_lb) { int i; if (nu->type == CU_BEZIER) { @@ -5299,12 +5262,11 @@ void BKE_curve_transform_ex(Curve *cu, const bool do_props, const float unit_scale) { - Nurb *nu; BPoint *bp; BezTriple *bezt; int i; - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->type == CU_BEZIER) { i = nu->pntsu; for (bezt = nu->bezt; i--; bezt++) { @@ -5329,12 +5291,11 @@ void BKE_curve_transform_ex(Curve *cu, } if (do_keys && cu->key) { - KeyBlock *kb; - for (kb = cu->key->block.first; kb; kb = kb->next) { + LISTBASE_FOREACH (KeyBlock *, kb, &cu->key->block) { float *fp = kb->data; int n = kb->totelem; - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->type == CU_BEZIER) { for (i = nu->pntsu; i && (n -= KEYELEM_ELEM_LEN_BEZTRIPLE) >= 0; i--) { mul_m4_v3(mat, &fp[0]); @@ -5490,9 +5451,8 @@ bool BKE_curve_material_index_validate(Curve *cu) } } else { - Nurb *nu; const int max_idx = max_ii(0, cu->totcol - 1); - for (nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { if (nu->mat_nr > max_idx) { nu->mat_nr = 0; is_valid = false; @@ -5558,12 +5518,12 @@ void BKE_curve_material_remap(Curve *cu, const unsigned int *remap, unsigned int void BKE_curve_smooth_flag_set(Curve *cu, const bool use_smooth) { if (use_smooth) { - for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { nu->flag |= CU_SMOOTH; } } else { - for (Nurb *nu = cu->nurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { nu->flag &= ~CU_SMOOTH; } } diff --git a/source/blender/blenkernel/intern/curve_decimate.c b/source/blender/blenkernel/intern/curve_decimate.c index 68c0d2a3cec..e4647908b58 100644 --- a/source/blender/blenkernel/intern/curve_decimate.c +++ b/source/blender/blenkernel/intern/curve_decimate.c @@ -269,11 +269,11 @@ uint BKE_curve_decimate_bezt_array(BezTriple *bezt_array, if (a == HD_VECT) { \ a = HD_FREE; \ } \ - else if (a == HD_AUTO || a == HD_AUTO_ANIM) { \ + else if (ELEM(a, HD_AUTO, HD_AUTO_ANIM)) { \ a = HD_ALIGN; \ } \ /* opposite handle */ \ - if (b == HD_AUTO || b == HD_AUTO_ANIM) { \ + if (ELEM(b, HD_AUTO, HD_AUTO_ANIM)) { \ b = HD_ALIGN; \ } \ } \ diff --git a/source/blender/blenkernel/intern/curve_deform.c b/source/blender/blenkernel/intern/curve_deform.c index d4f197521a1..049bd46c434 100644 --- a/source/blender/blenkernel/intern/curve_deform.c +++ b/source/blender/blenkernel/intern/curve_deform.c @@ -222,10 +222,10 @@ static bool calc_curve_deform( /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ - quat_apply_track( - quat, - axis, - (axis == 0 || axis == 2) ? 1 : 0); /* up flag is a dummy, set so no rotation is done */ + quat_apply_track(quat, + axis, + (ELEM(axis, 0, 2)) ? 1 : + 0); /* up flag is a dummy, set so no rotation is done */ vec_apply_track(cent, axis); cent[index] = 0.0f; diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index d762b1b0604..fdb3e246382 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2509,7 +2509,7 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data, return &data->layers[CustomData_get_layer_index(data, type)]; } - if ((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) { + if (ELEM(alloctype, CD_ASSIGN, CD_REFERENCE)) { newlayerdata = layerdata; } else if (totelem > 0 && typeInfo->size > 0) { @@ -2997,7 +2997,7 @@ void CustomData_free_elem(CustomData *data, int index, int count) /** * Interpolate given custom data source items into a single destination one. * - * \param src_indices Indices of every source items to interpolate into the destination one. + * \param src_indices: Indices of every source items to interpolate into the destination one. * \param weights: The weight to apply to each source value individually. If NULL, they will be * averaged. * \param sub_weights: The weights of sub-items, only used to affect each corners of a diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index bcb467e1230..f5257eb12ab 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -92,17 +92,13 @@ void BKE_displist_free(ListBase *lb) DispList *BKE_displist_find_or_create(ListBase *lb, int type) { - DispList *dl; - - dl = lb->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (dl->type == type) { return dl; } - dl = dl->next; } - dl = MEM_callocN(sizeof(DispList), "find_disp"); + DispList *dl = MEM_callocN(sizeof(DispList), "find_disp"); dl->type = type; BLI_addtail(lb, dl); @@ -111,14 +107,10 @@ DispList *BKE_displist_find_or_create(ListBase *lb, int type) DispList *BKE_displist_find(ListBase *lb, int type) { - DispList *dl; - - dl = lb->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (dl->type == type) { return dl; } - dl = dl->next; } return NULL; @@ -126,9 +118,7 @@ DispList *BKE_displist_find(ListBase *lb, int type) bool BKE_displist_has_faces(ListBase *lb) { - DispList *dl; - - for (dl = lb->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) { return true; } @@ -139,13 +129,10 @@ bool BKE_displist_has_faces(ListBase *lb) void BKE_displist_copy(ListBase *lbn, ListBase *lb) { - DispList *dln, *dl; - BKE_displist_free(lbn); - dl = lb->first; - while (dl) { - dln = MEM_dupallocN(dl); + LISTBASE_FOREACH (const DispList *, dl, lb) { + DispList *dln = MEM_dupallocN(dl); BLI_addtail(lbn, dln); dln->verts = MEM_dupallocN(dl->verts); dln->nors = MEM_dupallocN(dl->nors); @@ -154,22 +141,17 @@ void BKE_displist_copy(ListBase *lbn, ListBase *lb) if (dl->bevel_split) { dln->bevel_split = MEM_dupallocN(dl->bevel_split); } - - dl = dl->next; } } void BKE_displist_normals_add(ListBase *lb) { - DispList *dl = NULL; float *vdata, *ndata, nor[3]; float *v1, *v2, *v3, *v4; float *n1, *n2, *n3, *n4; int a, b, p1, p2, p3, p4; - dl = lb->first; - - while (dl) { + LISTBASE_FOREACH (DispList *, dl, lb) { if (dl->type == DL_INDEX3) { if (dl->nors == NULL) { dl->nors = MEM_callocN(sizeof(float[3]), "dlnors"); @@ -230,15 +212,12 @@ void BKE_displist_normals_add(ListBase *lb) } } } - dl = dl->next; } } void BKE_displist_count(ListBase *lb, int *totvert, int *totface, int *tottri) { - DispList *dl; - - for (dl = lb->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, lb) { int vert_tot = 0; int face_tot = 0; int tri_tot = 0; @@ -318,7 +297,6 @@ static void curve_to_displist(Curve *cu, ListBase *dispbase, const bool for_render) { - Nurb *nu; DispList *dl; BezTriple *bezt, *prevbezt; BPoint *bp; @@ -326,154 +304,154 @@ static void curve_to_displist(Curve *cu, int a, len, resolu; const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); - nu = nubase->first; - while (nu) { - if (nu->hide == 0 || editmode == false) { - if (for_render && cu->resolu_ren != 0) { - resolu = cu->resolu_ren; - } - else { - resolu = nu->resolu; - } - - if (!BKE_nurb_check_valid_u(nu)) { - /* pass */ - } - else if (nu->type == CU_BEZIER) { - /* count */ - len = 0; - a = nu->pntsu - 1; - if (nu->flagu & CU_NURB_CYCLIC) { - a++; - } - - prevbezt = nu->bezt; - bezt = prevbezt + 1; - while (a--) { - if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) { - bezt = nu->bezt; - } + LISTBASE_FOREACH (Nurb *, nu, nubase) { + if (nu->hide != 0 && editmode) { + continue; + } - if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { - len++; - } - else { - len += resolu; - } + if (for_render && cu->resolu_ren != 0) { + resolu = cu->resolu_ren; + } + else { + resolu = nu->resolu; + } - if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) { - len++; - } + if (!BKE_nurb_check_valid_u(nu)) { + /* pass */ + } + else if (nu->type == CU_BEZIER) { + /* count */ + len = 0; + a = nu->pntsu - 1; + if (nu->flagu & CU_NURB_CYCLIC) { + a++; + } - prevbezt = bezt; - bezt++; + prevbezt = nu->bezt; + bezt = prevbezt + 1; + while (a--) { + if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) { + bezt = nu->bezt; } - dl = MEM_callocN(sizeof(DispList), "makeDispListbez"); - /* len+1 because of 'forward_diff_bezier' function */ - dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts"); - BLI_addtail(dispbase, dl); - dl->parts = 1; - dl->nr = len; - dl->col = nu->mat_nr; - dl->charidx = nu->charidx; - - data = dl->verts; - - /* check that (len != 2) so we don't immediately loop back on ourselves */ - if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) { - dl->type = DL_POLY; - a = nu->pntsu; + if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { + len++; } else { - dl->type = DL_SEGM; - a = nu->pntsu - 1; + len += resolu; } - prevbezt = nu->bezt; - bezt = prevbezt + 1; + if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) == 0) { + len++; + } - while (a--) { - if (a == 0 && dl->type == DL_POLY) { - bezt = nu->bezt; - } + prevbezt = bezt; + bezt++; + } - if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { - copy_v3_v3(data, prevbezt->vec[1]); - data += 3; - } - else { - int j; - for (j = 0; j < 3; j++) { - BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], - prevbezt->vec[2][j], - bezt->vec[0][j], - bezt->vec[1][j], - data + j, - resolu, - sizeof(float[3])); - } + dl = MEM_callocN(sizeof(DispList), "makeDispListbez"); + /* len+1 because of 'forward_diff_bezier' function */ + dl->verts = MEM_mallocN((len + 1) * sizeof(float[3]), "dlverts"); + BLI_addtail(dispbase, dl); + dl->parts = 1; + dl->nr = len; + dl->col = nu->mat_nr; + dl->charidx = nu->charidx; + + data = dl->verts; + + /* check that (len != 2) so we don't immediately loop back on ourselves */ + if (nu->flagu & CU_NURB_CYCLIC && (dl->nr != 2)) { + dl->type = DL_POLY; + a = nu->pntsu; + } + else { + dl->type = DL_SEGM; + a = nu->pntsu - 1; + } - data += 3 * resolu; - } + prevbezt = nu->bezt; + bezt = prevbezt + 1; + + while (a--) { + if (a == 0 && dl->type == DL_POLY) { + bezt = nu->bezt; + } - if (a == 0 && dl->type == DL_SEGM) { - copy_v3_v3(data, bezt->vec[1]); + if (prevbezt->h2 == HD_VECT && bezt->h1 == HD_VECT) { + copy_v3_v3(data, prevbezt->vec[1]); + data += 3; + } + else { + int j; + for (j = 0; j < 3; j++) { + BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], + prevbezt->vec[2][j], + bezt->vec[0][j], + bezt->vec[1][j], + data + j, + resolu, + sizeof(float[3])); } - prevbezt = bezt; - bezt++; + data += 3 * resolu; } + + if (a == 0 && dl->type == DL_SEGM) { + copy_v3_v3(data, bezt->vec[1]); + } + + prevbezt = bezt; + bezt++; } - else if (nu->type == CU_NURBS) { - len = (resolu * SEGMENTSU(nu)); + } + else if (nu->type == CU_NURBS) { + len = (resolu * SEGMENTSU(nu)); - dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); - dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); - BLI_addtail(dispbase, dl); - dl->parts = 1; + dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); + dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); + BLI_addtail(dispbase, dl); + dl->parts = 1; - dl->nr = len; - dl->col = nu->mat_nr; - dl->charidx = nu->charidx; + dl->nr = len; + dl->col = nu->mat_nr; + dl->charidx = nu->charidx; - data = dl->verts; - if (nu->flagu & CU_NURB_CYCLIC) { - dl->type = DL_POLY; - } - else { - dl->type = DL_SEGM; - } - BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3])); + data = dl->verts; + if (nu->flagu & CU_NURB_CYCLIC) { + dl->type = DL_POLY; + } + else { + dl->type = DL_SEGM; + } + BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3])); + } + else if (nu->type == CU_POLY) { + len = nu->pntsu; + dl = MEM_callocN(sizeof(DispList), "makeDispListpoly"); + dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); + BLI_addtail(dispbase, dl); + dl->parts = 1; + dl->nr = len; + dl->col = nu->mat_nr; + dl->charidx = nu->charidx; + + data = dl->verts; + if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) { + dl->type = DL_POLY; + } + else { + dl->type = DL_SEGM; } - else if (nu->type == CU_POLY) { - len = nu->pntsu; - dl = MEM_callocN(sizeof(DispList), "makeDispListpoly"); - dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); - BLI_addtail(dispbase, dl); - dl->parts = 1; - dl->nr = len; - dl->col = nu->mat_nr; - dl->charidx = nu->charidx; - - data = dl->verts; - if ((nu->flagu & CU_NURB_CYCLIC) && (dl->nr != 2)) { - dl->type = DL_POLY; - } - else { - dl->type = DL_SEGM; - } - a = len; - bp = nu->bp; - while (a--) { - copy_v3_v3(data, bp->vec); - bp++; - data += 3; - } + a = len; + bp = nu->bp; + while (a--) { + copy_v3_v3(data, bp->vec); + bp++; + data += 3; } } - nu = nu->next; } } @@ -491,7 +469,7 @@ void BKE_displist_fill(ListBase *dispbase, ScanFillVert *sf_vert, *sf_vert_new, *sf_vert_last; ScanFillFace *sf_tri; MemArena *sf_arena; - DispList *dlnew = NULL, *dl; + DispList *dlnew = NULL; float *f1; int colnr = 0, charidx = 0, cont = 1, tot, a, *index, nextcol = 0; int totvert; @@ -515,8 +493,7 @@ void BKE_displist_fill(ListBase *dispbase, BLI_scanfill_begin_arena(&sf_ctx, sf_arena); - dl = dispbase->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { if (dl->type == DL_POLY) { if (charidx < dl->charidx) { cont = 1; @@ -558,7 +535,6 @@ void BKE_displist_fill(ListBase *dispbase, } dl_flag_accum |= dl->flag; } - dl = dl->next; } /* XXX (obedit && obedit->actcol) ? (obedit->actcol - 1) : 0)) { */ @@ -627,19 +603,17 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) { const float z_up[3] = {0.0f, 0.0f, -1.0f}; ListBase front, back; - DispList *dl, *dlnew; float *fp, *fp1; int a, dpoly; BLI_listbase_clear(&front); BLI_listbase_clear(&back); - dl = dispbase->first; - while (dl) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { if (dl->type == DL_SURF) { if ((dl->flag & DL_CYCL_V) && (dl->flag & DL_CYCL_U) == 0) { if ((cu->flag & CU_BACK) && (dl->flag & DL_BACK_CURVE)) { - dlnew = MEM_callocN(sizeof(DispList), "filldisp"); + DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp"); BLI_addtail(&front, dlnew); dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1"); dlnew->nr = dl->parts; @@ -660,7 +634,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) } } if ((cu->flag & CU_FRONT) && (dl->flag & DL_FRONT_CURVE)) { - dlnew = MEM_callocN(sizeof(DispList), "filldisp"); + DispList *dlnew = MEM_callocN(sizeof(DispList), "filldisp"); BLI_addtail(&back, dlnew); dlnew->verts = fp1 = MEM_mallocN(sizeof(float[3]) * dl->parts, "filldisp1"); dlnew->nr = dl->parts; @@ -682,7 +656,6 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase) } } } - dl = dl->next; } BKE_displist_fill(&front, dispbase, z_up, true); @@ -939,18 +912,17 @@ static bool curve_calc_modifiers_pre( static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3] { - DispList *dl; float(*allverts)[3], *fp; *r_vert_len = 0; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { *r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr; } allverts = MEM_mallocN(sizeof(float[3]) * (*r_vert_len), "displist_vert_coords_alloc allverts"); fp = (float *)allverts; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr); memcpy(fp, dl->verts, sizeof(float) * offs); fp += offs; @@ -961,11 +933,10 @@ static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[ static void displist_vert_coords_apply(ListBase *dispbase, float (*allverts)[3]) { - DispList *dl; const float *fp; fp = (float *)allverts; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { int offs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr); memcpy(dl->verts, fp, sizeof(float) * offs); fp += offs; @@ -1218,7 +1189,6 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, const bool for_orco) { ListBase nubase = {NULL, NULL}; - Nurb *nu; Curve *cu = ob->data; DispList *dl; float *data; @@ -1236,76 +1206,78 @@ void BKE_displist_make_surf(Depsgraph *depsgraph, force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); } - for (nu = nubase.first; nu; nu = nu->next) { - if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { - int resolu = nu->resolu, resolv = nu->resolv; + LISTBASE_FOREACH (Nurb *, nu, &nubase) { + if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) { + continue; + } + + int resolu = nu->resolu, resolv = nu->resolv; - if (for_render) { - if (cu->resolu_ren) { - resolu = cu->resolu_ren; - } - if (cu->resolv_ren) { - resolv = cu->resolv_ren; - } + if (for_render) { + if (cu->resolu_ren) { + resolu = cu->resolu_ren; + } + if (cu->resolv_ren) { + resolv = cu->resolv_ren; } + } - if (nu->pntsv == 1) { - len = SEGMENTSU(nu) * resolu; + if (nu->pntsv == 1) { + len = SEGMENTSU(nu) * resolu; - dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); - dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); + dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); + dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); - BLI_addtail(dispbase, dl); - dl->parts = 1; - dl->nr = len; - dl->col = nu->mat_nr; - dl->charidx = nu->charidx; + BLI_addtail(dispbase, dl); + dl->parts = 1; + dl->nr = len; + dl->col = nu->mat_nr; + dl->charidx = nu->charidx; - /* dl->rt will be used as flag for render face and */ - /* CU_2D conflicts with R_NOPUNOFLIP */ - dl->rt = nu->flag & ~CU_2D; + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt = nu->flag & ~CU_2D; - data = dl->verts; - if (nu->flagu & CU_NURB_CYCLIC) { - dl->type = DL_POLY; - } - else { - dl->type = DL_SEGM; - } - - BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3])); + data = dl->verts; + if (nu->flagu & CU_NURB_CYCLIC) { + dl->type = DL_POLY; } else { - len = (nu->pntsu * resolu) * (nu->pntsv * resolv); + dl->type = DL_SEGM; + } - dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); - dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); - BLI_addtail(dispbase, dl); + BKE_nurb_makeCurve(nu, data, NULL, NULL, NULL, resolu, sizeof(float[3])); + } + else { + len = (nu->pntsu * resolu) * (nu->pntsv * resolv); - dl->col = nu->mat_nr; - dl->charidx = nu->charidx; + dl = MEM_callocN(sizeof(DispList), "makeDispListsurf"); + dl->verts = MEM_mallocN(len * sizeof(float[3]), "dlverts"); + BLI_addtail(dispbase, dl); - /* dl->rt will be used as flag for render face and */ - /* CU_2D conflicts with R_NOPUNOFLIP */ - dl->rt = nu->flag & ~CU_2D; + dl->col = nu->mat_nr; + dl->charidx = nu->charidx; - data = dl->verts; - dl->type = DL_SURF; + /* dl->rt will be used as flag for render face and */ + /* CU_2D conflicts with R_NOPUNOFLIP */ + dl->rt = nu->flag & ~CU_2D; - dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */ - dl->nr = (nu->pntsv * resolv); - if (nu->flagv & CU_NURB_CYCLIC) { - dl->flag |= DL_CYCL_U; /* reverse too! */ - } - if (nu->flagu & CU_NURB_CYCLIC) { - dl->flag |= DL_CYCL_V; - } + data = dl->verts; + dl->type = DL_SURF; - BKE_nurb_makeFaces(nu, data, 0, resolu, resolv); - - /* gl array drawing: using indices */ - displist_surf_indices(dl); + dl->parts = (nu->pntsu * resolu); /* in reverse, because makeNurbfaces works that way */ + dl->nr = (nu->pntsv * resolv); + if (nu->flagv & CU_NURB_CYCLIC) { + dl->flag |= DL_CYCL_U; /* reverse too! */ + } + if (nu->flagu & CU_NURB_CYCLIC) { + dl->flag |= DL_CYCL_V; } + + BKE_nurb_makeFaces(nu, data, 0, resolu, resolv); + + /* gl array drawing: using indices */ + displist_surf_indices(dl); } } @@ -1851,12 +1823,11 @@ void BKE_displist_make_curveTypes_forRender(Depsgraph *depsgraph, void BKE_displist_minmax(ListBase *dispbase, float min[3], float max[3]) { - DispList *dl; const float *vert; int a, tot = 0; int doit = 0; - for (dl = dispbase->first; dl; dl = dl->next) { + LISTBASE_FOREACH (DispList *, dl, dispbase) { tot = (dl->type == DL_INDEX3) ? dl->nr : dl->nr * dl->parts; vert = dl->verts; for (a = 0; a < tot; a++, vert += 3) { diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index fef4b49de7e..95408c7d01f 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -123,7 +123,7 @@ static int neighStraightY[8] = {0, 1, 0, -1, 1, 1, -1, -1}; /* paint effect default movement per frame in global units */ #define EFF_MOVEMENT_PER_FRAME 0.05f /* initial wave time factor */ -#define WAVE_TIME_FAC (1.0f / 24.f) +#define WAVE_TIME_FAC (1.0f / 24.0f) #define CANVAS_REL_SIZE 5.0f /* drying limits */ #define MIN_WETNESS 0.001f @@ -762,7 +762,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min); copy_v3_v3(td, dim); copy_v3_v3(bData->dim, dim); - min_dim = max_fff(td[0], td[1], td[2]) / 1000.f; + min_dim = max_fff(td[0], td[1], td[2]) / 1000.0f; /* deactivate zero axises */ for (i = 0; i < 3; i++) { @@ -2700,7 +2700,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa const int final_tri_index = tempPoints[final_index].tri_index; /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */ - if (final_tri_index != target_tri && final_tri_index != -1) { + if (!ELEM(final_tri_index, target_tri, -1)) { /* Check if it's close enough to likely touch the intended triangle. Any triangle * becomes thinner than a pixel at its vertices, so robustness requires some margin. */ const float final_pt[2] = {((final_index % w) + 0.5f) / w, ((final_index / w) + 0.5f) / h}; @@ -3034,7 +3034,7 @@ int dynamicPaint_createUVSurface(Scene *scene, n_pos++; } } - else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) { + else if (ELEM(n_target, ON_MESH_EDGE, OUT_OF_TEXTURE)) { ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE; } } @@ -3736,7 +3736,7 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1, if (brush->collision == MOD_DPAINT_COL_VOLUME) { return boundsIntersect(b1, b2); } - if (brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) { + if (ELEM(brush->collision, MOD_DPAINT_COL_DIST, MOD_DPAINT_COL_VOLDIST)) { return boundsIntersectDist(b1, b2, brush_radius); } return true; @@ -4710,8 +4710,7 @@ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata, } /* Smooth range or color ramp */ - if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH || - brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) { + if (ELEM(brush->proximity_falloff, MOD_DPAINT_PRFALL_SMOOTH, MOD_DPAINT_PRFALL_RAMP)) { strength = 1.0f - distance / brush_radius; CLAMP(strength, 0.0f, 1.0f); } @@ -5116,7 +5115,7 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, madd_v3_v3fl(forc, scene->physics_settings.gravity, surface->effector_weights->global_gravity * surface->effector_weights->weight[0] / - 10.f); + 10.0f); } /* add surface point velocity and acceleration if enabled */ diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c index b3f6b543daf..9656c20f0be 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.c +++ b/source/blender/blenkernel/intern/editmesh_tangent.c @@ -35,6 +35,7 @@ /* interface */ #include "mikktspace.h" +/* -------------------------------------------------------------------- */ /** \name Tangent Space Calculation * \{ */ diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 967b961dbea..f9d3fff1cec 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -699,8 +699,8 @@ int get_effector_data(EffectorCache *eff, copy_v3_v3(efd->loc, state.co); /* rather than use the velocity use rotated x-axis (defaults to velocity) */ - efd->nor[0] = 1.f; - efd->nor[1] = efd->nor[2] = 0.f; + efd->nor[0] = 1.0f; + efd->nor[1] = efd->nor[2] = 0.0f; mul_qt_v3(state.rot, efd->nor); if (real_velocity) { @@ -1009,9 +1009,12 @@ static void do_physical_effector(EffectorCache *eff, else { add_v3_v3v3(temp, efd->vec_to_point2, efd->nor2); } - force[0] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[0], temp[1], temp[2], 2, 0, 2); - force[1] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[1], temp[2], temp[0], 2, 0, 2); - force[2] = -1.0f + 2.0f * BLI_gTurbulence(pd->f_size, temp[2], temp[0], temp[1], 2, 0, 2); + force[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence( + pd->f_size, temp[0], temp[1], temp[2], 2, 0, 2); + force[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence( + pd->f_size, temp[1], temp[2], temp[0], 2, 0, 2); + force[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence( + pd->f_size, temp[2], temp[0], temp[1], 2, 0, 2); mul_v3_fl(force, strength * efd->falloff); break; case PFIELD_DRAG: diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index dcf4c78dfd8..47d4b70fef5 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1064,6 +1064,84 @@ void fcurve_store_samples(FCurve *fcu, void *data, int start, int end, FcuSample fcu->totvert = end - start + 1; } +static void init_unbaked_bezt_data(BezTriple *bezt) +{ + bezt->f1 = bezt->f2 = bezt->f3 = SELECT; + /* Baked FCurve points always use linear interpolation. */ + bezt->ipo = BEZT_IPO_LIN; + bezt->h1 = bezt->h2 = HD_AUTO_ANIM; +} + +/* Convert baked/sampled fcurves into bezt/regular fcurves. */ +void fcurve_samples_to_keyframes(FCurve *fcu, const int start, const int end) +{ + + /* Sanity checks. */ + /* TODO: make these tests report errors using reports not CLOG's (Joshua Leung 2009). */ + if (fcu == NULL) { + CLOG_ERROR(&LOG, "No F-Curve with F-Curve Modifiers to Un-Bake"); + return; + } + + if (start > end) { + CLOG_ERROR(&LOG, "Error: Frame range to unbake F-Curve is inappropriate"); + return; + } + + if (fcu->fpt == NULL) { + /* No data to unbake. */ + CLOG_ERROR(&LOG, "Error: Curve containts no baked keyframes"); + return; + } + + /* Free any existing sample/keyframe data on the curve. */ + if (fcu->bezt) { + MEM_freeN(fcu->bezt); + } + + BezTriple *bezt; + FPoint *fpt = fcu->fpt; + int keyframes_to_insert = end - start; + int sample_points = fcu->totvert; + + bezt = fcu->bezt = MEM_callocN(sizeof(*fcu->bezt) * (size_t)keyframes_to_insert, __func__); + fcu->totvert = keyframes_to_insert; + + /* Get first sample point to 'copy' as keyframe. */ + for (; sample_points && (fpt->vec[0] < start); fpt++, sample_points--) { + /* pass */ + } + + /* Current position in the timeline. */ + int cur_pos = start; + + /* Add leading dummy flat points if needed. */ + for (; keyframes_to_insert && (fpt->vec[0] > start); cur_pos++, bezt++, keyframes_to_insert--) { + init_unbaked_bezt_data(bezt); + bezt->vec[1][0] = (float)cur_pos; + bezt->vec[1][1] = fpt->vec[1]; + } + + /* Copy actual sample points. */ + for (; keyframes_to_insert && sample_points; + cur_pos++, bezt++, keyframes_to_insert--, fpt++, sample_points--) { + init_unbaked_bezt_data(bezt); + copy_v2_v2(bezt->vec[1], fpt->vec); + } + + /* Add trailing dummy flat points if needed. */ + for (fpt--; keyframes_to_insert; cur_pos++, bezt++, keyframes_to_insert--) { + init_unbaked_bezt_data(bezt); + bezt->vec[1][0] = (float)cur_pos; + bezt->vec[1][1] = fpt->vec[1]; + } + + MEM_SAFE_FREE(fcu->fpt); + + /* Not strictly needed since we use linear interpolation, but better be consistent here. */ + calchandles_fcurve(fcu); +} + /* ***************************** F-Curve Sanity ********************************* */ /* The functions here are used in various parts of Blender, usually after some editing * of keyframe data has occurred. They ensure that keyframe data is properly ordered and @@ -1182,7 +1260,7 @@ void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag) /* For automatic ease in and out. */ if (BEZT_IS_AUTOH(bezt) && !cycle) { /* Only do this on first or last beztriple. */ - if ((a == 0) || (a == fcu->totvert - 1)) { + if (ELEM(a, 0, fcu->totvert - 1)) { /* Set both handles to have same horizontal value as keyframe. */ if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) { bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1]; @@ -1646,7 +1724,7 @@ static float fcurve_eval_keyframes_extrapolate( return endpoint_bezt->vec[1][1] - (fac * dx); } - /* Use the gradient of the second handle (later) of neighbour to calculate the gradient and thus + /* Use the gradient of the second handle (later) of neighbor to calculate the gradient and thus * the value of the curve at evaluation time. */ int handle = direction_to_neighbor > 0 ? 0 : 2; float dx = endpoint_bezt->vec[1][0] - evaltime; @@ -1922,7 +2000,7 @@ static float fcurve_eval_keyframes_interpolate(FCurve *fcu, BezTriple *bezts, fl return 0.0f; } -/* Calculate F-Curve value for 'evaltime' using BezTriple keyframes. */ +/* Calculate F-Curve value for 'evaltime' using #BezTriple keyframes. */ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime) { if (evaltime <= bezts->vec[1][0]) { @@ -1937,7 +2015,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime return fcurve_eval_keyframes_interpolate(fcu, bezts, evaltime); } -/* Calculate F-Curve value for 'evaltime' using FPoint samples. */ +/* Calculate F-Curve value for 'evaltime' using #FPoint samples. */ static float fcurve_eval_samples(FCurve *fcu, FPoint *fpts, float evaltime) { FPoint *prevfpt, *lastfpt, *fpt; diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index 9ad352c8455..a940a8a97c7 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -343,32 +343,37 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map) flags &= ~(FLUID_DOMAIN_BAKING_DATA | FLUID_DOMAIN_BAKED_DATA | FLUID_DOMAIN_OUTDATED_DATA); BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_CONFIG, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_DATA, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_SCRIPT, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } fds->cache_frame_pause_data = 0; } if (cache_map & FLUID_DOMAIN_OUTDATED_NOISE) { flags &= ~(FLUID_DOMAIN_BAKING_NOISE | FLUID_DOMAIN_BAKED_NOISE | FLUID_DOMAIN_OUTDATED_NOISE); BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_NOISE, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } fds->cache_frame_pause_noise = 0; } if (cache_map & FLUID_DOMAIN_OUTDATED_MESH) { flags &= ~(FLUID_DOMAIN_BAKING_MESH | FLUID_DOMAIN_BAKED_MESH | FLUID_DOMAIN_OUTDATED_MESH); BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_MESH, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } fds->cache_frame_pause_mesh = 0; } if (cache_map & FLUID_DOMAIN_OUTDATED_PARTICLES) { @@ -377,17 +382,18 @@ void BKE_fluid_cache_free(FluidDomainSettings *fds, Object *ob, int cache_map) BLI_path_join( temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_PARTICLES, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } fds->cache_frame_pause_particles = 0; } - if (cache_map & FLUID_DOMAIN_OUTDATED_GUIDE) { flags &= ~(FLUID_DOMAIN_BAKING_GUIDE | FLUID_DOMAIN_BAKED_GUIDE | FLUID_DOMAIN_OUTDATED_GUIDE); BLI_path_join(temp_dir, sizeof(temp_dir), fds->cache_directory, FLUID_DOMAIN_DIR_GUIDE, NULL); BLI_path_abs(temp_dir, relbase); - BLI_delete(temp_dir, true, true); /* BLI_exists(filepath) is implicit */ - + if (BLI_exists(temp_dir)) { + BLI_delete(temp_dir, true, true); + } fds->cache_frame_pause_guide = 0; } fds->cache_flag = flags; @@ -1987,7 +1993,7 @@ static void sample_mesh(FluidFlowSettings *ffs, /* Convert xyz velocities flow settings from world to grid space. */ float convert_vel[3]; copy_v3_v3(convert_vel, ffs->vel_coord); - float time_mult = 1.0 / (25.f * DT_DEFAULT); + float time_mult = 1.0 / (25.0f * DT_DEFAULT); float size_mult = MAX3(base_res[0], base_res[1], base_res[2]) / MAX3(global_size[0], global_size[1], global_size[2]); mul_v3_v3fl(convert_vel, ffs->vel_coord, size_mult * time_mult); @@ -3287,7 +3293,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obj /* If needed, vertex velocities will be read too. */ bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS; FluidDomainVertexVelocity *velarray = NULL; - float time_mult = 25.f * DT_DEFAULT; + float time_mult = 25.0f * DT_DEFAULT; if (use_speedvectors) { if (fds->mesh_velocities) { @@ -4424,7 +4430,7 @@ float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velo if (fmd && (fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain && fmd->domain->fluid) { FluidDomainSettings *fds = fmd->domain; - float time_mult = 25.f * DT_DEFAULT; + float time_mult = 25.0f * DT_DEFAULT; float size_mult = MAX3(fds->global_size[0], fds->global_size[1], fds->global_size[2]) / MAX3(fds->base_res[0], fds->base_res[1], fds->base_res[2]); float vel_mag; @@ -4691,9 +4697,11 @@ void BKE_fluid_fields_sanitize(FluidDomainSettings *settings) const char data_depth = settings->openvdb_data_depth; if (settings->type == FLUID_DOMAIN_TYPE_GAS) { - if (coba_field == FLUID_DOMAIN_FIELD_PHI || coba_field == FLUID_DOMAIN_FIELD_PHI_IN || - coba_field == FLUID_DOMAIN_FIELD_PHI_OUT || - coba_field == FLUID_DOMAIN_FIELD_PHI_OBSTACLE) { + if (ELEM(coba_field, + FLUID_DOMAIN_FIELD_PHI, + FLUID_DOMAIN_FIELD_PHI_IN, + FLUID_DOMAIN_FIELD_PHI_OUT, + FLUID_DOMAIN_FIELD_PHI_OBSTACLE)) { /* Defaulted to density for gas domain. */ settings->coba_field = FLUID_DOMAIN_FIELD_DENSITY; } @@ -4704,10 +4712,14 @@ void BKE_fluid_fields_sanitize(FluidDomainSettings *settings) } } else if (settings->type == FLUID_DOMAIN_TYPE_LIQUID) { - if (coba_field == FLUID_DOMAIN_FIELD_COLOR_R || coba_field == FLUID_DOMAIN_FIELD_COLOR_G || - coba_field == FLUID_DOMAIN_FIELD_COLOR_B || coba_field == FLUID_DOMAIN_FIELD_DENSITY || - coba_field == FLUID_DOMAIN_FIELD_FLAME || coba_field == FLUID_DOMAIN_FIELD_FUEL || - coba_field == FLUID_DOMAIN_FIELD_HEAT) { + if (ELEM(coba_field, + FLUID_DOMAIN_FIELD_COLOR_R, + FLUID_DOMAIN_FIELD_COLOR_G, + FLUID_DOMAIN_FIELD_COLOR_B, + FLUID_DOMAIN_FIELD_DENSITY, + FLUID_DOMAIN_FIELD_FLAME, + FLUID_DOMAIN_FIELD_FUEL, + FLUID_DOMAIN_FIELD_HEAT)) { /* Defaulted to phi for liquid domain. */ settings->coba_field = FLUID_DOMAIN_FIELD_PHI; } @@ -4987,6 +4999,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, tfds->fractions_threshold = fds->fractions_threshold; tfds->fractions_distance = fds->fractions_distance; tfds->sys_particle_maximum = fds->sys_particle_maximum; + tfds->simulation_method = fds->simulation_method; /* diffusion options*/ tfds->surface_tension = fds->surface_tension; diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index d13425f5ec9..6ebcef5caef 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -824,7 +824,8 @@ static void fcm_noise_evaluate( * - 0.1 is passed as the 'z' value, otherwise evaluation fails for size = phase = 1 * with evaltime being an integer (which happens when evaluating on frame by frame basis) */ - noise = BLI_turbulence(data->size, evaltime - data->offset, data->phase, 0.1f, data->depth); + noise = BLI_noise_turbulence( + data->size, evaltime - data->offset, data->phase, 0.1f, data->depth); /* combine the noise with existing motion data */ switch (data->modification) { diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index e0bbdfaeed6..9431915b4e4 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -168,6 +168,8 @@ IDTypeInfo IDType_ID_VF = { .blend_read_data = vfont_blend_read_data, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /***************************** VFont *******************************/ @@ -947,7 +949,7 @@ static bool vfont_to_curve(Object *ob, // CLOG_WARN(&LOG, "linewidth exceeded: %c%c%c...", mem[i], mem[i+1], mem[i+2]); for (j = i; j && (mem[j] != '\n') && (chartransdata[j].dobreak == 0); j--) { bool dobreak = false; - if (mem[j] == ' ' || mem[j] == '-') { + if (ELEM(mem[j], ' ', '-')) { ct -= (i - (j - 1)); cnr -= (i - (j - 1)); if (mem[j] == ' ') { diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 6c6ca996caa..4cf8e365cf6 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -288,6 +288,8 @@ IDTypeInfo IDType_ID_GD = { .blend_read_data = greasepencil_blend_read_data, .blend_read_lib = greasepencil_blend_read_lib, .blend_read_expand = greasepencil_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /* ************************************************** */ @@ -2009,12 +2011,12 @@ void BKE_gpencil_material_remap(struct bGPdata *gpd, /** * Load a table with material conversion index for merged materials. - * \param ob: Grease pencil object - * \param hue_threshold: Threshold for Hue - * \param sat_threshold: Threshold for Saturation - * \param val_threshold: Threshold for Value - * \param r_mat_table : return material table - * \return True if done + * \param ob: Grease pencil object. + * \param hue_threshold: Threshold for Hue. + * \param sat_threshold: Threshold for Saturation. + * \param val_threshold: Threshold for Value. + * \param r_mat_table: return material table. + * \return True if done. */ bool BKE_gpencil_merge_materials_table_get(Object *ob, const float hue_threshold, @@ -2668,7 +2670,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph, return; } - if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { + if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) { mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse); add_v3_v3(diff_mat[3], ob_eval->obmat[3]); return; @@ -2710,7 +2712,7 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob) if ((gpl->parent != NULL) && (gpl->actframe != NULL)) { Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent); /* calculate new matrix */ - if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { + if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) { copy_m4_m4(cur_mat, ob_parent->obmat); } else if (gpl->partype == PARBONE) { diff --git a/source/blender/blenkernel/intern/gpencil_geom.c b/source/blender/blenkernel/intern/gpencil_geom.c index 66a7ae757a2..ff7dde27db8 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.c +++ b/source/blender/blenkernel/intern/gpencil_geom.c @@ -189,7 +189,7 @@ BoundBox *BKE_gpencil_boundbox_get(Object *ob) /* Update orig object's boundbox with re-computed evaluated values. This function can be * called with the evaluated object and need update the original object bound box data * to keep both values synchronized. */ - if ((ob_orig != NULL) && (ob != ob_orig)) { + if (!ELEM(ob_orig, NULL, ob)) { if (ob_orig->runtime.bb == NULL) { ob_orig->runtime.bb = MEM_callocN(sizeof(BoundBox), "GPencil boundbox"); } @@ -778,7 +778,7 @@ bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf) /* Only affect endpoints by a fraction of the normal strength, * to prevent the stroke from shrinking too much */ - if ((i == 0) || (i == gps->totpoints - 1)) { + if (ELEM(i, 0, gps->totpoints - 1)) { inf *= 0.1f; } @@ -838,7 +838,7 @@ bool BKE_gpencil_stroke_smooth_strength(bGPDstroke *gps, int point_index, float } /* Only affect endpoints by a fraction of the normal influence */ float inf = influence; - if ((point_index == 0) || (point_index == gps->totpoints - 1)) { + if (ELEM(point_index, 0, gps->totpoints - 1)) { inf *= 0.01f; } /* Limit max influence to reduce pop effect. */ @@ -902,7 +902,7 @@ bool BKE_gpencil_stroke_smooth_thickness(bGPDstroke *gps, int point_index, float } /* Only affect endpoints by a fraction of the normal influence */ float inf = influence; - if ((point_index == 0) || (point_index == gps->totpoints - 1)) { + if (ELEM(point_index, 0, gps->totpoints - 1)) { inf *= 0.01f; } /* Limit max influence to reduce pop effect. */ @@ -1402,7 +1402,7 @@ bool BKE_gpencil_stroke_trim(bGPDstroke *gps) memcpy(dvert->dw, dvert_src->dw, sizeof(MDeformWeight)); } } - if (idx == start || idx == end) { + if (ELEM(idx, start, end)) { copy_v3_v3(&pt_new->x, point); } } diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index d12e445fe99..934791ccc35 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -39,6 +39,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BKE_gpencil.h" #include "BKE_gpencil_geom.h" @@ -411,6 +412,11 @@ void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname) strcat(r_idname, mti->name); } +void BKE_gpencil_modifier_panel_expand(GpencilModifierData *md) +{ + md->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT; +} + /** * Generic grease pencil modifier copy data. * \param md_src: Source modifier data diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c index 313b0d192dc..554919ad1a0 100644 --- a/source/blender/blenkernel/intern/hair.c +++ b/source/blender/blenkernel/intern/hair.c @@ -195,6 +195,8 @@ IDTypeInfo IDType_ID_HA = { .blend_read_data = hair_blend_read_data, .blend_read_lib = hair_blend_read_lib, .blend_read_expand = hair_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static void hair_random(Hair *hair) diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index bcec90cf0cf..eec9013d067 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -899,8 +899,10 @@ struct Icon_Geom *BKE_icon_geom_from_file(const char *filename) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Studio Light Icon * \{ */ + int BKE_icon_ensure_studio_light(struct StudioLight *sl, int id_type) { int icon_id = get_next_free_id(); diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 113d4cf50d7..b0991f1d343 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -68,9 +68,7 @@ static size_t idp_size_table[] = { }; /* -------------------------------------------------------------------- */ -/* Array Functions */ - -/** \name IDP Array API +/** \name Array Functions (IDP Array API) * \{ */ #define GETPROP(prop, i) &(IDP_IDPArray(prop)[i]) @@ -323,9 +321,7 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop, const int flag) /** \} */ /* -------------------------------------------------------------------- */ -/* String Functions */ - -/** \name IDProperty String API +/** \name String Functions (IDProperty String API) * \{ */ /** @@ -439,9 +435,7 @@ void IDP_FreeString(IDProperty *prop) /** \} */ /* -------------------------------------------------------------------- */ -/* ID Type */ - -/** \name IDProperty ID API +/** \name ID Type (IDProperty ID API) * \{ */ static IDProperty *IDP_CopyID(const IDProperty *prop, const int flag) @@ -477,9 +471,7 @@ void IDP_AssignID(IDProperty *prop, ID *id, const int flag) /** \} */ /* -------------------------------------------------------------------- */ -/* Group Functions */ - -/** \name IDProperty Group API +/** \name Group Functions (IDProperty Group API) * \{ */ /** @@ -760,10 +752,9 @@ static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user) /** \} */ /* -------------------------------------------------------------------- */ -/* Main Functions */ - -/** \name IDProperty Main API +/** \name Main Functions (IDProperty Main API) * \{ */ + IDProperty *IDP_CopyProperty_ex(const IDProperty *prop, const int flag) { switch (prop->type) { @@ -800,43 +791,6 @@ void IDP_CopyPropertyContent(IDProperty *dst, IDProperty *src) IDP_FreeProperty(idprop_tmp); } -/* Updates ID pointers after an object has been copied */ -/* TODO Nuke this once its only user has been correctly converted - * to use generic ID management from BKE_library! */ -void IDP_RelinkProperty(struct IDProperty *prop) -{ - if (!prop) { - return; - } - - switch (prop->type) { - case IDP_GROUP: { - LISTBASE_FOREACH (IDProperty *, loop, &prop->data.group) { - IDP_RelinkProperty(loop); - } - break; - } - case IDP_IDPARRAY: { - IDProperty *idp_array = IDP_Array(prop); - for (int i = 0; i < prop->len; i++) { - IDP_RelinkProperty(&idp_array[i]); - } - break; - } - case IDP_ID: { - ID *id = IDP_Id(prop); - if (id && id->newid) { - id_us_min(IDP_Id(prop)); - prop->data.pointer = id->newid; - id_us_plus(IDP_Id(prop)); - } - break; - } - default: - break; /* Nothing to do for other IDProp types. */ - } -} - /** * Get the Group property that contains the id properties for ID id. Set create_if_needed * to create the Group property and attach it to id if it doesn't exist; otherwise @@ -961,7 +915,7 @@ bool IDP_EqualsProperties(IDProperty *prop1, IDProperty *prop2) * This function takes three arguments: the ID property type, a union which defines * its initial value, and a name. * - * The union is simple to use; see the top of this header file for its definition. + * The union is simple to use; see the top of BKE_idprop.h for its definition. * An example of using this function: * * \code{.c} diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 187908573dd..f87b1b5ff45 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -84,7 +84,6 @@ #include "BKE_packedFile.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" /* seq_foreground_frame_get() */ #include "BKE_workspace.h" #include "BLF_api.h" @@ -93,6 +92,8 @@ #include "RE_pipeline.h" +#include "SEQ_sequencer.h" /* seq_foreground_frame_get() */ + #include "GPU_texture.h" #include "BLI_sys_types.h" /* for intptr_t support */ @@ -324,6 +325,8 @@ IDTypeInfo IDType_ID_IM = { .blend_read_data = image_blend_read_data, .blend_read_lib = image_blend_read_lib, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /* prototypes */ @@ -665,7 +668,7 @@ ImageTile *BKE_image_get_tile(Image *ima, int tile_number) /* Tile number 0 is a special case and refers to the first tile, typically * coming from non-UDIM-aware code. */ - if (tile_number == 0 || tile_number == 1001) { + if (ELEM(tile_number, 0, 1001)) { return ima->tiles.first; } @@ -802,7 +805,7 @@ Image *BKE_image_load_exists_ex(Main *bmain, const char *filepath, bool *r_exist /* first search an identical filepath */ for (ima = bmain->images.first; ima; ima = ima->id.next) { - if (ima->source != IMA_SRC_VIEWER && ima->source != IMA_SRC_GENERATED) { + if (!ELEM(ima->source, IMA_SRC_VIEWER, IMA_SRC_GENERATED)) { STRNCPY(strtest, ima->filepath); BLI_path_abs(strtest, ID_BLEND_PATH(bmain, &ima->id)); @@ -1313,7 +1316,7 @@ int BKE_image_imtype_to_ftype(const char imtype, ImbFormatOptions *r_options) return IMB_FTYPE_TIF; } #endif - if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) { + if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { return IMB_FTYPE_OPENEXR; } #ifdef WITH_CINEON @@ -1663,7 +1666,7 @@ static bool do_add_image_extension(char *string, } #endif #ifdef WITH_OPENEXR - else if (imtype == R_IMF_IMTYPE_OPENEXR || imtype == R_IMF_IMTYPE_MULTILAYER) { + else if (ELEM(imtype, R_IMF_IMTYPE_OPENEXR, R_IMF_IMTYPE_MULTILAYER)) { if (!BLI_path_extension_check(string, extension_test = ".exr")) { extension = extension_test; } diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 877747a257e..ceb13c4955e 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -379,10 +379,16 @@ static void checker_board_text( const float text_color[4] = {0.0, 0.0, 0.0, 1.0}; const float text_outline[4] = {1.0, 1.0, 1.0, 1.0}; + const char char_array[36] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + + int first_char_index = 0; for (y = 0; y < height; y += step) { - text[1] = '1'; + text[0] = char_array[first_char_index]; + int second_char_index = 27; for (x = 0; x < width; x += step) { + text[1] = char_array[second_char_index]; + /* hard coded offset */ pen_x = x + 33; pen_y = y + 44; @@ -412,9 +418,9 @@ static void checker_board_text( BLF_position(mono, pen_x, pen_y, 0.0); BLF_draw_buffer(mono, text, 2); - text[1]++; + second_char_index = (second_char_index + 1) % ARRAY_SIZE(char_array); } - text[0]++; + first_char_index = (first_char_index + 1) % ARRAY_SIZE(char_array); } /* cleanup the buffer. */ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 1a87b931689..5d2defa3030 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -68,12 +68,13 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_nla.h" -#include "BKE_sequencer.h" #include "CLG_log.h" #include "MEM_guardedalloc.h" +#include "SEQ_sequencer.h" + #ifdef WIN32 # include "BLI_math_base.h" /* M_PI */ #endif @@ -131,6 +132,8 @@ IDTypeInfo IDType_ID_IP = { .blend_read_data = NULL, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /* *************************************************** */ diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index 95a8419b95d..7468112b40e 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -214,6 +214,8 @@ IDTypeInfo IDType_ID_KE = { .blend_read_data = shapekey_blend_read_data, .blend_read_lib = shapekey_blend_read_lib, .blend_read_expand = shapekey_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; #define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */ @@ -1614,7 +1616,7 @@ int BKE_keyblock_element_count_from_shape(const Key *key, const int shape_index) int result = 0; int index = 0; for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) { - if ((shape_index == -1) || (index == shape_index)) { + if (ELEM(shape_index, -1, index)) { result += kb->totelem; } } @@ -1654,7 +1656,7 @@ void BKE_keyblock_data_get_from_shape(const Key *key, float (*arr)[3], const int uint8_t *elements = (uint8_t *)arr; int index = 0; for (const KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) { - if ((shape_index == -1) || (index == shape_index)) { + if (ELEM(shape_index, -1, index)) { const int block_elem_len = kb->totelem * key->elemsize; memcpy(elements, kb->data, block_elem_len); elements += block_elem_len; @@ -1684,7 +1686,7 @@ void BKE_keyblock_data_set_with_mat4(Key *key, int index = 0; for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) { - if ((shape_index == -1) || (index == shape_index)) { + if (ELEM(shape_index, -1, index)) { const int block_elem_len = kb->totelem; float(*block_data)[3] = (float(*)[3])kb->data; for (int data_offset = 0; data_offset < block_elem_len; ++data_offset) { @@ -1708,7 +1710,7 @@ void BKE_keyblock_curve_data_set_with_mat4( int index = 0; for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) { - if ((shape_index == -1) || (index == shape_index)) { + if (ELEM(shape_index, -1, index)) { const int block_elem_size = kb->totelem * key->elemsize; BKE_keyblock_curve_data_transform(nurb, mat, elements, kb->data); elements += block_elem_size; @@ -1724,7 +1726,7 @@ void BKE_keyblock_data_set(Key *key, const int shape_index, const void *data) const uint8_t *elements = data; int index = 0; for (KeyBlock *kb = key->block.first; kb; kb = kb->next, index++) { - if ((shape_index == -1) || (index == shape_index)) { + if (ELEM(shape_index, -1, index)) { const int block_elem_size = kb->totelem * key->elemsize; memcpy(kb->data, elements, block_elem_size); elements += block_elem_size; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index c0eb6b4b134..74f78106be5 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -203,6 +203,8 @@ IDTypeInfo IDType_ID_LT = { .blend_read_data = lattice_blend_read_data, .blend_read_lib = lattice_blend_read_lib, .blend_read_expand = lattice_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; int BKE_lattice_index_from_uvw(Lattice *lt, const int u, const int v, const int w) diff --git a/source/blender/blenkernel/intern/lattice_deform.c b/source/blender/blenkernel/intern/lattice_deform.c index 382661ff070..14c600caa46 100644 --- a/source/blender/blenkernel/intern/lattice_deform.c +++ b/source/blender/blenkernel/intern/lattice_deform.c @@ -169,7 +169,7 @@ void BKE_lattice_deform_data_eval_co(LatticeDeformData *lattice_deform_data, int ui, vi, wi, uu, vv, ww; /* vgroup influence */ - float co_prev[3], weight_blend = 0.0f; + float co_prev[4] = {0}, weight_blend = 0.0f; copy_v3_v3(co_prev, co); #ifdef __SSE2__ __m128 co_vec = _mm_loadu_ps(co_prev); diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c index 6efc9d0753e..4915ad4eaac 100644 --- a/source/blender/blenkernel/intern/layer.c +++ b/source/blender/blenkernel/intern/layer.c @@ -18,6 +18,9 @@ * \ingroup bke */ +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #include <string.h> #include "BLI_listbase.h" @@ -56,6 +59,8 @@ #include "MEM_guardedalloc.h" +#include "BLO_read_write.h" + /* Set of flags which are dependent on a collection settings. */ static const short g_base_collection_flags = (BASE_VISIBLE_DEPSGRAPH | BASE_VISIBLE_VIEWLAYER | BASE_SELECTABLE | BASE_ENABLED_VIEWPORT | @@ -1445,12 +1450,9 @@ static LayerCollection *find_layer_collection_by_scene_collection(LayerCollectio LayerCollection *BKE_layer_collection_first_from_scene_collection(ViewLayer *view_layer, const Collection *collection) { - for (LayerCollection *layer_collection = view_layer->layer_collections.first; - layer_collection != NULL; - layer_collection = layer_collection->next) { + LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) { LayerCollection *found = find_layer_collection_by_scene_collection(layer_collection, collection); - if (found != NULL) { return found; } @@ -1830,3 +1832,89 @@ void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph, BLI_assert(view_layer != NULL); layer_eval_view_layer(depsgraph, scene, view_layer); } + +static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, bool master) +{ + BLO_read_list(reader, lb); + LISTBASE_FOREACH (LayerCollection *, lc, lb) { +#ifdef USE_COLLECTION_COMPAT_28 + BLO_read_data_address(reader, &lc->scene_collection); +#endif + + /* Master collection is not a real data-lock. */ + if (master) { + BLO_read_data_address(reader, &lc->collection); + } + + direct_link_layer_collections(reader, &lc->layer_collections, false); + } +} + +void BKE_view_layer_blend_read_data(BlendDataReader *reader, ViewLayer *view_layer) +{ + view_layer->stats = NULL; + BLO_read_list(reader, &view_layer->object_bases); + BLO_read_data_address(reader, &view_layer->basact); + + direct_link_layer_collections(reader, &view_layer->layer_collections, true); + BLO_read_data_address(reader, &view_layer->active_collection); + + BLO_read_data_address(reader, &view_layer->id_properties); + IDP_BlendDataRead(reader, &view_layer->id_properties); + + BLO_read_list(reader, &(view_layer->freestyle_config.modules)); + BLO_read_list(reader, &(view_layer->freestyle_config.linesets)); + + BLI_listbase_clear(&view_layer->drawdata); + view_layer->object_bases_array = NULL; + view_layer->object_bases_hash = NULL; +} + +static void lib_link_layer_collection(BlendLibReader *reader, + Library *lib, + LayerCollection *layer_collection, + bool master) +{ + /* Master collection is not a real data-lock. */ + if (!master) { + BLO_read_id_address(reader, lib, &layer_collection->collection); + } + + LISTBASE_FOREACH ( + LayerCollection *, layer_collection_nested, &layer_collection->layer_collections) { + lib_link_layer_collection(reader, lib, layer_collection_nested, false); + } +} + +void BKE_view_layer_blend_read_lib(BlendLibReader *reader, Library *lib, ViewLayer *view_layer) +{ + LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) { + BLO_read_id_address(reader, lib, &fmc->script); + } + + LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { + BLO_read_id_address(reader, lib, &fls->linestyle); + BLO_read_id_address(reader, lib, &fls->group); + } + + LISTBASE_FOREACH_MUTABLE (Base *, base, &view_layer->object_bases) { + /* we only bump the use count for the collection objects */ + BLO_read_id_address(reader, lib, &base->object); + + if (base->object == NULL) { + /* Free in case linked object got lost. */ + BLI_freelinkN(&view_layer->object_bases, base); + if (view_layer->basact == base) { + view_layer->basact = NULL; + } + } + } + + LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) { + lib_link_layer_collection(reader, lib, layer_collection, true); + } + + BLO_read_id_address(reader, lib, &view_layer->mat_override); + + IDP_BlendReadLib(reader, view_layer->id_properties); +} diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index ae6ee71da82..cf9fff811ce 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -101,6 +101,15 @@ IDTypeInfo IDType_ID_LINK_PLACEHOLDER = { .copy_data = NULL, .free_data = NULL, .make_local = NULL, + .foreach_id = NULL, + .foreach_cache = NULL, + + .blend_write = NULL, + .blend_read_data = NULL, + .blend_read_lib = NULL, + .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /* GS reads the memory pointed at in a specific ordering. @@ -1322,7 +1331,7 @@ void id_sort_by_name(ListBase *lb, ID *id, ID *id_sorting_hint) BLI_remlink(lb, id); /* Check if we can actually insert id before or after id_sorting_hint, if given. */ - if (id_sorting_hint != NULL && id_sorting_hint != id) { + if (!ELEM(id_sorting_hint, NULL, id)) { BLI_assert(BLI_findindex(lb, id_sorting_hint) >= 0); ID *id_sorting_hint_next = id_sorting_hint->next; @@ -1560,7 +1569,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_ char base_name_test[MAX_ID_NAME - 2]; int number_test; if ((id != id_test) && !ID_IS_LINKED(id_test) && (name[0] == id_test->name[2]) && - (id_test->name[base_name_len + 2] == '.' || id_test->name[base_name_len + 2] == '\0') && + (ELEM(id_test->name[base_name_len + 2], '.', '\0')) && STREQLEN(name, id_test->name + 2, base_name_len) && (BLI_split_name_num(base_name_test, &number_test, id_test->name + 2, '.') == base_name_len)) { diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index f19ab96588e..aa5e28b35bf 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -1359,7 +1359,7 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) } if (GS(local->name) == ID_OB) { - /* Our beloved pose's bone cross-data pointers.. Usually, depsgraph evaluation would + /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would * ensure this is valid, but in some situations (like hidden collections etc.) this won't * be the case, so we need to take care of this ourselves. */ Object *ob_local = (Object *)local; @@ -1427,9 +1427,9 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for } /* Usual pose bones issue, need to be done outside of the threaded process or we may run into - * concurency issues here. + * concurrency issues here. * Note that calling #BKE_pose_ensure again in thread in - * #BKE_lib_override_library_operations_create is not a problem then.. */ + * #BKE_lib_override_library_operations_create is not a problem then. */ LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ob->type == OB_ARMATURE) { BLI_assert(ob->data != NULL); @@ -1442,6 +1442,15 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, const bool for FOREACH_MAIN_ID_BEGIN (bmain, id) { if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && (force_auto || (id->tag & LIB_TAG_OVERRIDE_LIBRARY_AUTOREFRESH))) { + /* Usual issue with pose, it's quiet rare but sometimes they may not be up to date when this + * function is called. */ + if (GS(id->name) == ID_OB) { + Object *ob = (Object *)id; + if (ob->type == OB_ARMATURE) { + BLI_assert(ob->data != NULL); + BKE_pose_ensure(bmain, ob, ob->data, true); + } + } /* Only check overrides if we do have the real reference data available, and not some empty * 'placeholder' for missing data (broken links). */ if ((id->override_library->reference->tag & LIB_TAG_MISSING) == 0) { diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 949e10d4721..6a560d51362 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -82,6 +82,8 @@ IDTypeInfo IDType_ID_LI = { .blend_read_data = NULL, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; void BKE_library_filepath_set(Main *bmain, Library *lib, const char *filepath) diff --git a/source/blender/blenkernel/intern/light.c b/source/blender/blenkernel/intern/light.c index 4780f0cf208..a47a0c043ff 100644 --- a/source/blender/blenkernel/intern/light.c +++ b/source/blender/blenkernel/intern/light.c @@ -207,6 +207,8 @@ IDTypeInfo IDType_ID_LA = { .blend_read_data = light_blend_read_data, .blend_read_lib = light_blend_read_lib, .blend_read_expand = light_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; Light *BKE_light_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c index 31653a9a0ac..0553c070fdf 100644 --- a/source/blender/blenkernel/intern/lightprobe.c +++ b/source/blender/blenkernel/intern/lightprobe.c @@ -105,6 +105,8 @@ IDTypeInfo IDType_ID_LP = { .blend_read_data = lightprobe_blend_read_data, .blend_read_lib = lightprobe_blend_read_lib, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; void BKE_lightprobe_type_set(LightProbe *probe, const short lightprobe_type) diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c index 733a2bcd1e1..69e6535a59f 100644 --- a/source/blender/blenkernel/intern/linestyle.c +++ b/source/blender/blenkernel/intern/linestyle.c @@ -765,6 +765,8 @@ IDTypeInfo IDType_ID_LS = { .blend_read_data = linestyle_blend_read_data, .blend_read_lib = linestyle_blend_read_lib, .blend_read_expand = linestyle_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static const char *modifier_name[LS_MODIFIER_NUM] = { diff --git a/source/blender/blenkernel/intern/main_idmap.c b/source/blender/blenkernel/intern/main_idmap.c index 9a6ead7eb2b..21f5e9c6fb2 100644 --- a/source/blender/blenkernel/intern/main_idmap.c +++ b/source/blender/blenkernel/intern/main_idmap.c @@ -36,6 +36,7 @@ * Utility functions for faster ID lookups. */ +/* -------------------------------------------------------------------- */ /** \name BKE_main_idmap API * * Cache ID (name, library lookups). diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index 1f9f155ee55..04fec1e57c4 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -268,6 +268,8 @@ IDTypeInfo IDType_ID_MSK = { .blend_read_data = mask_blend_read_data, .blend_read_lib = mask_blend_read_lib, .blend_read_expand = mask_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static struct { diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 4a85fab4e18..e892a3f4d53 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -272,6 +272,8 @@ IDTypeInfo IDType_ID_MA = { .blend_read_data = material_blend_read_data, .blend_read_lib = material_blend_read_lib, .blend_read_expand = material_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; void BKE_gpencil_material_attr_init(Material *ma) diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index d2bacb7d3bc..65ec91c57cf 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -202,6 +202,8 @@ IDTypeInfo IDType_ID_MB = { .blend_read_data = metaball_blend_read_data, .blend_read_lib = metaball_blend_read_lib, .blend_read_expand = metaball_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /* Functions */ diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c index 7273d2a920d..cb01927d992 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.c +++ b/source/blender/blenkernel/intern/mball_tessellate.c @@ -807,22 +807,22 @@ static void makecubetable(void) INTLIST *edges; for (edges = polys->list; edges; edges = edges->next) { - if (edges->i == LB || edges->i == LT || edges->i == LN || edges->i == LF) { + if (ELEM(edges->i, LB, LT, LN, LF)) { faces[i] |= 1 << L; } - if (edges->i == RB || edges->i == RT || edges->i == RN || edges->i == RF) { + if (ELEM(edges->i, RB, RT, RN, RF)) { faces[i] |= 1 << R; } - if (edges->i == LB || edges->i == RB || edges->i == BN || edges->i == BF) { + if (ELEM(edges->i, LB, RB, BN, BF)) { faces[i] |= 1 << B; } - if (edges->i == LT || edges->i == RT || edges->i == TN || edges->i == TF) { + if (ELEM(edges->i, LT, RT, TN, TF)) { faces[i] |= 1 << T; } - if (edges->i == LN || edges->i == RN || edges->i == BN || edges->i == TN) { + if (ELEM(edges->i, LN, RN, BN, TN)) { faces[i] |= 1 << N; } - if (edges->i == LF || edges->i == RF || edges->i == BF || edges->i == TF) { + if (ELEM(edges->i, LF, RF, BF, TF)) { faces[i] |= 1 << F; } } diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index ba47b8fc4af..9ccdf5189d1 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -275,50 +275,6 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) mesh->totselect = 0; } - /* Multires data */ - BLO_read_data_address(reader, &mesh->mr); - if (mesh->mr) { - BLO_read_list(reader, &mesh->mr->levels); - MultiresLevel *lvl = mesh->mr->levels.first; - - CustomData_blend_read(reader, &mesh->mr->vdata, lvl->totvert); - BKE_defvert_blend_read( - reader, lvl->totvert, CustomData_get(&mesh->mr->vdata, 0, CD_MDEFORMVERT)); - CustomData_blend_read(reader, &mesh->mr->fdata, lvl->totface); - - BLO_read_data_address(reader, &mesh->mr->edge_flags); - BLO_read_data_address(reader, &mesh->mr->edge_creases); - - BLO_read_data_address(reader, &mesh->mr->verts); - - /* If mesh has the same number of vertices as the - * highest multires level, load the current mesh verts - * into multires and discard the old data. Needed - * because some saved files either do not have a verts - * array, or the verts array contains out-of-date - * data. */ - if (mesh->totvert == ((MultiresLevel *)mesh->mr->levels.last)->totvert) { - if (mesh->mr->verts) { - MEM_freeN(mesh->mr->verts); - } - mesh->mr->verts = MEM_dupallocN(mesh->mvert); - } - - for (; lvl; lvl = lvl->next) { - BLO_read_data_address(reader, &lvl->verts); - BLO_read_data_address(reader, &lvl->faces); - BLO_read_data_address(reader, &lvl->edges); - BLO_read_data_address(reader, &lvl->colfaces); - } - } - - /* if multires is present but has no valid vertex data, - * there's no way to recover it; silently remove multires */ - if (mesh->mr && !mesh->mr->verts) { - multires_free(mesh->mr); - mesh->mr = NULL; - } - if ((BLO_read_requires_endian_switch(reader)) && mesh->tface) { TFace *tf = mesh->tface; for (int i = 0; i < mesh->totface; i++, tf++) { @@ -377,6 +333,8 @@ IDTypeInfo IDType_ID_ME = { .blend_read_data = mesh_blend_read_data, .blend_read_lib = mesh_blend_read_lib, .blend_read_expand = mesh_read_expand, + + .blend_read_undo_preserve = NULL, }; enum { @@ -1540,8 +1498,11 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) { + MVert *mvert = CustomData_duplicate_referenced_layer(&me->vdata, CD_MVERT, me->totvert); + /* If the referenced layer has been re-allocated need to update pointers stored in the mesh. */ + BKE_mesh_update_customdata_pointers(me, false); + int i = me->totvert; - MVert *mvert; for (mvert = me->mvert; i--; mvert++) { add_v3_v3(mvert->co, offset); } diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 24a32eeea66..9711dcc8ef3 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -949,7 +949,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce BKE_object_free_derived_caches(ob); } -void BKE_mesh_from_pointcloud(PointCloud *pointcloud, Mesh *me) +void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) { BLI_assert(pointcloud != NULL); diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c index 868694931cb..e118c1b6f6e 100644 --- a/source/blender/blenkernel/intern/mesh_merge.c +++ b/source/blender/blenkernel/intern/mesh_merge.c @@ -61,7 +61,7 @@ static int cddm_poly_compare(MLoop *mloop_array, MLoop *mloop_source, *mloop_target; - BLI_assert(direct_reverse == 1 || direct_reverse == -1); + BLI_assert(ELEM(direct_reverse, 1, -1)); i_loop_source = 0; mloop_source = mloop_array + mpoly_source->loopstart; diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c index 1c48cf6f3cb..f3b29171762 100644 --- a/source/blender/blenkernel/intern/mesh_remap.c +++ b/source/blender/blenkernel/intern/mesh_remap.c @@ -327,6 +327,7 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst, /** \} */ +/* -------------------------------------------------------------------- */ /** \name Mesh to mesh mapping * \{ */ diff --git a/source/blender/blenkernel/intern/mesh_runtime.c b/source/blender/blenkernel/intern/mesh_runtime.c index 150f7f19edc..f35f4ae3501 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.c +++ b/source/blender/blenkernel/intern/mesh_runtime.c @@ -267,6 +267,7 @@ void BKE_mesh_batch_cache_free(Mesh *me) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Mesh runtime debug helpers. * \{ */ /* evaluated mesh info printing function, diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 6fea2cc8bf5..b3c53df2d5f 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -52,6 +52,7 @@ static CLG_LogRef LOG = {"bke.mesh"}; +/* -------------------------------------------------------------------- */ /** \name Internal functions * \{ */ diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 0aa85f0ad50..0054d2f76d1 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -38,6 +38,7 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "BLI_linklist.h" #include "BLI_listbase.h" @@ -130,6 +131,11 @@ void BKE_modifier_type_panel_id(ModifierType type, char *r_idname) strcat(r_idname, mti->name); } +void BKE_modifier_panel_expand(ModifierData *md) +{ + md->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT; +} + /***/ ModifierData *BKE_modifier_new(int type) @@ -389,7 +395,7 @@ bool BKE_modifier_is_non_geometrical(ModifierData *md) return (mti->type == eModifierTypeType_NonGeometrical); } -void BKE_modifier_set_error(ModifierData *md, const char *_format, ...) +void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_format, ...) { char buffer[512]; va_list ap; @@ -406,7 +412,16 @@ void BKE_modifier_set_error(ModifierData *md, const char *_format, ...) md->error = BLI_strdup(buffer); - CLOG_STR_ERROR(&LOG, md->error); +#ifndef NDEBUG + if ((md->mode & eModifierMode_Virtual) == 0) { + /* Ensure correct object is passed in. */ + const Object *ob_orig = (Object *)DEG_get_original_id((ID *)&ob->id); + const ModifierData *md_orig = md->orig_modifier_data ? md->orig_modifier_data : md; + BLI_assert(BLI_findindex(&ob_orig->modifiers, md_orig) != -1); + } +#endif + + CLOG_ERROR(&LOG, "Object: \"%s\", Modifier: \"%s\", %s", ob->id.name + 2, md->name, md->error); } /* used for buttons, to find out if the 'draw deformed in editmode' option is diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 40b12d8a777..564496744df 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -359,6 +359,8 @@ IDTypeInfo IDType_ID_MC = { .blend_read_data = movieclip_blend_read_data, .blend_read_lib = movieclip_blend_read_lib, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /*********************** movieclip buffer loaders *************************/ @@ -519,7 +521,7 @@ static void movieclip_convert_multilayer_add_pass(void *UNUSED(layer), MEM_freeN(rect); return; } - if (STREQ(pass_name, RE_PASSNAME_COMBINED) || STREQ(chan_id, "RGBA") || STREQ(chan_id, "RGB")) { + if (STREQ(pass_name, RE_PASSNAME_COMBINED) || STR_ELEM(chan_id, "RGBA", "RGB")) { ctx->combined_pass = rect; ctx->num_combined_channels = num_channels; } diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 6e1168d8a16..441da8b134a 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -63,7 +63,6 @@ #include <string.h> /* MULTIRES MODIFIER */ -static const int multires_max_levels = 13; static const int multires_grid_tot[] = { 0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; static const int multires_side_tot[] = { @@ -76,7 +75,6 @@ typedef enum { ADD_DISPLACEMENTS, } DispOp; -static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert); static void multiresModifier_disp_run( DerivedMesh *dm, Mesh *me, DerivedMesh *dm2, DispOp op, CCGElem **oldGridData, int totlvl); @@ -241,40 +239,6 @@ static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level) md->hidden = subd; } -static MDisps *multires_mdisps_init_hidden(Mesh *me, int level) -{ - MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); - int gridsize = BKE_ccg_gridsize(level); - int gridarea = square_i(gridsize); - int i, j; - - for (i = 0; i < me->totpoly; i++) { - bool hide = false; - - for (j = 0; j < me->mpoly[i].totloop; j++) { - if (me->mvert[me->mloop[me->mpoly[i].loopstart + j].v].flag & ME_HIDE) { - hide = true; - break; - } - } - - if (!hide) { - continue; - } - - for (j = 0; j < me->mpoly[i].totloop; j++) { - MDisps *md = &mdisps[me->mpoly[i].loopstart + j]; - - BLI_assert(!md->hidden); - - md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden initialize"); - BLI_bitmap_set_all(md->hidden, true, gridarea); - } - } - - return mdisps; -} - Mesh *BKE_multires_create_mesh(struct Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd) @@ -429,12 +393,6 @@ void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl) mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl); } -static void multires_dm_mark_as_modified(DerivedMesh *dm, MultiresModifiedFlags flags) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - ccgdm->multires.modified_flags |= flags; -} - static void multires_ccg_mark_as_modified(SubdivCCG *subdiv_ccg, MultiresModifiedFlags flags) { if (flags & MULTIRES_COORDS_MODIFIED) { @@ -789,7 +747,6 @@ static DerivedMesh *multires_dm_create_local(Scene *scene, DerivedMesh *dm, int lvl, int totlvl, - int simple, bool alloc_paint_mask, int flags) { @@ -799,7 +756,6 @@ static DerivedMesh *multires_dm_create_local(Scene *scene, mmd.sculptlvl = lvl; mmd.renderlvl = lvl; mmd.totlvl = totlvl; - mmd.simple = simple; flags |= MULTIRES_USE_LOCAL_MMD; if (alloc_paint_mask) { @@ -850,110 +806,6 @@ static DerivedMesh *subsurf_dm_create_local(Scene *scene, return subsurf_make_derived_from_derived(dm, &smd, scene, NULL, flags); } -static void multires_subdivide_legacy( - MultiresModifierData *mmd, Scene *scene, Object *ob, int totlvl, int updateblock, int simple) -{ - Mesh *me = ob->data; - MDisps *mdisps; - const int lvl = mmd->totlvl; - - if ((totlvl > multires_max_levels) || (me->totpoly == 0)) { - return; - } - - BLI_assert(totlvl > lvl); - - multires_force_sculpt_rebuild(ob); - - mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); - if (!mdisps) { - mdisps = multires_mdisps_init_hidden(me, totlvl); - } - - if (mdisps->disps && !updateblock && lvl != 0) { - /* upsample */ - DerivedMesh *lowdm, *cddm, *highdm; - CCGElem **highGridData, **lowGridData, **subGridData; - CCGKey highGridKey, lowGridKey; - CCGSubSurf *ss; - int i, numGrids, highGridSize; - const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK); - - /* create subsurf DM from original mesh at high level */ - cddm = CDDM_from_mesh(me); - DM_set_only_copy(cddm, &CD_MASK_BAREMESH); - highdm = subsurf_dm_create_local(NULL, - ob, - cddm, - totlvl, - simple, - 0, - mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, - has_mask, - false, - SUBSURF_IGNORE_SIMPLIFY); - ss = ((CCGDerivedMesh *)highdm)->ss; - - /* create multires DM from original mesh at low level */ - lowdm = multires_dm_create_local( - scene, ob, cddm, lvl, lvl, simple, has_mask, MULTIRES_IGNORE_SIMPLIFY); - BLI_assert(lowdm != cddm); - cddm->release(cddm); - - /* copy subsurf grids and replace them with low displaced grids */ - numGrids = highdm->getNumGrids(highdm); - highGridSize = highdm->getGridSize(highdm); - highGridData = highdm->getGridData(highdm); - highdm->getGridKey(highdm, &highGridKey); - lowGridData = lowdm->getGridData(lowdm); - lowdm->getGridKey(lowdm, &lowGridKey); - - subGridData = MEM_calloc_arrayN(numGrids, sizeof(float *), "subGridData*"); - - for (i = 0; i < numGrids; i++) { - /* backup subsurf grids */ - subGridData[i] = MEM_calloc_arrayN( - highGridKey.elem_size, highGridSize * highGridSize, "subGridData"); - memcpy(subGridData[i], highGridData[i], highGridKey.elem_size * highGridSize * highGridSize); - - /* overwrite with current displaced grids */ - multires_copy_dm_grid(highGridData[i], lowGridData[i], &highGridKey, &lowGridKey); - } - - /* low lower level dm no longer needed at this point */ - lowdm->release(lowdm); - - /* subsurf higher levels again with displaced data */ - ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0); - ccgSubSurf_updateLevels(ss, lvl, NULL, 0); - - /* reallocate displacements */ - multires_reallocate_mdisps(me->totloop, mdisps, totlvl); - - /* compute displacements */ - multiresModifier_disp_run(highdm, me, NULL, CALC_DISPLACEMENTS, subGridData, totlvl); - - /* free */ - highdm->release(highdm); - for (i = 0; i < numGrids; i++) { - MEM_freeN(subGridData[i]); - } - MEM_freeN(subGridData); - } - else { - /* only reallocate, nothing to upsample */ - multires_reallocate_mdisps(me->totloop, mdisps, totlvl); - } - - multires_set_tot_level(ob, mmd, totlvl); -} - -void multiresModifier_subdivide_legacy( - MultiresModifierData *mmd, Scene *scene, Object *ob, int updateblock, int simple) -{ - multires_subdivide_legacy(mmd, scene, ob, mmd->totlvl + 1, updateblock, simple); -} - static void grid_tangent(const CCGKey *key, int x, int y, int axis, CCGElem *grid, float t[3]) { if (axis == 0) { @@ -1227,7 +1079,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene) ob, cddm, totlvl, - mmd->simple, + false, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, @@ -1237,7 +1089,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene) /* create multires DM from original mesh and displacements */ lowdm = multires_dm_create_local( - scene, ob, cddm, lvl, totlvl, mmd->simple, has_mask, MULTIRES_IGNORE_SIMPLIFY); + scene, ob, cddm, lvl, totlvl, has_mask, MULTIRES_IGNORE_SIMPLIFY); cddm->release(cddm); /* gather grid data */ @@ -1302,7 +1154,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene) ob, cddm, mmd->totlvl, - mmd->simple, + false, 0, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, @@ -1400,7 +1252,7 @@ DerivedMesh *multires_make_derived_from_derived( ob, dm, lvl, - mmd->simple, + false, mmd->flags & eMultiresModifierFlag_ControlEdges, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, flags & MULTIRES_ALLOC_PAINT_MASK, @@ -1449,9 +1301,6 @@ DerivedMesh *multires_make_derived_from_derived( return result; } -/**** Old Multires code **** - ***************************/ - /* Adapted from sculptmode.c */ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v) { @@ -1506,723 +1355,6 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, add_v3_v3v3(out, d2[0], d2[1]); } -static void old_mdisps_rotate( - int S, int UNUSED(newside), int oldside, int x, int y, float *u, float *v) -{ - float offset = oldside * 0.5f - 0.5f; - - if (S == 1) { - *u = offset + x; - *v = offset - y; - } - if (S == 2) { - *u = offset + y; - *v = offset + x; - } - if (S == 3) { - *u = offset - x; - *v = offset + y; - } - if (S == 0) { - *u = offset - y; - *v = offset - x; - } -} - -static void old_mdisps_convert(MFace *mface, MDisps *mdisp) -{ - int newlvl = log(sqrt(mdisp->totdisp) - 1) / M_LN2; - int oldlvl = newlvl + 1; - int oldside = multires_side_tot[oldlvl]; - int newside = multires_side_tot[newlvl]; - int nvert = (mface->v4) ? 4 : 3; - int newtotdisp = multires_grid_tot[newlvl] * nvert; - int x, y, S; - float(*disps)[3], (*out)[3], u = 0.0f, v = 0.0f; /* Quite gcc barking. */ - - disps = MEM_calloc_arrayN(newtotdisp, sizeof(float[3]), "multires disps"); - - out = disps; - for (S = 0; S < nvert; S++) { - for (y = 0; y < newside; y++) { - for (x = 0; x < newside; x++, out++) { - old_mdisps_rotate(S, newside, oldside, x, y, &u, &v); - old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v); - - if (S == 1) { - (*out)[1] = -(*out)[1]; - } - else if (S == 2) { - SWAP(float, (*out)[0], (*out)[1]); - } - else if (S == 3) { - (*out)[0] = -(*out)[0]; - } - else if (S == 0) { - SWAP(float, (*out)[0], (*out)[1]); - (*out)[0] = -(*out)[0]; - (*out)[1] = -(*out)[1]; - } - } - } - } - - MEM_freeN(mdisp->disps); - - mdisp->totdisp = newtotdisp; - mdisp->level = newlvl; - mdisp->disps = disps; -} - -void multires_load_old_250(Mesh *me) -{ - MDisps *mdisps, *mdisps2; - MFace *mf; - int i, j, k; - - mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); - - if (mdisps) { - for (i = 0; i < me->totface; i++) { - if (mdisps[i].totdisp) { - old_mdisps_convert(&me->mface[i], &mdisps[i]); - } - } - - CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); - mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS); - - k = 0; - mf = me->mface; - for (i = 0; i < me->totface; i++, mf++) { - int nvert = mf->v4 ? 4 : 3; - int totdisp = mdisps[i].totdisp / nvert; - - for (j = 0; j < nvert; j++, k++) { - mdisps2[k].disps = MEM_calloc_arrayN( - totdisp, sizeof(float[3]), "multires disp in conversion"); - mdisps2[k].totdisp = totdisp; - mdisps2[k].level = mdisps[i].level; - memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp * j, totdisp); - } - } - } -} - -/* Does not actually free lvl itself */ -static void multires_free_level(MultiresLevel *lvl) -{ - if (lvl) { - if (lvl->faces) { - MEM_freeN(lvl->faces); - } - if (lvl->edges) { - MEM_freeN(lvl->edges); - } - if (lvl->colfaces) { - MEM_freeN(lvl->colfaces); - } - } -} - -void multires_free(Multires *mr) -{ - if (mr) { - MultiresLevel *lvl = mr->levels.first; - - /* Free the first-level data */ - if (lvl) { - CustomData_free(&mr->vdata, lvl->totvert); - CustomData_free(&mr->fdata, lvl->totface); - if (mr->edge_flags) { - MEM_freeN(mr->edge_flags); - } - if (mr->edge_creases) { - MEM_freeN(mr->edge_creases); - } - } - - while (lvl) { - multires_free_level(lvl); - lvl = lvl->next; - } - - /* mr->verts may be NULL when loading old files, - * see direct_link_mesh() in readfile.c, and T43560. */ - MEM_SAFE_FREE(mr->verts); - - BLI_freelistN(&mr->levels); - - MEM_freeN(mr); - } -} - -typedef struct IndexNode { - struct IndexNode *next, *prev; - int index; -} IndexNode; - -static void create_old_vert_face_map(ListBase **map, - IndexNode **mem, - const MultiresFace *mface, - const int totvert, - const int totface) -{ - int i, j; - IndexNode *node = NULL; - - (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert face map"); - (*mem) = MEM_calloc_arrayN(totface, sizeof(IndexNode[4]), "vert face map mem"); - node = *mem; - - /* Find the users */ - for (i = 0; i < totface; i++) { - for (j = 0; j < (mface[i].v[3] ? 4 : 3); j++, node++) { - node->index = i; - BLI_addtail(&(*map)[mface[i].v[j]], node); - } - } -} - -static void create_old_vert_edge_map(ListBase **map, - IndexNode **mem, - const MultiresEdge *medge, - const int totvert, - const int totedge) -{ - int i, j; - IndexNode *node = NULL; - - (*map) = MEM_calloc_arrayN(totvert, sizeof(ListBase), "vert edge map"); - (*mem) = MEM_calloc_arrayN(totedge, sizeof(IndexNode[2]), "vert edge map mem"); - node = *mem; - - /* Find the users */ - for (i = 0; i < totedge; i++) { - for (j = 0; j < 2; j++, node++) { - node->index = i; - BLI_addtail(&(*map)[medge[i].v[j]], node); - } - } -} - -static MultiresFace *find_old_face( - ListBase *map, MultiresFace *faces, int v1, int v2, int v3, int v4) -{ - IndexNode *n1; - int v[4], i, j; - - v[0] = v1; - v[1] = v2; - v[2] = v3; - v[3] = v4; - - for (n1 = map[v1].first; n1; n1 = n1->next) { - int fnd[4] = {0, 0, 0, 0}; - - for (i = 0; i < 4; i++) { - for (j = 0; j < 4; j++) { - if (v[i] == faces[n1->index].v[j]) { - fnd[i] = 1; - } - } - } - - if (fnd[0] && fnd[1] && fnd[2] && fnd[3]) { - return &faces[n1->index]; - } - } - - return NULL; -} - -static MultiresEdge *find_old_edge(ListBase *map, MultiresEdge *edges, int v1, int v2) -{ - IndexNode *n1, *n2; - - for (n1 = map[v1].first; n1; n1 = n1->next) { - for (n2 = map[v2].first; n2; n2 = n2->next) { - if (n1->index == n2->index) { - return &edges[n1->index]; - } - } - } - - return NULL; -} - -static void multires_load_old_edges( - ListBase **emap, MultiresLevel *lvl, int *vvmap, int dst, int v1, int v2, int mov) -{ - int emid = find_old_edge(emap[2], lvl->edges, v1, v2)->mid; - vvmap[dst + mov] = emid; - - if (lvl->next->next) { - multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v1, emid, mov / 2); - multires_load_old_edges(emap + 1, lvl->next, vvmap, dst + mov, v2, emid, -mov / 2); - } -} - -static void multires_load_old_faces(ListBase **fmap, - ListBase **emap, - MultiresLevel *lvl, - int *vvmap, - int dst, - int v1, - int v2, - int v3, - int v4, - int st2, - int st3) -{ - int fmid; - int emid13, emid14, emid23, emid24; - - if (lvl && lvl->next) { - fmid = find_old_face(fmap[1], lvl->faces, v1, v2, v3, v4)->mid; - vvmap[dst] = fmid; - - emid13 = find_old_edge(emap[1], lvl->edges, v1, v3)->mid; - emid14 = find_old_edge(emap[1], lvl->edges, v1, v4)->mid; - emid23 = find_old_edge(emap[1], lvl->edges, v2, v3)->mid; - emid24 = find_old_edge(emap[1], lvl->edges, v2, v4)->mid; - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst + st2 * st3 + st3, - fmid, - v2, - emid23, - emid24, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst - st2 * st3 + st3, - emid14, - emid24, - fmid, - v4, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst + st2 * st3 - st3, - emid13, - emid23, - v3, - fmid, - st2, - st3 / 2); - - multires_load_old_faces(fmap + 1, - emap + 1, - lvl->next, - vvmap, - dst - st2 * st3 - st3, - v1, - fmid, - emid13, - emid14, - st2, - st3 / 2); - - if (lvl->next->next) { - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid24, fmid, st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid13, fmid, -st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid14, fmid, -st2 * st3); - multires_load_old_edges(emap, lvl->next, vvmap, dst, emid23, fmid, st2 * st3); - } - } -} - -static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - CCGSubSurf *ss = ccgdm->ss; - CCGElem *vd; - CCGKey key; - int index; - int totvert, totedge, totface; - int gridSize = ccgSubSurf_getGridSize(ss); - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int i = 0; - - dm->getGridKey(dm, &key); - - totface = ccgSubSurf_getNumFaces(ss); - for (index = 0; index < totface; index++) { - CCGFace *f = ccgdm->faceMap[index].face; - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - - vd = ccgSubSurf_getFaceCenterData(f); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - i++; - - for (S = 0; S < numVerts; S++) { - for (x = 1; x < gridSize - 1; x++, i++) { - vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - - for (S = 0; S < numVerts; S++) { - for (y = 1; y < gridSize - 1; y++) { - for (x = 1; x < gridSize - 1; x++, i++) { - vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - } - } - - totedge = ccgSubSurf_getNumEdges(ss); - for (index = 0; index < totedge; index++) { - CCGEdge *e = ccgdm->edgeMap[index].edge; - int x; - - for (x = 1; x < edgeSize - 1; x++, i++) { - vd = ccgSubSurf_getEdgeData(ss, e, x); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - } - } - - totvert = ccgSubSurf_getNumVerts(ss); - for (index = 0; index < totvert; index++) { - CCGVert *v = ccgdm->vertMap[index].vert; - - vd = ccgSubSurf_getVertData(ss, v); - copy_v3_v3(CCG_elem_co(&key, vd), mvert[i].co); - i++; - } - - ccgSubSurf_updateToFaces(ss, 0, NULL, 0); -} - -/* Loads a multires object stored in the old Multires struct into the new format */ -static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl) -{ - MultiresLevel *lvl, *lvl1; - Multires *mr = me->mr; - MVert *vsrc, *vdst; - unsigned int src, dst; - int st_last = multires_side_tot[totlvl - 1] - 1; - int extedgelen = multires_side_tot[totlvl] - 2; - int *vvmap; // inorder for dst, map to src - int crossedgelen; - int s, x, tottri, totquad; - unsigned int i, j, totvert; - - src = 0; - vsrc = mr->verts; - vdst = dm->getVertArray(dm); - totvert = (unsigned int)dm->getNumVerts(dm); - vvmap = MEM_calloc_arrayN(totvert, sizeof(int), "multires vvmap"); - - if (!vvmap) { - return; - } - - lvl1 = mr->levels.first; - /* Load base verts */ - for (i = 0; i < lvl1->totvert; i++) { - vvmap[totvert - lvl1->totvert + i] = src; - src++; - } - - /* Original edges */ - dst = totvert - lvl1->totvert - extedgelen * lvl1->totedge; - for (i = 0; i < lvl1->totedge; i++) { - int ldst = dst + extedgelen * i; - int lsrc = src; - lvl = lvl1->next; - - for (j = 2; j <= mr->level_count; j++) { - int base = multires_side_tot[totlvl - j + 1] - 2; - int skip = multires_side_tot[totlvl - j + 2] - 1; - int st = multires_side_tot[j - 1] - 1; - - for (x = 0; x < st; x++) { - vvmap[ldst + base + x * skip] = lsrc + st * i + x; - } - - lsrc += lvl->totvert - lvl->prev->totvert; - lvl = lvl->next; - } - } - - /* Center points */ - dst = 0; - for (i = 0; i < lvl1->totface; i++) { - int sides = lvl1->faces[i].v[3] ? 4 : 3; - - vvmap[dst] = src + lvl1->totedge + i; - dst += 1 + sides * (st_last - 1) * st_last; - } - - /* The rest is only for level 3 and up */ - if (lvl1->next && lvl1->next->next) { - ListBase **fmap, **emap; - IndexNode **fmem, **emem; - - /* Face edge cross */ - tottri = totquad = 0; - crossedgelen = multires_side_tot[totlvl - 1] - 2; - dst = 0; - for (i = 0; i < lvl1->totface; i++) { - int sides = lvl1->faces[i].v[3] ? 4 : 3; - - lvl = lvl1->next->next; - dst++; - - for (j = 3; j <= mr->level_count; j++) { - int base = multires_side_tot[totlvl - j + 1] - 2; - int skip = multires_side_tot[totlvl - j + 2] - 1; - int st = pow(2, j - 2); - int st2 = pow(2, j - 3); - int lsrc = lvl->prev->totvert; - - /* Skip exterior edge verts */ - lsrc += lvl1->totedge * st; - - /* Skip earlier face edge crosses */ - lsrc += st2 * (tottri * 3 + totquad * 4); - - for (s = 0; s < sides; s++) { - for (x = 0; x < st2; x++) { - vvmap[dst + crossedgelen * (s + 1) - base - x * skip - 1] = lsrc; - lsrc++; - } - } - - lvl = lvl->next; - } - - dst += sides * (st_last - 1) * st_last; - - if (sides == 4) { - totquad++; - } - else { - tottri++; - } - } - - /* calculate vert to edge/face maps for each level (except the last) */ - fmap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires fmap"); - emap = MEM_calloc_arrayN((mr->level_count - 1), sizeof(ListBase *), "multires emap"); - fmem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires fmem"); - emem = MEM_calloc_arrayN((mr->level_count - 1), sizeof(IndexNode *), "multires emem"); - lvl = lvl1; - for (i = 0; i < (unsigned int)mr->level_count - 1; i++) { - create_old_vert_face_map(fmap + i, fmem + i, lvl->faces, lvl->totvert, lvl->totface); - create_old_vert_edge_map(emap + i, emem + i, lvl->edges, lvl->totvert, lvl->totedge); - lvl = lvl->next; - } - - /* Interior face verts */ - /* lvl = lvl1->next->next; */ /* UNUSED */ - dst = 0; - for (j = 0; j < lvl1->totface; j++) { - int sides = lvl1->faces[j].v[3] ? 4 : 3; - int ldst = dst + 1 + sides * (st_last - 1); - - for (s = 0; s < sides; s++) { - int st2 = multires_side_tot[totlvl - 1] - 2; - int st3 = multires_side_tot[totlvl - 2] - 2; - int st4 = st3 == 0 ? 1 : (st3 + 1) / 2; - int mid = ldst + st2 * st3 + st3; - int cv = lvl1->faces[j].v[s]; - int nv = lvl1->faces[j].v[s == sides - 1 ? 0 : s + 1]; - int pv = lvl1->faces[j].v[s == 0 ? sides - 1 : s - 1]; - - multires_load_old_faces(fmap, - emap, - lvl1->next, - vvmap, - mid, - vvmap[dst], - cv, - find_old_edge(emap[0], lvl1->edges, pv, cv)->mid, - find_old_edge(emap[0], lvl1->edges, cv, nv)->mid, - st2, - st4); - - ldst += (st_last - 1) * (st_last - 1); - } - - dst = ldst; - } - - /*lvl = lvl->next;*/ /*UNUSED*/ - - for (i = 0; i < (unsigned int)(mr->level_count - 1); i++) { - MEM_freeN(fmap[i]); - MEM_freeN(fmem[i]); - MEM_freeN(emap[i]); - MEM_freeN(emem[i]); - } - - MEM_freeN(fmap); - MEM_freeN(emap); - MEM_freeN(fmem); - MEM_freeN(emem); - } - - /* Transfer verts */ - for (i = 0; i < totvert; i++) { - copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co); - } - - MEM_freeN(vvmap); - - multires_mvert_to_ss(dm, vdst); -} - -/* Copy the first-level vcol data to the mesh, if it exists */ -/* Warning: higher-level vcol data will be lost */ -static void multires_load_old_vcols(Mesh *me) -{ - MultiresLevel *lvl; - MultiresColFace *colface; - MCol *mcol; - int i, j; - - if (!(lvl = me->mr->levels.first)) { - return; - } - - if (!(colface = lvl->colfaces)) { - return; - } - - /* older multires format never supported multiple vcol layers, - * so we can assume the active vcol layer is the correct one */ - if (!(mcol = CustomData_get_layer(&me->fdata, CD_MCOL))) { - return; - } - - for (i = 0; i < me->totface; i++) { - for (j = 0; j < 4; j++) { - mcol[i * 4 + j].a = colface[i].col[j].a; - mcol[i * 4 + j].r = colface[i].col[j].r; - mcol[i * 4 + j].g = colface[i].col[j].g; - mcol[i * 4 + j].b = colface[i].col[j].b; - } - } -} - -/* Copy the first-level face-flag data to the mesh */ -static void multires_load_old_face_flags(Mesh *me) -{ - MultiresLevel *lvl; - MultiresFace *faces; - int i; - - if (!(lvl = me->mr->levels.first)) { - return; - } - - if (!(faces = lvl->faces)) { - return; - } - - for (i = 0; i < me->totface; i++) { - me->mface[i].flag = faces[i].flag; - } -} - -void multires_load_old(Object *ob, Mesh *me) -{ - MultiresLevel *lvl; - ModifierData *md; - MultiresModifierData *mmd; - DerivedMesh *dm, *orig; - CustomDataLayer *l; - int i; - - /* Load original level into the mesh */ - lvl = me->mr->levels.first; - CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert); - CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge); - CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface); - me->totvert = lvl->totvert; - me->totedge = lvl->totedge; - me->totface = lvl->totface; - me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert); - for (i = 0; i < me->totedge; i++) { - me->medge[i].v1 = lvl->edges[i].v[0]; - me->medge[i].v2 = lvl->edges[i].v[1]; - } - for (i = 0; i < me->totface; i++) { - me->mface[i].v1 = lvl->faces[i].v[0]; - me->mface[i].v2 = lvl->faces[i].v[1]; - me->mface[i].v3 = lvl->faces[i].v[2]; - me->mface[i].v4 = lvl->faces[i].v[3]; - me->mface[i].mat_nr = lvl->faces[i].mat_nr; - } - - /* Copy the first-level data to the mesh */ - /* XXX We must do this before converting tessfaces to polys/lopps! */ - for (i = 0, l = me->mr->vdata.layers; i < me->mr->vdata.totlayer; i++, l++) { - CustomData_add_layer(&me->vdata, l->type, CD_REFERENCE, l->data, me->totvert); - } - for (i = 0, l = me->mr->fdata.layers; i < me->mr->fdata.totlayer; i++, l++) { - CustomData_add_layer(&me->fdata, l->type, CD_REFERENCE, l->data, me->totface); - } - CustomData_reset(&me->mr->vdata); - CustomData_reset(&me->mr->fdata); - - multires_load_old_vcols(me); - multires_load_old_face_flags(me); - - /* multiresModifier_subdivide_legacy (actually, multires_subdivide_legacy) expects polys, not - * tessfaces! */ - BKE_mesh_convert_mfaces_to_mpolys(me); - - /* Add a multires modifier to the object */ - md = ob->modifiers.first; - while (md && BKE_modifier_get_info(md->type)->type == eModifierTypeType_OnlyDeform) { - md = md->next; - } - mmd = (MultiresModifierData *)BKE_modifier_new(eModifierType_Multires); - BLI_insertlinkbefore(&ob->modifiers, md, mmd); - - for (i = 0; i < me->mr->level_count - 1; i++) { - multiresModifier_subdivide_legacy(mmd, NULL, ob, 1, 0); - } - - mmd->lvl = mmd->totlvl; - orig = CDDM_from_mesh(me); - /* XXX We *must* alloc paint mask here, else we have some kind of mismatch in - * multires_modifier_update_mdisps() (called by dm->release(dm)), which always creates the - * reference subsurfed dm with this option, before calling multiresModifier_disp_run(), - * which implicitly expects both subsurfs from its first dm and oldGridData parameters to - * be of the same "format"! */ - dm = multires_make_derived_from_derived(orig, mmd, NULL, ob, 0); - - multires_load_old_dm(dm, me, mmd->totlvl + 1); - - multires_dm_mark_as_modified(dm, MULTIRES_COORDS_MODIFIED); - dm->release(dm); - orig->release(orig); - - /* Remove the old multires */ - multires_free(me->mr); - me->mr = NULL; -} - /* If 'ob_src' and 'ob_dst' both have multires modifiers, synchronize them * such that 'ob_dst' has the same total number of levels as 'ob_src'. */ void multiresModifier_sync_levels_ex(Object *ob_dst, @@ -2234,14 +1366,8 @@ void multiresModifier_sync_levels_ex(Object *ob_dst, } if (mmd_src->totlvl > mmd_dst->totlvl) { - if (mmd_dst->simple) { - multiresModifier_subdivide_to_level( - ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_SIMPLE); - } - else { - multiresModifier_subdivide_to_level( - ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK); - } + multiresModifier_subdivide_to_level( + ob_dst, mmd_dst, mmd_src->totlvl, MULTIRES_SUBDIVIDE_CATMULL_CLARK); } else { multires_del_higher(mmd_dst, ob_dst, mmd_src->totlvl); diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.c index 5bcf8f62f86..04ad78ec0de 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.c @@ -225,7 +225,7 @@ void multiresModifier_subdivide_to_level(struct Object *object, multires_flush_sculpt_updates(object); - if (!multires_reshape_context_create_from_subdivide(&reshape_context, object, mmd, top_level)) { + if (!multires_reshape_context_create_from_modifier(&reshape_context, object, mmd, top_level)) { return; } diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h index d6c1d79dfd7..36ecf1a6395 100644 --- a/source/blender/blenkernel/intern/multires_reshape.h +++ b/source/blender/blenkernel/intern/multires_reshape.h @@ -167,10 +167,16 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co struct Mesh *base_mesh, int top_level); -bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *reshape_context, - struct Object *object, - struct MultiresModifierData *mmd, - int top_level); +bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context, + struct Object *object, + struct MultiresModifierData *mmd, + int top_level); + +bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context, + struct Object *object, + struct MultiresModifierData *mmd, + struct Subdiv *subdiv, + int top_level); void multires_reshape_free_original_grids(MultiresReshapeContext *reshape_context); void multires_reshape_context_free(MultiresReshapeContext *reshape_context); diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index 6e7e2b90c05..b693b1114ba 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -81,11 +81,6 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context) { - if (reshape_context->mmd->simple) { - /* Simple subdivisions does not move base mesh verticies, so no refitting is needed. */ - return; - } - Mesh *base_mesh = reshape_context->base_mesh; MeshElemMap *pmap; diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c index 7b7c1efc533..d42a061084f 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c @@ -96,7 +96,7 @@ void multires_subdivide_create_tangent_displacement_linear_grids(Object *object, /* Convert the new grids to tangent displacement. */ multires_set_tot_level(object, mmd, new_top_level); - if (!multires_reshape_context_create_from_subdivide( + if (!multires_reshape_context_create_from_modifier( &reshape_context, object, mmd, new_top_level)) { return; } diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c index c8179dd8a2d..8fb406e54a5 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.c @@ -242,10 +242,26 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co return context_verify_or_free(reshape_context); } -bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *reshape_context, - struct Object *object, - struct MultiresModifierData *mmd, - int top_level) +bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context, + struct Object *object, + struct MultiresModifierData *mmd, + int top_level) +{ + Subdiv *subdiv = multires_reshape_create_subdiv(NULL, object, mmd); + + const bool result = multires_reshape_context_create_from_subdiv( + reshape_context, object, mmd, subdiv, top_level); + + reshape_context->need_free_subdiv = true; + + return result; +} + +bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context, + struct Object *object, + struct MultiresModifierData *mmd, + struct Subdiv *subdiv, + int top_level) { context_zero(reshape_context); @@ -254,8 +270,8 @@ bool multires_reshape_context_create_from_subdivide(MultiresReshapeContext *resh reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; - reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd); - reshape_context->need_free_subdiv = true; + reshape_context->subdiv = subdiv; + reshape_context->need_free_subdiv = false; reshape_context->reshape.level = mmd->totlvl; reshape_context->reshape.grid_size = BKE_subdiv_grid_size_from_level( diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.c index 73ef623fbfd..8156814d9f1 100644 --- a/source/blender/blenkernel/intern/multires_subdiv.c +++ b/source/blender/blenkernel/intern/multires_subdiv.c @@ -36,7 +36,7 @@ void BKE_multires_subdiv_settings_init(SubdivSettings *settings, const MultiresModifierData *mmd) { - settings->is_simple = (mmd->simple != 0); + settings->is_simple = false; settings->is_adaptive = true; settings->level = settings->is_simple ? 1 : mmd->quality; settings->use_creases = (mmd->flags & eMultiresModifierFlag_UseCrease); diff --git a/source/blender/blenkernel/intern/multires_versioning.c b/source/blender/blenkernel/intern/multires_versioning.c new file mode 100644 index 00000000000..4c0d7165cd0 --- /dev/null +++ b/source/blender/blenkernel/intern/multires_versioning.c @@ -0,0 +1,106 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2020 by Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_mesh_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BKE_subdiv.h" +#include "BKE_subdiv_eval.h" + +#include "multires_reshape.h" +#include "opensubdiv_converter_capi.h" +#include "subdiv_converter.h" + +static float simple_to_catmull_clark_get_edge_sharpness( + const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_edge_index)) +{ + return 10.0f; +} + +static bool simple_to_catmull_clark_is_infinite_sharp_vertex( + const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_vertex_index)) +{ + return true; +} + +static Subdiv *subdiv_for_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd) +{ + SubdivSettings subdiv_settings; + BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); + + Mesh *base_mesh = object->data; + + OpenSubdiv_Converter converter; + BKE_subdiv_converter_init_for_mesh(&converter, &subdiv_settings, base_mesh); + converter.getEdgeSharpness = simple_to_catmull_clark_get_edge_sharpness; + converter.isInfiniteSharpVertex = simple_to_catmull_clark_is_infinite_sharp_vertex; + + Subdiv *subdiv = BKE_subdiv_new_from_converter(&subdiv_settings, &converter); + BKE_subdiv_converter_free(&converter); + + if (!BKE_subdiv_eval_begin_from_mesh(subdiv, base_mesh, NULL)) { + BKE_subdiv_free(subdiv); + return NULL; + } + + return subdiv; +} + +void multires_do_versions_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd) +{ + const Mesh *base_mesh = object->data; + if (base_mesh->totloop == 0) { + return; + } + + /* Store the grids displacement in object space against the simple limit surface. */ + { + Subdiv *subdiv = subdiv_for_simple_to_catmull_clark(object, mmd); + MultiresReshapeContext reshape_context; + if (!multires_reshape_context_create_from_subdiv( + &reshape_context, object, mmd, subdiv, mmd->totlvl)) { + BKE_subdiv_free(subdiv); + return; + } + + multires_reshape_store_original_grids(&reshape_context); + multires_reshape_assign_final_coords_from_mdisps(&reshape_context); + multires_reshape_context_free(&reshape_context); + + BKE_subdiv_free(subdiv); + } + + /* Calculate the new tangent displacement against the new Catmull-Clark limit surface. */ + { + MultiresReshapeContext reshape_context; + if (!multires_reshape_context_create_from_modifier( + &reshape_context, object, mmd, mmd->totlvl)) { + return; + } + multires_reshape_object_grids_to_tangent_displacement(&reshape_context); + multires_reshape_context_free(&reshape_context); + } +} diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 80a553ff525..e2e61284d2e 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -404,6 +404,8 @@ static void write_node_socket_interface(BlendWriter *writer, bNodeSocket *sock) /* this is only direct data, tree itself should have been written */ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) { + BKE_id_blend_write(writer, &ntree->id); + /* for link_list() speed, we write per list */ if (ntree->adt) { @@ -525,9 +527,6 @@ static void ntree_blend_write(BlendWriter *writer, ID *id, const void *id_addres ntree->execdata = NULL; BLO_write_id_struct(writer, bNodeTree, id_address, &ntree->id); - /* Note that trees directly used by other IDs (materials etc.) are not 'real' ID, they cannot - * be linked, etc., so we write actual id data here only, for 'real' ID trees. */ - BKE_id_blend_write(writer, &ntree->id); ntreeBlendWrite(writer, ntree); } @@ -853,6 +852,8 @@ IDTypeInfo IDType_ID_NT = { .blend_read_data = ntree_blend_read_data, .blend_read_lib = ntree_blend_read_lib, .blend_read_expand = ntree_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) @@ -4662,7 +4663,7 @@ static void registerFunctionNodes(void) register_node_type_fn_random_float(); } -void init_nodesystem(void) +void BKE_node_system_init(void) { nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh"); nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh"); @@ -4689,7 +4690,7 @@ void init_nodesystem(void) registerFunctionNodes(); } -void free_nodesystem(void) +void BKE_node_system_exit(void) { if (nodetypes_hash) { NODE_TYPES_BEGIN (nt) { diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 398860b6796..f658594d878 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -123,7 +123,6 @@ #include "BKE_pointcloud.h" #include "BKE_rigidbody.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_shader_fx.h" #include "BKE_softbody.h" #include "BKE_speaker.h" @@ -136,6 +135,8 @@ #include "DRW_engine.h" +#include "SEQ_sequencer.h" + #ifdef WITH_PYTHON # include "BPY_extern.h" #endif @@ -537,6 +538,8 @@ IDTypeInfo IDType_ID_OB = { .blend_read_data = NULL, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; void BKE_object_workob_clear(Object *workob) diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index 04f7529c6cd..1e7624d0d7d 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -51,6 +51,7 @@ #include "BKE_object.h" #include "BKE_object_deform.h" /* own include */ +/* -------------------------------------------------------------------- */ /** \name Misc helpers * \{ */ @@ -106,6 +107,7 @@ void BKE_object_defgroup_remap_update_users(Object *ob, const int *map) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Group creation * \{ */ @@ -156,6 +158,7 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Group clearing * \{ */ @@ -256,6 +259,7 @@ bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Group removal * \{ */ diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c index 39d6ee2700c..a1b01bce6c9 100644 --- a/source/blender/blenkernel/intern/object_dupli.c +++ b/source/blender/blenkernel/intern/object_dupli.c @@ -1392,7 +1392,7 @@ static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem mat4_to_size(original_size, obmat); size_to_mat4(size_mat, original_size); - xvec[0] = -1.f; + xvec[0] = -1.0f; xvec[1] = xvec[2] = 0; vec_to_quat(q, xvec, ob->trackflag, ob->upflag); quat_to_mat4(obmat, q); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 42749a93988..f2af5520d16 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -125,6 +125,16 @@ static void palette_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_list(reader, &palette->colors); } +static void palette_undo_preserve(BlendLibReader *UNUSED(reader), ID *id_new, ID *id_old) +{ + /* Whole Palette is preserved accross undo's, and it has no extra pointer, simple. */ + /* Note: We do not care about potential internal references to self here, Palette has none. */ + /* Note: We do not swap IDProperties, as dealing with potential ID pointers in those would be + * fairly delicate. */ + BKE_lib_id_swap(NULL, id_new, id_old); + SWAP(IDProperty *, id_new->properties, id_old->properties); +} + IDTypeInfo IDType_ID_PAL = { .id_code = ID_PAL, .id_filter = FILTER_ID_PAL, @@ -146,6 +156,8 @@ IDTypeInfo IDType_ID_PAL = { .blend_read_data = palette_blend_read_data, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = palette_undo_preserve, }; static void paint_curve_copy_data(Main *UNUSED(bmain), @@ -207,6 +219,8 @@ IDTypeInfo IDType_ID_PC = { .blend_read_data = paint_curve_blend_read_data, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; const char PAINT_CURSOR_SCULPT[3] = {255, 100, 100}; @@ -1734,17 +1748,16 @@ void BKE_sculpt_color_layer_create_if_needed(struct Object *object) DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY); } +/** \warning Expects a fully evaluated depsgraph. */ void BKE_sculpt_update_object_for_edit( Depsgraph *depsgraph, Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors) { - /* Update from sculpt operators and undo, to update sculpt session - * and PBVH after edits. */ - Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig); - Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); - BLI_assert(ob_orig == DEG_get_original_object(ob_orig)); + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_orig); + Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); + BLI_assert(me_eval != NULL); + sculpt_update_object(depsgraph, ob_orig, me_eval, need_pmap, need_mask, need_colors); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 7b8ee7343ee..d323849d72d 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -21,6 +21,9 @@ * \ingroup bke */ +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #include <math.h> #include <stdlib.h> #include <string.h> @@ -52,6 +55,7 @@ #include "BLT_translation.h" +#include "BKE_anim_data.h" #include "BKE_anim_path.h" #include "BKE_boids.h" #include "BKE_cloth.h" @@ -80,6 +84,8 @@ #include "RE_render_ext.h" +#include "BLO_read_write.h" + #include "particle_private.h" static void fluid_free_settings(SPHFluidSettings *fluid); @@ -206,6 +212,279 @@ static void particle_settings_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void write_boid_state(BlendWriter *writer, BoidState *state) +{ + BLO_write_struct(writer, BoidState, state); + + LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { + switch (rule->type) { + case eBoidRuleType_Goal: + case eBoidRuleType_Avoid: + BLO_write_struct(writer, BoidRuleGoalAvoid, rule); + break; + case eBoidRuleType_AvoidCollision: + BLO_write_struct(writer, BoidRuleAvoidCollision, rule); + break; + case eBoidRuleType_FollowLeader: + BLO_write_struct(writer, BoidRuleFollowLeader, rule); + break; + case eBoidRuleType_AverageSpeed: + BLO_write_struct(writer, BoidRuleAverageSpeed, rule); + break; + case eBoidRuleType_Fight: + BLO_write_struct(writer, BoidRuleFight, rule); + break; + default: + BLO_write_struct(writer, BoidRule, rule); + break; + } + } +#if 0 + BoidCondition *cond = state->conditions.first; + for (; cond; cond = cond->next) { + BLO_write_struct(writer, BoidCondition, cond); + } +#endif +} + +static void particle_settings_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + ParticleSettings *part = (ParticleSettings *)id; + if (part->id.us > 0 || BLO_write_is_undo(writer)) { + /* write LibData */ + BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id); + BKE_id_blend_write(writer, &part->id); + + if (part->adt) { + BKE_animdata_blend_write(writer, part->adt); + } + BLO_write_struct(writer, PartDeflect, part->pd); + BLO_write_struct(writer, PartDeflect, part->pd2); + BLO_write_struct(writer, EffectorWeights, part->effector_weights); + + if (part->clumpcurve) { + BKE_curvemapping_blend_write(writer, part->clumpcurve); + } + if (part->roughcurve) { + BKE_curvemapping_blend_write(writer, part->roughcurve); + } + if (part->twistcurve) { + BKE_curvemapping_blend_write(writer, part->twistcurve); + } + + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { + /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ + if (dw->ob != NULL) { + dw->index = 0; + if (part->instance_collection) { /* can be NULL if lining fails or set to None */ + FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) { + if (object == dw->ob) { + break; + } + dw->index++; + } + FOREACH_COLLECTION_OBJECT_RECURSIVE_END; + } + } + BLO_write_struct(writer, ParticleDupliWeight, dw); + } + + if (part->boids && part->phystype == PART_PHYS_BOIDS) { + BLO_write_struct(writer, BoidSettings, part->boids); + + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { + write_boid_state(writer, state); + } + } + if (part->fluid && part->phystype == PART_PHYS_FLUID) { + BLO_write_struct(writer, SPHFluidSettings, part->fluid); + } + + for (int a = 0; a < MAX_MTEX; a++) { + if (part->mtex[a]) { + BLO_write_struct(writer, MTex, part->mtex[a]); + } + } + } +} + +void BKE_particle_partdeflect_blend_read_data(BlendDataReader *UNUSED(reader), PartDeflect *pd) +{ + if (pd) { + pd->rng = NULL; + } +} + +static void particle_settings_blend_read_data(BlendDataReader *reader, ID *id) +{ + ParticleSettings *part = (ParticleSettings *)id; + BLO_read_data_address(reader, &part->adt); + BLO_read_data_address(reader, &part->pd); + BLO_read_data_address(reader, &part->pd2); + + BKE_animdata_blend_read_data(reader, part->adt); + BKE_particle_partdeflect_blend_read_data(reader, part->pd); + BKE_particle_partdeflect_blend_read_data(reader, part->pd2); + + BLO_read_data_address(reader, &part->clumpcurve); + if (part->clumpcurve) { + BKE_curvemapping_blend_read(reader, part->clumpcurve); + } + BLO_read_data_address(reader, &part->roughcurve); + if (part->roughcurve) { + BKE_curvemapping_blend_read(reader, part->roughcurve); + } + BLO_read_data_address(reader, &part->twistcurve); + if (part->twistcurve) { + BKE_curvemapping_blend_read(reader, part->twistcurve); + } + + BLO_read_data_address(reader, &part->effector_weights); + if (!part->effector_weights) { + part->effector_weights = BKE_effector_add_weights(part->force_group); + } + + BLO_read_list(reader, &part->instance_weights); + + BLO_read_data_address(reader, &part->boids); + BLO_read_data_address(reader, &part->fluid); + + if (part->boids) { + BLO_read_list(reader, &part->boids->states); + + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { + BLO_read_list(reader, &state->rules); + BLO_read_list(reader, &state->conditions); + BLO_read_list(reader, &state->actions); + } + } + for (int a = 0; a < MAX_MTEX; a++) { + BLO_read_data_address(reader, &part->mtex[a]); + } + + /* Protect against integer overflow vulnerability. */ + CLAMP(part->trail_count, 1, 100000); +} + +void BKE_particle_partdeflect_blend_read_lib(BlendLibReader *reader, ID *id, PartDeflect *pd) +{ + if (pd && pd->tex) { + BLO_read_id_address(reader, id->lib, &pd->tex); + } + if (pd && pd->f_source) { + BLO_read_id_address(reader, id->lib, &pd->f_source); + } +} + +static void particle_settings_blend_read_lib(BlendLibReader *reader, ID *id) +{ + ParticleSettings *part = (ParticleSettings *)id; + BLO_read_id_address( + reader, part->id.lib, &part->ipo); /* XXX deprecated - old animation system */ + + BLO_read_id_address(reader, part->id.lib, &part->instance_object); + BLO_read_id_address(reader, part->id.lib, &part->instance_collection); + BLO_read_id_address(reader, part->id.lib, &part->force_group); + BLO_read_id_address(reader, part->id.lib, &part->bb_ob); + BLO_read_id_address(reader, part->id.lib, &part->collision_group); + + BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd); + BKE_particle_partdeflect_blend_read_lib(reader, &part->id, part->pd2); + + if (part->effector_weights) { + BLO_read_id_address(reader, part->id.lib, &part->effector_weights->group); + } + else { + part->effector_weights = BKE_effector_add_weights(part->force_group); + } + + if (part->instance_weights.first && part->instance_collection) { + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { + BLO_read_id_address(reader, part->id.lib, &dw->ob); + } + } + else { + BLI_listbase_clear(&part->instance_weights); + } + + if (part->boids) { + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { + LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { + switch (rule->type) { + case eBoidRuleType_Goal: + case eBoidRuleType_Avoid: { + BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule; + BLO_read_id_address(reader, part->id.lib, &brga->ob); + break; + } + case eBoidRuleType_FollowLeader: { + BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule; + BLO_read_id_address(reader, part->id.lib, &brfl->ob); + break; + } + } + } + } + } + + for (int a = 0; a < MAX_MTEX; a++) { + MTex *mtex = part->mtex[a]; + if (mtex) { + BLO_read_id_address(reader, part->id.lib, &mtex->tex); + BLO_read_id_address(reader, part->id.lib, &mtex->object); + } + } +} + +static void particle_settings_blend_read_expand(BlendExpander *expander, ID *id) +{ + ParticleSettings *part = (ParticleSettings *)id; + BLO_expand(expander, part->instance_object); + BLO_expand(expander, part->instance_collection); + BLO_expand(expander, part->force_group); + BLO_expand(expander, part->bb_ob); + BLO_expand(expander, part->collision_group); + + for (int a = 0; a < MAX_MTEX; a++) { + if (part->mtex[a]) { + BLO_expand(expander, part->mtex[a]->tex); + BLO_expand(expander, part->mtex[a]->object); + } + } + + if (part->effector_weights) { + BLO_expand(expander, part->effector_weights->group); + } + + if (part->pd) { + BLO_expand(expander, part->pd->tex); + BLO_expand(expander, part->pd->f_source); + } + if (part->pd2) { + BLO_expand(expander, part->pd2->tex); + BLO_expand(expander, part->pd2->f_source); + } + + if (part->boids) { + LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { + LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { + if (rule->type == eBoidRuleType_Avoid) { + BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule; + BLO_expand(expander, gabr->ob); + } + else if (rule->type == eBoidRuleType_FollowLeader) { + BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule; + BLO_expand(expander, flbr->ob); + } + } + } + } + + LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { + BLO_expand(expander, dw->ob); + } +} + IDTypeInfo IDType_ID_PA = { .id_code = ID_PA, .id_filter = FILTER_ID_PA, @@ -223,17 +502,19 @@ IDTypeInfo IDType_ID_PA = { .foreach_id = particle_settings_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = particle_settings_blend_write, + .blend_read_data = particle_settings_blend_read_data, + .blend_read_lib = particle_settings_blend_read_lib, + .blend_read_expand = particle_settings_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; unsigned int PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT]; unsigned int PSYS_FRAND_SEED_MULTIPLIER[PSYS_FRAND_COUNT]; float PSYS_FRAND_BASE[PSYS_FRAND_COUNT]; -void psys_init_rng(void) +void BKE_particle_init_rng(void) { RNG *rng = BLI_rng_new_srandom(5831); /* arbitrary */ for (int i = 0; i < PSYS_FRAND_COUNT; i++) { @@ -917,7 +1198,7 @@ static float interpolate_particle_value( value += w[3] * v4; } - CLAMP(value, 0.f, 1.f); + CLAMP(value, 0.0f, 1.0f); return value; } @@ -1146,7 +1427,7 @@ static void do_particle_interpolation(ParticleSystem *psys, PTCacheEditPoint *point = pind->epoint; ParticleKey keys[4]; int point_vel = (point && point->keys->vel); - float real_t, dfra, keytime, invdt = 1.f; + float real_t, dfra, keytime, invdt = 1.0f; /* billboards wont fill in all of these, so start cleared */ memset(keys, 0, sizeof(keys)); @@ -1316,7 +1597,7 @@ static void do_particle_interpolation(ParticleSystem *psys, /* Convert velocity to time-step size. */ if (pind->keyed || pind->cache || point_vel) { - invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.f); + invdt = dfra * 0.04f * (psys ? psys->part->timetweak : 1.0f); mul_v3_fl(keys[1].vel, invdt); mul_v3_fl(keys[2].vel, invdt); interp_qt_qtqt(result->rot, keys[1].rot, keys[2].rot, keytime); @@ -1335,7 +1616,7 @@ static void do_particle_interpolation(ParticleSystem *psys, /* the velocity needs to be converted back from cubic interpolation */ if (pind->keyed || pind->cache || point_vel) { - mul_v3_fl(result->vel, 1.f / invdt); + mul_v3_fl(result->vel, 1.0f / invdt); } } @@ -2200,7 +2481,7 @@ int do_guides(Depsgraph *depsgraph, pd->kink_freq, pd->kink_shape, pd->kink_amp, - 0.f, + 0.0f, pd->kink, pd->kink_axis, 0, @@ -2550,12 +2831,12 @@ static void psys_thread_create_path(ParticleTask *task, if (ctx->between) { ParticleData *pa = psys->particles + cpa->pa[0]; int w, needupdate; - float foffset, wsum = 0.f; + float foffset, wsum = 0.0f; float co[3]; float p_min = part->parting_min; float p_max = part->parting_max; /* Virtual parents don't work nicely with parting. */ - float p_fac = part->parents > 0.f ? 0.f : part->parting_fac; + float p_fac = part->parents > 0.0f ? 0.0f : part->parting_fac; if (ctx->editupdate) { needupdate = 0; @@ -2583,15 +2864,15 @@ static void psys_thread_create_path(ParticleTask *task, } else { key[w] = pcache[0]; - weight[w] = 0.f; + weight[w] = 0.0f; } } /* modify weights to create parting */ - if (p_fac > 0.f) { + if (p_fac > 0.0f) { const ParticleCacheKey *key_0_last = pcache_key_segment_endpoint_safe(key[0]); for (w = 0; w < 4; w++) { - if (w && (weight[w] > 0.f)) { + if (w && (weight[w] > 0.0f)) { const ParticleCacheKey *key_w_last = pcache_key_segment_endpoint_safe(key[w]); float d; if (part->flag & PART_CHILD_LONG_HAIR) { @@ -2600,7 +2881,7 @@ static void psys_thread_create_path(ParticleTask *task, float d1 = len_v3v3(key[0]->co, key[w]->co); float d2 = len_v3v3(key_0_last->co, key_w_last->co); - d = d1 > 0.f ? d2 / d1 - 1.f : 10000.f; + d = d1 > 0.0f ? d2 / d1 - 1.0f : 10000.0f; } else { float v1[3], v2[3]; @@ -2616,13 +2897,13 @@ static void psys_thread_create_path(ParticleTask *task, d = (d - p_min) / (p_max - p_min); } else { - d = (d - p_min) <= 0.f ? 0.f : 1.f; + d = (d - p_min) <= 0.0f ? 0.0f : 1.0f; } - CLAMP(d, 0.f, 1.f); + CLAMP(d, 0.0f, 1.0f); - if (d > 0.f) { - weight[w] *= (1.f - d); + if (d > 0.0f) { + weight[w] *= (1.0f - d); } } wsum += weight[w]; @@ -3059,7 +3340,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re LOOP_PARTICLES { if (!psys->totchild) { - psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); + psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.0f); pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); if (vg_length) { pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); @@ -3716,19 +3997,25 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob if (psys->part->type == PART_FLUID_FLIP) { fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FLIP; } - if (psys->part->type == PART_FLUID_SPRAY || psys->part->type == PART_FLUID_SPRAYFOAM || - psys->part->type == PART_FLUID_SPRAYBUBBLE || - psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) { + if (ELEM(psys->part->type, + PART_FLUID_SPRAY, + PART_FLUID_SPRAYFOAM, + PART_FLUID_SPRAYBUBBLE, + PART_FLUID_SPRAYFOAMBUBBLE)) { fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_SPRAY; } - if (psys->part->type == PART_FLUID_FOAM || psys->part->type == PART_FLUID_SPRAYFOAM || - psys->part->type == PART_FLUID_FOAMBUBBLE || - psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) { + if (ELEM(psys->part->type, + PART_FLUID_FOAM, + PART_FLUID_SPRAYFOAM, + PART_FLUID_FOAMBUBBLE, + PART_FLUID_SPRAYFOAMBUBBLE)) { fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_FOAM; } - if (psys->part->type == PART_FLUID_BUBBLE || psys->part->type == PART_FLUID_FOAMBUBBLE || - psys->part->type == PART_FLUID_SPRAYBUBBLE || - psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) { + if (ELEM(psys->part->type, + PART_FLUID_BUBBLE, + PART_FLUID_FOAMBUBBLE, + PART_FLUID_SPRAYBUBBLE, + PART_FLUID_SPRAYFOAMBUBBLE)) { fmd->domain->particle_type &= ~FLUID_DOMAIN_PARTICLE_BUBBLE; } if (psys->part->type == PART_FLUID_TRACER) { @@ -3736,9 +4023,11 @@ void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob } /* Disable combined export if combined particle system was deleted. */ - if (psys->part->type == PART_FLUID_SPRAYFOAM || psys->part->type == PART_FLUID_SPRAYBUBBLE || - psys->part->type == PART_FLUID_FOAMBUBBLE || - psys->part->type == PART_FLUID_SPRAYFOAMBUBBLE) { + if (ELEM(psys->part->type, + PART_FLUID_SPRAYFOAM, + PART_FLUID_SPRAYBUBBLE, + PART_FLUID_FOAMBUBBLE, + PART_FLUID_SPRAYFOAMBUBBLE)) { fmd->domain->sndparticle_combined_export = SNDPARTICLE_COMBINED_EXPORT_OFF; } } @@ -3992,9 +4281,9 @@ static void get_cpa_texture(Mesh *mesh, break; case TEXCO_PARTICLE: /* texture coordinates in range [-1, 1] */ - texvec[0] = 2.f * (cfra - par->time) / (par->dietime - par->time) - 1.f; - texvec[1] = 0.f; - texvec[2] = 0.f; + texvec[0] = 2.0f * (cfra - par->time) / (par->dietime - par->time) - 1.0f; + texvec[1] = 0.0f; + texvec[2] = 0.0f; break; } @@ -4102,14 +4391,15 @@ void psys_get_texture( break; case TEXCO_PARTICLE: /* texture coordinates in range [-1, 1] */ - texvec[0] = 2.f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.f; + texvec[0] = 2.0f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.0f; if (sim->psys->totpart > 0) { - texvec[1] = 2.f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart - 1.f; + texvec[1] = 2.0f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart - + 1.0f; } else { texvec[1] = 0.0f; } - texvec[2] = 0.f; + texvec[2] = 0.0f; break; } @@ -4654,8 +4944,8 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta else { float dfra, frs_sec = sim->scene->r.frs_sec; /* let's interpolate to try to be as accurate as possible */ - if (pa->state.time + 2.f >= state->time && pa->prev_state.time - 2.f <= state->time) { - if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.f) { + if (pa->state.time + 2.0f >= state->time && pa->prev_state.time - 2.0f <= state->time) { + if (pa->prev_state.time >= pa->state.time || pa->prev_state.time < 0.0f) { /* prev_state is wrong so let's not use it, * this can happen at frames 1, 0 or particle birth. */ dfra = state->time - pa->state.time; @@ -4682,13 +4972,13 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta psys_interpolate_particle(-1, keys, keytime, state, 1); /* convert back to real velocity */ - mul_v3_fl(state->vel, 1.f / (dfra * timestep)); + mul_v3_fl(state->vel, 1.0f / (dfra * timestep)); interp_v3_v3v3(state->ave, keys[1].ave, keys[2].ave, keytime); interp_qt_qtqt(state->rot, keys[1].rot, keys[2].rot, keytime); } } - else if (pa->state.time + 1.f >= state->time && pa->state.time - 1.f <= state->time) { + else if (pa->state.time + 1.0f >= state->time && pa->state.time - 1.0f <= state->time) { /* linear interpolation using only pa->state */ dfra = state->time - pa->state.time; diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index da5fdc85561..98a55c3de95 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -88,7 +88,7 @@ static void do_kink_spiral_deform(ParticleKey *state, { float result[3]; - CLAMP(time, 0.f, 1.f); + CLAMP(time, 0.0f, 1.0f); copy_v3_v3(result, state->co); @@ -426,21 +426,21 @@ void do_kink(ParticleKey *state, float obmat[4][4], int smooth_start) { - float kink[3] = {1.f, 0.f, 0.f}, par_vec[3], q1[4] = {1.f, 0.f, 0.f, 0.f}; - float t, dt = 1.f, result[3]; + float kink[3] = {1.0f, 0.0f, 0.0f}, par_vec[3], q1[4] = {1.0f, 0.0f, 0.0f, 0.0f}; + float t, dt = 1.0f, result[3]; if (ELEM(type, PART_KINK_NO, PART_KINK_SPIRAL)) { return; } - CLAMP(time, 0.f, 1.f); + CLAMP(time, 0.0f, 1.0f); if (shape != 0.0f && !ELEM(type, PART_KINK_BRAID)) { if (shape < 0.0f) { - time = (float)pow(time, 1.f + shape); + time = (float)pow(time, 1.0f + shape); } else { - time = (float)pow(time, 1.f / (1.f - shape)); + time = (float)pow(time, 1.0f / (1.0f - shape)); } } @@ -449,14 +449,14 @@ void do_kink(ParticleKey *state, if (smooth_start) { dt = fabsf(t); /* smooth the beginning of kink */ - CLAMP(dt, 0.f, (float)M_PI); - dt = sinf(dt / 2.f); + CLAMP(dt, 0.0f, (float)M_PI); + dt = sinf(dt / 2.0f); } if (!ELEM(type, PART_KINK_RADIAL)) { float temp[3]; - kink[axis] = 1.f; + kink[axis] = 1.0f; if (obmat) { mul_mat3_m4_v3(obmat, kink); @@ -487,7 +487,7 @@ void do_kink(ParticleKey *state, break; } case PART_KINK_RADIAL: { - if (flat > 0.f) { + if (flat > 0.0f) { float proj[3]; /* flatten along strand */ project_v3_v3v3(proj, par_vec, par_vel); @@ -500,7 +500,7 @@ void do_kink(ParticleKey *state, case PART_KINK_WAVE: { madd_v3_v3fl(result, kink, amplitude * sinf(t)); - if (flat > 0.f) { + if (flat > 0.0f) { float proj[3]; /* flatten along wave */ project_v3_v3v3(proj, par_vec, kink); @@ -513,8 +513,8 @@ void do_kink(ParticleKey *state, break; } case PART_KINK_BRAID: { - float y_vec[3] = {0.f, 1.f, 0.f}; - float z_vec[3] = {0.f, 0.f, 1.f}; + float y_vec[3] = {0.0f, 1.0f, 0.0f}; + float z_vec[3] = {0.0f, 0.0f, 1.0f}; float vec_one[3], state_co[3]; float inp_y, inp_z, length; @@ -533,21 +533,21 @@ void do_kink(ParticleKey *state, copy_v3_v3(state_co, y_vec); mul_v3_fl(y_vec, amplitude * cosf(t)); - mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t)); + mul_v3_fl(z_vec, amplitude / 2.0f * sinf(2.0f * t)); } else if (inp_z > 0.0f) { - mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f)); + mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.0f)); madd_v3_v3fl(state_co, y_vec, -0.5f); - mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f)); - mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f)); + mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.0f)); + mul_v3_fl(z_vec, amplitude / 2.0f * cosf(2.0f * t + (float)M_PI / 6.0f)); } else { - mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f)); + mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.0f)); madd_v3_v3fl(state_co, y_vec, -0.5f); - mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f)); - mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f)); + mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.0f)); + mul_v3_fl(z_vec, amplitude / 2.0f * -sinf(2.0f * t + (float)M_PI / 3.0f)); } mul_v3_fl(state_co, amplitude); @@ -555,13 +555,13 @@ void do_kink(ParticleKey *state, sub_v3_v3v3(par_vec, state->co, state_co); length = normalize_v3(par_vec); - mul_v3_fl(par_vec, MIN2(length, amplitude / 2.f)); + mul_v3_fl(par_vec, MIN2(length, amplitude / 2.0f)); add_v3_v3v3(state_co, par_co, y_vec); add_v3_v3(state_co, z_vec); add_v3_v3(state_co, par_vec); - shape = 2.f * (float)M_PI * (1.f + shape); + shape = 2.0f * (float)M_PI * (1.0f + shape); if (t < shape) { shape = t / shape; @@ -576,7 +576,7 @@ void do_kink(ParticleKey *state, } /* blend the start of the kink */ - if (dt < 1.f) { + if (dt < 1.0f) { interp_v3_v3v3(state->co, state->co, result, dt); } else { @@ -642,7 +642,7 @@ float do_clump(ParticleKey *state, float da[4], pa[12]; mul_v3_v3fl(noisevec, orco_offset, 1.0f / clump_noise_size); - voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0); + BLI_noise_voronoi(noisevec[0], noisevec[1], noisevec[2], da, pa, 1.0f, 0); mul_v3_fl(&pa[0], clump_noise_size); add_v3_v3v3(center, par_co, &pa[0]); @@ -674,9 +674,9 @@ static void do_rough(const float loc[3], copy_v3_v3(rco, loc); mul_v3_fl(rco, t); - rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); - rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); - rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); + rough[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); + rough[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); + rough[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); madd_v3_v3fl(state->co, mat[0], fac * rough[0]); madd_v3_v3fl(state->co, mat[1], fac * rough[1]); @@ -718,9 +718,9 @@ static void do_rough_curve(const float loc[3], copy_v3_v3(rco, loc); mul_v3_fl(rco, time); - rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); - rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); - rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); + rough[0] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[0], rco[1], rco[2], 2, 0, 2); + rough[1] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[1], rco[2], rco[0], 2, 0, 2); + rough[2] = -1.0f + 2.0f * BLI_noise_generic_turbulence(size, rco[2], rco[0], rco[1], 2, 0, 2); madd_v3_v3fl(state->co, mat[0], fac * rough[0]); madd_v3_v3fl(state->co, mat[1], fac * rough[1]); @@ -881,8 +881,8 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx, part->clump_noise_size, clumpcurve); - if (kink_freq != 0.f) { - kink_amp *= (1.f - kink_amp_clump * clump); + if (kink_freq != 0.0f) { + kink_amp *= (1.0f - kink_amp_clump * clump); do_kink(state, modifier_ctx->par_co, @@ -904,17 +904,17 @@ void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx, do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state); } else { - if (rough1 > 0.f) { + if (rough1 > 0.0f) { do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state); } - if (rough2 > 0.f) { + if (rough2 > 0.0f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state); } - if (rough_end > 0.f) { + if (rough_end > 0.0f) { float vec[3]; psys_frand_vec(sim->psys, i + 27, vec); do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state); diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index d5999196b60..194593be4ff 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -150,9 +150,9 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) size[2] = MAX2(size[2], 1); /* no full offset for flat/thin objects */ - min[0] += d < delta[0] ? d / 2.f : delta[0] / 2.f; - min[1] += d < delta[1] ? d / 2.f : delta[1] / 2.f; - min[2] += d < delta[2] ? d / 2.f : delta[2] / 2.f; + min[0] += d < delta[0] ? d / 2.0f : delta[0] / 2.0f; + min[1] += d < delta[1] ? d / 2.0f : delta[1] / 2.0f; + min[2] += d < delta[2] ? d / 2.0f : delta[2] / 2.0f; for (i = 0, p = 0, pa = psys->particles; i < res; i++) { for (j = 0; j < res; j++) { @@ -220,7 +220,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) pa = psys->particles + a1 * a1mul + a2 * a2mul; copy_v3_v3(co1, pa->fuv); - co1[a] -= d < delta[a] ? d / 2.f : delta[a] / 2.f; + co1[a] -= d < delta[a] ? d / 2.0f : delta[a] / 2.0f; copy_v3_v3(co2, co1); co2[a] += delta[a] + 0.001f * d; co1[a] -= 0.001f * d; @@ -295,12 +295,12 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) for (j = 0; j < res; j++) { for (k = 0; k < res; k++, p++, pa++) { if (j % 2) { - pa->fuv[0] += d / 2.f; + pa->fuv[0] += d / 2.0f; } if (k % 2) { - pa->fuv[0] += d / 2.f; - pa->fuv[1] += d / 2.f; + pa->fuv[0] += d / 2.0f; + pa->fuv[1] += d / 2.0f; } } } @@ -318,7 +318,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) } } - if (psys->part->grid_rand > 0.f) { + if (psys->part->grid_rand > 0.0f) { float rfac = d * psys->part->grid_rand; for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++) { if (pa->flag & PARS_UNEXIST) { @@ -1052,7 +1052,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, /* Calculate weights from face areas */ if ((part->flag & PART_EDISTR || children) && from != PART_FROM_VERT) { MVert *v1, *v2, *v3, *v4; - float totarea = 0.f, co1[3], co2[3], co3[3], co4[3]; + float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3]; float(*orcodata)[3]; orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 060a9b4d794..91bdfaeae95 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -574,7 +574,7 @@ static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleSettings *part = psys->part; ParticleTexture ptex; - psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f); + psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.0f); switch (part->type) { case PART_EMITTER: @@ -587,7 +587,7 @@ static void init_particle_texture(ParticleSimulationData *sim, ParticleData *pa, if (ptex.exist < psys_frand(psys, p + 125)) { pa->flag |= PARS_UNEXIST; } - pa->time = 0.f; + pa->time = 0.0f; break; } } @@ -697,28 +697,28 @@ static void get_angular_velocity_vector(short avemode, ParticleKey *state, float case PART_AVE_HORIZONTAL: { float zvec[3]; zvec[0] = zvec[1] = 0; - zvec[2] = 1.f; + zvec[2] = 1.0f; cross_v3_v3v3(vec, state->vel, zvec); break; } case PART_AVE_VERTICAL: { float zvec[3], temp[3]; zvec[0] = zvec[1] = 0; - zvec[2] = 1.f; + zvec[2] = 1.0f; cross_v3_v3v3(temp, state->vel, zvec); cross_v3_v3v3(vec, temp, state->vel); break; } case PART_AVE_GLOBAL_X: - vec[0] = 1.f; + vec[0] = 1.0f; vec[1] = vec[2] = 0; break; case PART_AVE_GLOBAL_Y: - vec[1] = 1.f; + vec[1] = 1.0f; vec[0] = vec[2] = 0; break; case PART_AVE_GLOBAL_Z: - vec[2] = 1.f; + vec[2] = 1.0f; vec[0] = vec[1] = 0; break; } @@ -864,36 +864,36 @@ void psys_get_birth_coords( /* -velocity from: */ /* *reactions */ - if (dtime > 0.f) { + if (dtime > 0.0f) { sub_v3_v3v3(vel, pa->state.vel, pa->prev_state.vel); } /* *emitter velocity */ - if (dtime != 0.f && part->obfac != 0.f) { + if (dtime != 0.0f && part->obfac != 0.0f) { sub_v3_v3v3(vel, loc, state->co); mul_v3_fl(vel, part->obfac / dtime); } /* *emitter normal */ - if (part->normfac != 0.f) { + if (part->normfac != 0.0f) { madd_v3_v3fl(vel, nor, part->normfac); } /* *emitter tangent */ - if (sim->psmd && part->tanfac != 0.f) { + if (sim->psmd && part->tanfac != 0.0f) { madd_v3_v3fl(vel, vtan, part->tanfac); } /* *emitter object orientation */ - if (part->ob_vel[0] != 0.f) { + if (part->ob_vel[0] != 0.0f) { normalize_v3_v3(vec, ob->obmat[0]); madd_v3_v3fl(vel, vec, part->ob_vel[0]); } - if (part->ob_vel[1] != 0.f) { + if (part->ob_vel[1] != 0.0f) { normalize_v3_v3(vec, ob->obmat[1]); madd_v3_v3fl(vel, vec, part->ob_vel[1]); } - if (part->ob_vel[2] != 0.f) { + if (part->ob_vel[2] != 0.0f) { normalize_v3_v3(vec, ob->obmat[2]); madd_v3_v3fl(vel, vec, part->ob_vel[2]); } @@ -902,12 +902,12 @@ void psys_get_birth_coords( /* TODO */ /* *random */ - if (part->randfac != 0.f) { + if (part->randfac != 0.0f) { madd_v3_v3fl(vel, r_vel, part->randfac); } /* *particle */ - if (part->partfac != 0.f) { + if (part->partfac != 0.0f) { madd_v3_v3fl(vel, p_vel, part->partfac); } @@ -1077,7 +1077,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, part = psys->part; /* get precise emitter matrix if particle is born */ - if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) { + if (part->type != PART_HAIR && dtime > 0.0f && pa->time < cfra && pa->time >= sim->psys->cfra) { evaluate_emitter_anim(sim->depsgraph, sim->scene, sim->ob, pa->time); psys->flag |= PSYS_OB_ANIM_RESTORE; @@ -1165,7 +1165,7 @@ ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt) { ParticleSystem *psys = NULL; - if (pt->ob == NULL || pt->ob == ob) { + if (ELEM(pt->ob, NULL, ob)) { psys = BLI_findlink(&ob->particlesystem, pt->psys - 1); } else { @@ -1427,7 +1427,7 @@ static void integrate_particle( copy_v3_v3(oldpos, pa->state.co); /* Verlet integration behaves strangely with moving emitters, so do first step with euler. */ - if (pa->prev_state.time < 0.f && integrator == PART_INT_VERLET) { + if (pa->prev_state.time < 0.0f && integrator == PART_INT_VERLET) { integrator = PART_INT_EULER; } @@ -1450,7 +1450,7 @@ static void integrate_particle( copy_particle_key(states + i, &pa->state, 1); } - states->time = 0.f; + states->time = 0.0f; for (i = 0; i < steps; i++) { zero_v3(force); @@ -1611,9 +1611,9 @@ static void sph_springs_modify(ParticleSystem *psys, float dtime) float yield_ratio = fluid->yield_ratio; float plasticity = fluid->plasticity_constant; /* scale things according to dtime */ - float timefix = 25.f * dtime; + float timefix = 25.0f * dtime; - if ((fluid->flag & SPH_VISCOELASTIC_SPRINGS) == 0 || fluid->spring_k == 0.f) { + if ((fluid->flag & SPH_VISCOELASTIC_SPRINGS) == 0 || fluid->spring_k == 0.0f) { return; } @@ -1636,7 +1636,7 @@ static void sph_springs_modify(ParticleSystem *psys, float dtime) spring->rest_length -= plasticity * (Lij - d - rij) * timefix; } - h = 4.f * pa1->size; + h = 4.0f * pa1->size; if (spring->rest_length > h) { spring->delete_flag = 1; @@ -1743,7 +1743,7 @@ static void sph_density_accum_cb(void *userdata, int index, const float co[3], f pfr->tot_neighbors++; dist = sqrtf(squared_dist); - q = (1.f - dist / pfr->h) * pfr->massfac; + q = (1.0f - dist / pfr->h) * pfr->massfac; if (pfr->use_size) { q *= npa->size; @@ -1799,7 +1799,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa float visc = fluid->viscosity_omega; float stiff_visc = fluid->viscosity_beta * - (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f); + (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.0f); float inv_mass = 1.0f / sphdata->mass; float spring_constant = fluid->spring_k; @@ -1809,13 +1809,13 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa (fluid->flag & SPH_FAC_RADIUS ? 4.0f * pa->size : 1.0f); float h = interaction_radius * sphdata->hfac; /* 4.77 is an experimentally determined density factor */ - float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); + float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.0f); float rest_length = fluid->rest_length * - (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f); + (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.0f); float stiffness = fluid->stiffness_k; float stiffness_near_fac = fluid->stiffness_knear * - (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.f); + (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.0f); ParticleData *npa; float vec[3]; @@ -1849,7 +1849,7 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa sub_v3_v3v3(vec, co, state->co); rij = normalize_v3(vec); - q = (1.f - rij / h) * pfn->psys->part->mass * inv_mass; + q = (1.0f - rij / h) * pfn->psys->part->mass * inv_mass; if (pfn->psys->part->flag & PART_SIZEMASS) { q *= npa->size; @@ -1861,20 +1861,20 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa madd_v3_v3fl(force, vec, -(pressure + near_pressure * q) * q); /* Viscosity */ - if (visc > 0.f || stiff_visc > 0.f) { + if (visc > 0.0f || stiff_visc > 0.0f) { sub_v3_v3v3(dv, vel, state->vel); u = dot_v3v3(vec, dv); - if (u < 0.f && visc > 0.f) { + if (u < 0.0f && visc > 0.0f) { madd_v3_v3fl(force, vec, 0.5f * q * visc * u); } - if (u > 0.f && stiff_visc > 0.f) { + if (u > 0.0f && stiff_visc > 0.0f) { madd_v3_v3fl(force, vec, 0.5f * q * stiff_visc * u); } } - if (spring_constant > 0.f) { + if (spring_constant > 0.0f) { /* Viscoelastic spring force */ if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) { /* BLI_edgehash_lookup appears to be thread-safe. - z0r */ @@ -1883,8 +1883,9 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa if (spring_index) { spring = psys[0]->fluid_springs + spring_index - 1; - madd_v3_v3fl( - force, vec, -10.f * spring_constant * (1.f - rij / h) * (spring->rest_length - rij)); + madd_v3_v3fl(force, + vec, + -10.0f * spring_constant * (1.0f - rij / h) * (spring->rest_length - rij)); } else if (fluid->spring_frames == 0 || (pa->prev_state.time - pa->time) <= fluid->spring_frames) { @@ -1898,13 +1899,14 @@ static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, floa } } else { /* PART_SPRING_HOOKES - Hooke's spring force */ - madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij / h) * (rest_length - rij)); + madd_v3_v3fl( + force, vec, -10.0f * spring_constant * (1.0f - rij / h) * (rest_length - rij)); } } } /* Artificial buoyancy force in negative gravity direction */ - if (fluid->buoyancy > 0.f && gravity) { + if (fluid->buoyancy > 0.0f && gravity) { madd_v3_v3fl(force, gravity, fluid->buoyancy * (density - rest_density)); } @@ -1922,7 +1924,7 @@ static void sphclassical_density_accum_cb(void *userdata, SPHRangeData *pfr = (SPHRangeData *)userdata; ParticleData *npa = pfr->npsys->particles + index; float q; - float qfac = 21.0f / (256.f * (float)M_PI); + float qfac = 21.0f / (256.0f * (float)M_PI); float rij, rij_h; float vec[3]; @@ -2079,7 +2081,7 @@ static void sphclassical_force_cb(void *sphdata_v, } /* Artificial buoyancy force in negative gravity direction */ - if (fluid->buoyancy > 0.f && gravity) { + if (fluid->buoyancy > 0.0f && gravity) { madd_v3_v3fl(force, gravity, fluid->buoyancy * (pa->sphdensity - rest_density)); } @@ -2199,7 +2201,7 @@ static void sph_integrate(ParticleSimulationData *sim, { ParticleSettings *part = sim->psys->part; // float timestep = psys_get_timestep(sim); // UNUSED - float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f); + float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.0f); float dtime = dfra * psys_get_timestep(sim); // int steps = 1; // UNUSED float effector_acceleration[3]; @@ -2211,7 +2213,7 @@ static void sph_integrate(ParticleSimulationData *sim, /* restore previous state and treat gravity & effectors as external acceleration*/ sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel); - mul_v3_fl(effector_acceleration, 1.f / dtime); + mul_v3_fl(effector_acceleration, 1.0f / dtime); copy_particle_key(&pa->state, &pa->prev_state, 0); @@ -2300,8 +2302,8 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa integrate_particle(part, pa, dtime, gravity, basic_force_cb, &efdata); /* damp affects final velocity */ - if (part->dampfac != 0.f) { - mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime); + if (part->dampfac != 0.0f) { + mul_v3_fl(pa->state.vel, 1.0f - part->dampfac * efdata.ptex.damp * 25.0f * dtime); } // copy_v3_v3(pa->state.ave, states->ave); @@ -2406,7 +2408,7 @@ static float nr_signed_distance_to_plane(float *p, d = dot_v3v3(p0, nor); if (pce->inv_nor == -1) { - if (d < 0.f) { + if (d < 0.0f) { pce->inv_nor = 1; } else { @@ -2452,7 +2454,7 @@ static void collision_interpolate_element(ParticleCollisionElement *pce, /* fac is the starting factor for current collision iteration */ /* The col->fac's are factors for the particle subframe step start * and end during collision modifier step. */ - float f = fac + t * (1.f - fac); + float f = fac + t * (1.0f - fac); float mul = col->fac1 + f * (col->fac2 - col->fac1); if (pce->tot > 0) { madd_v3_v3v3fl(pce->x0, pce->x[0], pce->v[0], mul); @@ -2485,8 +2487,8 @@ static void collision_point_velocity(ParticleCollisionElement *pce) static float collision_point_distance_with_normal( float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *nor) { - if (fac >= 0.f) { - collision_interpolate_element(pce, 0.f, fac, col); + if (fac >= 0.0f) { + collision_interpolate_element(pce, 0.0f, fac, col); } switch (pce->tot) { @@ -2504,14 +2506,14 @@ static float collision_point_distance_with_normal( return normalize_v3(nor); } case 3: - return nr_signed_distance_to_plane(p, 0.f, pce, nor); + return nr_signed_distance_to_plane(p, 0.0f, pce, nor); } return 0; } static void collision_point_on_surface( const float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *co) { - collision_interpolate_element(pce, 0.f, fac, col); + collision_interpolate_element(pce, 0.0f, fac, col); switch (pce->tot) { case 1: { @@ -2575,11 +2577,11 @@ static float collision_newton_rhapson(ParticleCollision *col, } /* start from the beginning */ - t0 = 0.f; + t0 = 0.0f; collision_interpolate_element(pce, t0, col->f, col); d0 = distance_func(col->co1, radius, pce, n); t1 = dt_init; - d1 = 0.f; + d1 = 0.0f; for (iter = 0; iter < 10; iter++) { //, itersum++) { /* get current location */ @@ -2589,11 +2591,11 @@ static float collision_newton_rhapson(ParticleCollision *col, d1 = distance_func(pce->p, radius, pce, n); /* particle already inside face, so report collision */ - if (iter == 0 && d0 < 0.f && d0 > -radius) { + if (iter == 0 && d0 < 0.0f && d0 > -radius) { copy_v3_v3(pce->p, col->co1); copy_v3_v3(pce->nor, n); pce->inside = 1; - return 0.f; + return 0.0f; } /* Zero gradient (no movement relative to element). Can't step from @@ -2602,15 +2604,15 @@ static float collision_newton_rhapson(ParticleCollision *col, /* If first iteration, try from other end where the gradient may be * greater. Note: code duplicated below. */ if (iter == 0) { - t0 = 1.f; + t0 = 1.0f; collision_interpolate_element(pce, t0, col->f, col); d0 = distance_func(col->co2, radius, pce, n); t1 = 1.0f - dt_init; - d1 = 0.f; + d1 = 0.0f; continue; } - return -1.f; + return -1.0f; } dd = (t1 - t0) / (d1 - d0); @@ -2622,30 +2624,30 @@ static float collision_newton_rhapson(ParticleCollision *col, /* Particle moving away from plane could also mean a strangely rotating * face, so check from end. Note: code duplicated above. */ - if (iter == 0 && t1 < 0.f) { - t0 = 1.f; + if (iter == 0 && t1 < 0.0f) { + t0 = 1.0f; collision_interpolate_element(pce, t0, col->f, col); d0 = distance_func(col->co2, radius, pce, n); t1 = 1.0f - dt_init; - d1 = 0.f; + d1 = 0.0f; continue; } - if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f)) { - return -1.f; + if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.0f)) { + return -1.0f; } if (d1 <= COLLISION_ZERO && d1 >= -COLLISION_ZERO) { - if (t1 >= -COLLISION_ZERO && t1 <= 1.f) { + if (t1 >= -COLLISION_ZERO && t1 <= 1.0f) { if (distance_func == nr_signed_distance_to_plane) { copy_v3_v3(pce->nor, n); } - CLAMP(t1, 0.f, 1.f); + CLAMP(t1, 0.0f, 1.0f); return t1; } - return -1.f; + return -1.0f; } } return -1.0; @@ -2663,7 +2665,7 @@ static int collision_sphere_to_tri(ParticleCollision *col, ct = collision_newton_rhapson(col, radius, pce, nr_signed_distance_to_plane); - if (ct >= 0.f && ct < *t && (result->inside == 0 || pce->inside == 1)) { + if (ct >= 0.0f && ct < *t && (result->inside == 0 || pce->inside == 1)) { float e1[3], e2[3], p0[3]; float e1e1, e1e2, e1p0, e2e2, e2p0, inv; @@ -2678,11 +2680,11 @@ static int collision_sphere_to_tri(ParticleCollision *col, e2e2 = dot_v3v3(e2, e2); e2p0 = dot_v3v3(e2, p0); - inv = 1.f / (e1e1 * e2e2 - e1e2 * e1e2); + inv = 1.0f / (e1e1 * e2e2 - e1e2 * e1e2); u = (e2e2 * e1p0 - e1e2 * e2p0) * inv; v = (e1e1 * e2p0 - e1e2 * e1p0) * inv; - if (u >= 0.f && u <= 1.f && v >= 0.f && u + v <= 1.f) { + if (u >= 0.0f && u <= 1.0f && v >= 0.0f && u + v <= 1.0f) { *result = *pce; /* normal already calculated in pce */ @@ -2718,14 +2720,14 @@ static int collision_sphere_to_edges(ParticleCollision *col, ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_edge); - if (ct >= 0.f && ct < *t) { + if (ct >= 0.0f && ct < *t) { float u, e[3], vec[3]; sub_v3_v3v3(e, cur->x1, cur->x0); sub_v3_v3v3(vec, cur->p, cur->x0); u = dot_v3v3(vec, e) / dot_v3v3(e, e); - if (u < 0.f || u > 1.f) { + if (u < 0.0f || u > 1.0f) { break; } @@ -2763,7 +2765,7 @@ static int collision_sphere_to_verts(ParticleCollision *col, ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_vert); - if (ct >= 0.f && ct < *t) { + if (ct >= 0.0f && ct < *t) { *result = *cur; sub_v3_v3v3(result->nor, cur->p, cur->x0); @@ -3019,7 +3021,7 @@ static int collision_response(ParticleSimulationData *sim, (vc_dot < 0.0f && v0_dot < 0.0f && vc_dot < v0_dot))) { mul_v3_v3fl(v0_nor, pce->nor, vc_dot); } - else if (v0_dot > 0.f) { + else if (v0_dot > 0.0f) { mul_v3_v3fl(v0_nor, pce->nor, vc_dot + v0_dot); } else { @@ -3045,25 +3047,25 @@ static int collision_response(ParticleSimulationData *sim, /* make sure particle stays on the right side of the surface */ if (!through) { - distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor); + distance = collision_point_distance_with_normal(co, pce, -1.0f, col, nor); if (distance < col->radius + COLLISION_MIN_DISTANCE) { madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); } dot = dot_v3v3(nor, v0); - if (dot < 0.f) { + if (dot < 0.0f) { madd_v3_v3fl(v0, nor, -dot); } - distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor); + distance = collision_point_distance_with_normal(pa->state.co, pce, 1.0f, col, nor); if (distance < col->radius + COLLISION_MIN_DISTANCE) { madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance); } dot = dot_v3v3(nor, pa->state.vel); - if (dot < 0.f) { + if (dot < 0.0f) { madd_v3_v3fl(pa->state.vel, nor, -dot); } } @@ -3090,7 +3092,7 @@ static int collision_response(ParticleSimulationData *sim, static void collision_fail(ParticleData *pa, ParticleCollision *col) { /* final chance to prevent total failure, so stick to the surface and hope for the best */ - collision_point_on_surface(col->co1, &col->pce, 1.f, col, pa->state.co); + collision_point_on_surface(col->co1, &col->pce, 1.0f, col, pa->state.co); copy_v3_v3(pa->state.vel, col->pce.vel); mul_v3_fl(pa->state.vel, col->inv_timestep); @@ -3128,7 +3130,7 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa /* get acceleration (from gravity, forcefields etc. to be re-applied in collision response) */ sub_v3_v3v3(col.acc, pa->state.vel, pa->prev_state.vel); - mul_v3_fl(col.acc, 1.f / col.total_time); + mul_v3_fl(col.acc, 1.0f / col.total_time); /* set values for first iteration */ copy_v3_v3(col.co1, pa->prev_state.co); @@ -3925,7 +3927,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) if (ELEM(pa->alive, PARS_ALIVE, PARS_DYING) == 0 || (pa->flag & (PARS_UNEXIST | PARS_NO_DISP))) { - pa->state.time = -1.f; + pa->state.time = -1.0f; } } @@ -4149,20 +4151,17 @@ static bool particles_has_tracer(short parttype) static bool particles_has_spray(short parttype) { - return ((parttype == PART_FLUID_SPRAY) || (parttype == PART_FLUID_SPRAYFOAM) || - (parttype == PART_FLUID_SPRAYFOAMBUBBLE)); + return (ELEM(parttype, PART_FLUID_SPRAY, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE)); } static bool particles_has_bubble(short parttype) { - return ((parttype == PART_FLUID_BUBBLE) || (parttype == PART_FLUID_FOAMBUBBLE) || - (parttype == PART_FLUID_SPRAYFOAMBUBBLE)); + return (ELEM(parttype, PART_FLUID_BUBBLE, PART_FLUID_FOAMBUBBLE, PART_FLUID_SPRAYFOAMBUBBLE)); } static bool particles_has_foam(short parttype) { - return ((parttype == PART_FLUID_FOAM) || (parttype == PART_FLUID_SPRAYFOAM) || - (parttype == PART_FLUID_SPRAYFOAMBUBBLE)); + return (ELEM(parttype, PART_FLUID_FOAM, PART_FLUID_SPRAYFOAM, PART_FLUID_SPRAYFOAMBUBBLE)); } static void particles_fluid_step(ParticleSimulationData *sim, @@ -4410,7 +4409,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, zero_v3(pa->state.ave); unit_qt(pa->state.rot); - pa->time = 1.f; + pa->time = 1.0f; pa->dietime = sim->scene->r.efra + 1; pa->lifetime = sim->scene->r.efra; pa->alive = PARS_ALIVE; @@ -4590,8 +4589,8 @@ static void system_step(ParticleSimulationData *sim, float cfra, const bool use_ dt_frac = psys->dt_frac; for (t_frac = dt_frac; t_frac <= 1.0f; t_frac += dt_frac) { sim->courant_num = 0.0f; - dynamics_step(sim, cfra + dframe + t_frac - 1.f); - psys->cfra = cfra + dframe + t_frac - 1.f; + dynamics_step(sim, cfra + dframe + t_frac - 1.0f); + psys->cfra = cfra + dframe + t_frac - 1.0f; if (part->time_flag & PART_TIME_AUTOSF) { update_timestep(psys, sim); @@ -4692,17 +4691,17 @@ void BKE_particlesettings_fluid_default_settings(ParticleSettings *part) { SPHFluidSettings *fluid = part->fluid; - fluid->spring_k = 0.f; + fluid->spring_k = 0.0f; fluid->plasticity_constant = 0.1f; fluid->yield_ratio = 0.1f; - fluid->rest_length = 1.f; - fluid->viscosity_omega = 2.f; + fluid->rest_length = 1.0f; + fluid->viscosity_omega = 2.0f; fluid->viscosity_beta = 0.1f; - fluid->stiffness_k = 1.f; - fluid->stiffness_knear = 1.f; - fluid->rest_density = 1.f; - fluid->buoyancy = 0.f; - fluid->radius = 1.f; + fluid->stiffness_k = 1.0f; + fluid->stiffness_knear = 1.0f; + fluid->rest_density = 1.0f; + fluid->buoyancy = 0.0f; + fluid->radius = 1.0f; fluid->flag |= SPH_FAC_REPULSION | SPH_FAC_DENSITY | SPH_FAC_RADIUS | SPH_FAC_VISCOSITY | SPH_FAC_REST_LENGTH; } diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index d31b0d54784..09e4ad93baa 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -63,6 +63,7 @@ static void pbvh_bmesh_verify(PBVH *pbvh); #endif +/* -------------------------------------------------------------------- */ /** \name BMesh Utility API * * Use some local functions which assume triangles. diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 7c8527a8702..6a93245d995 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -256,7 +256,9 @@ static int ptcache_softbody_totpoint(void *soft_v, int UNUSED(cfra)) SoftBody *soft = soft_v; return soft->totpoint; } -static void ptcache_softbody_error(void *UNUSED(soft_v), const char *UNUSED(message)) +static void ptcache_softbody_error(const ID *UNUSED(owner_id), + void *UNUSED(soft_v), + const char *UNUSED(message)) { /* ignored for now */ } @@ -460,7 +462,7 @@ static void ptcache_particle_interpolate(int index, psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, &pa->state, 1); interp_qt_qtqt(pa->state.rot, keys[1].rot, keys[2].rot, (cfra - cfra1) / dfra); - mul_v3_fl(pa->state.vel, 1.f / (dfra * timestep)); + mul_v3_fl(pa->state.vel, 1.0f / (dfra * timestep)); pa->state.time = cfra; } @@ -471,7 +473,9 @@ static int ptcache_particle_totpoint(void *psys_v, int UNUSED(cfra)) return psys->totpart; } -static void ptcache_particle_error(void *UNUSED(psys_v), const char *UNUSED(message)) +static void ptcache_particle_error(const ID *UNUSED(owner_id), + void *UNUSED(psys_v), + const char *UNUSED(message)) { /* ignored for now */ } @@ -642,10 +646,11 @@ static int ptcache_cloth_totpoint(void *cloth_v, int UNUSED(cfra)) return clmd->clothObject ? clmd->clothObject->mvert_num : 0; } -static void ptcache_cloth_error(void *cloth_v, const char *message) +static void ptcache_cloth_error(const ID *owner_id, void *cloth_v, const char *message) { ClothModifierData *clmd = cloth_v; - BKE_modifier_set_error(&clmd->modifier, "%s", message); + BLI_assert(GS(owner_id->name) == ID_OB); + BKE_modifier_set_error((Object *)owner_id, &clmd->modifier, "%s", message); } static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra)) @@ -659,7 +664,9 @@ static int ptcache_dynamicpaint_totpoint(void *sd, int UNUSED(cfra)) return surface->data->total_points; } -static void ptcache_dynamicpaint_error(void *UNUSED(sd), const char *UNUSED(message)) +static void ptcache_dynamicpaint_error(const ID *UNUSED(owner_id), + void *UNUSED(sd), + const char *UNUSED(message)) { /* ignored for now */ } @@ -731,8 +738,7 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v) if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { data_len = sizeof(PaintPoint); } - else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE || - surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { + else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WEIGHT)) { data_len = sizeof(float); } else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { @@ -853,7 +859,9 @@ static int ptcache_rigidbody_totpoint(void *rb_v, int UNUSED(cfra)) return rbw->numbodies; } -static void ptcache_rigidbody_error(void *UNUSED(rb_v), const char *UNUSED(message)) +static void ptcache_rigidbody_error(const struct ID *UNUSED(owner_id), + void *UNUSED(rb_v), + const char *UNUSED(message)) { /* ignored for now */ } @@ -2098,19 +2106,19 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra) } if (!ptcache_file_header_begin_read(pf)) { - pid->error(pid->calldata, "Failed to read point cache file"); + pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file"); error = 1; } else if (pf->type != pid->type) { - pid->error(pid->calldata, "Point cache file has wrong type"); + pid->error(pid->owner_id, pid->calldata, "Point cache file has wrong type"); error = 1; } else if (!pid->read_header(pf)) { - pid->error(pid->calldata, "Failed to read point cache file header"); + pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file header"); error = 1; } else if (pf->totpoint != pid->totpoint(pid->calldata, cfra)) { - pid->error(pid->calldata, "Number of points in cache does not match mesh"); + pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh"); error = 1; } @@ -2119,7 +2127,7 @@ static int ptcache_read_stream(PTCacheID *pid, int cfra) /* We have stream reading here. */ if (!pid->read_stream(pf, pid->calldata)) { - pid->error(pid->calldata, "Failed to read point cache file data"); + pid->error(pid->owner_id, pid->calldata, "Failed to read point cache file data"); error = 1; } } @@ -2155,7 +2163,7 @@ static int ptcache_read(PTCacheID *pid, int cfra) int pid_totpoint = pid->totpoint(pid->calldata, cfra); if (totpoint != pid_totpoint) { - pid->error(pid->calldata, "Number of points in cache does not match mesh"); + pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh"); totpoint = MIN2(totpoint, pid_totpoint); } } @@ -2211,7 +2219,7 @@ static int ptcache_interpolate(PTCacheID *pid, float cfra, int cfra1, int cfra2) int pid_totpoint = pid->totpoint(pid->calldata, (int)cfra); if (totpoint != pid_totpoint) { - pid->error(pid->calldata, "Number of points in cache does not match mesh"); + pid->error(pid->owner_id, pid->calldata, "Number of points in cache does not match mesh"); totpoint = MIN2(totpoint, pid_totpoint); } } diff --git a/source/blender/blenkernel/intern/pointcloud.c b/source/blender/blenkernel/intern/pointcloud.c index 78acf7251fa..62c4c4441ba 100644 --- a/source/blender/blenkernel/intern/pointcloud.c +++ b/source/blender/blenkernel/intern/pointcloud.c @@ -184,6 +184,8 @@ IDTypeInfo IDType_ID_PT = { .blend_read_data = pointcloud_blend_read_data, .blend_read_lib = pointcloud_blend_read_lib, .blend_read_expand = pointcloud_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; static void pointcloud_random(PointCloud *pointcloud) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 416f5aa7edd..5153618d6e7 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -90,7 +90,6 @@ #include "BKE_rigidbody.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_unit.h" #include "BKE_workspace.h" @@ -103,6 +102,10 @@ #include "RE_engine.h" +#include "SEQ_sequencer.h" + +#include "BLO_read_write.h" + #include "engines/eevee/eevee_lightcache.h" #include "PIL_time.h" @@ -454,53 +457,216 @@ static void scene_foreach_rigidbodyworldSceneLooper(struct RigidBodyWorld *UNUSE BKE_lib_query_foreachid_process(data, id_pointer, cb_flag); } -static void scene_foreach_paint(LibraryForeachIDData *data, Paint *paint) -{ - BKE_LIB_FOREACHID_PROCESS(data, paint->brush, IDWALK_CB_USER); - for (int i = 0; i < paint->tool_slots_len; i++) { - BKE_LIB_FOREACHID_PROCESS(data, paint->tool_slots[i].brush, IDWALK_CB_USER); +/** + * This code is shared by both the regular `foreach_id` looper, and the code trying to restore or + * preserve ID pointers like brushes across undoes. + */ +typedef enum eSceneForeachUndoPreserveProcess { + /* Undo when preserving tool-settings from old scene, we also want to try to preserve that ID + * pointer from its old scene's value. */ + SCENE_FOREACH_UNDO_RESTORE, + /* Undo when preserving tool-settings from old scene, we want to keep the new value of that ID + * pointer. */ + SCENE_FOREACH_UNDO_NO_RESTORE, +} eSceneForeachUndoPreserveProcess; + +static void scene_foreach_toolsettings_id_pointer_process( + ID **id_p, + const eSceneForeachUndoPreserveProcess action, + BlendLibReader *reader, + ID **id_old_p, + const uint cb_flag) +{ + switch (action) { + case SCENE_FOREACH_UNDO_RESTORE: { + ID *id_old = *id_old_p; + /* Old data has not been remapped to new values of the pointers, if we want to keep the old + * pointer here we need its new address. */ + ID *id_old_new = id_old != NULL ? BLO_read_get_new_id_address(reader, id_old->lib, id_old) : + NULL; + if (id_old_new != NULL) { + BLI_assert(ELEM(id_old, id_old_new, id_old_new->orig_id)); + *id_old_p = id_old_new; + if (cb_flag & IDWALK_CB_USER) { + id_us_plus_no_lib(id_old_new); + id_us_min(id_old); + } + break; + } + /* We failed to find a new valid pointer for the previous ID, just keep the current one as + * if we had been under SCENE_FOREACH_UNDO_NO_RESTORE case. */ + SWAP(ID *, *id_p, *id_old_p); + break; + } + case SCENE_FOREACH_UNDO_NO_RESTORE: + /* Counteract the swap of the whole ToolSettings container struct. */ + SWAP(ID *, *id_p, *id_old_p); + break; } - BKE_LIB_FOREACHID_PROCESS(data, paint->palette, IDWALK_CB_USER); } -static void scene_foreach_toolsettings(LibraryForeachIDData *data, ToolSettings *toolsett) -{ - BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.scene, IDWALK_CB_NOP); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.object, IDWALK_CB_NOP); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->particle.shape_object, IDWALK_CB_NOP); - - scene_foreach_paint(data, &toolsett->imapaint.paint); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.stencil, IDWALK_CB_USER); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.clone, IDWALK_CB_USER); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->imapaint.canvas, IDWALK_CB_USER); +#define BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS( \ + __data, __id, __do_undo_restore, __action, __reader, __id_old, __cb_flag) \ + { \ + if (__do_undo_restore) { \ + scene_foreach_toolsettings_id_pointer_process( \ + (ID **)&(__id), __action, __reader, (ID **)&(__id_old), __cb_flag); \ + } \ + else { \ + BKE_LIB_FOREACHID_PROCESS(__data, __id, __cb_flag); \ + } \ + } \ + (void)0 + +static void scene_foreach_paint(LibraryForeachIDData *data, + Paint *paint, + const bool do_undo_restore, + BlendLibReader *reader, + Paint *paint_old) +{ + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + paint->brush, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + paint_old->brush, + IDWALK_CB_USER); + for (int i = 0; i < paint_old->tool_slots_len; i++) { + /* This is a bit tricky. + * - In case we do not do `undo_restore`, `paint` and `paint_old` pointers are the same, so + * this is equivalent to simply looping over slots from `paint`. + * - In case we do `undo_restore`, we only want to consider the slots from the old one, since + * those are the one we keep in the end. + * + In case the new data has less valid slots, we feed in a dummy NULL pointer. + * + In case the new data has more valid slots, the extra ones are ignored. + */ + Brush *brush_tmp = NULL; + Brush **brush_p = i < paint->tool_slots_len ? &paint->tool_slots[i].brush : &brush_tmp; + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + *brush_p, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + paint_old->brush, + IDWALK_CB_USER); + } + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + paint->palette, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + paint_old->palette, + IDWALK_CB_USER); +} + +static void scene_foreach_toolsettings(LibraryForeachIDData *data, + ToolSettings *toolsett, + const bool do_undo_restore, + BlendLibReader *reader, + ToolSettings *toolsett_old) +{ + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->particle.scene, + do_undo_restore, + SCENE_FOREACH_UNDO_NO_RESTORE, + reader, + toolsett_old->particle.scene, + IDWALK_CB_NOP); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->particle.object, + do_undo_restore, + SCENE_FOREACH_UNDO_NO_RESTORE, + reader, + toolsett_old->particle.object, + IDWALK_CB_NOP); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->particle.shape_object, + do_undo_restore, + SCENE_FOREACH_UNDO_NO_RESTORE, + reader, + toolsett_old->particle.shape_object, + IDWALK_CB_NOP); + + scene_foreach_paint( + data, &toolsett->imapaint.paint, do_undo_restore, reader, &toolsett_old->imapaint.paint); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->imapaint.stencil, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + toolsett_old->imapaint.stencil, + IDWALK_CB_USER); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->imapaint.clone, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + toolsett_old->imapaint.clone, + IDWALK_CB_USER); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->imapaint.canvas, + do_undo_restore, + SCENE_FOREACH_UNDO_RESTORE, + reader, + toolsett_old->imapaint.canvas, + IDWALK_CB_USER); if (toolsett->vpaint) { - scene_foreach_paint(data, &toolsett->vpaint->paint); + scene_foreach_paint( + data, &toolsett->vpaint->paint, do_undo_restore, reader, &toolsett_old->vpaint->paint); } if (toolsett->wpaint) { - scene_foreach_paint(data, &toolsett->wpaint->paint); + scene_foreach_paint( + data, &toolsett->wpaint->paint, do_undo_restore, reader, &toolsett_old->wpaint->paint); } if (toolsett->sculpt) { - scene_foreach_paint(data, &toolsett->sculpt->paint); - BKE_LIB_FOREACHID_PROCESS(data, toolsett->sculpt->gravity_object, IDWALK_CB_NOP); + scene_foreach_paint( + data, &toolsett->sculpt->paint, do_undo_restore, reader, &toolsett_old->sculpt->paint); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->sculpt->gravity_object, + do_undo_restore, + SCENE_FOREACH_UNDO_NO_RESTORE, + reader, + toolsett_old->sculpt->gravity_object, + IDWALK_CB_NOP); } if (toolsett->uvsculpt) { - scene_foreach_paint(data, &toolsett->uvsculpt->paint); + scene_foreach_paint( + data, &toolsett->uvsculpt->paint, do_undo_restore, reader, &toolsett_old->uvsculpt->paint); } if (toolsett->gp_paint) { - scene_foreach_paint(data, &toolsett->gp_paint->paint); + scene_foreach_paint( + data, &toolsett->gp_paint->paint, do_undo_restore, reader, &toolsett_old->gp_paint->paint); } if (toolsett->gp_vertexpaint) { - scene_foreach_paint(data, &toolsett->gp_vertexpaint->paint); + scene_foreach_paint(data, + &toolsett->gp_vertexpaint->paint, + do_undo_restore, + reader, + &toolsett_old->gp_vertexpaint->paint); } if (toolsett->gp_sculptpaint) { - scene_foreach_paint(data, &toolsett->gp_sculptpaint->paint); + scene_foreach_paint(data, + &toolsett->gp_sculptpaint->paint, + do_undo_restore, + reader, + &toolsett_old->gp_sculptpaint->paint); } if (toolsett->gp_weightpaint) { - scene_foreach_paint(data, &toolsett->gp_weightpaint->paint); + scene_foreach_paint(data, + &toolsett->gp_weightpaint->paint, + do_undo_restore, + reader, + &toolsett_old->gp_weightpaint->paint); } - BKE_LIB_FOREACHID_PROCESS(data, toolsett->gp_sculpt.guide.reference_object, IDWALK_CB_NOP); + BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS(data, + toolsett->gp_sculpt.guide.reference_object, + do_undo_restore, + SCENE_FOREACH_UNDO_NO_RESTORE, + reader, + toolsett_old->gp_sculpt.guide.reference_object, + IDWALK_CB_NOP); } static void scene_foreach_layer_collection(LibraryForeachIDData *data, ListBase *lb) @@ -592,7 +758,7 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) ToolSettings *toolsett = scene->toolsettings; if (toolsett) { - scene_foreach_toolsettings(data, toolsett); + scene_foreach_toolsettings(data, toolsett, false, NULL, toolsett); } if (scene->rigidbody_world) { @@ -619,6 +785,22 @@ static void scene_foreach_cache(ID *id, user_data); } +static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) +{ + Scene *scene_new = (Scene *)id_new; + Scene *scene_old = (Scene *)id_old; + + SWAP(View3DCursor, scene_old->cursor, scene_new->cursor); + if (scene_new->toolsettings != NULL && scene_old->toolsettings != NULL) { + /* First try to restore ID pointers that can be and should be preserved (like brushes or + * palettes), and counteract the swap of the whole ToolSettings structs below for the others + * (like object ones). */ + scene_foreach_toolsettings( + NULL, scene_new->toolsettings, true, reader, scene_old->toolsettings); + SWAP(ToolSettings, *scene_old->toolsettings, *scene_new->toolsettings); + } +} + IDTypeInfo IDType_ID_SCE = { .id_code = ID_SCE, .id_filter = FILTER_ID_SCE, @@ -642,6 +824,8 @@ IDTypeInfo IDType_ID_SCE = { .blend_read_data = NULL, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = scene_undo_preserve, }; const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; @@ -1971,7 +2155,7 @@ bool BKE_scene_multiview_is_render_view_active(const RenderData *rd, const Scene } /* SCE_VIEWS_SETUP_BASIC */ - if (STREQ(srv->name, STEREO_LEFT_NAME) || STREQ(srv->name, STEREO_RIGHT_NAME)) { + if (STR_ELEM(srv->name, STEREO_LEFT_NAME, STEREO_RIGHT_NAME)) { return true; } diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index d9686eba29a..1b8360a1cec 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -21,6 +21,9 @@ * \ingroup bke */ +/* Allow using deprecated functionality for .blend file I/O. */ +#define DNA_DEPRECATED_ALLOW + #ifdef WIN32 # include "BLI_winstuff.h" #endif @@ -49,14 +52,18 @@ #include "BLT_translation.h" +#include "BKE_gpencil.h" #include "BKE_icons.h" #include "BKE_idprop.h" #include "BKE_idtype.h" +#include "BKE_lib_id.h" #include "BKE_lib_query.h" #include "BKE_node.h" #include "BKE_screen.h" #include "BKE_workspace.h" +#include "BLO_read_write.h" + static void screen_free_data(ID *id) { bScreen *screen = (bScreen *)id; @@ -230,6 +237,40 @@ static void screen_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void screen_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + bScreen *screen = (bScreen *)id; + /* Screens are reference counted, only saved if used by a workspace. */ + if (screen->id.us > 0 || BLO_write_is_undo(writer)) { + /* write LibData */ + /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ + BLO_write_struct_at_address_with_filecode(writer, ID_SCRN, bScreen, id_address, screen); + BKE_id_blend_write(writer, &screen->id); + + BKE_previewimg_blend_write(writer, screen->preview); + + /* direct data */ + BKE_screen_area_map_blend_write(writer, AREAMAP_FROM_SCREEN(screen)); + } +} + +/* note: file read without screens option G_FILE_NO_UI; + * check lib pointers in call below */ +static void screen_blend_read_lib(BlendLibReader *reader, ID *id) +{ + bScreen *screen = (bScreen *)id; + /* deprecated, but needed for versioning (will be NULL'ed then) */ + BLO_read_id_address(reader, screen->id.lib, &screen->scene); + + screen->animtimer = NULL; /* saved in rare cases */ + screen->tool_tip = NULL; + screen->scrubbing = false; + + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + BKE_screen_area_blend_read_lib(reader, &screen->id, area); + } +} + IDTypeInfo IDType_ID_SCR = { .id_code = ID_SCR, .id_filter = 0, @@ -247,10 +288,13 @@ IDTypeInfo IDType_ID_SCR = { .foreach_id = screen_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, + .blend_write = screen_blend_write, + /* Cannot be used yet, because #direct_link_screen has a return value. */ .blend_read_data = NULL, - .blend_read_lib = NULL, + .blend_read_lib = screen_blend_read_lib, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /* ************ Spacetype/regiontype handling ************** */ @@ -312,7 +356,7 @@ SpaceType *BKE_spacetype_from_id(int spaceid) return NULL; } -ARegionType *BKE_regiontype_from_id_or_first(SpaceType *st, int regionid) +ARegionType *BKE_regiontype_from_id_or_first(const SpaceType *st, int regionid) { ARegionType *art; @@ -327,7 +371,7 @@ ARegionType *BKE_regiontype_from_id_or_first(SpaceType *st, int regionid) return st->regiontypes.first; } -ARegionType *BKE_regiontype_from_id(SpaceType *st, int regionid) +ARegionType *BKE_regiontype_from_id(const SpaceType *st, int regionid) { ARegionType *art; @@ -404,7 +448,7 @@ static void panel_list_copy(ListBase *newlb, const ListBase *lb) } } -ARegion *BKE_area_region_copy(SpaceType *st, ARegion *region) +ARegion *BKE_area_region_copy(const SpaceType *st, const ARegion *region) { ARegion *newar = MEM_dupallocN(region); @@ -918,7 +962,7 @@ ARegion *BKE_area_find_region_xy(ScrArea *area, const int regiontype, int x, int if (area) { ARegion *region; for (region = area->regionbase.first; region; region = region->next) { - if ((regiontype == RGN_TYPE_ANY) || (region->regiontype == regiontype)) { + if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) { if (BLI_rcti_isect_pt(®ion->winrct, x, y)) { region_found = region; break; @@ -936,7 +980,7 @@ ARegion *BKE_screen_find_region_xy(bScreen *screen, const int regiontype, int x, { ARegion *region_found = NULL; LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) { - if ((regiontype == RGN_TYPE_ANY) || (region->regiontype == regiontype)) { + if (ELEM(regiontype, RGN_TYPE_ANY, region->regiontype)) { if (BLI_rcti_isect_pt(®ion->winrct, x, y)) { region_found = region; break; @@ -973,7 +1017,7 @@ ScrArea *BKE_screen_find_big_area(bScreen *screen, const int spacetype, const sh int size, maxsize = 0; for (area = screen->areabase.first; area; area = area->next) { - if ((spacetype == SPACE_TYPE_ANY) || (area->spacetype == spacetype)) { + if (ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) { if (min <= area->winx && min <= area->winy) { size = area->winx * area->winy; if (size > maxsize) { @@ -994,7 +1038,7 @@ ScrArea *BKE_screen_area_map_find_area_xy(const ScrAreaMap *areamap, { LISTBASE_FOREACH (ScrArea *, area, &areamap->areabase) { if (BLI_rcti_isect_pt(&area->totrct, x, y)) { - if ((spacetype == SPACE_TYPE_ANY) || (area->spacetype == spacetype)) { + if (ELEM(spacetype, SPACE_TYPE_ANY, area->spacetype)) { return area; } break; @@ -1111,3 +1155,797 @@ void BKE_screen_header_alignment_reset(bScreen *screen) } screen->do_refresh = true; } + +void BKE_screen_view3d_shading_blend_write(BlendWriter *writer, View3DShading *shading) +{ + if (shading->prop) { + IDP_BlendWrite(writer, shading->prop); + } +} + +void BKE_screen_view3d_shading_blend_read_data(BlendDataReader *reader, View3DShading *shading) +{ + if (shading->prop) { + BLO_read_data_address(reader, &shading->prop); + IDP_BlendDataRead(reader, &shading->prop); + } +} + +static void write_region(BlendWriter *writer, ARegion *region, int spacetype) +{ + BLO_write_struct(writer, ARegion, region); + + if (region->regiondata) { + if (region->flag & RGN_FLAG_TEMP_REGIONDATA) { + return; + } + + switch (spacetype) { + case SPACE_VIEW3D: + if (region->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = region->regiondata; + BLO_write_struct(writer, RegionView3D, rv3d); + + if (rv3d->localvd) { + BLO_write_struct(writer, RegionView3D, rv3d->localvd); + } + if (rv3d->clipbb) { + BLO_write_struct(writer, BoundBox, rv3d->clipbb); + } + } + else { + printf("regiondata write missing!\n"); + } + break; + default: + printf("regiondata write missing!\n"); + } + } +} + +static void write_uilist(BlendWriter *writer, uiList *ui_list) +{ + BLO_write_struct(writer, uiList, ui_list); + + if (ui_list->properties) { + IDP_BlendWrite(writer, ui_list->properties); + } +} + +static void write_space_outliner(BlendWriter *writer, SpaceOutliner *space_outliner) +{ + BLI_mempool *ts = space_outliner->treestore; + + if (ts) { + SpaceOutliner space_outliner_flat = *space_outliner; + + int elems = BLI_mempool_len(ts); + /* linearize mempool to array */ + TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; + + if (data) { + /* In this block we use the memory location of the treestore + * but _not_ its data, the addresses in this case are UUID's, + * since we can't rely on malloc giving us different values each time. + */ + TreeStore ts_flat = {0}; + + /* we know the treestore is at least as big as a pointer, + * so offsetting works to give us a UUID. */ + void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *)); + + ts_flat.usedelem = elems; + ts_flat.totelem = elems; + ts_flat.data = data_addr; + + BLO_write_struct(writer, SpaceOutliner, space_outliner); + + BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat); + BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data); + + MEM_freeN(data); + } + else { + space_outliner_flat.treestore = NULL; + BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat); + } + } + else { + BLO_write_struct(writer, SpaceOutliner, space_outliner); + } +} + +static void write_panel_list(BlendWriter *writer, ListBase *lb) +{ + LISTBASE_FOREACH (Panel *, panel, lb) { + BLO_write_struct(writer, Panel, panel); + write_panel_list(writer, &panel->children); + } +} + +static void write_area_regions(BlendWriter *writer, ScrArea *area) +{ + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + write_region(writer, region, area->spacetype); + write_panel_list(writer, ®ion->panels); + + LISTBASE_FOREACH (PanelCategoryStack *, pc_act, ®ion->panels_category_active) { + BLO_write_struct(writer, PanelCategoryStack, pc_act); + } + + LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { + write_uilist(writer, ui_list); + } + + LISTBASE_FOREACH (uiPreview *, ui_preview, ®ion->ui_previews) { + BLO_write_struct(writer, uiPreview, ui_preview); + } + } + + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { + write_region(writer, region, sl->spacetype); + } + + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + BLO_write_struct(writer, View3D, v3d); + + if (v3d->localvd) { + BLO_write_struct(writer, View3D, v3d->localvd); + } + + BKE_screen_view3d_shading_blend_write(writer, &v3d->shading); + } + else if (sl->spacetype == SPACE_GRAPH) { + SpaceGraph *sipo = (SpaceGraph *)sl; + ListBase tmpGhosts = sipo->runtime.ghost_curves; + + /* temporarily disable ghost curves when saving */ + BLI_listbase_clear(&sipo->runtime.ghost_curves); + + BLO_write_struct(writer, SpaceGraph, sl); + if (sipo->ads) { + BLO_write_struct(writer, bDopeSheet, sipo->ads); + } + + /* reenable ghost curves */ + sipo->runtime.ghost_curves = tmpGhosts; + } + else if (sl->spacetype == SPACE_PROPERTIES) { + BLO_write_struct(writer, SpaceProperties, sl); + } + else if (sl->spacetype == SPACE_FILE) { + SpaceFile *sfile = (SpaceFile *)sl; + + BLO_write_struct(writer, SpaceFile, sl); + if (sfile->params) { + BLO_write_struct(writer, FileSelectParams, sfile->params); + } + } + else if (sl->spacetype == SPACE_SEQ) { + BLO_write_struct(writer, SpaceSeq, sl); + } + else if (sl->spacetype == SPACE_OUTLINER) { + SpaceOutliner *space_outliner = (SpaceOutliner *)sl; + write_space_outliner(writer, space_outliner); + } + else if (sl->spacetype == SPACE_IMAGE) { + BLO_write_struct(writer, SpaceImage, sl); + } + else if (sl->spacetype == SPACE_TEXT) { + BLO_write_struct(writer, SpaceText, sl); + } + else if (sl->spacetype == SPACE_SCRIPT) { + SpaceScript *scr = (SpaceScript *)sl; + scr->but_refs = NULL; + BLO_write_struct(writer, SpaceScript, sl); + } + else if (sl->spacetype == SPACE_ACTION) { + BLO_write_struct(writer, SpaceAction, sl); + } + else if (sl->spacetype == SPACE_NLA) { + SpaceNla *snla = (SpaceNla *)sl; + + BLO_write_struct(writer, SpaceNla, snla); + if (snla->ads) { + BLO_write_struct(writer, bDopeSheet, snla->ads); + } + } + else if (sl->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + BLO_write_struct(writer, SpaceNode, snode); + + LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) { + BLO_write_struct(writer, bNodeTreePath, path); + } + } + else if (sl->spacetype == SPACE_CONSOLE) { + SpaceConsole *con = (SpaceConsole *)sl; + + LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) { + /* 'len_alloc' is invalid on write, set from 'len' on read */ + BLO_write_struct(writer, ConsoleLine, cl); + BLO_write_raw(writer, (size_t)cl->len + 1, cl->line); + } + BLO_write_struct(writer, SpaceConsole, sl); + } + else if (sl->spacetype == SPACE_TOPBAR) { + BLO_write_struct(writer, SpaceTopBar, sl); + } + else if (sl->spacetype == SPACE_STATUSBAR) { + BLO_write_struct(writer, SpaceStatusBar, sl); + } + else if (sl->spacetype == SPACE_USERPREF) { + BLO_write_struct(writer, SpaceUserPref, sl); + } + else if (sl->spacetype == SPACE_CLIP) { + BLO_write_struct(writer, SpaceClip, sl); + } + else if (sl->spacetype == SPACE_INFO) { + BLO_write_struct(writer, SpaceInfo, sl); + } + } +} + +void BKE_screen_area_map_blend_write(BlendWriter *writer, ScrAreaMap *area_map) +{ + BLO_write_struct_list(writer, ScrVert, &area_map->vertbase); + BLO_write_struct_list(writer, ScrEdge, &area_map->edgebase); + LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { + area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */ + + BLO_write_struct(writer, ScrArea, area); + + BLO_write_struct(writer, ScrGlobalAreaData, area->global); + + write_area_regions(writer, area); + + area->butspacetype = SPACE_EMPTY; /* Unset again, was changed above. */ + } +} + +static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb) +{ + BLO_read_list(reader, lb); + + LISTBASE_FOREACH (Panel *, panel, lb) { + panel->runtime_flag = 0; + panel->activedata = NULL; + panel->type = NULL; + panel->runtime.custom_data_ptr = NULL; + direct_link_panel_list(reader, &panel->children); + } +} + +static void direct_link_region(BlendDataReader *reader, ARegion *region, int spacetype) +{ + direct_link_panel_list(reader, ®ion->panels); + + BLO_read_list(reader, ®ion->panels_category_active); + + BLO_read_list(reader, ®ion->ui_lists); + + /* The area's search filter is runtime only, so we need to clear the active flag on read. */ + region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE; + + LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { + ui_list->type = NULL; + ui_list->dyn_data = NULL; + BLO_read_data_address(reader, &ui_list->properties); + IDP_BlendDataRead(reader, &ui_list->properties); + } + + BLO_read_list(reader, ®ion->ui_previews); + + if (spacetype == SPACE_EMPTY) { + /* unknown space type, don't leak regiondata */ + region->regiondata = NULL; + } + else if (region->flag & RGN_FLAG_TEMP_REGIONDATA) { + /* Runtime data, don't use. */ + region->regiondata = NULL; + } + else { + BLO_read_data_address(reader, ®ion->regiondata); + if (region->regiondata) { + if (spacetype == SPACE_VIEW3D) { + RegionView3D *rv3d = region->regiondata; + + BLO_read_data_address(reader, &rv3d->localvd); + BLO_read_data_address(reader, &rv3d->clipbb); + + rv3d->depths = NULL; + rv3d->render_engine = NULL; + rv3d->sms = NULL; + rv3d->smooth_timer = NULL; + + rv3d->rflag &= ~(RV3D_NAVIGATING | RV3D_PAINTING); + rv3d->runtime_viewlock = 0; + } + } + } + + region->v2d.sms = NULL; + region->v2d.alpha_hor = region->v2d.alpha_vert = 255; /* visible by default */ + BLI_listbase_clear(®ion->panels_category); + BLI_listbase_clear(®ion->handlers); + BLI_listbase_clear(®ion->uiblocks); + region->headerstr = NULL; + region->visible = 0; + region->type = NULL; + region->do_draw = 0; + region->gizmo_map = NULL; + region->regiontimer = NULL; + region->draw_buffer = NULL; + memset(®ion->drawrct, 0, sizeof(region->drawrct)); +} + +/* for the saved 2.50 files without regiondata */ +/* and as patch for 2.48 and older */ +void BKE_screen_view3d_do_versions_250(View3D *v3d, ListBase *regions) +{ + LISTBASE_FOREACH (ARegion *, region, regions) { + if (region->regiontype == RGN_TYPE_WINDOW && region->regiondata == NULL) { + RegionView3D *rv3d; + + rv3d = region->regiondata = MEM_callocN(sizeof(RegionView3D), "region v3d patch"); + rv3d->persp = (char)v3d->persp; + rv3d->view = (char)v3d->view; + rv3d->dist = v3d->dist; + copy_v3_v3(rv3d->ofs, v3d->ofs); + copy_qt_qt(rv3d->viewquat, v3d->viewquat); + } + } + + /* this was not initialized correct always */ + if (v3d->gridsubdiv == 0) { + v3d->gridsubdiv = 10; + } +} + +static void direct_link_area(BlendDataReader *reader, ScrArea *area) +{ + BLO_read_list(reader, &(area->spacedata)); + BLO_read_list(reader, &(area->regionbase)); + + BLI_listbase_clear(&area->handlers); + area->type = NULL; /* spacetype callbacks */ + + /* Should always be unset so that rna_Area_type_get works correctly. */ + area->butspacetype = SPACE_EMPTY; + + area->region_active_win = -1; + + area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; + + BLO_read_data_address(reader, &area->global); + + /* if we do not have the spacetype registered we cannot + * free it, so don't allocate any new memory for such spacetypes. */ + if (!BKE_spacetype_exists(area->spacetype)) { + /* Hint for versioning code to replace deprecated space types. */ + area->butspacetype = area->spacetype; + + area->spacetype = SPACE_EMPTY; + } + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + direct_link_region(reader, region, area->spacetype); + } + + /* accident can happen when read/save new file with older version */ + /* 2.50: we now always add spacedata for info */ + if (area->spacedata.first == NULL) { + SpaceInfo *sinfo = MEM_callocN(sizeof(SpaceInfo), "spaceinfo"); + area->spacetype = sinfo->spacetype = SPACE_INFO; + BLI_addtail(&area->spacedata, sinfo); + } + /* add local view3d too */ + else if (area->spacetype == SPACE_VIEW3D) { + BKE_screen_view3d_do_versions_250(area->spacedata.first, &area->regionbase); + } + + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + BLO_read_list(reader, &(sl->regionbase)); + + /* if we do not have the spacetype registered we cannot + * free it, so don't allocate any new memory for such spacetypes. */ + if (!BKE_spacetype_exists(sl->spacetype)) { + sl->spacetype = SPACE_EMPTY; + } + + LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { + direct_link_region(reader, region, sl->spacetype); + } + + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + + v3d->flag |= V3D_INVALID_BACKBUF; + + if (v3d->gpd) { + BLO_read_data_address(reader, &v3d->gpd); + BKE_gpencil_blend_read_data(reader, v3d->gpd); + } + BLO_read_data_address(reader, &v3d->localvd); + + /* Runtime data */ + v3d->runtime.properties_storage = NULL; + v3d->runtime.flag = 0; + + /* render can be quite heavy, set to solid on load */ + if (v3d->shading.type == OB_RENDER) { + v3d->shading.type = OB_SOLID; + } + v3d->shading.prev_type = OB_SOLID; + + BKE_screen_view3d_shading_blend_read_data(reader, &v3d->shading); + + BKE_screen_view3d_do_versions_250(v3d, &sl->regionbase); + } + else if (sl->spacetype == SPACE_GRAPH) { + SpaceGraph *sipo = (SpaceGraph *)sl; + + BLO_read_data_address(reader, &sipo->ads); + BLI_listbase_clear(&sipo->runtime.ghost_curves); + } + else if (sl->spacetype == SPACE_NLA) { + SpaceNla *snla = (SpaceNla *)sl; + + BLO_read_data_address(reader, &snla->ads); + } + else if (sl->spacetype == SPACE_OUTLINER) { + SpaceOutliner *space_outliner = (SpaceOutliner *)sl; + + /* use #BLO_read_get_new_data_address_no_us and do not free old memory avoiding double + * frees and use of freed memory. this could happen because of a + * bug fixed in revision 58959 where the treestore memory address + * was not unique */ + TreeStore *ts = BLO_read_get_new_data_address_no_us(reader, space_outliner->treestore); + space_outliner->treestore = NULL; + if (ts) { + TreeStoreElem *elems = BLO_read_get_new_data_address_no_us(reader, ts->data); + + space_outliner->treestore = BLI_mempool_create( + sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER); + if (ts->usedelem && elems) { + for (int i = 0; i < ts->usedelem; i++) { + TreeStoreElem *new_elem = BLI_mempool_alloc(space_outliner->treestore); + *new_elem = elems[i]; + } + } + /* we only saved what was used */ + space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */ + } + space_outliner->treehash = NULL; + space_outliner->tree.first = space_outliner->tree.last = NULL; + } + else if (sl->spacetype == SPACE_IMAGE) { + SpaceImage *sima = (SpaceImage *)sl; + + sima->iuser.scene = NULL; + sima->iuser.ok = 1; + sima->scopes.waveform_1 = NULL; + sima->scopes.waveform_2 = NULL; + sima->scopes.waveform_3 = NULL; + sima->scopes.vecscope = NULL; + sima->scopes.ok = 0; + + /* WARNING: gpencil data is no longer stored directly in sima after 2.5 + * so sacrifice a few old files for now to avoid crashes with new files! + * committed: r28002 */ +#if 0 + sima->gpd = newdataadr(fd, sima->gpd); + if (sima->gpd) { + BKE_gpencil_blend_read_data(fd, sima->gpd); + } +#endif + } + else if (sl->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)sl; + + if (snode->gpd) { + BLO_read_data_address(reader, &snode->gpd); + BKE_gpencil_blend_read_data(reader, snode->gpd); + } + + BLO_read_list(reader, &snode->treepath); + snode->edittree = NULL; + snode->iofsd = NULL; + BLI_listbase_clear(&snode->linkdrag); + } + else if (sl->spacetype == SPACE_TEXT) { + SpaceText *st = (SpaceText *)sl; + memset(&st->runtime, 0, sizeof(st->runtime)); + } + else if (sl->spacetype == SPACE_SEQ) { + SpaceSeq *sseq = (SpaceSeq *)sl; + + /* grease pencil data is not a direct data and can't be linked from direct_link* + * functions, it should be linked from lib_link* functions instead + * + * otherwise it'll lead to lost grease data on open because it'll likely be + * read from file after all other users of grease pencil and newdataadr would + * simple return NULL here (sergey) + */ +#if 0 + if (sseq->gpd) { + sseq->gpd = newdataadr(fd, sseq->gpd); + BKE_gpencil_blend_read_data(fd, sseq->gpd); + } +#endif + sseq->scopes.reference_ibuf = NULL; + sseq->scopes.zebra_ibuf = NULL; + sseq->scopes.waveform_ibuf = NULL; + sseq->scopes.sep_waveform_ibuf = NULL; + sseq->scopes.vector_ibuf = NULL; + sseq->scopes.histogram_ibuf = NULL; + } + else if (sl->spacetype == SPACE_PROPERTIES) { + SpaceProperties *sbuts = (SpaceProperties *)sl; + + sbuts->path = NULL; + sbuts->texuser = NULL; + sbuts->mainbo = sbuts->mainb; + sbuts->mainbuser = sbuts->mainb; + sbuts->runtime = NULL; + } + else if (sl->spacetype == SPACE_CONSOLE) { + SpaceConsole *sconsole = (SpaceConsole *)sl; + + BLO_read_list(reader, &sconsole->scrollback); + BLO_read_list(reader, &sconsole->history); + + /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression, + * from left to right. the right-most expression sets the result of the comma + * expression as a whole*/ + LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) { + BLO_read_data_address(reader, &cl->line); + if (cl->line) { + /* the allocted length is not written, so reset here */ + cl->len_alloc = cl->len + 1; + } + else { + BLI_remlink(&sconsole->history, cl); + MEM_freeN(cl); + } + } + } + else if (sl->spacetype == SPACE_FILE) { + SpaceFile *sfile = (SpaceFile *)sl; + + /* this sort of info is probably irrelevant for reloading... + * plus, it isn't saved to files yet! + */ + sfile->folders_prev = sfile->folders_next = NULL; + sfile->files = NULL; + sfile->layout = NULL; + sfile->op = NULL; + sfile->previews_timer = NULL; + BLO_read_data_address(reader, &sfile->params); + } + else if (sl->spacetype == SPACE_CLIP) { + SpaceClip *sclip = (SpaceClip *)sl; + + sclip->scopes.track_search = NULL; + sclip->scopes.track_preview = NULL; + sclip->scopes.ok = 0; + } + } + + BLI_listbase_clear(&area->actionzones); + + BLO_read_data_address(reader, &area->v1); + BLO_read_data_address(reader, &area->v2); + BLO_read_data_address(reader, &area->v3); + BLO_read_data_address(reader, &area->v4); +} + +/** + * \return false on error. + */ +bool BKE_screen_area_map_blend_read_data(BlendDataReader *reader, ScrAreaMap *area_map) +{ + BLO_read_list(reader, &area_map->vertbase); + BLO_read_list(reader, &area_map->edgebase); + BLO_read_list(reader, &area_map->areabase); + LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { + direct_link_area(reader, area); + } + + /* edges */ + LISTBASE_FOREACH (ScrEdge *, se, &area_map->edgebase) { + BLO_read_data_address(reader, &se->v1); + BLO_read_data_address(reader, &se->v2); + BKE_screen_sort_scrvert(&se->v1, &se->v2); + + if (se->v1 == NULL) { + BLI_remlink(&area_map->edgebase, se); + + return false; + } + } + + return true; +} + +void BKE_screen_area_blend_read_lib(BlendLibReader *reader, ID *parent_id, ScrArea *area) +{ + BLO_read_id_address(reader, parent_id->lib, &area->full); + + memset(&area->runtime, 0x0, sizeof(area->runtime)); + + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + switch (sl->spacetype) { + case SPACE_VIEW3D: { + View3D *v3d = (View3D *)sl; + + BLO_read_id_address(reader, parent_id->lib, &v3d->camera); + BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center); + + if (v3d->localvd) { + BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera); + } + break; + } + case SPACE_GRAPH: { + SpaceGraph *sipo = (SpaceGraph *)sl; + bDopeSheet *ads = sipo->ads; + + if (ads) { + BLO_read_id_address(reader, parent_id->lib, &ads->source); + BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); + } + break; + } + case SPACE_PROPERTIES: { + SpaceProperties *sbuts = (SpaceProperties *)sl; + BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid); + if (sbuts->pinid == NULL) { + sbuts->flag &= ~SB_PIN_CONTEXT; + } + break; + } + case SPACE_FILE: + break; + case SPACE_ACTION: { + SpaceAction *saction = (SpaceAction *)sl; + bDopeSheet *ads = &saction->ads; + + if (ads) { + BLO_read_id_address(reader, parent_id->lib, &ads->source); + BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); + } + + BLO_read_id_address(reader, parent_id->lib, &saction->action); + break; + } + case SPACE_IMAGE: { + SpaceImage *sima = (SpaceImage *)sl; + + BLO_read_id_address(reader, parent_id->lib, &sima->image); + BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask); + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so fingers crossed this works fine! + */ + BLO_read_id_address(reader, parent_id->lib, &sima->gpd); + break; + } + case SPACE_SEQ: { + SpaceSeq *sseq = (SpaceSeq *)sl; + + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so fingers crossed this works fine! + */ + BLO_read_id_address(reader, parent_id->lib, &sseq->gpd); + break; + } + case SPACE_NLA: { + SpaceNla *snla = (SpaceNla *)sl; + bDopeSheet *ads = snla->ads; + + if (ads) { + BLO_read_id_address(reader, parent_id->lib, &ads->source); + BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); + } + break; + } + case SPACE_TEXT: { + SpaceText *st = (SpaceText *)sl; + + BLO_read_id_address(reader, parent_id->lib, &st->text); + break; + } + case SPACE_SCRIPT: { + SpaceScript *scpt = (SpaceScript *)sl; + /*scpt->script = NULL; - 2.45 set to null, better re-run the script */ + if (scpt->script) { + BLO_read_id_address(reader, parent_id->lib, &scpt->script); + if (scpt->script) { + SCRIPT_SET_NULL(scpt->script); + } + } + break; + } + case SPACE_OUTLINER: { + SpaceOutliner *space_outliner = (SpaceOutliner *)sl; + BLO_read_id_address(reader, NULL, &space_outliner->search_tse.id); + + if (space_outliner->treestore) { + TreeStoreElem *tselem; + BLI_mempool_iter iter; + + BLI_mempool_iternew(space_outliner->treestore, &iter); + while ((tselem = BLI_mempool_iterstep(&iter))) { + BLO_read_id_address(reader, NULL, &tselem->id); + } + if (space_outliner->treehash) { + /* rebuild hash table, because it depends on ids too */ + space_outliner->storeflag |= SO_TREESTORE_REBUILD; + } + } + break; + } + case SPACE_NODE: { + SpaceNode *snode = (SpaceNode *)sl; + + /* node tree can be stored locally in id too, link this first */ + BLO_read_id_address(reader, parent_id->lib, &snode->id); + BLO_read_id_address(reader, parent_id->lib, &snode->from); + + bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : NULL; + if (ntree) { + snode->nodetree = ntree; + } + else { + BLO_read_id_address(reader, parent_id->lib, &snode->nodetree); + } + + bNodeTreePath *path; + for (path = snode->treepath.first; path; path = path->next) { + if (path == snode->treepath.first) { + /* first nodetree in path is same as snode->nodetree */ + path->nodetree = snode->nodetree; + } + else { + BLO_read_id_address(reader, parent_id->lib, &path->nodetree); + } + + if (!path->nodetree) { + break; + } + } + + /* remaining path entries are invalid, remove */ + bNodeTreePath *path_next; + for (; path; path = path_next) { + path_next = path->next; + + BLI_remlink(&snode->treepath, path); + MEM_freeN(path); + } + + /* edittree is just the last in the path, + * set this directly since the path may have been shortened above */ + if (snode->treepath.last) { + path = snode->treepath.last; + snode->edittree = path->nodetree; + } + else { + snode->edittree = NULL; + } + break; + } + case SPACE_CLIP: { + SpaceClip *sclip = (SpaceClip *)sl; + BLO_read_id_address(reader, parent_id->lib, &sclip->clip); + BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask); + break; + } + default: + break; + } + } +} diff --git a/source/blender/blenkernel/intern/shader_fx.c b/source/blender/blenkernel/intern/shader_fx.c index f2cdf08b415..2ae95492708 100644 --- a/source/blender/blenkernel/intern/shader_fx.c +++ b/source/blender/blenkernel/intern/shader_fx.c @@ -36,6 +36,7 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_screen_types.h" #include "DNA_shader_fx_types.h" #include "BKE_gpencil.h" @@ -175,6 +176,11 @@ void BKE_shaderfxType_panel_id(ShaderFxType type, char *r_idname) strcat(r_idname, fxi->name); } +void BKE_shaderfx_panel_expand(ShaderFxData *fx) +{ + fx->ui_expand_flag |= UI_PANEL_DATA_EXPAND_ROOT; +} + void BKE_shaderfx_copydata_generic(const ShaderFxData *fx_src, ShaderFxData *fx_dst) { const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info(fx_src->type); diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c index 0c9ee61ca19..ae39b200b56 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.c +++ b/source/blender/blenkernel/intern/shrinkwrap.c @@ -1548,8 +1548,8 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object ssmd.shrinkMode = MOD_SHRINKWRAP_ON_SURFACE; ssmd.shrinkOpts = MOD_SHRINKWRAP_PROJECT_ALLOW_NEG_DIR | MOD_SHRINKWRAP_PROJECT_ALLOW_POS_DIR; ssmd.keepDist = 0.0f; - - /* Tolerance value to prevent artifacts on sharp edges of a mesh. + + /* Tolerance value to prevent artifacts on sharp edges of a mesh. * This constant and based on experimenting with different values. */ const float projLimitTolerance = 5.0f; ssmd.projLimit = target_me->remesh_voxel_size * projLimitTolerance; diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index 2e1f8bd581e..6e4ce2eaee2 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -171,6 +171,8 @@ IDTypeInfo IDType_ID_SIM = { /* blend_read_data */ simulation_blend_read_data, /* blend_read_lib */ simulation_blend_read_lib, /* blend_read_expand */ simulation_blend_read_expand, + + /* blend_read_undo_preserve */ NULL, }; void *BKE_simulation_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index bf61c27ee2f..efed9453003 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1063,7 +1063,7 @@ static int sb_detect_face_pointCached(const float face_v1[3], GHash *hash; GHashIterator *ihash; float nv1[3], edge1[3], edge2[3], d_nvect[3], aabbmin[3], aabbmax[3]; - float facedist, outerfacethickness, tune = 10.f; + float facedist, outerfacethickness, tune = 10.0f; int a, deflected = 0; aabbmin[0] = min_fff(face_v1[0], face_v2[0], face_v3[0]); @@ -2032,7 +2032,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, attached = 0; for (b = obp->nofsprings; b > 0; b--) { bs = sb->bspring + obp->springs[b - 1]; - if ((ilast - bb == bs->v2) || (ilast - bb == bs->v1)) { + if (ELEM(ilast - bb, bs->v2, bs->v1)) { attached = 1; continue; } @@ -2797,8 +2797,8 @@ static void reference_to_scratch(Object *ob) SoftBody *sb = ob->soft; ReferenceVert *rp; BodyPoint *bp; - float accu_pos[3] = {0.f, 0.f, 0.f}; - float accu_mass = 0.f; + float accu_pos[3] = {0.0f, 0.0f, 0.0f}; + float accu_mass = 0.0f; int a; sb->scratch->Ref.ivert = MEM_mallocN(sizeof(ReferenceVert) * sb->totpoint, "SB_Reference"); diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index 8bec9f331c5..07532d525bd 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -60,7 +60,6 @@ #include "BKE_main.h" #include "BKE_packedFile.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "DEG_depsgraph.h" @@ -68,6 +67,8 @@ #include "BLO_read_write.h" +#include "SEQ_sequencer.h" + static void sound_free_audio(bSound *sound); static void sound_copy_data(Main *UNUSED(bmain), @@ -211,6 +212,8 @@ IDTypeInfo IDType_ID_SO = { .blend_read_data = sound_blend_read_data, .blend_read_lib = sound_blend_read_lib, .blend_read_expand = sound_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; #ifdef WITH_AUDASPACE diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c index a98093d1893..fabf0bb8971 100644 --- a/source/blender/blenkernel/intern/speaker.c +++ b/source/blender/blenkernel/intern/speaker.c @@ -112,6 +112,8 @@ IDTypeInfo IDType_ID_SPK = { .blend_read_data = speaker_blend_read_data, .blend_read_lib = speaker_blend_read_lib, .blend_read_expand = speaker_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; void *BKE_speaker_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 93306703686..6f4ac4c44a0 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -256,6 +256,8 @@ IDTypeInfo IDType_ID_TXT = { .blend_read_data = text_blend_read_data, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; /** \} */ @@ -2333,7 +2335,7 @@ int txt_setcurr_tab_spaces(Text *text, int space) if (ch == ':') { is_indent = 1; } - else if (ch != ' ' && ch != '\t') { + else if (!ELEM(ch, ' ', '\t')) { is_indent = 0; } } @@ -2459,7 +2461,7 @@ int text_check_identifier_nodigit_unicode(const unsigned int ch) bool text_check_whitespace(const char ch) { - if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { + if (ELEM(ch, ' ', '\t', '\r', '\n')) { return true; } return false; diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 90c4f71ce7a..a77e0ed2b7d 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -224,6 +224,8 @@ IDTypeInfo IDType_ID_TE = { .blend_read_data = texture_blend_read_data, .blend_read_lib = texture_blend_read_lib, .blend_read_expand = texture_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; /* Utils for all IDs using those texture slots. */ diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index cb33610a93f..7f927a8838e 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -338,6 +338,7 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_weight = 1.0f; tracking->settings.dist = 1; tracking->settings.object_distance = 1; + tracking->settings.refine_camera_intrinsics = REFINE_NO_INTRINSICS; tracking->stabilization.scaleinf = 1.0f; tracking->stabilization.anchor_frame = 1; diff --git a/source/blender/blenkernel/intern/tracking_solver.c b/source/blender/blenkernel/intern/tracking_solver.c index 7df8bf62b16..d89d36f85ea 100644 --- a/source/blender/blenkernel/intern/tracking_solver.c +++ b/source/blender/blenkernel/intern/tracking_solver.c @@ -291,12 +291,12 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, flags |= LIBMV_REFINE_PRINCIPAL_POINT; } - if (refine & REFINE_RADIAL_DISTORTION_K1) { - flags |= LIBMV_REFINE_RADIAL_DISTORTION_K1; + if (refine & REFINE_RADIAL_DISTORTION) { + flags |= LIBMV_REFINE_RADIAL_DISTORTION; } - if (refine & REFINE_RADIAL_DISTORTION_K2) { - flags |= LIBMV_REFINE_RADIAL_DISTORTION_K2; + if (refine & REFINE_TANGENTIAL_DISTORTION) { + flags |= LIBMV_REFINE_TANGENTIAL_DISTORTION; } return flags; diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c index bc6c94343b5..c7e4e0d5c08 100644 --- a/source/blender/blenkernel/intern/tracking_util.c +++ b/source/blender/blenkernel/intern/tracking_util.c @@ -722,7 +722,7 @@ static ImBuf *make_grayscale_ibuf_copy(ImBuf *ibuf) { ImBuf *grayscale = IMB_allocImBuf(ibuf->x, ibuf->y, 32, 0); - BLI_assert(ibuf->channels == 3 || ibuf->channels == 4); + BLI_assert(ELEM(ibuf->channels, 3, 4)); /* TODO(sergey): Bummer, currently IMB API only allows to create 4 channels * float buffer, so we do it manually here. @@ -880,7 +880,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor, } /* Transform number of channels. */ if (input_mode == LIBMV_IMAGE_MODE_RGBA) { - BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4); + BLI_assert(ELEM(orig_ibuf->channels, 3, 4)); /* pass */ } else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ { diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index 93f70b606dc..b687254fd69 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -95,7 +95,7 @@ static bool g_undo_callback_running = false; /** \name Public Undo Types * * Unfortunately we need this for a handful of places. - */ + * \{ */ const UndoType *BKE_UNDOSYS_TYPE_IMAGE = NULL; const UndoType *BKE_UNDOSYS_TYPE_MEMFILE = NULL; const UndoType *BKE_UNDOSYS_TYPE_PAINTCURVE = NULL; @@ -357,7 +357,7 @@ void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain) void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C) { const UndoType *ut = BKE_undosys_type_from_context(C); - if ((ut != NULL) && (ut != BKE_UNDOSYS_TYPE_MEMFILE)) { + if (!ELEM(ut, NULL, BKE_UNDOSYS_TYPE_MEMFILE)) { BKE_undosys_step_push_with_type(ustack, C, IFACE_("Original Mode"), ut); } } @@ -549,6 +549,8 @@ bool BKE_undosys_step_push_with_type(UndoStack *ustack, BLI_strncpy(us->name, name, sizeof(us->name)); } us->type = ut; + /* True by default, code needs to explicitely set it to false if necessary. */ + us->use_old_bmain_data = true; /* Initialized, not added yet. */ CLOG_INFO(&LOG, 1, "addr=%p, name='%s', type='%s'", us, us->name, us->type->name); @@ -897,7 +899,7 @@ void BKE_undosys_stack_group_end(UndoStack *ustack) /** \name ID Reference Utilities * * Unfortunately we need this for a handful of places. - */ + * \{ */ static void UNUSED_FUNCTION(BKE_undosys_foreach_ID_ref(UndoStack *ustack, UndoTypeForEachIDRefFn foreach_ID_ref_fn, diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 73bf149bf2a..249a35a0af8 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -822,7 +822,7 @@ static char *find_next_op(const char *str, char *remaining_str, int len_max) } /* Check for scientific notation. */ - if (remaining_str[i - 1] == 'e' || remaining_str[i - 1] == 'E') { + if (ELEM(remaining_str[i - 1], 'e', 'E')) { scientific_notation = true; continue; } @@ -1184,7 +1184,7 @@ bool BKE_unit_replace_string( /* Any operators after this? */ for (ch = str_found + 1; *ch != '\0'; ch++) { - if (*ch == ' ' || *ch == '\t') { + if (ELEM(*ch, ' ', '\t')) { continue; } op_found = (ch_is_op(*ch) || ELEM(*ch, ',', ')')); diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 87993695486..9c60cb842ae 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -633,6 +633,8 @@ IDTypeInfo IDType_ID_VO = { /* blend_read_data */ volume_blend_read_data, /* blend_read_lib */ volume_blend_read_lib, /* blend_read_expand */ volume_blend_read_expand, + + /* blend_read_undo_preserve */ NULL, }; void BKE_volume_init_grids(Volume *volume) diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c index cd163b7c8bf..291116556c3 100644 --- a/source/blender/blenkernel/intern/workspace.c +++ b/source/blender/blenkernel/intern/workspace.c @@ -48,6 +48,8 @@ #include "MEM_guardedalloc.h" +#include "BLO_read_write.h" + /* -------------------------------------------------------------------- */ static void workspace_free_data(ID *id) @@ -75,6 +77,98 @@ static void workspace_foreach_id(ID *id, LibraryForeachIDData *data) } } +static void workspace_blend_write(BlendWriter *writer, ID *id, const void *id_address) +{ + WorkSpace *workspace = (WorkSpace *)id; + + BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id); + BKE_id_blend_write(writer, &workspace->id); + BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts); + BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations); + BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids); + BLO_write_struct_list(writer, bToolRef, &workspace->tools); + LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { + if (tref->properties) { + IDP_BlendWrite(writer, tref->properties); + } + } +} + +static void workspace_blend_read_data(BlendDataReader *reader, ID *id) +{ + WorkSpace *workspace = (WorkSpace *)id; + + BLO_read_list(reader, &workspace->layouts); + BLO_read_list(reader, &workspace->hook_layout_relations); + BLO_read_list(reader, &workspace->owner_ids); + BLO_read_list(reader, &workspace->tools); + + LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { + /* parent pointer does not belong to workspace data and is therefore restored in lib_link step + * of window manager.*/ + BLO_read_data_address(reader, &relation->value); + } + + LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { + tref->runtime = NULL; + BLO_read_data_address(reader, &tref->properties); + IDP_BlendDataRead(reader, &tref->properties); + } + + workspace->status_text = NULL; + + id_us_ensure_real(&workspace->id); +} + +static void workspace_blend_read_lib(BlendLibReader *reader, ID *id) +{ + WorkSpace *workspace = (WorkSpace *)id; + Main *bmain = BLO_read_lib_get_main(reader); + + /* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */ + LISTBASE_FOREACH_MUTABLE (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { + relation->parent = NULL; + LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + if (win->winid == relation->parentid) { + relation->parent = win->workspace_hook; + } + } + } + if (relation->parent == NULL) { + BLI_freelinkN(&workspace->hook_layout_relations, relation); + } + } + + LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) { + BLO_read_id_address(reader, id->lib, &layout->screen); + + if (layout->screen) { + if (ID_IS_LINKED(id)) { + layout->screen->winid = 0; + if (layout->screen->temp) { + /* delete temp layouts when appending */ + BKE_workspace_layout_remove(bmain, workspace, layout); + } + } + } + else { + /* If we're reading a layout without screen stored, it's useless and we shouldn't keep it + * around. */ + BKE_workspace_layout_remove(bmain, workspace, layout); + } + } +} + +static void workspace_blend_read_expand(BlendExpander *expander, ID *id) +{ + WorkSpace *workspace = (WorkSpace *)id; + + LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { + BLO_expand(expander, BKE_workspace_layout_screen_get(layout)); + } +} + IDTypeInfo IDType_ID_WS = { .id_code = ID_WS, .id_filter = FILTER_ID_WS, @@ -92,12 +186,15 @@ IDTypeInfo IDType_ID_WS = { .foreach_id = workspace_foreach_id, .foreach_cache = NULL, - .blend_write = NULL, - .blend_read_data = NULL, - .blend_read_lib = NULL, - .blend_read_expand = NULL, + .blend_write = workspace_blend_write, + .blend_read_data = workspace_blend_read_data, + .blend_read_lib = workspace_blend_read_lib, + .blend_read_expand = workspace_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; +/* -------------------------------------------------------------------- */ /** \name Internal Utils * \{ */ diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 094557502a3..8fe7653fc25 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -204,6 +204,8 @@ IDTypeInfo IDType_ID_WO = { .blend_read_data = world_blend_read_data, .blend_read_lib = world_blend_read_lib, .blend_read_expand = world_blend_read_expand, + + .blend_read_undo_preserve = NULL, }; World *BKE_world_add(Main *bmain, const char *name) diff --git a/source/blender/blenlib/BLI_args.h b/source/blender/blenlib/BLI_args.h index 54b5161f15a..b12b7ff5d1e 100644 --- a/source/blender/blenlib/BLI_args.h +++ b/source/blender/blenlib/BLI_args.h @@ -38,41 +38,41 @@ typedef struct bArgs bArgs; */ typedef int (*BA_ArgCallback)(int argc, const char **argv, void *data); -struct bArgs *BLI_argsInit(int argc, const char **argv); -void BLI_argsFree(struct bArgs *ba); +struct bArgs *BLI_args_create(int argc, const char **argv); +void BLI_args_destroy(struct bArgs *ba); + +/** The pass to use for #BLI_args_add. */ +void BLI_args_pass_set(struct bArgs *ba, int current_pass); /** * Pass starts at 1, -1 means valid all the time * short_arg or long_arg can be null to specify no short or long versions */ -void BLI_argsAdd(struct bArgs *ba, - int pass, - const char *short_arg, - const char *long_arg, - const char *doc, - BA_ArgCallback cb, - void *data); +void BLI_args_add(struct bArgs *ba, + const char *short_arg, + const char *long_arg, + const char *doc, + BA_ArgCallback cb, + void *data); /** * Short_case and long_case specify if those arguments are case specific */ -void BLI_argsAddCase(struct bArgs *ba, - int pass, - const char *short_arg, - int short_case, - const char *long_arg, - int long_case, - const char *doc, - BA_ArgCallback cb, - void *data); +void BLI_args_add_case(struct bArgs *ba, + const char *short_arg, + int short_case, + const char *long_arg, + int long_case, + const char *doc, + BA_ArgCallback cb, + void *data); -void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *data); +void BLI_args_parse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *data); -void BLI_argsPrintArgDoc(struct bArgs *ba, const char *arg); -void BLI_argsPrintOtherDoc(struct bArgs *ba); +void BLI_args_print_arg_doc(struct bArgs *ba, const char *arg); +void BLI_args_print_other_doc(struct bArgs *ba); -void BLI_argsPrint(struct bArgs *ba); -const char **BLI_argsArgv(struct bArgs *ba); +void BLI_args_print(struct bArgs *ba); #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index 960ce44c58c..c97be6eed3c 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -106,7 +106,7 @@ typedef unsigned int BLI_bitmap; #define BLI_BITMAP_RESIZE(_bitmap, _tot) \ { \ CHECK_TYPE(_bitmap, BLI_bitmap *); \ - (_bitmap) = MEM_reallocN(_bitmap, BLI_BITMAP_SIZE(_tot)); \ + (_bitmap) = MEM_recallocN(_bitmap, BLI_BITMAP_SIZE(_tot)); \ } \ (void)0 diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index e38848e2967..bc517f81955 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -74,6 +74,7 @@ enum { #endif }; +/* -------------------------------------------------------------------- */ /** \name GHash API * * Defined in ``BLI_ghash.c`` @@ -124,6 +125,7 @@ void BLI_ghash_flag_clear(GHash *gh, unsigned int flag); /** \} */ +/* -------------------------------------------------------------------- */ /** \name GHash Iterator * \{ */ @@ -175,6 +177,7 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) /** \} */ +/* -------------------------------------------------------------------- */ /** \name GSet API * A 'set' implementation (unordered collection of unique elements). * @@ -222,6 +225,7 @@ void *BLI_gset_pop_key(GSet *gs, const void *key) ATTR_WARN_UNUSED_RESULT; /** \} */ +/* -------------------------------------------------------------------- */ /** \name GSet Iterator * \{ */ @@ -272,6 +276,7 @@ BLI_INLINE bool BLI_gsetIterator_done(GSetIterator *gsi) /** \} */ +/* -------------------------------------------------------------------- */ /** \name GHash/GSet Debugging API's * \{ */ @@ -297,6 +302,7 @@ double BLI_gset_calc_quality(GSet *gs); #endif /* GHASH_INTERNAL_API */ /** \} */ +/* -------------------------------------------------------------------- */ /** \name GHash/GSet Macros * \{ */ @@ -324,6 +330,7 @@ double BLI_gset_calc_quality(GSet *gs); /** \} */ +/* -------------------------------------------------------------------- */ /** \name GHash/GSet Utils * * Defined in ``BLI_ghash_utils.c`` diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h index 065ed12f353..be98304e6b5 100644 --- a/source/blender/blenlib/BLI_linklist_stack.h +++ b/source/blender/blenlib/BLI_linklist_stack.h @@ -32,12 +32,9 @@ */ /* -------------------------------------------------------------------- */ -/* Linked Stack using BLI_mempool - * - * Uses mempool for storage. - */ - /** \name Linked Stack (mempool) + * + * Uses #BLI_mempool for storage. * \{ */ #define BLI_LINKSTACK_DECLARE(var, type) \ @@ -94,13 +91,12 @@ /** \} */ /* -------------------------------------------------------------------- */ -/* Linked Stack, using stack memory (alloca) +/** \name Linked Stack (alloca) + * + * Linked Stack, using stack memory (alloca). * * alloca never frees, pop'd items are stored in a free-list for reuse. * only use for lists small enough to fit on the stack. - */ - -/** \name Linked Stack (alloca) * \{ */ #ifdef __GNUC__ diff --git a/source/blender/blenlib/BLI_map.hh b/source/blender/blenlib/BLI_map.hh index 08fe1a3cdbc..9480af89107 100644 --- a/source/blender/blenlib/BLI_map.hh +++ b/source/blender/blenlib/BLI_map.hh @@ -230,19 +230,25 @@ class Map { */ void add_new(const Key &key, const Value &value) { - this->add_new__impl(key, value, hash_(key)); + this->add_new_as(key, value); } void add_new(const Key &key, Value &&value) { - this->add_new__impl(key, std::move(value), hash_(key)); + this->add_new_as(key, std::move(value)); } void add_new(Key &&key, const Value &value) { - this->add_new__impl(std::move(key), value, hash_(key)); + this->add_new_as(std::move(key), value); } void add_new(Key &&key, Value &&value) { - this->add_new__impl(std::move(key), std::move(value), hash_(key)); + this->add_new_as(std::move(key), std::move(value)); + } + template<typename ForwardKey, typename ForwardValue> + void add_new_as(ForwardKey &&key, ForwardValue &&value) + { + this->add_new__impl( + std::forward<ForwardKey>(key), std::forward<ForwardValue>(value), hash_(key)); } /** @@ -1010,7 +1016,7 @@ class Map { return; } else { - auto return_value = create_value(value_ptr); + auto &&return_value = create_value(value_ptr); slot.occupy_no_value(std::forward<ForwardKey>(key), hash); occupied_and_removed_slots_++; return return_value; diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 9f6c56d698a..d971f48c4cf 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -322,9 +322,13 @@ void mat4_to_size(float size[3], const float M[4][4]); void mat4_to_size_fix_shear(float size[3], const float M[4][4]); +void translate_m3(float mat[3][3], float tx, float ty); void translate_m4(float mat[4][4], float tx, float ty, float tz); +void rotate_m3(float mat[3][3], const float angle); void rotate_m4(float mat[4][4], const char axis, const float angle); +void rescale_m3(float mat[3][3], const float scale[2]); void rescale_m4(float mat[4][4], const float scale[3]); +void transform_pivot_set_m3(float mat[3][3], const float pivot[2]); void transform_pivot_set_m4(float mat[4][4], const float pivot[3]); void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]); @@ -334,6 +338,10 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3]); +void loc_rot_size_to_mat3(float R[3][3], + const float loc[2], + const float angle, + const float size[2]); void loc_rot_size_to_mat4(float R[4][4], const float loc[3], const float rot[3][3], diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h index cb66b0552df..37afd8ee031 100644 --- a/source/blender/blenlib/BLI_noise.h +++ b/source/blender/blenlib/BLI_noise.h @@ -27,53 +27,54 @@ extern "C" { #endif -/* noise.h: */ -float BLI_hnoise(float noisesize, float x, float y, float z); -float BLI_hnoisep(float noisesize, float x, float y, float z); -float BLI_turbulence(float noisesize, float x, float y, float z, int nr); -float BLI_turbulence1(float noisesize, float x, float y, float z, int nr); +float BLI_noise_hnoise(float noisesize, float x, float y, float z); +float BLI_noise_hnoisep(float noisesize, float x, float y, float z); +float BLI_noise_turbulence(float noisesize, float x, float y, float z, int nr); /* newnoise: generic noise & turbulence functions - * to replace the above BLI_hnoise/p & BLI_turbulence/1. + * to replace the above BLI_noise_hnoise/p & BLI_noise_turbulence/1. * This is done so different noise basis functions can be used */ -float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noisebasis); -float BLI_gTurbulence( - float noisesize, float x, float y, float z, int oct, int hard, int noisebasis); +float BLI_noise_generic_noise( + float noisesize, float x, float y, float z, bool hard, int noisebasis); +float BLI_noise_generic_turbulence( + float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis); /* newnoise: musgrave functions */ -float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); -float mg_MultiFractal( +float BLI_noise_mg_fbm( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); -float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2); -float mg_HeteroTerrain(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - int noisebasis); -float mg_HybridMultiFractal(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - float gain, - int noisebasis); -float mg_RidgedMultiFractal(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - float gain, - int noisebasis); +float BLI_noise_mg_multi_fractal( + float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); +float BLI_noise_mg_variable_lacunarity( + float x, float y, float z, float distortion, int nbas1, int nbas2); +float BLI_noise_mg_hetero_terrain(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + int noisebasis); +float BLI_noise_mg_hybrid_multi_fractal(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + float gain, + int noisebasis); +float BLI_noise_mg_ridged_multi_fractal(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + float gain, + int noisebasis); /* newnoise: voronoi */ -void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype); -/* newnoise: cellNoise & cellNoiseV (for vector/point/color) */ -float cellNoise(float x, float y, float z); -void cellNoiseV(float x, float y, float z, float r_ca[3]); +void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype); +/* newnoise: BLI_noise_cell & BLI_noise_cell_v3 (for vector/point/color) */ +float BLI_noise_cell(float x, float y, float z); +void BLI_noise_cell_v3(float x, float y, float z, float r_ca[3]); #ifdef __cplusplus } diff --git a/source/blender/blenlib/BLI_set.hh b/source/blender/blenlib/BLI_set.hh index f1cf44018c9..06b56c3f8e5 100644 --- a/source/blender/blenlib/BLI_set.hh +++ b/source/blender/blenlib/BLI_set.hh @@ -48,7 +48,7 @@ * - Small buffer optimization is enabled by default, if the key is not too large. * - The methods `add_new` and `remove_contained` should be used instead of `add` and `remove` * whenever appropriate. Assumptions and intention are described better this way. - * - Look-ups can be performed using types other than Key without conversion. For that use the + * - Lookups can be performed using types other than Key without conversion. For that use the * methods ending with `_as`. The template parameters Hash and #IsEqual have to support the other * key type. This can greatly improve performance when the set contains strings. * - The default constructor is cheap, even when a large #InlineBufferCapacity is used. A large diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 6434464a012..2d745e63764 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -147,6 +147,7 @@ int BLI_string_find_split_words(const char *str, int r_words[][2], int words_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); +/* -------------------------------------------------------------------- */ /** \name String Copy/Format Macros * Avoid repeating destination with `sizeof(..)`. * \note `ARRAY_SIZE` allows pointers on some platforms. diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index b633bbfa435..65d9d7863c3 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -103,6 +103,7 @@ int BLI_str_utf8_offset_from_column(const char *str, int column); #define BLI_UTF8_WIDTH_MAX 2 /* columns */ #define BLI_UTF8_ERR ((unsigned int)-1) +/* -------------------------------------------------------------------- */ /** \name String Copy/Format Macros * Avoid repeating destination with `sizeof(..)`. * \note `ARRAY_SIZE` allows pointers on some platforms. diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c index 91aabca7747..3d4521a3304 100644 --- a/source/blender/blenlib/intern/BLI_args.c +++ b/source/blender/blenlib/intern/BLI_args.c @@ -63,6 +63,9 @@ struct bArgs { int argc; const char **argv; int *passes; + + /* Only use when initializing arguments. */ + int current_pass; }; static uint case_strhash(const void *ptr) @@ -108,7 +111,7 @@ static bArgument *lookUp(struct bArgs *ba, const char *arg, int pass, int case_s return BLI_ghash_lookup(ba->items, &key); } -bArgs *BLI_argsInit(int argc, const char **argv) +bArgs *BLI_args_create(int argc, const char **argv) { bArgs *ba = MEM_callocN(sizeof(bArgs), "bArgs"); ba->passes = MEM_callocN(sizeof(int) * argc, "bArgs passes"); @@ -117,10 +120,13 @@ bArgs *BLI_argsInit(int argc, const char **argv) ba->argc = argc; ba->argv = argv; + /* Must be initialized by #BLI_args_pass_set. */ + ba->current_pass = 0; + return ba; } -void BLI_argsFree(struct bArgs *ba) +void BLI_args_destroy(struct bArgs *ba) { BLI_ghash_free(ba->items, MEM_freeN, MEM_freeN); MEM_freeN(ba->passes); @@ -128,7 +134,13 @@ void BLI_argsFree(struct bArgs *ba) MEM_freeN(ba); } -void BLI_argsPrint(struct bArgs *ba) +void BLI_args_pass_set(struct bArgs *ba, int current_pass) +{ + BLI_assert((current_pass != 0) && (current_pass >= -1)); + ba->current_pass = current_pass; +} + +void BLI_args_print(struct bArgs *ba) { int i; for (i = 0; i < ba->argc; i++) { @@ -136,11 +148,6 @@ void BLI_argsPrint(struct bArgs *ba) } } -const char **BLI_argsArgv(struct bArgs *ba) -{ - return ba->argv; -} - static bArgDoc *internalDocs(struct bArgs *ba, const char *short_arg, const char *long_arg, @@ -163,14 +170,10 @@ static bArgDoc *internalDocs(struct bArgs *ba, return d; } -static void internalAdd(struct bArgs *ba, - const char *arg, - int pass, - int case_str, - BA_ArgCallback cb, - void *data, - bArgDoc *d) +static void internalAdd( + struct bArgs *ba, const char *arg, int case_str, BA_ArgCallback cb, void *data, bArgDoc *d) { + const int pass = ba->current_pass; bArgument *a; bAKey *key; @@ -203,36 +206,34 @@ static void internalAdd(struct bArgs *ba, BLI_ghash_insert(ba->items, key, a); } -void BLI_argsAddCase(struct bArgs *ba, - int pass, - const char *short_arg, - int short_case, - const char *long_arg, - int long_case, - const char *doc, - BA_ArgCallback cb, - void *data) +void BLI_args_add_case(struct bArgs *ba, + const char *short_arg, + int short_case, + const char *long_arg, + int long_case, + const char *doc, + BA_ArgCallback cb, + void *data) { bArgDoc *d = internalDocs(ba, short_arg, long_arg, doc); if (short_arg) { - internalAdd(ba, short_arg, pass, short_case, cb, data, d); + internalAdd(ba, short_arg, short_case, cb, data, d); } if (long_arg) { - internalAdd(ba, long_arg, pass, long_case, cb, data, d); + internalAdd(ba, long_arg, long_case, cb, data, d); } } -void BLI_argsAdd(struct bArgs *ba, - int pass, - const char *short_arg, - const char *long_arg, - const char *doc, - BA_ArgCallback cb, - void *data) +void BLI_args_add(struct bArgs *ba, + const char *short_arg, + const char *long_arg, + const char *doc, + BA_ArgCallback cb, + void *data) { - BLI_argsAddCase(ba, pass, short_arg, 0, long_arg, 0, doc, cb, data); + BLI_args_add_case(ba, short_arg, 0, long_arg, 0, doc, cb, data); } static void internalDocPrint(bArgDoc *d) @@ -250,7 +251,7 @@ static void internalDocPrint(bArgDoc *d) printf(" %s\n\n", d->documentation); } -void BLI_argsPrintArgDoc(struct bArgs *ba, const char *arg) +void BLI_args_print_arg_doc(struct bArgs *ba, const char *arg) { bArgument *a = lookUp(ba, arg, -1, -1); @@ -263,7 +264,7 @@ void BLI_argsPrintArgDoc(struct bArgs *ba, const char *arg) } } -void BLI_argsPrintOtherDoc(struct bArgs *ba) +void BLI_args_print_other_doc(struct bArgs *ba) { bArgDoc *d; @@ -274,8 +275,9 @@ void BLI_argsPrintOtherDoc(struct bArgs *ba) } } -void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *default_data) +void BLI_args_parse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *default_data) { + BLI_assert((pass != 0) && (pass >= -1)); int i = 0; for (i = 1; i < ba->argc; i++) { /* skip argv[0] */ diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index d20f0ce49d0..a221820d4c4 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -67,6 +67,7 @@ struct Heap { } nodes; }; +/* -------------------------------------------------------------------- */ /** \name Internal Functions * \{ */ @@ -146,6 +147,7 @@ static void heap_up(Heap *heap, uint i) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Internal Memory Management * \{ */ @@ -187,6 +189,7 @@ static void heap_node_free(Heap *heap, HeapNode *node) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Public Heap API * \{ */ diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c index a6a0c21b104..847cb42186a 100644 --- a/source/blender/blenlib/intern/array_store.c +++ b/source/blender/blenlib/intern/array_store.c @@ -112,6 +112,7 @@ /* only for BLI_array_store_is_valid */ #include "BLI_ghash.h" +/* -------------------------------------------------------------------- */ /** \name Defines * * Some of the logic for merging is quite involved, @@ -206,6 +207,7 @@ /** \} */ +/* -------------------------------------------------------------------- */ /** \name Internal Structs * \{ */ @@ -313,6 +315,7 @@ typedef struct BTableRef { static size_t bchunk_list_size(const BChunkList *chunk_list); +/* -------------------------------------------------------------------- */ /** \name Internal BChunk API * \{ */ @@ -360,6 +363,7 @@ static bool bchunk_data_compare(const BChunk *chunk, /** \} */ +/* -------------------------------------------------------------------- */ /** \name Internal BChunkList API * \{ */ @@ -732,10 +736,11 @@ static void bchunk_list_fill_from_array(const BArrayInfo *info, /** \} */ -/* --------------------------------------------------------------------------- +/* * Internal Table Lookup Functions */ +/* -------------------------------------------------------------------- */ /** \name Internal Hashing/De-Duplication API * * Only used by #bchunk_list_from_data_merge @@ -1005,6 +1010,7 @@ static const BChunkRef *table_lookup(const BArrayInfo *info, /** \} */ +/* -------------------------------------------------------------------- */ /** \name Main Data De-Duplication Function * * \{ */ @@ -1307,7 +1313,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info, ASSERT_CHUNKLIST_DATA(chunk_list, data); /* its likely that the next chunk in the list will be a match, so check it! */ - while ((cref_found->next != NULL) && (cref_found->next != chunk_list_reference_last)) { + while (!ELEM(cref_found->next, NULL, chunk_list_reference_last)) { cref_found = cref_found->next; BChunk *chunk_found = cref_found->link; @@ -1390,6 +1396,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info, /** \} */ +/* -------------------------------------------------------------------- */ /** \name Main Array Storage API * \{ */ @@ -1405,7 +1412,7 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info, * * \param chunk_count: Number of elements to split each chunk into. * - A small value increases the ability to de-duplicate chunks, - * but adds overhead by increasing the number of chunks to look-up when searching for duplicates, + * but adds overhead by increasing the number of chunks to look up when searching for duplicates, * as well as some overhead constructing the original array again, with more calls to ``memcpy``. * - Larger values reduce the *book keeping* overhead, * but increase the chance a small, @@ -1496,6 +1503,7 @@ void BLI_array_store_clear(BArrayStore *bs) /** \} */ +/* -------------------------------------------------------------------- */ /** \name BArrayStore Statistics * \{ */ @@ -1530,6 +1538,7 @@ size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs) /** \} */ +/* -------------------------------------------------------------------- */ /** \name BArrayState Access * \{ */ @@ -1653,6 +1662,7 @@ void *BLI_array_store_state_data_get_alloc(BArrayState *state, size_t *r_data_le /** \} */ +/* -------------------------------------------------------------------- */ /** \name Debugging API (for testing). * \{ */ diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c index 250a3fdf21b..9840dc77148 100644 --- a/source/blender/blenlib/intern/boxpack_2d.c +++ b/source/blender/blenlib/intern/boxpack_2d.c @@ -97,6 +97,7 @@ BLI_INLINE int quad_flag(uint q) #define TL 2 #define BR 3 +/* -------------------------------------------------------------------- */ /** \name Box Accessor Functions * \{ */ @@ -121,6 +122,7 @@ static float box_ymax_get(const BoxPack *box) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Box Placement * \{ */ @@ -165,6 +167,7 @@ static void box_ymax_set(BoxPack *box, const float f) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Box Utils * \{ */ @@ -203,6 +206,7 @@ static void vert_bias_update(BoxVert *v) printf("\tBox Debug i %i, w:%.3f h:%.3f x:%.3f y:%.3f\n", b->index, b->w, b->h, b->x, b->y) #endif +/* -------------------------------------------------------------------- */ /** \name Box/Vert Sorting * \{ */ diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c index 6e4a8623077..a3d24787d27 100644 --- a/source/blender/blenlib/intern/convexhull_2d.c +++ b/source/blender/blenlib/intern/convexhull_2d.c @@ -37,6 +37,7 @@ * http://softsurfer.com/Archive/algorithm_0203/algorithm_0203.htm */ +/* -------------------------------------------------------------------- */ /** \name Main Convex-Hull Calculation * \{ */ @@ -227,9 +228,9 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) /** \} */ -/* -------------------------------------------------------------------- */ /* Helper functions */ +/* -------------------------------------------------------------------- */ /** \name Utility Convex-Hull Functions * \{ */ diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index ac3662284d0..568a3206b18 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -1308,8 +1308,8 @@ template<typename T> inline int tri_orient(const SymEdge<T> *t) * For case (a), 'vert' will be the vertex, and lambda will be 0, and 'in' will be the #SymEdge * from 'vert' that has as face the one that you go through to get to this vertex. If you go * exactly along an edge then we set 'in' to NULL, since it won't be needed. The first crossing - * will have 'in' = NULL. We set 'out' to the #SymEdge that has the face we go through to get to the - * next crossing, or, if the next crossing is a case (a), then it is the edge that goes to that + * will have 'in' = NULL. We set 'out' to the #SymEdge that has the face we go through to get to + * the next crossing, or, if the next crossing is a case (a), then it is the edge that goes to that * next vertex. 'out' will be NULL for the last one. * * For case (b), vert will be NULL at first, and later filled in with the created split vertex, @@ -2008,7 +2008,7 @@ template<typename T> void dissolve_symedge(CDT_state<T> *cdt_state, SymEdge<T> * se = sym(se); symse = sym(se); } - if (cdt->outer_face->symedge == se || cdt->outer_face->symedge == symse) { + if (ELEM(cdt->outer_face->symedge, se, symse)) { /* Advancing by 2 to get past possible 'sym(se)'. */ if (se->next->next == se) { cdt->outer_face->symedge = NULL; diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 1b388dcf11f..8cc5c31a4c7 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -611,7 +611,7 @@ MINLINE int compare_ff_relative(float a, float b, const float max_diff, const in MINLINE float signf(float f) { - return (f < 0.f) ? -1.f : 1.f; + return (f < 0.0f) ? -1.0f : 1.0f; } MINLINE float compatible_signf(float f) diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc index f8bf8676f50..a345bc1d0af 100644 --- a/source/blender/blenlib/intern/math_boolean.cc +++ b/source/blender/blenlib/intern/math_boolean.cc @@ -470,7 +470,7 @@ void exactinit() } every_other = !every_other; check = 1.0 + epsilon; - } while ((check != 1.0) && (check != lastcheck)); + } while (!ELEM(check, 1.0, lastcheck)); splitter += 1.0; /* Error bounds for orientation and #incircle tests. */ diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c index 85aabbb672a..1264620cf36 100644 --- a/source/blender/blenlib/intern/math_color_inline.c +++ b/source/blender/blenlib/intern/math_color_inline.c @@ -261,6 +261,7 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack) r_col[2] = ((pack) >> 16) & 0xFF; } +/* -------------------------------------------------------------------- */ /** \name RGB/Grayscale Functions * * \warning diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 2f913a294e0..1d2480f4d62 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1418,7 +1418,7 @@ int isect_seg_seg_v2_lambda_mu_db(const double v1[2], /** * \param l1, l2: Coordinates (point of line). - * \param sp, r: Coordinate and radius (sphere). + * \param sp, r: Coordinate and radius (sphere). * \return r_p1, r_p2: Intersection coordinates. * * \note The order of assignment for intersection points (\a r_p1, \a r_p2) is predictable, @@ -4181,6 +4181,7 @@ int interp_sparse_array(float *array, const int list_size, const float skipval) return 1; } +/* -------------------------------------------------------------------- */ /** \name interp_weights_poly_v2, v3 * \{ */ @@ -5496,7 +5497,7 @@ void vcloud_estimate_transform_v3(const int list_size, stunt[1] = q[1][1]; stunt[2] = q[2][2]; /* renormalizing for numeric stability */ - mul_m3_fl(q, 1.f / len_v3(stunt)); + mul_m3_fl(q, 1.0f / len_v3(stunt)); /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */ /* without the far case ... but seems to work here pretty neat */ diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 13a1816f1bd..3cec3db9806 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -517,7 +517,7 @@ void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer, * otherwise at high texture magnifications circular artifacts are visible. */ #define EWA_MAXIDX 255 const float EWA_WTS[EWA_MAXIDX + 1] = { - 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, + 1.0f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f, 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f, 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f, 0.794079f, 0.786653f, 0.779284f, @@ -553,7 +553,7 @@ const float EWA_WTS[EWA_MAXIDX + 1] = { 0.0324175f, 0.0309415f, 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f, 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, 0.00754159f, 0.00625989f, 0.00498819f, - 0.00372644f, 0.00247454f, 0.00123242f, 0.f, + 0.00372644f, 0.00247454f, 0.00123242f, 0.0f, }; static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *C, float *F) @@ -625,7 +625,7 @@ void BLI_ewa_filter(const int width, * Use a different radius based on interpolation switch, * just enough to anti-alias when interpolation is off, * and slightly larger to make result a bit smoother than bilinear interpolation when - * interpolation is on (minimum values: const float rmin = intpol ? 1.f : 0.5f;) */ + * interpolation is on (minimum values: const float rmin = intpol ? 1.0f : 0.5f;) */ const float rmin = (intpol ? 1.5625f : 0.765625f) / ff2; BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc); if ((b2 = b * b) < rmin) { diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 656f37c9f18..6b5efc3f8c4 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -274,7 +274,7 @@ void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]) void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]) { - BLI_assert(R != A && R != B); + BLI_assert(!ELEM(R, A, B)); /* matrix product: R[j][k] = A[j][i] . B[i][k] */ #ifdef __SSE2__ @@ -319,7 +319,7 @@ void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]) void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4][4]) { - BLI_assert(R != A && R != B); + BLI_assert(!ELEM(R, A, B)); /* matrix product: R[j][k] = A[j][i] . B[i][k] */ @@ -347,7 +347,7 @@ void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4] void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B[4][4]) { /* Remove second check since types don't match. */ - BLI_assert(R != A /* && R != B */); + BLI_assert(!ELEM(R, A /*, B */)); /* matrix product: R[j][k] = A[j][i] . B[i][k] */ @@ -419,7 +419,7 @@ void mul_m3_m3_post(float R[3][3], const float B[3][3]) void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]) { - BLI_assert(R != A && R != B); + BLI_assert(!ELEM(R, A, B)); R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; @@ -535,8 +535,10 @@ void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4]) R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2]; } +/* -------------------------------------------------------------------- */ /** \name Macro helpers for: mul_m3_series * \{ */ + void _va_mul_m3_series_3(float r[3][3], const float m1[3][3], const float m2[3][3]) { mul_m3_m3m3(r, m1, m2); @@ -621,8 +623,10 @@ void _va_mul_m3_series_9(float r[3][3], } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Macro helpers for: mul_m4_series * \{ */ + void _va_mul_m4_series_3(float r[4][4], const float m1[4][4], const float m2[4][4]) { mul_m4_m4m4(r, m1, m2); @@ -2219,6 +2223,12 @@ void scale_m4_fl(float R[4][4], float scale) R[3][0] = R[3][1] = R[3][2] = 0.0; } +void translate_m3(float mat[3][3], float tx, float ty) +{ + mat[2][0] += (tx * mat[0][0] + ty * mat[1][0]); + mat[2][1] += (tx * mat[0][1] + ty * mat[1][1]); +} + void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) { mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]); @@ -2226,6 +2236,18 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz) mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]); } +void rotate_m3(float mat[3][3], const float angle) +{ + const float angle_cos = cosf(angle); + const float angle_sin = sinf(angle); + + for (int col = 0; col < 3; col++) { + float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col]; + mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col]; + mat[0][col] = temp; + } +} + /* TODO: enum for axis? */ /** * Rotate a matrix in-place. @@ -2271,6 +2293,12 @@ void rotate_m4(float mat[4][4], const char axis, const float angle) } } +void rescale_m3(float mat[3][3], const float scale[2]) +{ + mul_v3_fl(mat[0], scale[0]); + mul_v3_fl(mat[1], scale[1]); +} + /** Scale a matrix in-place. */ void rescale_m4(float mat[4][4], const float scale[3]) { @@ -2301,6 +2329,20 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]) mul_m4_m4m4(mat, mat, tmat); } +void transform_pivot_set_m3(float mat[3][3], const float pivot[2]) +{ + float tmat[3][3]; + + unit_m3(tmat); + + copy_v2_v2(tmat[2], pivot); + mul_m3_m3m3(mat, tmat, mat); + + /* invert the matrix */ + negate_v2(tmat[2]); + mul_m3_m3m3(mat, mat, tmat); +} + void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], @@ -2481,6 +2523,21 @@ bool equals_m4m4(const float mat1[4][4], const float mat2[4][4]) } /** + * Make a 3x3 matrix out of 3 transform components. + * Matrices are made in the order: `loc * rot * scale` + */ +void loc_rot_size_to_mat3(float R[3][3], + const float loc[2], + const float angle, + const float size[2]) +{ + unit_m3(R); + translate_m3(R, loc[0], loc[1]); + rotate_m3(R, angle); + rescale_m3(R, size); +} + +/** * Make a 4x4 matrix out of 3 transform components. * Matrices are made in the order: `scale * rot * loc` */ @@ -2863,7 +2920,7 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) if (ks == k) { break; } - t = (ks != p ? fabsf(e[ks]) : 0.f) + (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f); + t = (ks != p ? fabsf(e[ks]) : 0.0f) + (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f); if (fabsf(s[ks]) <= eps * t) { s[ks] = 0.0f; break; diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c index 4d7efa4b6f4..5f3297134c6 100644 --- a/source/blender/blenlib/intern/math_vector.c +++ b/source/blender/blenlib/intern/math_vector.c @@ -162,6 +162,7 @@ void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[ } } +/* -------------------------------------------------------------------- */ /** \name Cubic curve interpolation (bezier spline). * \{ */ @@ -1395,6 +1396,7 @@ void copy_vn_fl(float *array_tar, const int size, const float val) } } +/* -------------------------------------------------------------------- */ /** \name Double precision versions 'db'. * \{ */ diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index f6841ef52b0..f17b7535258 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -1288,6 +1288,7 @@ MINLINE bool is_one_v3(const float v[3]) return (v[0] == 1.0f && v[1] == 1.0f && v[2] == 1.0f); } +/* -------------------------------------------------------------------- */ /** \name Vector Comparison * * \note use ``value <= limit``, so a limit of zero doesn't fail on an exact match. @@ -1395,6 +1396,7 @@ MINLINE bool compare_size_v3v3(const float v1[3], const float v2[3], const float return true; } +/* -------------------------------------------------------------------- */ /** \name Vector Clamping * \{ */ diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index bad0b84d10f..c85adf835fe 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -2851,7 +2851,7 @@ static bool dissolve_leaves_valid_bmesh(FaceMergeState *fms, * saying which faces a vertex touches. */ for (int a_v_index = 0; ok && a_v_index < alen; ++a_v_index) { const Vert *a_v = mf_left.vert[a_v_index]; - if (a_v != me.v1 && a_v != me.v2) { + if (!ELEM(a_v, me.v1, me.v2)) { for (int b_v_index = 0; b_v_index < blen; ++b_v_index) { const Vert *b_v = mf_right.vert[b_v_index]; if (a_v == b_v) { diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index a777833dff4..b1b8bd61b40 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -2637,8 +2637,7 @@ struct SubdivideTrisData { tm(tm), itt_map(itt_map), overlap(overlap), - arena(arena), - overlap_tri_range{} + arena(arena) { } }; @@ -2771,7 +2770,7 @@ static CDT_data calc_cluster_subdivided(const CoplanarClusterInfo &clinfo, std::pair<int, int> key = canon_int_pair(t, t_other); if (itt_map.contains(key)) { ITT_value itt = itt_map.lookup(key); - if (itt.kind != INONE && itt.kind != ICOPLANAR) { + if (!ELEM(itt.kind, INONE, ICOPLANAR)) { itts.append(itt); if (dbg_level > 0) { std::cout << " itt = " << itt << "\n"; diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 1ae1c91a3bd..f9b6218eae5 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -24,7 +24,9 @@ #include <math.h> #include "BLI_compiler_compat.h" -#include "BLI_noise.h" +#include "BLI_sys_types.h" + +#include "BLI_noise.h" /* Own include. */ /* local */ static float noise3_perlin(const float vec[3]); @@ -319,7 +321,8 @@ static float newPerlin(float x, float y, float z) lerp(u, grad(hash[AB + 1], x, y - 1, z - 1), grad(hash[BB + 1], x - 1, y - 1, z - 1)))); } -/* for use with BLI_gNoise()/BLI_gTurbulence(), returns unsigned improved perlin noise */ +/* for use with BLI_noise_generic_noise()/BLI_noise_generic_turbulence(), returns unsigned improved + * perlin noise */ static float newPerlinU(float x, float y, float z) { return (0.5f + 0.5f * newPerlin(x, y, z)); @@ -329,7 +332,7 @@ static float newPerlinU(float x, float y, float z) /* END OF IMPROVED PERLIN */ /**************************/ -/* Was BLI_hnoise(), removed noisesize, so other functions can call it without scaling. */ +/* Was BLI_noise_hnoise(), removed noisesize, so other functions can call it without scaling. */ static float orgBlenderNoise(float x, float y, float z) { float cn1, cn2, cn3, cn4, cn5, cn6, i; @@ -425,7 +428,7 @@ static float orgBlenderNoiseS(float x, float y, float z) } /* separated from orgBlenderNoise above, with scaling */ -float BLI_hnoise(float noisesize, float x, float y, float z) +float BLI_noise_hnoise(float noisesize, float x, float y, float z) { if (noisesize == 0.0f) { return 0.0f; @@ -437,32 +440,15 @@ float BLI_hnoise(float noisesize, float x, float y, float z) } /* original turbulence functions */ -float BLI_turbulence(float noisesize, float x, float y, float z, int nr) -{ - float s, d = 0.5, div = 1.0; - - s = BLI_hnoise(noisesize, x, y, z); - - while (nr > 0) { - - s += d * BLI_hnoise(noisesize * d, x, y, z); - div += d; - d *= 0.5f; - - nr--; - } - return s / div; -} - -float BLI_turbulence1(float noisesize, float x, float y, float z, int nr) +float BLI_noise_turbulence(float noisesize, float x, float y, float z, int nr) { float s, d = 0.5, div = 1.0; - s = fabsf((-1.0f + 2.0f * BLI_hnoise(noisesize, x, y, z))); + s = BLI_noise_hnoise(noisesize, x, y, z); while (nr > 0) { - s += fabsf(d * (-1.0f + 2.0f * BLI_hnoise(noisesize * d, x, y, z))); + s += d * BLI_noise_hnoise(noisesize * d, x, y, z); div += d; d *= 0.5f; @@ -786,14 +772,13 @@ static float noise3_perlin(const float vec[3]) int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v; const float *q; - int i, j; SETUP(vec[0], bx0, bx1, rx0, rx1); SETUP(vec[1], by0, by1, ry0, ry1); SETUP(vec[2], bz0, bz1, rz0, rz1); - i = p[bx0]; - j = p[bx1]; + int i = p[bx0]; + int j = p[bx1]; b00 = p[i + by0]; b10 = p[j + by0]; @@ -843,31 +828,23 @@ static float noise3_perlin(const float vec[3]) #undef SURVE } -/* for use with BLI_gNoise/gTurbulence, returns signed noise */ +/* for use with BLI_noise_generic_noise/gTurbulence, returns signed noise */ static float orgPerlinNoise(float x, float y, float z) { - float v[3]; - - v[0] = x; - v[1] = y; - v[2] = z; + float v[3] = {x, y, z}; return noise3_perlin(v); } -/* for use with BLI_gNoise/gTurbulence, returns unsigned noise */ +/* for use with BLI_noise_generic_noise/gTurbulence, returns unsigned noise */ static float orgPerlinNoiseU(float x, float y, float z) { - float v[3]; - - v[0] = x; - v[1] = y; - v[2] = z; + float v[3] = {x, y, z}; return (0.5f + 0.5f * noise3_perlin(v)); } /* *************** CALL AS: *************** */ -float BLI_hnoisep(float noisesize, float x, float y, float z) +float BLI_noise_hnoisep(float noisesize, float x, float y, float z) { float vec[3]; @@ -906,13 +883,12 @@ static float dist_Manhattan(float x, float y, float z, float e) /* Chebychev */ static float dist_Chebychev(float x, float y, float z, float e) { - float t; (void)e; x = fabsf(x); y = fabsf(y); z = fabsf(z); - t = (x > y) ? x : y; + float t = (x > y) ? x : y; return ((z > t) ? z : t); } @@ -942,11 +918,8 @@ static float dist_Minkovsky(float x, float y, float z, float e) /* Not 'pure' Worley, but the results are virtually the same. * Returns distances in da and point coords in pa */ -void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype) +void BLI_noise_voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype) { - int xx, yy, zz, xi, yi, zi; - float xd, yd, zd, d; - float (*distfunc)(float, float, float, float); switch (dtype) { case 1: @@ -973,18 +946,18 @@ void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtyp break; } - xi = (int)(floor(x)); - yi = (int)(floor(y)); - zi = (int)(floor(z)); + int xi = (int)(floor(x)); + int yi = (int)(floor(y)); + int zi = (int)(floor(z)); da[0] = da[1] = da[2] = da[3] = 1e10f; - for (xx = xi - 1; xx <= xi + 1; xx++) { - for (yy = yi - 1; yy <= yi + 1; yy++) { - for (zz = zi - 1; zz <= zi + 1; zz++) { + for (int xx = xi - 1; xx <= xi + 1; xx++) { + for (int yy = yi - 1; yy <= yi + 1; yy++) { + for (int zz = zi - 1; zz <= zi + 1; zz++) { const float *p = HASHPNT(xx, yy, zz); - xd = x - (p[0] + xx); - yd = y - (p[1] + yy); - zd = z - (p[2] + zz); - d = distfunc(xd, yd, zd, me); + float xd = x - (p[0] + xx); + float yd = y - (p[1] + yy); + float zd = z - (p[2] + zz); + float d = distfunc(xd, yd, zd, me); if (d < da[0]) { da[3] = da[2]; da[2] = da[1]; @@ -1038,39 +1011,39 @@ void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtyp } } -/* returns different feature points for use in BLI_gNoise() */ +/* returns different feature points for use in BLI_noise_generic_noise() */ static float voronoi_F1(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return da[0]; } static float voronoi_F2(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return da[1]; } static float voronoi_F3(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return da[2]; } static float voronoi_F4(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return da[3]; } static float voronoi_F1F2(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (da[1] - da[0]); } @@ -1078,8 +1051,8 @@ static float voronoi_F1F2(float x, float y, float z) static float voronoi_Cr(float x, float y, float z) { float t = 10 * voronoi_F1F2(x, y, z); - if (t > 1.f) { - return 1.f; + if (t > 1.0f) { + return 1.0f; } return t; } @@ -1090,35 +1063,35 @@ static float voronoi_Cr(float x, float y, float z) static float voronoi_F1S(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (2.0f * da[0] - 1.0f); } static float voronoi_F2S(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (2.0f * da[1] - 1.0f); } static float voronoi_F3S(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (2.0f * da[2] - 1.0f); } static float voronoi_F4S(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (2.0f * da[3] - 1.0f); } static float voronoi_F1F2S(float x, float y, float z) { float da[4], pa[12]; - voronoi(x, y, z, da, pa, 1, 0); + BLI_noise_voronoi(x, y, z, da, pa, 1, 0); return (2.0f * (da[1] - da[0]) - 1.0f); } @@ -1126,8 +1099,8 @@ static float voronoi_F1F2S(float x, float y, float z) static float voronoi_CrS(float x, float y, float z) { float t = 10 * voronoi_F1F2(x, y, z); - if (t > 1.f) { - return 1.f; + if (t > 1.0f) { + return 1.0f; } return (2.0f * t - 1.0f); } @@ -1141,7 +1114,7 @@ static float voronoi_CrS(float x, float y, float z) /*************/ /* returns unsigned cellnoise */ -static float cellNoiseU(float x, float y, float z) +static float BLI_cellNoiseU(float x, float y, float z) { /* avoid precision issues on unit coordinates */ x = (x + 0.000001f) * 1.00001f; @@ -1157,13 +1130,13 @@ static float cellNoiseU(float x, float y, float z) } /* idem, signed */ -float cellNoise(float x, float y, float z) +float BLI_noise_cell(float x, float y, float z) { - return (2.0f * cellNoiseU(x, y, z) - 1.0f); + return (2.0f * BLI_cellNoiseU(x, y, z) - 1.0f); } /* returns a vector/point/color in ca, using point hasharray directly */ -void cellNoiseV(float x, float y, float z, float ca[3]) +void BLI_noise_cell_v3(float x, float y, float z, float ca[3]) { /* avoid precision issues on unit coordinates */ x = (x + 0.000001f) * 1.00001f; @@ -1184,7 +1157,8 @@ void cellNoiseV(float x, float y, float z, float ca[3]) /*****************/ /* newnoise: generic noise function for use with different noisebases */ -float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noisebasis) +float BLI_noise_generic_noise( + float noisesize, float x, float y, float z, bool hard, int noisebasis) { float (*noisefunc)(float, float, float); @@ -1214,12 +1188,12 @@ float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noise noisefunc = voronoi_Cr; break; case 14: - noisefunc = cellNoiseU; + noisefunc = BLI_cellNoiseU; break; case 0: default: { noisefunc = orgBlenderNoise; - /* add one to make return value same as BLI_hnoise */ + /* add one to make return value same as BLI_noise_hnoise */ x += 1; y += 1; z += 1; @@ -1241,13 +1215,10 @@ float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noise } /* newnoise: generic turbulence function for use with different noisebasis */ -float BLI_gTurbulence( - float noisesize, float x, float y, float z, int oct, int hard, int noisebasis) +float BLI_noise_generic_turbulence( + float noisesize, float x, float y, float z, int oct, bool hard, int noisebasis) { float (*noisefunc)(float, float, float); - float sum, t, amp = 1, fscale = 1; - int i; - switch (noisebasis) { case 1: noisefunc = orgPerlinNoiseU; @@ -1274,7 +1245,7 @@ float BLI_gTurbulence( noisefunc = voronoi_Cr; break; case 14: - noisefunc = cellNoiseU; + noisefunc = BLI_cellNoiseU; break; case 0: default: @@ -1292,9 +1263,9 @@ float BLI_gTurbulence( z *= noisesize; } - sum = 0; - for (i = 0; i <= oct; i++, amp *= 0.5f, fscale *= 2.0f) { - t = noisefunc(fscale * x, fscale * y, fscale * z); + float sum = 0, amp = 1, fscale = 1; + for (int i = 0; i <= oct; i++, amp *= 0.5f, fscale *= 2.0f) { + float t = noisefunc(fscale * x, fscale * y, fscale * z); if (hard) { t = fabsf(2.0f * t - 1.0f); } @@ -1319,11 +1290,9 @@ float BLI_gTurbulence( * ``lacunarity'' is the gap between successive frequencies * ``octaves'' is the number of frequencies in the fBm */ -float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis) +float BLI_noise_mg_fbm( + float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis) { - float rmd, value = 0.0, pwr = 1.0, pwHL = powf(lacunarity, -H); - int i; - float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1351,7 +1320,7 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves noisefunc = voronoi_CrS; break; case 14: - noisefunc = cellNoise; + noisefunc = BLI_noise_cell; break; case 0: default: { @@ -1360,7 +1329,8 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves } } - for (i = 0; i < (int)octaves; i++) { + float value = 0.0, pwr = 1.0, pwHL = powf(lacunarity, -H); + for (int i = 0; i < (int)octaves; i++) { value += noisefunc(x, y, z) * pwr; pwr *= pwHL; x *= lacunarity; @@ -1368,7 +1338,7 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves z *= lacunarity; } - rmd = octaves - floorf(octaves); + float rmd = octaves - floorf(octaves); if (rmd != 0.0f) { value += rmd * noisefunc(x, y, z) * pwr; } @@ -1391,12 +1361,9 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves /* this one is in fact rather confusing, * there seem to be errors in the original source code (in all three versions of proc.text&mod), * I modified it to something that made sense to me, so it might be wrong... */ -float mg_MultiFractal( +float BLI_noise_mg_multi_fractal( float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis) { - float rmd, value = 1.0, pwr = 1.0, pwHL = powf(lacunarity, -H); - int i; - float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1424,7 +1391,7 @@ float mg_MultiFractal( noisefunc = voronoi_CrS; break; case 14: - noisefunc = cellNoise; + noisefunc = BLI_noise_cell; break; case 0: default: { @@ -1433,14 +1400,15 @@ float mg_MultiFractal( } } - for (i = 0; i < (int)octaves; i++) { + float value = 1.0, pwr = 1.0, pwHL = powf(lacunarity, -H); + for (int i = 0; i < (int)octaves; i++) { value *= (pwr * noisefunc(x, y, z) + 1.0f); pwr *= pwHL; x *= lacunarity; y *= lacunarity; z *= lacunarity; } - rmd = octaves - floorf(octaves); + float rmd = octaves - floorf(octaves); if (rmd != 0.0f) { value *= (rmd * noisefunc(x, y, z) * pwr + 1.0f); } @@ -1459,20 +1427,15 @@ float mg_MultiFractal( * ``octaves'' is the number of frequencies in the fBm * ``offset'' raises the terrain from `sea level' */ -float mg_HeteroTerrain(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - int noisebasis) +float BLI_noise_mg_hetero_terrain(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + int noisebasis) { - float value, increment, rmd; - int i; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; /* starts with i=1 instead of 0 */ - float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1500,7 +1463,7 @@ float mg_HeteroTerrain(float x, noisefunc = voronoi_CrS; break; case 14: - noisefunc = cellNoise; + noisefunc = BLI_noise_cell; break; case 0: default: { @@ -1510,13 +1473,15 @@ float mg_HeteroTerrain(float x, } /* first unscaled octave of function; later octaves are scaled */ - value = offset + noisefunc(x, y, z); + float value = offset + noisefunc(x, y, z); x *= lacunarity; y *= lacunarity; z *= lacunarity; - for (i = 1; i < (int)octaves; i++) { - increment = (noisefunc(x, y, z) + offset) * pwr * value; + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; /* starts with i=1 instead of 0 */ + for (int i = 1; i < (int)octaves; i++) { + float increment = (noisefunc(x, y, z) + offset) * pwr * value; value += increment; pwr *= pwHL; x *= lacunarity; @@ -1524,9 +1489,9 @@ float mg_HeteroTerrain(float x, z *= lacunarity; } - rmd = octaves - floorf(octaves); + float rmd = octaves - floorf(octaves); if (rmd != 0.0f) { - increment = (noisefunc(x, y, z) + offset) * pwr * value; + float increment = (noisefunc(x, y, z) + offset) * pwr * value; value += rmd * increment; } return value; @@ -1539,22 +1504,17 @@ float mg_HeteroTerrain(float x, * H: 0.25 * offset: 0.7 */ -float mg_HybridMultiFractal(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - float gain, - int noisebasis) +float BLI_noise_mg_hybrid_multi_fractal(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + float gain, + int noisebasis) { - float result, signal, weight, rmd; - int i; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; /* starts with i=1 instead of 0 */ float (*noisefunc)(float, float, float); - switch (noisebasis) { case 1: noisefunc = orgPerlinNoise; @@ -1581,7 +1541,7 @@ float mg_HybridMultiFractal(float x, noisefunc = voronoi_CrS; break; case 14: - noisefunc = cellNoise; + noisefunc = BLI_noise_cell; break; case 0: default: { @@ -1590,17 +1550,19 @@ float mg_HybridMultiFractal(float x, } } - result = noisefunc(x, y, z) + offset; - weight = gain * result; + float result = noisefunc(x, y, z) + offset; + float weight = gain * result; x *= lacunarity; y *= lacunarity; z *= lacunarity; - for (i = 1; (weight > 0.001f) && (i < (int)octaves); i++) { + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; /* starts with i=1 instead of 0 */ + for (int i = 1; (weight > 0.001f) && (i < (int)octaves); i++) { if (weight > 1.0f) { weight = 1.0f; } - signal = (noisefunc(x, y, z) + offset) * pwr; + float signal = (noisefunc(x, y, z) + offset) * pwr; pwr *= pwHL; result += weight * signal; weight *= gain * signal; @@ -1609,8 +1571,8 @@ float mg_HybridMultiFractal(float x, z *= lacunarity; } - rmd = octaves - floorf(octaves); - if (rmd != 0.f) { + float rmd = octaves - floorf(octaves); + if (rmd != 0.0f) { result += rmd * ((noisefunc(x, y, z) + offset) * pwr); } @@ -1626,21 +1588,16 @@ float mg_HybridMultiFractal(float x, * offset: 1.0 * gain: 2.0 */ -float mg_RidgedMultiFractal(float x, - float y, - float z, - float H, - float lacunarity, - float octaves, - float offset, - float gain, - int noisebasis) +float BLI_noise_mg_ridged_multi_fractal(float x, + float y, + float z, + float H, + float lacunarity, + float octaves, + float offset, + float gain, + int noisebasis) { - float result, signal, weight; - int i; - float pwHL = powf(lacunarity, -H); - float pwr = pwHL; /* starts with i=1 instead of 0 */ - float (*noisefunc)(float, float, float); switch (noisebasis) { case 1: @@ -1668,7 +1625,7 @@ float mg_RidgedMultiFractal(float x, noisefunc = voronoi_CrS; break; case 14: - noisefunc = cellNoise; + noisefunc = BLI_noise_cell; break; case 0: default: { @@ -1677,15 +1634,14 @@ float mg_RidgedMultiFractal(float x, } } - signal = offset - fabsf(noisefunc(x, y, z)); - signal *= signal; - result = signal; - - for (i = 1; i < (int)octaves; i++) { + float result, signal = powf(offset - fabsf(noisefunc(x, y, z)), 2); + for (int i = 1; i < (int)octaves; i++) { + float pwHL = powf(lacunarity, -H); + float pwr = pwHL; /* starts with i=1 instead of 0 */ x *= lacunarity; y *= lacunarity; z *= lacunarity; - weight = signal * gain; + float weight = signal * gain; if (weight > 1.0f) { weight = 1.0f; } @@ -1705,12 +1661,10 @@ float mg_RidgedMultiFractal(float x, /* "Variable Lacunarity Noise" * A distorted variety of Perlin noise. */ -float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2) +float BLI_noise_mg_variable_lacunarity( + float x, float y, float z, float distortion, int nbas1, int nbas2) { - float rv[3]; float (*noisefunc1)(float, float, float); - float (*noisefunc2)(float, float, float); - switch (nbas1) { case 1: noisefunc1 = orgPerlinNoise; @@ -1737,7 +1691,7 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba noisefunc1 = voronoi_CrS; break; case 14: - noisefunc1 = cellNoise; + noisefunc1 = BLI_noise_cell; break; case 0: default: { @@ -1746,6 +1700,7 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba } } + float (*noisefunc2)(float, float, float); switch (nbas2) { case 1: noisefunc2 = orgPerlinNoise; @@ -1772,7 +1727,7 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba noisefunc2 = voronoi_CrS; break; case 14: - noisefunc2 = cellNoise; + noisefunc2 = BLI_noise_cell; break; case 0: default: { @@ -1782,9 +1737,12 @@ float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nba } /* get a random vector and scale the randomization */ - rv[0] = noisefunc1(x + 13.5f, y + 13.5f, z + 13.5f) * distortion; - rv[1] = noisefunc1(x, y, z) * distortion; - rv[2] = noisefunc1(x - 13.5f, y - 13.5f, z - 13.5f) * distortion; + float rv[3] = { + rv[0] = noisefunc1(x + 13.5f, y + 13.5f, z + 13.5f) * distortion, + rv[1] = noisefunc1(x, y, z) * distortion, + rv[2] = noisefunc1(x - 13.5f, y - 13.5f, z - 13.5f) * distortion, + }; + return noisefunc2(x + rv[0], y + rv[1], z + rv[2]); /* distorted-domain noise */ } diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index bec5f0ab3ba..61e0ec393cb 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -1085,9 +1085,9 @@ void print_rcti(const char *str, const rcti *rect) BLI_rcti_size_y(rect)); } -/* -------------------------------------------------------------------- */ /* Comprehensive math (float only) */ +/* -------------------------------------------------------------------- */ /** \name Rect math functions * \{ */ diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 660d3dca807..b49239547c2 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -157,14 +157,14 @@ static ScanFillEdge *edge_step(PolyInfo *poly_info, eed = (e_curr->next && e_curr != poly_info[poly_nr].edge_last) ? e_curr->next : poly_info[poly_nr].edge_first; if ((v_curr == eed->v1 || v_curr == eed->v2) == true && - (v_prev == eed->v1 || v_prev == eed->v2) == false) { + (ELEM(v_prev, eed->v1, eed->v2)) == false) { return eed; } eed = (e_curr->prev && e_curr != poly_info[poly_nr].edge_first) ? e_curr->prev : poly_info[poly_nr].edge_last; if ((v_curr == eed->v1 || v_curr == eed->v2) == true && - (v_prev == eed->v1 || v_prev == eed->v2) == false) { + (ELEM(v_prev, eed->v1, eed->v2)) == false) { return eed; } diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index a091b41af23..5961893cae3 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -349,6 +349,7 @@ void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr return BLI_smallhash_iternext_p(iter, key); } +/* -------------------------------------------------------------------- */ /** \name Debugging & Introspection * \{ */ diff --git a/source/blender/blenlib/intern/sort.c b/source/blender/blenlib/intern/sort.c index e65be760a2c..6a13c0aa6f0 100644 --- a/source/blender/blenlib/intern/sort.c +++ b/source/blender/blenlib/intern/sort.c @@ -45,8 +45,8 @@ * * \note modified to use glibc arg order for callbacks. */ -BLI_INLINE char *med3(char */*a*/, char */*b*/, char */*c*/, BLI_sort_cmp_t /*cmp*/, void */*thunk*/); -BLI_INLINE void swapfunc(char */*a*/, char */*b*/, int /*n*/, int /*swaptype*/); +BLI_INLINE char *med3(char *a, char *b, char *c, BLI_sort_cmp_t cmp, void *thunk); +BLI_INLINE void swapfunc(char *a, char *b, int n, int swaptype); #define min(a, b) (a) < (b) ? (a) : (b) #define swapcode(TYPE, parmi, parmj, n) \ diff --git a/source/blender/blenlib/intern/storage_apple.mm b/source/blender/blenlib/intern/storage_apple.mm index 564ef5a199a..2a4bbffa60e 100644 --- a/source/blender/blenlib/intern/storage_apple.mm +++ b/source/blender/blenlib/intern/storage_apple.mm @@ -29,7 +29,7 @@ #include "BLI_path_util.h" /** - * \param r_targetpath Buffer for the target path an alias points to. + * \param r_targetpath: Buffer for the target path an alias points to. * \return Whether the file at the input path is an alias. */ /* False alarm by clang-tidy: #getFileSystemRepresentation changes the return value argument. */ diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c index 2c8eb9f5a13..eac01a0e2aa 100644 --- a/source/blender/blenlib/intern/voxel.c +++ b/source/blender/blenlib/intern/voxel.c @@ -51,7 +51,7 @@ float BLI_voxel_sample_nearest(const float *data, const int res[3], const float BLI_INLINE int FLOORI(float x) { const int r = (int)x; - return ((x >= 0.f) || (float)r == x) ? r : (r - 1); + return ((x >= 0.0f) || (float)r == x) ? r : (r - 1); } /* clamp function, cannot use the CLAMPIS macro, @@ -92,9 +92,9 @@ float BLI_voxel_sample_trilinear(const float *data, const int res[3], const floa const float dy = yf - (float)y; const float dz = zf - (float)z; - const float u[2] = {1.f - dx, dx}; - const float v[2] = {1.f - dy, dy}; - const float w[2] = {1.f - dz, dz}; + const float u[2] = {1.0f - dx, dx}; + const float v[2] = {1.0f - dy, dy}; + const float w[2] = {1.0f - dz, dz}; return w[0] * (v[0] * (u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]]) + @@ -103,7 +103,7 @@ float BLI_voxel_sample_trilinear(const float *data, const int res[3], const floa (v[0] * (u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]]) + v[1] * (u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]])); } - return 0.f; + return 0.0f; } float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const float co[3]) @@ -132,9 +132,9 @@ float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const f }; const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z; - const float u[3] = {dx * (0.5f * dx - 1.f) + 0.5f, dx * (1.0f - dx) + 0.5f, 0.5f * dx * dx}; - const float v[3] = {dy * (0.5f * dy - 1.f) + 0.5f, dy * (1.0f - dy) + 0.5f, 0.5f * dy * dy}; - const float w[3] = {dz * (0.5f * dz - 1.f) + 0.5f, dz * (1.0f - dz) + 0.5f, 0.5f * dz * dz}; + const float u[3] = {dx * (0.5f * dx - 1.0f) + 0.5f, dx * (1.0f - dx) + 0.5f, 0.5f * dx * dx}; + const float v[3] = {dy * (0.5f * dy - 1.0f) + 0.5f, dy * (1.0f - dy) + 0.5f, 0.5f * dy * dy}; + const float w[3] = {dz * (0.5f * dz - 1.0f) + 0.5f, dz * (1.0f - dz) + 0.5f, 0.5f * dz * dz}; return w[0] * (v[0] * (u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] + @@ -158,7 +158,7 @@ float BLI_voxel_sample_triquadratic(const float *data, const int res[3], const f v[2] * (u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] + u[2] * data[xc[2] + yc[2] + zc[2]])); } - return 0.f; + return 0.0f; } float BLI_voxel_sample_tricubic(const float *data, @@ -195,18 +195,18 @@ float BLI_voxel_sample_tricubic(const float *data, float u[4], v[4], w[4]; if (bspline) { // B-Spline - u[0] = (((-1.f / 6.f) * dx + 0.5f) * dx - 0.5f) * dx + (1.f / 6.f); - u[1] = ((0.5f * dx - 1.f) * dx) * dx + (2.f / 3.f); - u[2] = ((-0.5f * dx + 0.5f) * dx + 0.5f) * dx + (1.f / 6.f); - u[3] = (1.f / 6.f) * dx * dx * dx; - v[0] = (((-1.f / 6.f) * dy + 0.5f) * dy - 0.5f) * dy + (1.f / 6.f); - v[1] = ((0.5f * dy - 1.f) * dy) * dy + (2.f / 3.f); - v[2] = ((-0.5f * dy + 0.5f) * dy + 0.5f) * dy + (1.f / 6.f); - v[3] = (1.f / 6.f) * dy * dy * dy; - w[0] = (((-1.f / 6.f) * dz + 0.5f) * dz - 0.5f) * dz + (1.f / 6.f); - w[1] = ((0.5f * dz - 1.f) * dz) * dz + (2.f / 3.f); - w[2] = ((-0.5f * dz + 0.5f) * dz + 0.5f) * dz + (1.f / 6.f); - w[3] = (1.f / 6.f) * dz * dz * dz; + u[0] = (((-1.0f / 6.0f) * dx + 0.5f) * dx - 0.5f) * dx + (1.0f / 6.0f); + u[1] = ((0.5f * dx - 1.0f) * dx) * dx + (2.0f / 3.0f); + u[2] = ((-0.5f * dx + 0.5f) * dx + 0.5f) * dx + (1.0f / 6.0f); + u[3] = (1.0f / 6.0f) * dx * dx * dx; + v[0] = (((-1.0f / 6.0f) * dy + 0.5f) * dy - 0.5f) * dy + (1.0f / 6.0f); + v[1] = ((0.5f * dy - 1.0f) * dy) * dy + (2.0f / 3.0f); + v[2] = ((-0.5f * dy + 0.5f) * dy + 0.5f) * dy + (1.0f / 6.0f); + v[3] = (1.0f / 6.0f) * dy * dy * dy; + w[0] = (((-1.0f / 6.0f) * dz + 0.5f) * dz - 0.5f) * dz + (1.0f / 6.0f); + w[1] = ((0.5f * dz - 1.0f) * dz) * dz + (2.0f / 3.0f); + w[2] = ((-0.5f * dz + 0.5f) * dz + 0.5f) * dz + (1.0f / 6.0f); + w[3] = (1.0f / 6.0f) * dz * dz * dz; } else { // Catmull-Rom u[0] = ((-0.5f * dx + 1.0f) * dx - 0.5f) * dx; @@ -260,5 +260,5 @@ float BLI_voxel_sample_tricubic(const float *data, v[3] * (u[0] * data[xc[0] + yc[3] + zc[3]] + u[1] * data[xc[1] + yc[3] + zc[3]] + u[2] * data[xc[2] + yc[3] + zc[3]] + u[3] * data[xc[3] + yc[3] + zc[3]])); } - return 0.f; + return 0.0f; } diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc index 14db4254f70..caacbf1a2c4 100644 --- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc +++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc @@ -667,7 +667,7 @@ template<typename T> void crosssegs_test() if (out.vert.size() == 5) { int v_intersect = -1; for (int i = 0; i < 5; i++) { - if (i != v0_out && i != v1_out && i != v2_out && i != v3_out) { + if (!ELEM(i, v0_out, v1_out, v2_out, v3_out)) { EXPECT_EQ(v_intersect, -1); v_intersect = i; } diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc index 91c6335b949..e61d638c681 100644 --- a/source/blender/blenlib/tests/BLI_map_test.cc +++ b/source/blender/blenlib/tests/BLI_map_test.cc @@ -295,6 +295,24 @@ TEST(map, AddOrModify) EXPECT_EQ(map.lookup(1), 15.0f); } +TEST(map, AddOrModifyReference) +{ + Map<int, std::unique_ptr<int>> map; + auto create_func = [](std::unique_ptr<int> *value) -> int & { + new (value) std::unique_ptr<int>(new int{10}); + return **value; + }; + auto modify_func = [](std::unique_ptr<int> *value) -> int & { + **value += 5; + return **value; + }; + EXPECT_EQ(map.add_or_modify(1, create_func, modify_func), 10); + int &a = map.add_or_modify(1, create_func, modify_func); + EXPECT_EQ(a, 15); + a = 100; + EXPECT_EQ(*map.lookup(1), 100); +} + TEST(map, AddOverwrite) { Map<int, float> map; diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h index 5d685cc6687..3600ae504a1 100644 --- a/source/blender/blenloader/BLO_read_write.h +++ b/source/blender/blenloader/BLO_read_write.h @@ -52,6 +52,8 @@ typedef struct BlendExpander BlendExpander; typedef struct BlendLibReader BlendLibReader; typedef struct BlendWriter BlendWriter; +struct Main; + /* Blend Write API * =============== * @@ -106,6 +108,14 @@ void BLO_write_struct_at_address_by_id(BlendWriter *writer, BLO_write_struct_at_address_by_id( \ writer, BLO_get_struct_id(writer, struct_name), address, data_ptr) +/* Write single struct at address and specify a filecode. */ +void BLO_write_struct_at_address_by_id_with_filecode( + BlendWriter *writer, int filecode, int struct_id, const void *address, const void *data_ptr); +#define BLO_write_struct_at_address_with_filecode( \ + writer, filecode, struct_name, address, data_ptr) \ + BLO_write_struct_at_address_by_id_with_filecode( \ + writer, filecode, BLO_get_struct_id(writer, struct_name), address, data_ptr) + /* Write struct array. */ void BLO_write_struct_array_by_name(BlendWriter *writer, const char *struct_name, @@ -177,6 +187,7 @@ bool BLO_write_is_undo(BlendWriter *writer); */ void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_address); +void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address); void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_address); #define BLO_read_data_address(reader, ptr_p) \ @@ -214,6 +225,7 @@ ID *BLO_read_get_new_id_address(BlendLibReader *reader, struct Library *lib, str /* Misc. */ bool BLO_read_lib_is_undo(BlendLibReader *reader); +struct Main *BLO_read_lib_get_main(BlendLibReader *reader); /* Blend Expand API * =================== diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index c44bd8d0039..833a5abb630 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -33,8 +33,8 @@ set(INC ../render/extern/include ../sequencer ../windowmanager - ../../../intern/guardedalloc ../../../intern/clog + ../../../intern/guardedalloc # for writefile.c: dna_type_offsets.h ${CMAKE_BINARY_DIR}/source/blender/makesdna/intern diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 5a6324eb8e1..855d320a63d 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -156,7 +156,6 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_shader_fx.h" #include "BKE_simulation.h" #include "BKE_sound.h" @@ -177,6 +176,8 @@ #include "RE_engine.h" +#include "SEQ_sequencer.h" + #include "engines/eevee/eevee_lightcache.h" #include "readfile.h" @@ -268,10 +269,6 @@ static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const static BHead *find_bhead_from_idname(FileData *fd, const char *idname); static bool library_link_idcode_needs_tag_check(const short idcode, const int flag); -#ifdef USE_COLLECTION_COMPAT_28 -static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc); -#endif - typedef struct BHeadN { struct BHeadN *next, *prev; #ifdef USE_BHEAD_READ_ON_DEMAND @@ -2262,7 +2259,6 @@ static void link_glob_list(FileData *fd, ListBase *lb) /* for glob data */ * \{ */ static void lib_link_id(BlendLibReader *reader, ID *id); -static void lib_link_collection(BlendLibReader *reader, Collection *collection); static void lib_link_id_embedded_id(BlendLibReader *reader, ID *id) { @@ -2278,7 +2274,7 @@ static void lib_link_id_embedded_id(BlendLibReader *reader, ID *id) Scene *scene = (Scene *)id; if (scene->master_collection != NULL) { lib_link_id(reader, &scene->master_collection->id); - lib_link_collection(reader, scene->master_collection); + BKE_collection_blend_read_lib(reader, scene->master_collection); } } } @@ -2325,7 +2321,6 @@ static void direct_link_id_override_property_cb(BlendDataReader *reader, void *d static void direct_link_id_common( BlendDataReader *reader, Library *current_library, ID *id, ID *id_old, const int tag); -static void direct_link_collection(BlendDataReader *reader, Collection *collection); static void direct_link_id_embedded_id(BlendDataReader *reader, Library *current_library, @@ -2353,7 +2348,7 @@ static void direct_link_id_embedded_id(BlendDataReader *reader, &scene->master_collection->id, id_old != NULL ? &((Scene *)id_old)->master_collection->id : NULL, 0); - direct_link_collection(reader, scene->master_collection); + BKE_collection_blend_read_data(reader, scene->master_collection); } } } @@ -2577,69 +2572,6 @@ static void lib_link_constraint_channels(BlendLibReader *reader, ID *id, ListBas /** \name Read ID: WorkSpace * \{ */ -static void lib_link_workspaces(BlendLibReader *reader, WorkSpace *workspace) -{ - ID *id = (ID *)workspace; - - /* Restore proper 'parent' pointers to relevant data, and clean up unused/invalid entries. */ - LISTBASE_FOREACH_MUTABLE (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { - relation->parent = NULL; - LISTBASE_FOREACH (wmWindowManager *, wm, &reader->main->wm) { - LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { - if (win->winid == relation->parentid) { - relation->parent = win->workspace_hook; - } - } - } - if (relation->parent == NULL) { - BLI_freelinkN(&workspace->hook_layout_relations, relation); - } - } - - LISTBASE_FOREACH_MUTABLE (WorkSpaceLayout *, layout, &workspace->layouts) { - BLO_read_id_address(reader, id->lib, &layout->screen); - - if (layout->screen) { - if (ID_IS_LINKED(id)) { - layout->screen->winid = 0; - if (layout->screen->temp) { - /* delete temp layouts when appending */ - BKE_workspace_layout_remove(reader->main, workspace, layout); - } - } - } - else { - /* If we're reading a layout without screen stored, it's useless and we shouldn't keep it - * around. */ - BKE_workspace_layout_remove(reader->main, workspace, layout); - } - } -} - -static void direct_link_workspace(BlendDataReader *reader, WorkSpace *workspace) -{ - BLO_read_list(reader, &workspace->layouts); - BLO_read_list(reader, &workspace->hook_layout_relations); - BLO_read_list(reader, &workspace->owner_ids); - BLO_read_list(reader, &workspace->tools); - - LISTBASE_FOREACH (WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { - /* parent pointer does not belong to workspace data and is therefore restored in lib_link step - * of window manager.*/ - BLO_read_data_address(reader, &relation->value); - } - - LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { - tref->runtime = NULL; - BLO_read_data_address(reader, &tref->properties); - IDP_BlendDataRead(reader, &tref->properties); - } - - workspace->status_text = NULL; - - id_us_ensure_real(&workspace->id); -} - static void lib_link_workspace_instance_hook(BlendLibReader *reader, WorkSpaceInstanceHook *hook, ID *id) @@ -2729,8 +2661,8 @@ static void direct_link_constraints(BlendDataReader *reader, ListBase *lb) case CONSTRAINT_TYPE_KINEMATIC: { bKinematicConstraint *data = con->data; - con->lin_error = 0.f; - con->rot_error = 0.f; + con->lin_error = 0.0f; + con->rot_error = 0.0f; /* version patch for runtime flag, was not cleared in some case */ data->flag &= ~CONSTRAINT_IK_AUTO; @@ -2913,132 +2845,6 @@ static void direct_link_pointcache_list(BlendDataReader *reader, } } -static void lib_link_partdeflect(BlendLibReader *reader, ID *id, PartDeflect *pd) -{ - if (pd && pd->tex) { - BLO_read_id_address(reader, id->lib, &pd->tex); - } - if (pd && pd->f_source) { - BLO_read_id_address(reader, id->lib, &pd->f_source); - } -} - -static void lib_link_particlesettings(BlendLibReader *reader, ParticleSettings *part) -{ - BLO_read_id_address( - reader, part->id.lib, &part->ipo); /* XXX deprecated - old animation system */ - - BLO_read_id_address(reader, part->id.lib, &part->instance_object); - BLO_read_id_address(reader, part->id.lib, &part->instance_collection); - BLO_read_id_address(reader, part->id.lib, &part->force_group); - BLO_read_id_address(reader, part->id.lib, &part->bb_ob); - BLO_read_id_address(reader, part->id.lib, &part->collision_group); - - lib_link_partdeflect(reader, &part->id, part->pd); - lib_link_partdeflect(reader, &part->id, part->pd2); - - if (part->effector_weights) { - BLO_read_id_address(reader, part->id.lib, &part->effector_weights->group); - } - else { - part->effector_weights = BKE_effector_add_weights(part->force_group); - } - - if (part->instance_weights.first && part->instance_collection) { - LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - BLO_read_id_address(reader, part->id.lib, &dw->ob); - } - } - else { - BLI_listbase_clear(&part->instance_weights); - } - - if (part->boids) { - LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { - switch (rule->type) { - case eBoidRuleType_Goal: - case eBoidRuleType_Avoid: { - BoidRuleGoalAvoid *brga = (BoidRuleGoalAvoid *)rule; - BLO_read_id_address(reader, part->id.lib, &brga->ob); - break; - } - case eBoidRuleType_FollowLeader: { - BoidRuleFollowLeader *brfl = (BoidRuleFollowLeader *)rule; - BLO_read_id_address(reader, part->id.lib, &brfl->ob); - break; - } - } - } - } - } - - for (int a = 0; a < MAX_MTEX; a++) { - MTex *mtex = part->mtex[a]; - if (mtex) { - BLO_read_id_address(reader, part->id.lib, &mtex->tex); - BLO_read_id_address(reader, part->id.lib, &mtex->object); - } - } -} - -static void direct_link_partdeflect(PartDeflect *pd) -{ - if (pd) { - pd->rng = NULL; - } -} - -static void direct_link_particlesettings(BlendDataReader *reader, ParticleSettings *part) -{ - BLO_read_data_address(reader, &part->adt); - BLO_read_data_address(reader, &part->pd); - BLO_read_data_address(reader, &part->pd2); - - BKE_animdata_blend_read_data(reader, part->adt); - direct_link_partdeflect(part->pd); - direct_link_partdeflect(part->pd2); - - BLO_read_data_address(reader, &part->clumpcurve); - if (part->clumpcurve) { - BKE_curvemapping_blend_read(reader, part->clumpcurve); - } - BLO_read_data_address(reader, &part->roughcurve); - if (part->roughcurve) { - BKE_curvemapping_blend_read(reader, part->roughcurve); - } - BLO_read_data_address(reader, &part->twistcurve); - if (part->twistcurve) { - BKE_curvemapping_blend_read(reader, part->twistcurve); - } - - BLO_read_data_address(reader, &part->effector_weights); - if (!part->effector_weights) { - part->effector_weights = BKE_effector_add_weights(part->force_group); - } - - BLO_read_list(reader, &part->instance_weights); - - BLO_read_data_address(reader, &part->boids); - BLO_read_data_address(reader, &part->fluid); - - if (part->boids) { - BLO_read_list(reader, &part->boids->states); - - LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - BLO_read_list(reader, &state->rules); - BLO_read_list(reader, &state->conditions); - BLO_read_list(reader, &state->actions); - } - } - for (int a = 0; a < MAX_MTEX; a++) { - BLO_read_data_address(reader, &part->mtex[a]); - } - - /* Protect against integer overflow vulnerability. */ - CLAMP(part->trail_count, 1, 100000); -} - static void lib_link_particlesystems(BlendLibReader *reader, Object *ob, ID *id, @@ -3364,7 +3170,7 @@ static void lib_link_object(BlendLibReader *reader, Object *ob) /* texture field */ if (ob->pd) { - lib_link_partdeflect(reader, &ob->id, ob->pd); + BKE_particle_partdeflect_blend_read_lib(reader, &ob->id, ob->pd); } if (ob->soft) { @@ -3948,7 +3754,7 @@ static void direct_link_object(BlendDataReader *reader, Object *ob) } BLO_read_data_address(reader, &ob->pd); - direct_link_partdeflect(ob->pd); + BKE_particle_partdeflect_blend_read_data(reader, ob->pd); BLO_read_data_address(reader, &ob->soft); if (ob->soft) { SoftBody *sb = ob->soft; @@ -4064,187 +3870,6 @@ static void direct_link_view_settings(BlendDataReader *reader, /** \} */ /* -------------------------------------------------------------------- */ -/** \name Read View Layer (Collection Data) - * \{ */ - -static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb, bool master) -{ - BLO_read_list(reader, lb); - LISTBASE_FOREACH (LayerCollection *, lc, lb) { -#ifdef USE_COLLECTION_COMPAT_28 - BLO_read_data_address(reader, &lc->scene_collection); -#endif - - /* Master collection is not a real data-lock. */ - if (master) { - BLO_read_data_address(reader, &lc->collection); - } - - direct_link_layer_collections(reader, &lc->layer_collections, false); - } -} - -static void direct_link_view_layer(BlendDataReader *reader, ViewLayer *view_layer) -{ - view_layer->stats = NULL; - BLO_read_list(reader, &view_layer->object_bases); - BLO_read_data_address(reader, &view_layer->basact); - - direct_link_layer_collections(reader, &view_layer->layer_collections, true); - BLO_read_data_address(reader, &view_layer->active_collection); - - BLO_read_data_address(reader, &view_layer->id_properties); - IDP_BlendDataRead(reader, &view_layer->id_properties); - - BLO_read_list(reader, &(view_layer->freestyle_config.modules)); - BLO_read_list(reader, &(view_layer->freestyle_config.linesets)); - - BLI_listbase_clear(&view_layer->drawdata); - view_layer->object_bases_array = NULL; - view_layer->object_bases_hash = NULL; -} - -static void lib_link_layer_collection(BlendLibReader *reader, - Library *lib, - LayerCollection *layer_collection, - bool master) -{ - /* Master collection is not a real data-lock. */ - if (!master) { - BLO_read_id_address(reader, lib, &layer_collection->collection); - } - - LISTBASE_FOREACH ( - LayerCollection *, layer_collection_nested, &layer_collection->layer_collections) { - lib_link_layer_collection(reader, lib, layer_collection_nested, false); - } -} - -static void lib_link_view_layer(BlendLibReader *reader, Library *lib, ViewLayer *view_layer) -{ - LISTBASE_FOREACH (FreestyleModuleConfig *, fmc, &view_layer->freestyle_config.modules) { - BLO_read_id_address(reader, lib, &fmc->script); - } - - LISTBASE_FOREACH (FreestyleLineSet *, fls, &view_layer->freestyle_config.linesets) { - BLO_read_id_address(reader, lib, &fls->linestyle); - BLO_read_id_address(reader, lib, &fls->group); - } - - for (Base *base = view_layer->object_bases.first, *base_next = NULL; base; base = base_next) { - base_next = base->next; - - /* we only bump the use count for the collection objects */ - BLO_read_id_address(reader, lib, &base->object); - - if (base->object == NULL) { - /* Free in case linked object got lost. */ - BLI_freelinkN(&view_layer->object_bases, base); - if (view_layer->basact == base) { - view_layer->basact = NULL; - } - } - } - - LISTBASE_FOREACH (LayerCollection *, layer_collection, &view_layer->layer_collections) { - lib_link_layer_collection(reader, lib, layer_collection, true); - } - - BLO_read_id_address(reader, lib, &view_layer->mat_override); - - IDP_BlendReadLib(reader, view_layer->id_properties); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Read ID: Collection - * \{ */ - -#ifdef USE_COLLECTION_COMPAT_28 -static void direct_link_scene_collection(BlendDataReader *reader, SceneCollection *sc) -{ - BLO_read_list(reader, &sc->objects); - BLO_read_list(reader, &sc->scene_collections); - - LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { - direct_link_scene_collection(reader, nsc); - } -} - -static void lib_link_scene_collection(BlendLibReader *reader, Library *lib, SceneCollection *sc) -{ - LISTBASE_FOREACH (LinkData *, link, &sc->objects) { - BLO_read_id_address(reader, lib, &link->data); - BLI_assert(link->data); - } - - LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { - lib_link_scene_collection(reader, lib, nsc); - } -} -#endif - -static void direct_link_collection(BlendDataReader *reader, Collection *collection) -{ - BLO_read_list(reader, &collection->gobject); - BLO_read_list(reader, &collection->children); - - BLO_read_data_address(reader, &collection->preview); - BKE_previewimg_blend_read(reader, collection->preview); - - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->tag = 0; - BLI_listbase_clear(&collection->object_cache); - BLI_listbase_clear(&collection->parents); - -#ifdef USE_COLLECTION_COMPAT_28 - /* This runs before the very first doversion. */ - BLO_read_data_address(reader, &collection->collection); - if (collection->collection != NULL) { - direct_link_scene_collection(reader, collection->collection); - } - - BLO_read_data_address(reader, &collection->view_layer); - if (collection->view_layer != NULL) { - direct_link_view_layer(reader, collection->view_layer); - } -#endif -} - -static void lib_link_collection_data(BlendLibReader *reader, Library *lib, Collection *collection) -{ - LISTBASE_FOREACH_MUTABLE (CollectionObject *, cob, &collection->gobject) { - BLO_read_id_address(reader, lib, &cob->ob); - - if (cob->ob == NULL) { - BLI_freelinkN(&collection->gobject, cob); - } - } - - LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - BLO_read_id_address(reader, lib, &child->collection); - } -} - -static void lib_link_collection(BlendLibReader *reader, Collection *collection) -{ -#ifdef USE_COLLECTION_COMPAT_28 - if (collection->collection) { - lib_link_scene_collection(reader, collection->id.lib, collection->collection); - } - - if (collection->view_layer) { - lib_link_view_layer(reader, collection->id.lib, collection->view_layer); - } -#endif - - lib_link_collection_data(reader, collection->id.lib, collection); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Read ID: Scene * \{ */ @@ -4325,14 +3950,6 @@ static void direct_link_lightcache(BlendDataReader *reader, LightCache *cache) BLO_read_data_address(reader, &cache->grid_data); } -static void direct_link_view3dshading(BlendDataReader *reader, View3DShading *shading) -{ - if (shading->prop) { - BLO_read_data_address(reader, &shading->prop); - IDP_BlendDataRead(reader, &shading->prop); - } -} - /* check for cyclic set-scene, * libs can cause this case which is normally prevented, see (T#####) */ #define USE_SETSCENE_CHECK @@ -4530,12 +4147,12 @@ static void lib_link_scene(BlendLibReader *reader, Scene *sce) #ifdef USE_COLLECTION_COMPAT_28 if (sce->collection) { - lib_link_scene_collection(reader, sce->id.lib, sce->collection); + BKE_collection_compat_blend_read_lib(reader, sce->id.lib, sce->collection); } #endif LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { - lib_link_view_layer(reader, sce->id.lib, view_layer); + BKE_view_layer_blend_read_lib(reader, sce->id.lib, view_layer); } if (sce->r.bake.cage_object) { @@ -4776,7 +4393,7 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce) seq->strip->proxy->anim = NULL; } else if (seq->flag & SEQ_USE_PROXY) { - BKE_sequencer_proxy_set(seq, true); + SEQ_proxy_set(seq, true); } /* need to load color balance to it could be converted to modifier */ @@ -4919,14 +4536,14 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce) /* this runs before the very first doversion */ if (sce->collection) { BLO_read_data_address(reader, &sce->collection); - direct_link_scene_collection(reader, sce->collection); + BKE_collection_compat_blend_read_data(reader, sce->collection); } #endif /* insert into global old-new map for reading without UI (link_global accesses it again) */ link_glob_list(reader->fd, &sce->view_layers); LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) { - direct_link_view_layer(reader, view_layer); + BKE_view_layer_blend_read_data(reader, view_layer); } if (BLO_read_data_is_undo(reader)) { @@ -4941,7 +4558,7 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce) } EEVEE_lightcache_info_update(&sce->eevee); - direct_link_view3dshading(reader, &sce->display.shading); + BKE_screen_view3d_shading_blend_read_data(reader, &sce->display.shading); BLO_read_data_address(reader, &sce->layer_properties); IDP_BlendDataRead(reader, &sce->layer_properties); @@ -4950,540 +4567,12 @@ static void direct_link_scene(BlendDataReader *reader, Scene *sce) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Read Screen Area/Region (Screen Data) - * \{ */ - -static void direct_link_panel_list(BlendDataReader *reader, ListBase *lb) -{ - BLO_read_list(reader, lb); - - LISTBASE_FOREACH (Panel *, panel, lb) { - panel->runtime_flag = 0; - panel->activedata = NULL; - panel->type = NULL; - panel->runtime.custom_data_ptr = NULL; - direct_link_panel_list(reader, &panel->children); - } -} - -static void direct_link_region(BlendDataReader *reader, ARegion *region, int spacetype) -{ - direct_link_panel_list(reader, ®ion->panels); - - BLO_read_list(reader, ®ion->panels_category_active); - - BLO_read_list(reader, ®ion->ui_lists); - - /* The area's search filter is runtime only, so we need to clear the active flag on read. */ - region->flag &= ~RGN_FLAG_SEARCH_FILTER_ACTIVE; - - LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { - ui_list->type = NULL; - ui_list->dyn_data = NULL; - BLO_read_data_address(reader, &ui_list->properties); - IDP_BlendDataRead(reader, &ui_list->properties); - } - - BLO_read_list(reader, ®ion->ui_previews); - - if (spacetype == SPACE_EMPTY) { - /* unknown space type, don't leak regiondata */ - region->regiondata = NULL; - } - else if (region->flag & RGN_FLAG_TEMP_REGIONDATA) { - /* Runtime data, don't use. */ - region->regiondata = NULL; - } - else { - BLO_read_data_address(reader, ®ion->regiondata); - if (region->regiondata) { - if (spacetype == SPACE_VIEW3D) { - RegionView3D *rv3d = region->regiondata; - - BLO_read_data_address(reader, &rv3d->localvd); - BLO_read_data_address(reader, &rv3d->clipbb); - - rv3d->depths = NULL; - rv3d->render_engine = NULL; - rv3d->sms = NULL; - rv3d->smooth_timer = NULL; - - rv3d->rflag &= ~(RV3D_NAVIGATING | RV3D_PAINTING); - rv3d->runtime_viewlock = 0; - } - } - } - - region->v2d.sms = NULL; - region->v2d.alpha_hor = region->v2d.alpha_vert = 255; /* visible by default */ - BLI_listbase_clear(®ion->panels_category); - BLI_listbase_clear(®ion->handlers); - BLI_listbase_clear(®ion->uiblocks); - region->headerstr = NULL; - region->visible = 0; - region->type = NULL; - region->do_draw = 0; - region->gizmo_map = NULL; - region->regiontimer = NULL; - region->draw_buffer = NULL; - memset(®ion->drawrct, 0, sizeof(region->drawrct)); -} - -static void direct_link_area(BlendDataReader *reader, ScrArea *area) -{ - BLO_read_list(reader, &(area->spacedata)); - BLO_read_list(reader, &(area->regionbase)); - - BLI_listbase_clear(&area->handlers); - area->type = NULL; /* spacetype callbacks */ - - /* Should always be unset so that rna_Area_type_get works correctly. */ - area->butspacetype = SPACE_EMPTY; - - area->region_active_win = -1; - - area->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; - - BLO_read_data_address(reader, &area->global); - - /* if we do not have the spacetype registered we cannot - * free it, so don't allocate any new memory for such spacetypes. */ - if (!BKE_spacetype_exists(area->spacetype)) { - /* Hint for versioning code to replace deprecated space types. */ - area->butspacetype = area->spacetype; - - area->spacetype = SPACE_EMPTY; - } - - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - direct_link_region(reader, region, area->spacetype); - } - - /* accident can happen when read/save new file with older version */ - /* 2.50: we now always add spacedata for info */ - if (area->spacedata.first == NULL) { - SpaceInfo *sinfo = MEM_callocN(sizeof(SpaceInfo), "spaceinfo"); - area->spacetype = sinfo->spacetype = SPACE_INFO; - BLI_addtail(&area->spacedata, sinfo); - } - /* add local view3d too */ - else if (area->spacetype == SPACE_VIEW3D) { - blo_do_versions_view3d_split_250(area->spacedata.first, &area->regionbase); - } - - LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - BLO_read_list(reader, &(sl->regionbase)); - - /* if we do not have the spacetype registered we cannot - * free it, so don't allocate any new memory for such spacetypes. */ - if (!BKE_spacetype_exists(sl->spacetype)) { - sl->spacetype = SPACE_EMPTY; - } - - LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { - direct_link_region(reader, region, sl->spacetype); - } - - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - - v3d->flag |= V3D_INVALID_BACKBUF; - - if (v3d->gpd) { - BLO_read_data_address(reader, &v3d->gpd); - BKE_gpencil_blend_read_data(reader, v3d->gpd); - } - BLO_read_data_address(reader, &v3d->localvd); - - /* Runtime data */ - v3d->runtime.properties_storage = NULL; - v3d->runtime.flag = 0; - - /* render can be quite heavy, set to solid on load */ - if (v3d->shading.type == OB_RENDER) { - v3d->shading.type = OB_SOLID; - } - v3d->shading.prev_type = OB_SOLID; - - direct_link_view3dshading(reader, &v3d->shading); - - blo_do_versions_view3d_split_250(v3d, &sl->regionbase); - } - else if (sl->spacetype == SPACE_GRAPH) { - SpaceGraph *sipo = (SpaceGraph *)sl; - - BLO_read_data_address(reader, &sipo->ads); - BLI_listbase_clear(&sipo->runtime.ghost_curves); - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla = (SpaceNla *)sl; - - BLO_read_data_address(reader, &snla->ads); - } - else if (sl->spacetype == SPACE_OUTLINER) { - SpaceOutliner *space_outliner = (SpaceOutliner *)sl; - - /* use newdataadr_no_us and do not free old memory avoiding double - * frees and use of freed memory. this could happen because of a - * bug fixed in revision 58959 where the treestore memory address - * was not unique */ - TreeStore *ts = newdataadr_no_us(reader->fd, space_outliner->treestore); - space_outliner->treestore = NULL; - if (ts) { - TreeStoreElem *elems = newdataadr_no_us(reader->fd, ts->data); - - space_outliner->treestore = BLI_mempool_create( - sizeof(TreeStoreElem), ts->usedelem, 512, BLI_MEMPOOL_ALLOW_ITER); - if (ts->usedelem && elems) { - for (int i = 0; i < ts->usedelem; i++) { - TreeStoreElem *new_elem = BLI_mempool_alloc(space_outliner->treestore); - *new_elem = elems[i]; - } - } - /* we only saved what was used */ - space_outliner->storeflag |= SO_TREESTORE_CLEANUP; /* at first draw */ - } - space_outliner->treehash = NULL; - space_outliner->tree.first = space_outliner->tree.last = NULL; - } - else if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; - - sima->iuser.scene = NULL; - sima->iuser.ok = 1; - sima->scopes.waveform_1 = NULL; - sima->scopes.waveform_2 = NULL; - sima->scopes.waveform_3 = NULL; - sima->scopes.vecscope = NULL; - sima->scopes.ok = 0; - - /* WARNING: gpencil data is no longer stored directly in sima after 2.5 - * so sacrifice a few old files for now to avoid crashes with new files! - * committed: r28002 */ -#if 0 - sima->gpd = newdataadr(fd, sima->gpd); - if (sima->gpd) { - BKE_gpencil_blend_read_data(fd, sima->gpd); - } -#endif - } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - - if (snode->gpd) { - BLO_read_data_address(reader, &snode->gpd); - BKE_gpencil_blend_read_data(reader, snode->gpd); - } - - BLO_read_list(reader, &snode->treepath); - snode->edittree = NULL; - snode->iofsd = NULL; - BLI_listbase_clear(&snode->linkdrag); - } - else if (sl->spacetype == SPACE_TEXT) { - SpaceText *st = (SpaceText *)sl; - memset(&st->runtime, 0, sizeof(st->runtime)); - } - else if (sl->spacetype == SPACE_SEQ) { - SpaceSeq *sseq = (SpaceSeq *)sl; - - /* grease pencil data is not a direct data and can't be linked from direct_link* - * functions, it should be linked from lib_link* functions instead - * - * otherwise it'll lead to lost grease data on open because it'll likely be - * read from file after all other users of grease pencil and newdataadr would - * simple return NULL here (sergey) - */ -#if 0 - if (sseq->gpd) { - sseq->gpd = newdataadr(fd, sseq->gpd); - BKE_gpencil_blend_read_data(fd, sseq->gpd); - } -#endif - sseq->scopes.reference_ibuf = NULL; - sseq->scopes.zebra_ibuf = NULL; - sseq->scopes.waveform_ibuf = NULL; - sseq->scopes.sep_waveform_ibuf = NULL; - sseq->scopes.vector_ibuf = NULL; - sseq->scopes.histogram_ibuf = NULL; - } - else if (sl->spacetype == SPACE_PROPERTIES) { - SpaceProperties *sbuts = (SpaceProperties *)sl; - - sbuts->path = NULL; - sbuts->texuser = NULL; - sbuts->mainbo = sbuts->mainb; - sbuts->mainbuser = sbuts->mainb; - sbuts->runtime = NULL; - } - else if (sl->spacetype == SPACE_CONSOLE) { - SpaceConsole *sconsole = (SpaceConsole *)sl; - - BLO_read_list(reader, &sconsole->scrollback); - BLO_read_list(reader, &sconsole->history); - - /* comma expressions, (e.g. expr1, expr2, expr3) evaluate each expression, - * from left to right. the right-most expression sets the result of the comma - * expression as a whole*/ - LISTBASE_FOREACH_MUTABLE (ConsoleLine *, cl, &sconsole->history) { - BLO_read_data_address(reader, &cl->line); - if (cl->line) { - /* the allocted length is not written, so reset here */ - cl->len_alloc = cl->len + 1; - } - else { - BLI_remlink(&sconsole->history, cl); - MEM_freeN(cl); - } - } - } - else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - - /* this sort of info is probably irrelevant for reloading... - * plus, it isn't saved to files yet! - */ - sfile->folders_prev = sfile->folders_next = NULL; - sfile->files = NULL; - sfile->layout = NULL; - sfile->op = NULL; - sfile->previews_timer = NULL; - BLO_read_data_address(reader, &sfile->params); - } - else if (sl->spacetype == SPACE_CLIP) { - SpaceClip *sclip = (SpaceClip *)sl; - - sclip->scopes.track_search = NULL; - sclip->scopes.track_preview = NULL; - sclip->scopes.ok = 0; - } - } - - BLI_listbase_clear(&area->actionzones); - - BLO_read_data_address(reader, &area->v1); - BLO_read_data_address(reader, &area->v2); - BLO_read_data_address(reader, &area->v3); - BLO_read_data_address(reader, &area->v4); -} - -static void lib_link_area(BlendLibReader *reader, ID *parent_id, ScrArea *area) -{ - BLO_read_id_address(reader, parent_id->lib, &area->full); - - memset(&area->runtime, 0x0, sizeof(area->runtime)); - - LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - switch (sl->spacetype) { - case SPACE_VIEW3D: { - View3D *v3d = (View3D *)sl; - - BLO_read_id_address(reader, parent_id->lib, &v3d->camera); - BLO_read_id_address(reader, parent_id->lib, &v3d->ob_center); - - if (v3d->localvd) { - BLO_read_id_address(reader, parent_id->lib, &v3d->localvd->camera); - } - break; - } - case SPACE_GRAPH: { - SpaceGraph *sipo = (SpaceGraph *)sl; - bDopeSheet *ads = sipo->ads; - - if (ads) { - BLO_read_id_address(reader, parent_id->lib, &ads->source); - BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); - } - break; - } - case SPACE_PROPERTIES: { - SpaceProperties *sbuts = (SpaceProperties *)sl; - BLO_read_id_address(reader, parent_id->lib, &sbuts->pinid); - if (sbuts->pinid == NULL) { - sbuts->flag &= ~SB_PIN_CONTEXT; - } - break; - } - case SPACE_FILE: - break; - case SPACE_ACTION: { - SpaceAction *saction = (SpaceAction *)sl; - bDopeSheet *ads = &saction->ads; - - if (ads) { - BLO_read_id_address(reader, parent_id->lib, &ads->source); - BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); - } - - BLO_read_id_address(reader, parent_id->lib, &saction->action); - break; - } - case SPACE_IMAGE: { - SpaceImage *sima = (SpaceImage *)sl; - - BLO_read_id_address(reader, parent_id->lib, &sima->image); - BLO_read_id_address(reader, parent_id->lib, &sima->mask_info.mask); - - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so fingers crossed this works fine! - */ - BLO_read_id_address(reader, parent_id->lib, &sima->gpd); - break; - } - case SPACE_SEQ: { - SpaceSeq *sseq = (SpaceSeq *)sl; - - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so fingers crossed this works fine! - */ - BLO_read_id_address(reader, parent_id->lib, &sseq->gpd); - break; - } - case SPACE_NLA: { - SpaceNla *snla = (SpaceNla *)sl; - bDopeSheet *ads = snla->ads; - - if (ads) { - BLO_read_id_address(reader, parent_id->lib, &ads->source); - BLO_read_id_address(reader, parent_id->lib, &ads->filter_grp); - } - break; - } - case SPACE_TEXT: { - SpaceText *st = (SpaceText *)sl; - - BLO_read_id_address(reader, parent_id->lib, &st->text); - break; - } - case SPACE_SCRIPT: { - SpaceScript *scpt = (SpaceScript *)sl; - /*scpt->script = NULL; - 2.45 set to null, better re-run the script */ - if (scpt->script) { - BLO_read_id_address(reader, parent_id->lib, &scpt->script); - if (scpt->script) { - SCRIPT_SET_NULL(scpt->script); - } - } - break; - } - case SPACE_OUTLINER: { - SpaceOutliner *space_outliner = (SpaceOutliner *)sl; - BLO_read_id_address(reader, NULL, &space_outliner->search_tse.id); - - if (space_outliner->treestore) { - TreeStoreElem *tselem; - BLI_mempool_iter iter; - - BLI_mempool_iternew(space_outliner->treestore, &iter); - while ((tselem = BLI_mempool_iterstep(&iter))) { - BLO_read_id_address(reader, NULL, &tselem->id); - } - if (space_outliner->treehash) { - /* rebuild hash table, because it depends on ids too */ - space_outliner->storeflag |= SO_TREESTORE_REBUILD; - } - } - break; - } - case SPACE_NODE: { - SpaceNode *snode = (SpaceNode *)sl; - - /* node tree can be stored locally in id too, link this first */ - BLO_read_id_address(reader, parent_id->lib, &snode->id); - BLO_read_id_address(reader, parent_id->lib, &snode->from); - - bNodeTree *ntree = snode->id ? ntreeFromID(snode->id) : NULL; - if (ntree) { - snode->nodetree = ntree; - } - else { - BLO_read_id_address(reader, parent_id->lib, &snode->nodetree); - } - - bNodeTreePath *path; - for (path = snode->treepath.first; path; path = path->next) { - if (path == snode->treepath.first) { - /* first nodetree in path is same as snode->nodetree */ - path->nodetree = snode->nodetree; - } - else { - BLO_read_id_address(reader, parent_id->lib, &path->nodetree); - } - - if (!path->nodetree) { - break; - } - } - - /* remaining path entries are invalid, remove */ - bNodeTreePath *path_next; - for (; path; path = path_next) { - path_next = path->next; - - BLI_remlink(&snode->treepath, path); - MEM_freeN(path); - } - - /* edittree is just the last in the path, - * set this directly since the path may have been shortened above */ - if (snode->treepath.last) { - path = snode->treepath.last; - snode->edittree = path->nodetree; - } - else { - snode->edittree = NULL; - } - break; - } - case SPACE_CLIP: { - SpaceClip *sclip = (SpaceClip *)sl; - BLO_read_id_address(reader, parent_id->lib, &sclip->clip); - BLO_read_id_address(reader, parent_id->lib, &sclip->mask_info.mask); - break; - } - default: - break; - } - } -} - -/** - * \return false on error. - */ -static bool direct_link_area_map(BlendDataReader *reader, ScrAreaMap *area_map) -{ - BLO_read_list(reader, &area_map->vertbase); - BLO_read_list(reader, &area_map->edgebase); - BLO_read_list(reader, &area_map->areabase); - LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { - direct_link_area(reader, area); - } - - /* edges */ - LISTBASE_FOREACH (ScrEdge *, se, &area_map->edgebase) { - BLO_read_data_address(reader, &se->v1); - BLO_read_data_address(reader, &se->v2); - BKE_screen_sort_scrvert(&se->v1, &se->v2); - - if (se->v1 == NULL) { - BLI_remlink(&area_map->edgebase, se); - - return false; - } - } - - return true; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name XR-data * \{ */ static void direct_link_wm_xr_data(BlendDataReader *reader, wmXrData *xr_data) { - direct_link_view3dshading(reader, &xr_data->session_settings.shading); + BKE_screen_view3d_shading_blend_read_data(reader, &xr_data->session_settings.shading); } static void lib_link_wm_xr_data(BlendLibReader *reader, ID *parent_id, wmXrData *xr_data) @@ -5520,7 +4609,7 @@ static void direct_link_windowmanager(BlendDataReader *reader, wmWindowManager * win->workspace_hook->temp_layout_store = NULL; } - direct_link_area_map(reader, &win->global_areas); + BKE_screen_area_map_blend_read_data(reader, &win->global_areas); win->ghostwin = NULL; win->gpuctx = NULL; @@ -5591,7 +4680,7 @@ static void lib_link_windowmanager(BlendLibReader *reader, wmWindowManager *wm) BLO_read_id_address(reader, NULL, &win->screen); LISTBASE_FOREACH (ScrArea *, area, &win->global_areas.areabase) { - lib_link_area(reader, &wm->id, area); + BKE_screen_area_blend_read_lib(reader, &wm->id, area); } lib_link_wm_xr_data(reader, &wm->id, &wm->xr); @@ -5604,22 +4693,6 @@ static void lib_link_windowmanager(BlendLibReader *reader, wmWindowManager *wm) /** \name Read ID: Screen * \{ */ -/* note: file read without screens option G_FILE_NO_UI; - * check lib pointers in call below */ -static void lib_link_screen(BlendLibReader *reader, bScreen *screen) -{ - /* deprecated, but needed for versioning (will be NULL'ed then) */ - BLO_read_id_address(reader, screen->id.lib, &screen->scene); - - screen->animtimer = NULL; /* saved in rare cases */ - screen->tool_tip = NULL; - screen->scrubbing = false; - - LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - lib_link_area(reader, &screen->id, area); - } -} - /* how to handle user count on pointer restore */ typedef enum ePointerUserMode { USER_IGNORE = 0, /* ignore user count */ @@ -6096,29 +5169,6 @@ void blo_lib_link_restore(Main *oldmain, BKE_main_idmap_destroy(id_map); } -/* for the saved 2.50 files without regiondata */ -/* and as patch for 2.48 and older */ -void blo_do_versions_view3d_split_250(View3D *v3d, ListBase *regions) -{ - LISTBASE_FOREACH (ARegion *, region, regions) { - if (region->regiontype == RGN_TYPE_WINDOW && region->regiondata == NULL) { - RegionView3D *rv3d; - - rv3d = region->regiondata = MEM_callocN(sizeof(RegionView3D), "region v3d patch"); - rv3d->persp = (char)v3d->persp; - rv3d->view = (char)v3d->view; - rv3d->dist = v3d->dist; - copy_v3_v3(rv3d->ofs, v3d->ofs); - copy_qt_qt(rv3d->viewquat, v3d->viewquat); - } - } - - /* this was not initialized correct always */ - if (v3d->gridsubdiv == 0) { - v3d->gridsubdiv = 10; - } -} - static bool direct_link_screen(BlendDataReader *reader, bScreen *screen) { bool success = true; @@ -6130,7 +5180,7 @@ static bool direct_link_screen(BlendDataReader *reader, bScreen *screen) BLO_read_data_address(reader, &screen->preview); BKE_previewimg_blend_read(reader, screen->preview); - if (!direct_link_area_map(reader, AREAMAP_FROM_SCREEN(screen))) { + if (!BKE_screen_area_map_blend_read_data(reader, AREAMAP_FROM_SCREEN(screen))) { printf("Error reading Screen %s... removing it.\n", screen->id.name + 2); success = false; } @@ -6399,15 +5449,9 @@ static bool direct_link_id(FileData *fd, Main *main, const int tag, ID *id, ID * case ID_LI: direct_link_library(fd, (Library *)id, main); break; - case ID_GR: - direct_link_collection(&reader, (Collection *)id); - break; - case ID_PA: - direct_link_particlesettings(&reader, (ParticleSettings *)id); - break; case ID_WS: - direct_link_workspace(&reader, (WorkSpace *)id); - break; + case ID_PA: + case ID_GR: case ID_ME: case ID_LT: case ID_AC: @@ -6628,15 +5672,6 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, const short idcode = GS(id->name); - /* XXX 3DCursor (witch is UI data and as such should not be affected by undo) is stored in - * Scene... So this requires some special handling, previously done in `blo_lib_link_restore()`, - * but this cannot work anymore when we overwrite existing memory... */ - if (idcode == ID_SCE) { - Scene *scene_old = (Scene *)id_old; - Scene *scene = (Scene *)id; - SWAP(View3DCursor, scene_old->cursor, scene->cursor); - } - Main *old_bmain = fd->old_mainlist->first; ListBase *old_lb = which_libbase(old_bmain, idcode); ListBase *new_lb = which_libbase(main, idcode); @@ -6648,6 +5683,11 @@ static void read_libblock_undo_restore_at_old_address(FileData *fd, Main *main, * process). So we can pass NULL for the Main pointer parameter. */ BKE_lib_id_swap_full(NULL, id, id_old); + /* Special temporary usage of this pointer, necessary for the `undo_preserve` call after + * lib-linking to restore some data that should never be affected by undo, e.g. the 3D cursor of + * #Scene. */ + id_old->orig_id = id; + BLI_addtail(new_lb, id_old); BLI_addtail(old_lb, id); } @@ -7026,27 +6066,12 @@ static void lib_link_all(FileData *fd, Main *bmain) case ID_WM: lib_link_windowmanager(&reader, (wmWindowManager *)id); break; - case ID_WS: - /* Could we skip WS in undo case? */ - lib_link_workspaces(&reader, (WorkSpace *)id); - break; case ID_SCE: lib_link_scene(&reader, (Scene *)id); break; case ID_OB: lib_link_object(&reader, (Object *)id); break; - case ID_SCR: - /* DO NOT skip screens here, 3D viewport may contains pointers - * to other ID data (like #View3D.ob_center)! See T41411. */ - lib_link_screen(&reader, (bScreen *)id); - break; - case ID_PA: - lib_link_particlesettings(&reader, (ParticleSettings *)id); - break; - case ID_GR: - lib_link_collection(&reader, (Collection *)id); - break; case ID_IP: /* XXX deprecated... still needs to be maintained for version patches still. */ lib_link_ipo(&reader, (Ipo *)id); @@ -7054,6 +6079,10 @@ static void lib_link_all(FileData *fd, Main *bmain) case ID_LI: lib_link_library(&reader, (Library *)id); /* Only init users. */ break; + case ID_WS: + case ID_SCR: + case ID_PA: + case ID_GR: case ID_ME: case ID_LT: case ID_AC: @@ -7090,6 +6119,18 @@ static void lib_link_all(FileData *fd, Main *bmain) } id->tag &= ~LIB_TAG_NEED_LINK; + + /* Some data that should be persistent, like the 3DCursor or the tool settings, are + * stored in IDs affected by undo, like Scene. So this requires some specific handling. */ + if (id_type->blend_read_undo_preserve != NULL && id->orig_id != NULL) { + id_type->blend_read_undo_preserve(&reader, id, id->orig_id); + } + } + FOREACH_MAIN_ID_END; + + /* Cleanup `ID.orig_id`, this is now reserved for depsgraph/COW usage only. */ + FOREACH_MAIN_ID_BEGIN (bmain, id) { + id->orig_id = NULL; } FOREACH_MAIN_ID_END; @@ -7668,7 +6709,6 @@ static void expand_constraint_channels(BlendExpander *expander, ListBase *chanba } static void expand_id(BlendExpander *expander, ID *id); -static void expand_collection(BlendExpander *expander, Collection *collection); static void expand_id_embedded_id(BlendExpander *expander, ID *id) { @@ -7683,7 +6723,7 @@ static void expand_id_embedded_id(BlendExpander *expander, ID *id) Scene *scene = (Scene *)id; if (scene->master_collection != NULL) { expand_id(expander, &scene->master_collection->id); - expand_collection(expander, scene->master_collection); + BKE_collection_blend_read_expand(expander, scene->master_collection); } } } @@ -7705,71 +6745,6 @@ static void expand_id(BlendExpander *expander, ID *id) expand_id_embedded_id(expander, id); } -static void expand_particlesettings(BlendExpander *expander, ParticleSettings *part) -{ - BLO_expand(expander, part->instance_object); - BLO_expand(expander, part->instance_collection); - BLO_expand(expander, part->force_group); - BLO_expand(expander, part->bb_ob); - BLO_expand(expander, part->collision_group); - - for (int a = 0; a < MAX_MTEX; a++) { - if (part->mtex[a]) { - BLO_expand(expander, part->mtex[a]->tex); - BLO_expand(expander, part->mtex[a]->object); - } - } - - if (part->effector_weights) { - BLO_expand(expander, part->effector_weights->group); - } - - if (part->pd) { - BLO_expand(expander, part->pd->tex); - BLO_expand(expander, part->pd->f_source); - } - if (part->pd2) { - BLO_expand(expander, part->pd2->tex); - BLO_expand(expander, part->pd2->f_source); - } - - if (part->boids) { - LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { - if (rule->type == eBoidRuleType_Avoid) { - BoidRuleGoalAvoid *gabr = (BoidRuleGoalAvoid *)rule; - BLO_expand(expander, gabr->ob); - } - else if (rule->type == eBoidRuleType_FollowLeader) { - BoidRuleFollowLeader *flbr = (BoidRuleFollowLeader *)rule; - BLO_expand(expander, flbr->ob); - } - } - } - } - - LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - BLO_expand(expander, dw->ob); - } -} - -static void expand_collection(BlendExpander *expander, Collection *collection) -{ - LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { - BLO_expand(expander, cob->ob); - } - - LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - BLO_expand(expander, child->collection); - } - -#ifdef USE_COLLECTION_COMPAT_28 - if (collection->collection != NULL) { - expand_scene_collection(expander, collection->collection); - } -#endif -} - /* callback function used to expand constraint ID-links */ static void expand_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, @@ -7895,19 +6870,6 @@ static void expand_object(BlendExpander *expander, Object *ob) } } -#ifdef USE_COLLECTION_COMPAT_28 -static void expand_scene_collection(BlendExpander *expander, SceneCollection *sc) -{ - LISTBASE_FOREACH (LinkData *, link, &sc->objects) { - BLO_expand(expander, link->data); - } - - LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) { - expand_scene_collection(expander, nsc); - } -} -#endif - static void expand_scene(BlendExpander *expander, Scene *sce) { LISTBASE_FOREACH (Base *, base_legacy, &sce->base) { @@ -8005,7 +6967,7 @@ static void expand_scene(BlendExpander *expander, Scene *sce) #ifdef USE_COLLECTION_COMPAT_28 if (sce->collection) { - expand_scene_collection(expander, sce->collection); + BKE_collection_compat_blend_read_expand(expander, sce->collection); } #endif @@ -8014,13 +6976,6 @@ static void expand_scene(BlendExpander *expander, Scene *sce) } } -static void expand_workspace(BlendExpander *expander, WorkSpace *workspace) -{ - LISTBASE_FOREACH (WorkSpaceLayout *, layout, &workspace->layouts) { - BLO_expand(expander, BKE_workspace_layout_screen_get(layout)); - } -} - /** * Set the callback func used over all ID data found by \a BLO_expand_main func. * @@ -8070,18 +7025,9 @@ void BLO_expand_main(void *fdhandle, Main *mainvar) case ID_SCE: expand_scene(&expander, (Scene *)id); break; - case ID_GR: - expand_collection(&expander, (Collection *)id); - break; case ID_IP: expand_ipo(&expander, (Ipo *)id); /* XXX deprecated - old animation system */ break; - case ID_PA: - expand_particlesettings(&expander, (ParticleSettings *)id); - break; - case ID_WS: - expand_workspace(&expander, (WorkSpace *)id); - break; default: break; } @@ -8123,6 +7069,31 @@ static bool object_in_any_collection(Main *bmain, Object *ob) return false; } +/** + * Shared operations to perform on the object's base after adding it to the scene. + */ +static void object_base_instance_init( + Object *ob, bool set_selected, bool set_active, ViewLayer *view_layer, const View3D *v3d) +{ + Base *base = BKE_view_layer_base_find(view_layer, ob); + + if (v3d != NULL) { + base->local_view_bits |= v3d->local_view_uuid; + } + + if (set_selected) { + if (base->flag & BASE_SELECTABLE) { + base->flag |= BASE_SELECTED; + } + } + + if (set_active) { + view_layer->basact = base; + } + + BKE_scene_object_base_flag_sync_from_base(base); +} + static void add_loose_objects_to_scene(Main *mainvar, Main *bmain, Scene *scene, @@ -8168,19 +7139,12 @@ static void add_loose_objects_to_scene(Main *mainvar, ob->mode = OB_MODE_OBJECT; BKE_collection_object_add(bmain, active_collection, ob); - Base *base = BKE_view_layer_base_find(view_layer, ob); - - if (v3d != NULL) { - base->local_view_bits |= v3d->local_view_uuid; - } - - if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { - /* Do NOT make base active here! screws up GUI stuff, - * if you want it do it at the editor level. */ - base->flag |= BASE_SELECTED; - } - BKE_scene_object_base_flag_sync_from_base(base); + const bool set_selected = (flag & FILE_AUTOSELECT) != 0; + /* Do NOT make base active here! screws up GUI stuff, + * if you want it do it at the editor level. */ + const bool set_active = false; + object_base_instance_init(ob, set_selected, set_active, view_layer, v3d); ob->id.tag &= ~LIB_TAG_INDIRECT; ob->id.flag &= ~LIB_INDIRECT_WEAK_LINK; @@ -8226,19 +7190,12 @@ static void add_loose_object_data_to_scene(Main *mainvar, BKE_object_materials_test(bmain, ob, ob->data); BKE_collection_object_add(bmain, active_collection, ob); - Base *base = BKE_view_layer_base_find(view_layer, ob); - if (v3d != NULL) { - base->local_view_bits |= v3d->local_view_uuid; - } - - if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { - /* Do NOT make base active here! screws up GUI stuff, - * if you want it do it at the editor level. */ - base->flag |= BASE_SELECTED; - } - - BKE_scene_object_base_flag_sync_from_base(base); + const bool set_selected = (flag & FILE_AUTOSELECT) != 0; + /* Do NOT make base active here! screws up GUI stuff, + * if you want it do it at the editor level. */ + bool set_active = false; + object_base_instance_init(ob, set_selected, set_active, view_layer, v3d); copy_v3_v3(ob->loc, scene->cursor.location); } @@ -8272,23 +7229,15 @@ static void add_collections_to_scene(Main *mainvar, ob->empty_drawsize = U.collection_instance_empty_size; BKE_collection_object_add(bmain, active_collection, ob); - Base *base = BKE_view_layer_base_find(view_layer, ob); - if (v3d != NULL) { - base->local_view_bits |= v3d->local_view_uuid; - } - - if ((flag & FILE_AUTOSELECT) && (base->flag & BASE_SELECTABLE)) { - base->flag |= BASE_SELECTED; - } + const bool set_selected = (flag & FILE_AUTOSELECT) != 0; + /* TODO: why is it OK to make this active here but not in other situations? + * See other callers of #object_base_instance_init */ + const bool set_active = set_selected; + object_base_instance_init(ob, set_selected, set_active, view_layer, v3d); - BKE_scene_object_base_flag_sync_from_base(base); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); - if (flag & FILE_AUTOSELECT) { - view_layer->basact = base; - } - /* Assign the collection. */ ob->instance_collection = collection; id_us_plus(&collection->id); @@ -9042,6 +7991,11 @@ void *BLO_read_get_new_data_address(BlendDataReader *reader, const void *old_add return newdataadr(reader->fd, old_address); } +void *BLO_read_get_new_data_address_no_us(BlendDataReader *reader, const void *old_address) +{ + return newdataadr_no_us(reader->fd, old_address); +} + void *BLO_read_get_new_packed_address(BlendDataReader *reader, const void *old_address) { return newpackedadr(reader->fd, old_address); @@ -9212,6 +8166,11 @@ bool BLO_read_lib_is_undo(BlendLibReader *reader) return reader->fd->memfile != NULL; } +Main *BLO_read_lib_get_main(BlendLibReader *reader) +{ + return reader->main; +} + void BLO_expand_id(BlendExpander *expander, ID *id) { expand_doit(expander->fd, expander->main, id); diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index 4fa41731454..57d6779d1cb 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -187,7 +187,6 @@ void *blo_do_versions_newlibadr_us(struct FileData *fd, const void *lib, const v struct PartEff *blo_do_version_give_parteff_245(struct Object *ob); void blo_do_version_old_trackto_to_constraints(struct Object *ob); -void blo_do_versions_view3d_split_250(struct View3D *v3d, struct ListBase *regions); void blo_do_versions_key_uidgen(struct Key *key); void blo_do_versions_userdef(struct UserDef *userdef); diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 5046ee6aab1..c86ad639216 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -73,10 +73,11 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_texture.h" +#include "SEQ_sequencer.h" + #include "NOD_socket.h" #include "BLO_readfile.h" @@ -266,7 +267,7 @@ static void area_add_window_regions(ScrArea *area, SpaceLink *sl, ListBase *lb) /* and we split view3d */ switch (sl->spacetype) { case SPACE_VIEW3D: - blo_do_versions_view3d_split_250((View3D *)sl, lb); + BKE_screen_view3d_do_versions_250((View3D *)sl, lb); break; case SPACE_OUTLINER: { @@ -799,20 +800,6 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) // BLI_freelistN(&pidlist); - if (ob->type == OB_MESH) { - Mesh *me = blo_do_versions_newlibadr(fd, lib, ob->data); - void *olddata = ob->data; - ob->data = me; - - /* XXX - library meshes crash on loading most yoFrankie levels, - * the multires pointer gets invalid - Campbell */ - if (me && me->id.lib == NULL && me->mr && me->mr->level_count > 1) { - multires_load_old(ob, me); - } - - ob->data = olddata; - } - if (ob->totcol && ob->matbits == NULL) { int a; @@ -1152,7 +1139,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (bmain->versionfile == 250 && bmain->subversionfile > 1) { for (me = bmain->meshes.first; me; me = me->id.next) { - multires_load_old_250(me); + CustomData_free_layer_active(&me->fdata, CD_MDISPS, me->totface); } for (ob = bmain->objects.first; ob; ob = ob->id.next) { @@ -1179,7 +1166,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if (md->type == eModifierType_Cloth) { ClothModifierData *clmd = (ClothModifierData *)md; if (clmd->sim_parms->velocity_smooth < 0.01f) { - clmd->sim_parms->velocity_smooth = 0.f; + clmd->sim_parms->velocity_smooth = 0.0f; } } } @@ -1514,9 +1501,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) while (node) { if (node->type == CMP_NODE_COLORBALANCE) { NodeColorBalance *n = (NodeColorBalance *)node->storage; - n->lift[0] += 1.f; - n->lift[1] += 1.f; - n->lift[2] += 1.f; + n->lift[0] += 1.0f; + n->lift[1] += 1.0f; + n->lift[2] += 1.0f; } node = node->next; } @@ -1529,9 +1516,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) while (node) { if (node->type == CMP_NODE_COLORBALANCE) { NodeColorBalance *n = (NodeColorBalance *)node->storage; - n->lift[0] += 1.f; - n->lift[1] += 1.f; - n->lift[2] += 1.f; + n->lift[0] += 1.0f; + n->lift[1] += 1.0f; + n->lift[2] += 1.0f; } node = node->next; @@ -1849,7 +1836,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } part->flag &= ~PART_HAIR_REGROW; /* this was a deprecated flag before */ - part->kink_amp_clump = 1.f; /* keep old files looking similar */ + part->kink_amp_clump = 1.0f; /* keep old files looking similar */ } for (screen = bmain->screens.first; screen; screen = screen->id.next) { diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index a7c5d7b933c..c33f2a8cad5 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -61,11 +61,12 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_text.h" /* for txt_extended_ascii_as_utf8 */ #include "BKE_texture.h" #include "BKE_tracking.h" +#include "SEQ_sequencer.h" + #ifdef WITH_FFMPEG # include "BKE_writeffmpeg.h" #endif @@ -2065,10 +2066,9 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *bmain) if (srl->freestyleConfig.mode == 0) { srl->freestyleConfig.mode = FREESTYLE_CONTROL_EDITOR_MODE; } - if (srl->freestyleConfig.raycasting_algorithm == - FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE || - srl->freestyleConfig.raycasting_algorithm == - FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL) { + if (ELEM(srl->freestyleConfig.raycasting_algorithm, + FREESTYLE_ALGO_CULLED_ADAPTIVE_CUMULATIVE, + FREESTYLE_ALGO_CULLED_ADAPTIVE_TRADITIONAL)) { srl->freestyleConfig.raycasting_algorithm = 0; /* deprecated */ srl->freestyleConfig.flags |= FREESTYLE_CULLING; } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 2452ac43bd4..41e46f8f0a0 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -63,9 +63,10 @@ #include "BKE_node.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_tracking.h" +#include "SEQ_sequencer.h" + #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 8e082f1c0f9..0b7830c922a 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -93,11 +93,12 @@ #include "BKE_report.h" #include "BKE_rigidbody.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_studiolight.h" #include "BKE_unit.h" #include "BKE_workspace.h" +#include "SEQ_sequencer.h" + /* Only for IMB_BlendMode */ #include "IMB_imbuf.h" @@ -2099,7 +2100,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 280, 8)) { /* Blender Internal removal */ for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { - if (STREQ(scene->r.engine, "BLENDER_RENDER") || STREQ(scene->r.engine, "BLENDER_GAME")) { + if (STR_ELEM(scene->r.engine, "BLENDER_RENDER", "BLENDER_GAME")) { BLI_strncpy(scene->r.engine, RE_engine_id_BLENDER_EEVEE, sizeof(scene->r.engine)); } @@ -3419,7 +3420,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) case SPACE_OUTLINER: { SpaceOutliner *space_outliner = (SpaceOutliner *)sl; space_outliner->filter &= ~(SO_FILTER_UNUSED_1 | SO_FILTER_UNUSED_5 | - SO_FILTER_UNUSED_12); + SO_FILTER_OB_STATE_SELECTABLE); space_outliner->storeflag &= ~(SO_TREESTORE_UNUSED_1); break; } @@ -3493,7 +3494,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { ob->flag &= ~(OB_FLAG_UNUSED_11 | OB_FLAG_UNUSED_12); - ob->transflag &= ~(OB_TRANSFLAG_UNUSED_0 | OB_TRANSFLAG_UNUSED_1); + ob->transflag &= ~(OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK | OB_TRANSFLAG_UNUSED_1); ob->shapeflag &= ~OB_SHAPE_FLAG_UNUSED_1; } @@ -3662,8 +3663,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } - ob->transflag &= ~(OB_TRANSFLAG_UNUSED_0 | OB_TRANSFLAG_UNUSED_1 | OB_TRANSFLAG_UNUSED_3 | - OB_TRANSFLAG_UNUSED_6 | OB_TRANSFLAG_UNUSED_12); + ob->transflag &= ~(OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK | OB_TRANSFLAG_UNUSED_1 | + OB_TRANSFLAG_UNUSED_3 | OB_TRANSFLAG_UNUSED_6 | OB_TRANSFLAG_UNUSED_12); ob->nlaflag &= ~(OB_ADS_UNUSED_1 | OB_ADS_UNUSED_2); } @@ -4078,8 +4079,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (STREQ(view_settings->view_transform, "Default")) { STRNCPY(view_settings->view_transform, "Standard"); } - else if (STREQ(view_settings->view_transform, "RRT") || - STREQ(view_settings->view_transform, "Film")) { + else if (STR_ELEM(view_settings->view_transform, "RRT", "Film")) { STRNCPY(view_settings->view_transform, "Filmic"); } else if (STREQ(view_settings->view_transform, "Log")) { diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index eeb0dd336a3..fab4ce6727f 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -44,25 +44,171 @@ #include "DNA_rigidbody_types.h" #include "DNA_screen_types.h" #include "DNA_shader_fx_types.h" +#include "DNA_space_types.h" +#include "DNA_tracking_types.h" #include "DNA_workspace_types.h" #include "BKE_animsys.h" #include "BKE_collection.h" #include "BKE_colortools.h" +#include "BKE_fcurve.h" #include "BKE_gpencil.h" #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_multires.h" #include "BKE_node.h" #include "MEM_guardedalloc.h" +#include "RNA_access.h" + +#include "SEQ_sequencer.h" + #include "BLO_readfile.h" #include "readfile.h" /* Make preferences read-only, use versioning_userdef.c. */ #define U (*((const UserDef *)&U)) +/* image_size is width or height depending what RNA property is converted - X or Y. */ +static void seq_convert_transform_animation(const Scene *scene, + const char *path, + const int image_size) +{ + if (scene->adt == NULL || scene->adt->action == NULL) { + return; + } + + FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0); + if (fcu != NULL && !BKE_fcurve_is_empty(fcu)) { + BezTriple *bezt = fcu->bezt; + for (int i = 0; i < fcu->totvert; i++, bezt++) { + /* Same math as with old_image_center_*, but simplified. */ + bezt->vec[1][1] = image_size / 2 + bezt->vec[1][1] - scene->r.xsch / 2; + } + } +} + +static void seq_convert_transform_crop(const Scene *scene, + Sequence *seq, + const eSpaceSeq_Proxy_RenderSize render_size) +{ + StripCrop *c = seq->strip->crop; + StripTransform *t = seq->strip->transform; + int old_image_center_x = scene->r.xsch / 2; + int old_image_center_y = scene->r.ysch / 2; + int image_size_x = scene->r.xsch; + int image_size_y = scene->r.ysch; + + /* Hardcoded legacy bit-flags which has been removed. */ + const uint32_t use_transform_flag = (1 << 16); + const uint32_t use_crop_flag = (1 << 17); + + const StripElem *s_elem = SEQ_render_give_stripelem(seq, seq->start); + if (s_elem != NULL) { + image_size_x = s_elem->orig_width; + image_size_y = s_elem->orig_height; + + if (SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(render_size))) { + image_size_x /= SEQ_rendersize_to_scale_factor(render_size); + image_size_y /= SEQ_rendersize_to_scale_factor(render_size); + } + } + + /* Default scale. */ + if (t->scale_x == 0.0f && t->scale_y == 0.0f) { + t->scale_x = 1.0f; + t->scale_y = 1.0f; + } + + /* Clear crop if it was unused. This must happen before converting values. */ + if ((seq->flag & use_crop_flag) == 0) { + c->bottom = c->top = c->left = c->right = 0; + } + + if ((seq->flag & use_transform_flag) == 0) { + t->xofs = t->yofs = 0; + + /* Reverse scale to fit for strips not using offset. */ + float project_aspect = (float)scene->r.xsch / (float)scene->r.ysch; + float image_aspect = (float)image_size_x / (float)image_size_y; + if (project_aspect > image_aspect) { + t->scale_x = project_aspect / image_aspect; + } + else { + t->scale_y = image_aspect / project_aspect; + } + } + + if ((seq->flag & use_crop_flag) != 0 && (seq->flag & use_transform_flag) == 0) { + /* Calculate image offset. */ + float s_x = scene->r.xsch / image_size_x; + float s_y = scene->r.ysch / image_size_y; + old_image_center_x += c->right * s_x - c->left * s_x; + old_image_center_y += c->top * s_y - c->bottom * s_y; + + /* Convert crop to scale. */ + int cropped_image_size_x = image_size_x - c->right - c->left; + int cropped_image_size_y = image_size_y - c->top - c->bottom; + c->bottom = c->top = c->left = c->right = 0; + t->scale_x *= (float)image_size_x / (float)cropped_image_size_x; + t->scale_y *= (float)image_size_y / (float)cropped_image_size_y; + } + + if ((seq->flag & use_transform_flag) != 0) { + /* Convert image offset. */ + old_image_center_x = image_size_x / 2 - c->left + t->xofs; + old_image_center_y = image_size_y / 2 - c->bottom + t->yofs; + + /* Preserve original image size. */ + t->scale_x = t->scale_y = MAX2((float)image_size_x / (float)scene->r.xsch, + (float)image_size_y / (float)scene->r.ysch); + + /* Convert crop. */ + if ((seq->flag & use_crop_flag) != 0) { + c->top /= t->scale_x; + c->bottom /= t->scale_x; + c->left /= t->scale_x; + c->right /= t->scale_x; + } + } + + t->xofs = old_image_center_x - scene->r.xsch / 2; + t->yofs = old_image_center_y - scene->r.ysch / 2; + + /* Convert offset animation, but only if crop is not used. */ + if ((seq->flag & use_transform_flag) != 0 && (seq->flag & use_crop_flag) == 0) { + char name_esc[(sizeof(seq->name) - 2) * 2], *path; + BLI_strescape(name_esc, seq->name + 2, sizeof(name_esc)); + + path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_x", name_esc); + seq_convert_transform_animation(scene, path, image_size_x); + MEM_freeN(path); + path = BLI_sprintfN("sequence_editor.sequences_all[\"%s\"].transform.offset_y", name_esc); + seq_convert_transform_animation(scene, path, image_size_y); + MEM_freeN(path); + } + + seq->flag &= ~use_transform_flag; + seq->flag &= ~use_crop_flag; +} + +static void seq_convert_transform_crop_lb(const Scene *scene, + const ListBase *lb, + const eSpaceSeq_Proxy_RenderSize render_size) +{ + + LISTBASE_FOREACH (Sequence *, seq, lb) { + if (seq->type != SEQ_TYPE_SOUND_RAM) { + seq_convert_transform_crop(scene, seq, render_size); + } + if (seq->type == SEQ_TYPE_META) { + seq_convert_transform_crop_lb(scene, &seq->seqbase, render_size); + } + } +} + void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) { if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) { @@ -275,6 +421,46 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) } } + /* Convert all Multires displacement to Catmull-Clark subdivision limit surface. */ + if (!MAIN_VERSION_ATLEAST(bmain, 292, 1)) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Multires) { + MultiresModifierData *mmd = (MultiresModifierData *)md; + if (mmd->simple) { + multires_do_versions_simple_to_catmull_clark(ob, mmd); + } + } + } + } + } + + if (!MAIN_VERSION_ATLEAST(bmain, 292, 2)) { + + eSpaceSeq_Proxy_RenderSize render_size = 100; + + for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + switch (sl->spacetype) { + case SPACE_SEQ: { + SpaceSeq *sseq = (SpaceSeq *)sl; + render_size = sseq->render_size; + break; + } + } + } + } + } + + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { + if (scene->ed != NULL) { + seq_convert_transform_crop_lb(scene, &scene->ed->seqbase, render_size); + } + } + } + /** * Versioning code until next subversion bump goes here. * @@ -913,6 +1099,35 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 292, 1)) { + { + const int LEGACY_REFINE_RADIAL_DISTORTION_K1 = (1 << 2); + + LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingSettings *settings = &tracking->settings; + int new_refine_camera_intrinsics = 0; + + if (settings->refine_camera_intrinsics & REFINE_FOCAL_LENGTH) { + new_refine_camera_intrinsics |= REFINE_FOCAL_LENGTH; + } + + if (settings->refine_camera_intrinsics & REFINE_PRINCIPAL_POINT) { + new_refine_camera_intrinsics |= REFINE_PRINCIPAL_POINT; + } + + /* The end goal is to enable radial distortion refinement if either K1 or K2 were set for + * refinement. It is enough to only check for L1 it was not possible to refine K2 without + * K1. */ + if (settings->refine_camera_intrinsics & LEGACY_REFINE_RADIAL_DISTORTION_K1) { + new_refine_camera_intrinsics |= REFINE_RADIAL_DISTORTION; + } + + settings->refine_camera_intrinsics = new_refine_camera_intrinsics; + } + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 26329fca6fa..19e392734f0 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -1197,8 +1197,7 @@ static void update_voronoi_node_square_distance(bNodeTree *ntree) NodeTexVoronoi *tex = (NodeTexVoronoi *)node->storage; bNodeSocket *sockDistance = nodeFindSocket(node, SOCK_OUT, "Distance"); if (tex->distance == SHD_VORONOI_EUCLIDEAN && - (tex->feature == SHD_VORONOI_F1 || tex->feature == SHD_VORONOI_F2) && - socket_is_used(sockDistance)) { + (ELEM(tex->feature, SHD_VORONOI_F1, SHD_VORONOI_F2)) && socket_is_used(sockDistance)) { bNode *multiplyNode = nodeAddStaticNode(NULL, ntree, SH_NODE_MATH); multiplyNode->custom1 = NODE_MATH_MULTIPLY; multiplyNode->locx = node->locx + node->width + 20.0f; @@ -1237,7 +1236,7 @@ static void update_noise_and_wave_distortion(bNodeTree *ntree) bool need_update = false; LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - if (node->type == SH_NODE_TEX_NOISE || node->type == SH_NODE_TEX_WAVE) { + if (ELEM(node->type, SH_NODE_TEX_NOISE, SH_NODE_TEX_WAVE)) { bNodeSocket *sockDistortion = nodeFindSocket(node, SOCK_IN, "Distortion"); float *distortion = cycles_node_socket_float_value(sockDistortion); diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c index 4acf98cc58b..9178ec97d3d 100644 --- a/source/blender/blenloader/intern/versioning_legacy.c +++ b/source/blender/blenloader/intern/versioning_legacy.c @@ -77,7 +77,8 @@ #include "BKE_modifier.h" #include "BKE_particle.h" #include "BKE_pointcache.h" -#include "BKE_sequencer.h" + +#include "SEQ_sequencer.h" #include "NOD_socket.h" @@ -1252,7 +1253,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) ed = sce->ed; if (ed) { SEQ_ALL_BEGIN (sce->ed, seq) { - if (seq->type == SEQ_TYPE_IMAGE || seq->type == SEQ_TYPE_MOVIE) { + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { seq->alpha_mode = SEQ_ALPHA_STRAIGHT; } } @@ -1959,7 +1960,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) Light *la; Material *ma; ParticleSettings *part; - Mesh *me; bNodeTree *ntree; Tex *tex; ModifierData *md; @@ -2074,23 +2074,6 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain) } } - /* Copy over old per-level multires vertex data - * into a single vertex array in struct Multires */ - for (me = bmain->meshes.first; me; me = me->id.next) { - if (me->mr && !me->mr->verts) { - MultiresLevel *lvl = me->mr->levels.last; - if (lvl) { - me->mr->verts = lvl->verts; - lvl->verts = NULL; - /* Don't need the other vert arrays */ - for (lvl = lvl->prev; lvl; lvl = lvl->prev) { - MEM_freeN(lvl->verts); - lvl->verts = NULL; - } - } - } - } - if (bmain->versionfile != 245 || bmain->subversionfile < 1) { for (la = bmain->lights.first; la; la = la->id.next) { la->falloff_type = LA_FALLOFF_INVLINEAR; diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 6b6d226bd90..d152230e4bf 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -800,6 +800,14 @@ void blo_do_versions_userdef(UserDef *userdef) } } + if (!USER_VERSION_ATLEAST(292, 3)) { + if (userdef->pixelsize == 0.0f) { + userdef->pixelsize = 1.0f; + } + /* Clear old userdef flag for "Camera Parent Lock". */ + userdef->uiflag &= ~USER_UIFLAG_UNUSED_3; + } + /** * Versioning code until next subversion bump goes here. * @@ -813,10 +821,6 @@ void blo_do_versions_userdef(UserDef *userdef) /* Keep this block, even when empty. */ } - if (userdef->pixelsize == 0.0f) { - userdef->pixelsize = 1.0f; - } - LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) { do_versions_theme(userdef, btheme); } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index a37ec2d9f0a..e4995c991e1 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -155,7 +155,7 @@ #include "BKE_packedFile.h" #include "BKE_pointcache.h" #include "BKE_report.h" -#include "BKE_sequencer.h" +#include "BKE_screen.h" #include "BKE_shader_fx.h" #include "BKE_subsurf.h" #include "BKE_workspace.h" @@ -167,6 +167,8 @@ #include "BLO_undofile.h" #include "BLO_writefile.h" +#include "SEQ_sequencer.h" + #include "readfile.h" #include <errno.h> @@ -804,41 +806,6 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef) } } -static void write_boid_state(BlendWriter *writer, BoidState *state) -{ - BLO_write_struct(writer, BoidState, state); - - LISTBASE_FOREACH (BoidRule *, rule, &state->rules) { - switch (rule->type) { - case eBoidRuleType_Goal: - case eBoidRuleType_Avoid: - BLO_write_struct(writer, BoidRuleGoalAvoid, rule); - break; - case eBoidRuleType_AvoidCollision: - BLO_write_struct(writer, BoidRuleAvoidCollision, rule); - break; - case eBoidRuleType_FollowLeader: - BLO_write_struct(writer, BoidRuleFollowLeader, rule); - break; - case eBoidRuleType_AverageSpeed: - BLO_write_struct(writer, BoidRuleAverageSpeed, rule); - break; - case eBoidRuleType_Fight: - BLO_write_struct(writer, BoidRuleFight, rule); - break; - default: - BLO_write_struct(writer, BoidRule, rule); - break; - } - } -#if 0 - BoidCondition *cond = state->conditions.first; - for (; cond; cond = cond->next) { - BLO_write_struct(writer, BoidCondition, cond); - } -#endif -} - /* update this also to readfile.c */ static const char *ptcache_data_struct[] = { "", // BPHYS_DATA_INDEX @@ -889,68 +856,6 @@ static void write_pointcaches(BlendWriter *writer, ListBase *ptcaches) } } -static void write_particlesettings(BlendWriter *writer, - ParticleSettings *part, - const void *id_address) -{ - if (part->id.us > 0 || BLO_write_is_undo(writer)) { - /* write LibData */ - BLO_write_id_struct(writer, ParticleSettings, id_address, &part->id); - BKE_id_blend_write(writer, &part->id); - - if (part->adt) { - BKE_animdata_blend_write(writer, part->adt); - } - BLO_write_struct(writer, PartDeflect, part->pd); - BLO_write_struct(writer, PartDeflect, part->pd2); - BLO_write_struct(writer, EffectorWeights, part->effector_weights); - - if (part->clumpcurve) { - BKE_curvemapping_blend_write(writer, part->clumpcurve); - } - if (part->roughcurve) { - BKE_curvemapping_blend_write(writer, part->roughcurve); - } - if (part->twistcurve) { - BKE_curvemapping_blend_write(writer, part->twistcurve); - } - - LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ - if (dw->ob != NULL) { - dw->index = 0; - if (part->instance_collection) { /* can be NULL if lining fails or set to None */ - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) { - if (object == dw->ob) { - break; - } - dw->index++; - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - } - } - BLO_write_struct(writer, ParticleDupliWeight, dw); - } - - if (part->boids && part->phystype == PART_PHYS_BOIDS) { - BLO_write_struct(writer, BoidSettings, part->boids); - - LISTBASE_FOREACH (BoidState *, state, &part->boids->states) { - write_boid_state(writer, state); - } - } - if (part->fluid && part->phystype == PART_PHYS_FLUID) { - BLO_write_struct(writer, SPHFluidSettings, part->fluid); - } - - for (int a = 0; a < MAX_MTEX; a++) { - if (part->mtex[a]) { - BLO_write_struct(writer, MTex, part->mtex[a]); - } - } - } -} - static void write_particlesystems(BlendWriter *writer, ListBase *particles) { LISTBASE_FOREACH (ParticleSystem *, psys, particles) { @@ -1384,37 +1289,6 @@ static void write_object(BlendWriter *writer, Object *ob, const void *id_address } } -static void write_collection_nolib(BlendWriter *writer, Collection *collection) -{ - /* Shared function for collection data-blocks and scene master collection. */ - BKE_previewimg_blend_write(writer, collection->preview); - - LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { - BLO_write_struct(writer, CollectionObject, cob); - } - - LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - BLO_write_struct(writer, CollectionChild, child); - } -} - -static void write_collection(BlendWriter *writer, Collection *collection, const void *id_address) -{ - if (collection->id.us > 0 || BLO_write_is_undo(writer)) { - /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->tag = 0; - BLI_listbase_clear(&collection->object_cache); - BLI_listbase_clear(&collection->parents); - - /* write LibData */ - BLO_write_id_struct(writer, Collection, id_address, &collection->id); - BKE_id_blend_write(writer, &collection->id); - - write_collection_nolib(writer, collection); - } -} - static void write_sequence_modifiers(BlendWriter *writer, ListBase *modbase) { LISTBASE_FOREACH (SequenceModifierData *, smd, modbase) { @@ -1447,13 +1321,6 @@ static void write_view_settings(BlendWriter *writer, ColorManagedViewSettings *v } } -static void write_view3dshading(BlendWriter *writer, View3DShading *shading) -{ - if (shading->prop) { - IDP_BlendWrite(writer, shading->prop); - } -} - static void write_paint(BlendWriter *writer, Paint *p) { if (p->cavity_curve) { @@ -1745,7 +1612,7 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address) if (sce->master_collection) { BLO_write_struct(writer, Collection, sce->master_collection); - write_collection_nolib(writer, sce->master_collection); + BKE_collection_blend_write_nolib(writer, sce->master_collection); } /* Eevee Lightcache */ @@ -1754,7 +1621,7 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address) write_lightcache(writer, sce->eevee.light_cache_data); } - write_view3dshading(writer, &sce->display.shading); + BKE_screen_view3d_shading_blend_write(writer, &sce->display.shading); /* Freed on doversion. */ BLI_assert(sce->layer_properties == NULL); @@ -1762,245 +1629,7 @@ static void write_scene(BlendWriter *writer, Scene *sce, const void *id_address) static void write_wm_xr_data(BlendWriter *writer, wmXrData *xr_data) { - write_view3dshading(writer, &xr_data->session_settings.shading); -} - -static void write_region(BlendWriter *writer, ARegion *region, int spacetype) -{ - BLO_write_struct(writer, ARegion, region); - - if (region->regiondata) { - if (region->flag & RGN_FLAG_TEMP_REGIONDATA) { - return; - } - - switch (spacetype) { - case SPACE_VIEW3D: - if (region->regiontype == RGN_TYPE_WINDOW) { - RegionView3D *rv3d = region->regiondata; - BLO_write_struct(writer, RegionView3D, rv3d); - - if (rv3d->localvd) { - BLO_write_struct(writer, RegionView3D, rv3d->localvd); - } - if (rv3d->clipbb) { - BLO_write_struct(writer, BoundBox, rv3d->clipbb); - } - } - else { - printf("regiondata write missing!\n"); - } - break; - default: - printf("regiondata write missing!\n"); - } - } -} - -static void write_uilist(BlendWriter *writer, uiList *ui_list) -{ - BLO_write_struct(writer, uiList, ui_list); - - if (ui_list->properties) { - IDP_BlendWrite(writer, ui_list->properties); - } -} - -static void write_space_outliner(BlendWriter *writer, SpaceOutliner *space_outliner) -{ - BLI_mempool *ts = space_outliner->treestore; - - if (ts) { - SpaceOutliner space_outliner_flat = *space_outliner; - - int elems = BLI_mempool_len(ts); - /* linearize mempool to array */ - TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL; - - if (data) { - /* In this block we use the memory location of the treestore - * but _not_ its data, the addresses in this case are UUID's, - * since we can't rely on malloc giving us different values each time. - */ - TreeStore ts_flat = {0}; - - /* we know the treestore is at least as big as a pointer, - * so offsetting works to give us a UUID. */ - void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *)); - - ts_flat.usedelem = elems; - ts_flat.totelem = elems; - ts_flat.data = data_addr; - - BLO_write_struct(writer, SpaceOutliner, space_outliner); - - BLO_write_struct_at_address(writer, TreeStore, ts, &ts_flat); - BLO_write_struct_array_at_address(writer, TreeStoreElem, elems, data_addr, data); - - MEM_freeN(data); - } - else { - space_outliner_flat.treestore = NULL; - BLO_write_struct_at_address(writer, SpaceOutliner, space_outliner, &space_outliner_flat); - } - } - else { - BLO_write_struct(writer, SpaceOutliner, space_outliner); - } -} - -static void write_panel_list(BlendWriter *writer, ListBase *lb) -{ - LISTBASE_FOREACH (Panel *, panel, lb) { - BLO_write_struct(writer, Panel, panel); - write_panel_list(writer, &panel->children); - } -} - -static void write_area_regions(BlendWriter *writer, ScrArea *area) -{ - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - write_region(writer, region, area->spacetype); - write_panel_list(writer, ®ion->panels); - - LISTBASE_FOREACH (PanelCategoryStack *, pc_act, ®ion->panels_category_active) { - BLO_write_struct(writer, PanelCategoryStack, pc_act); - } - - LISTBASE_FOREACH (uiList *, ui_list, ®ion->ui_lists) { - write_uilist(writer, ui_list); - } - - LISTBASE_FOREACH (uiPreview *, ui_preview, ®ion->ui_previews) { - BLO_write_struct(writer, uiPreview, ui_preview); - } - } - - LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - LISTBASE_FOREACH (ARegion *, region, &sl->regionbase) { - write_region(writer, region, sl->spacetype); - } - - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; - BLO_write_struct(writer, View3D, v3d); - - if (v3d->localvd) { - BLO_write_struct(writer, View3D, v3d->localvd); - } - - write_view3dshading(writer, &v3d->shading); - } - else if (sl->spacetype == SPACE_GRAPH) { - SpaceGraph *sipo = (SpaceGraph *)sl; - ListBase tmpGhosts = sipo->runtime.ghost_curves; - - /* temporarily disable ghost curves when saving */ - BLI_listbase_clear(&sipo->runtime.ghost_curves); - - BLO_write_struct(writer, SpaceGraph, sl); - if (sipo->ads) { - BLO_write_struct(writer, bDopeSheet, sipo->ads); - } - - /* reenable ghost curves */ - sipo->runtime.ghost_curves = tmpGhosts; - } - else if (sl->spacetype == SPACE_PROPERTIES) { - BLO_write_struct(writer, SpaceProperties, sl); - } - else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - - BLO_write_struct(writer, SpaceFile, sl); - if (sfile->params) { - BLO_write_struct(writer, FileSelectParams, sfile->params); - } - } - else if (sl->spacetype == SPACE_SEQ) { - BLO_write_struct(writer, SpaceSeq, sl); - } - else if (sl->spacetype == SPACE_OUTLINER) { - SpaceOutliner *space_outliner = (SpaceOutliner *)sl; - write_space_outliner(writer, space_outliner); - } - else if (sl->spacetype == SPACE_IMAGE) { - BLO_write_struct(writer, SpaceImage, sl); - } - else if (sl->spacetype == SPACE_TEXT) { - BLO_write_struct(writer, SpaceText, sl); - } - else if (sl->spacetype == SPACE_SCRIPT) { - SpaceScript *scr = (SpaceScript *)sl; - scr->but_refs = NULL; - BLO_write_struct(writer, SpaceScript, sl); - } - else if (sl->spacetype == SPACE_ACTION) { - BLO_write_struct(writer, SpaceAction, sl); - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla = (SpaceNla *)sl; - - BLO_write_struct(writer, SpaceNla, snla); - if (snla->ads) { - BLO_write_struct(writer, bDopeSheet, snla->ads); - } - } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - BLO_write_struct(writer, SpaceNode, snode); - - LISTBASE_FOREACH (bNodeTreePath *, path, &snode->treepath) { - BLO_write_struct(writer, bNodeTreePath, path); - } - } - else if (sl->spacetype == SPACE_CONSOLE) { - SpaceConsole *con = (SpaceConsole *)sl; - - LISTBASE_FOREACH (ConsoleLine *, cl, &con->history) { - /* 'len_alloc' is invalid on write, set from 'len' on read */ - BLO_write_struct(writer, ConsoleLine, cl); - BLO_write_raw(writer, (size_t)cl->len + 1, cl->line); - } - BLO_write_struct(writer, SpaceConsole, sl); - } -#ifdef WITH_GLOBAL_AREA_WRITING - else if (sl->spacetype == SPACE_TOPBAR) { - BLO_write_struct(writer, SpaceTopBar, sl); - } - else if (sl->spacetype == SPACE_STATUSBAR) { - BLO_write_struct(writer, SpaceStatusBar, sl); - } -#endif - else if (sl->spacetype == SPACE_USERPREF) { - BLO_write_struct(writer, SpaceUserPref, sl); - } - else if (sl->spacetype == SPACE_CLIP) { - BLO_write_struct(writer, SpaceClip, sl); - } - else if (sl->spacetype == SPACE_INFO) { - BLO_write_struct(writer, SpaceInfo, sl); - } - } -} - -static void write_area_map(BlendWriter *writer, ScrAreaMap *area_map) -{ - BLO_write_struct_list(writer, ScrVert, &area_map->vertbase); - BLO_write_struct_list(writer, ScrEdge, &area_map->edgebase); - LISTBASE_FOREACH (ScrArea *, area, &area_map->areabase) { - area->butspacetype = area->spacetype; /* Just for compatibility, will be reset below. */ - - BLO_write_struct(writer, ScrArea, area); - -#ifdef WITH_GLOBAL_AREA_WRITING - BLO_write_struct(writer, ScrGlobalAreaData, area->global); -#endif - - write_area_regions(writer, area); - - area->butspacetype = SPACE_EMPTY; /* Unset again, was changed above. */ - } + BKE_screen_view3d_shading_blend_write(writer, &xr_data->session_settings.shading); } static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const void *id_address) @@ -2010,12 +1639,6 @@ static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const write_wm_xr_data(writer, &wm->xr); LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { -#ifndef WITH_GLOBAL_AREA_WRITING - /* Don't write global areas yet, while we make changes to them. */ - ScrAreaMap global_areas = win->global_areas; - memset(&win->global_areas, 0, sizeof(win->global_areas)); -#endif - /* update deprecated screen member (for so loading in 2.7x uses the correct screen) */ win->screen = BKE_workspace_active_screen_get(win->workspace_hook); @@ -2023,48 +1646,13 @@ static void write_windowmanager(BlendWriter *writer, wmWindowManager *wm, const BLO_write_struct(writer, WorkSpaceInstanceHook, win->workspace_hook); BLO_write_struct(writer, Stereo3dFormat, win->stereo3d_format); -#ifdef WITH_GLOBAL_AREA_WRITING - write_area_map(writer, &win->global_areas); -#else - win->global_areas = global_areas; -#endif + BKE_screen_area_map_blend_write(writer, &win->global_areas); /* data is written, clear deprecated data again */ win->screen = NULL; } } -static void write_screen(BlendWriter *writer, bScreen *screen, const void *id_address) -{ - /* Screens are reference counted, only saved if used by a workspace. */ - if (screen->id.us > 0 || BLO_write_is_undo(writer)) { - /* write LibData */ - /* in 2.50+ files, the file identifier for screens is patched, forward compatibility */ - writestruct_at_address(writer->wd, ID_SCRN, bScreen, 1, id_address, screen); - BKE_id_blend_write(writer, &screen->id); - - BKE_previewimg_blend_write(writer, screen->preview); - - /* direct data */ - write_area_map(writer, AREAMAP_FROM_SCREEN(screen)); - } -} - -static void write_workspace(BlendWriter *writer, WorkSpace *workspace, const void *id_address) -{ - BLO_write_id_struct(writer, WorkSpace, id_address, &workspace->id); - BKE_id_blend_write(writer, &workspace->id); - BLO_write_struct_list(writer, WorkSpaceLayout, &workspace->layouts); - BLO_write_struct_list(writer, WorkSpaceDataRelation, &workspace->hook_layout_relations); - BLO_write_struct_list(writer, wmOwnerID, &workspace->owner_ids); - BLO_write_struct_list(writer, bToolRef, &workspace->tools); - LISTBASE_FOREACH (bToolRef *, tref, &workspace->tools) { - if (tref->properties) { - IDP_BlendWrite(writer, tref->properties); - } - } -} - /* Keep it last of write_foodata functions. */ static void write_libraries(WriteData *wd, Main *main) { @@ -2326,24 +1914,16 @@ static bool write_file_handle(Main *mainvar, case ID_WM: write_windowmanager(&writer, (wmWindowManager *)id_buffer, id); break; - case ID_WS: - write_workspace(&writer, (WorkSpace *)id_buffer, id); - break; - case ID_SCR: - write_screen(&writer, (bScreen *)id_buffer, id); - break; case ID_SCE: write_scene(&writer, (Scene *)id_buffer, id); break; - case ID_GR: - write_collection(&writer, (Collection *)id_buffer, id); - break; case ID_OB: write_object(&writer, (Object *)id_buffer, id); break; + case ID_WS: + case ID_SCR: case ID_PA: - write_particlesettings(&writer, (ParticleSettings *)id_buffer, id); - break; + case ID_GR: case ID_ME: case ID_LT: case ID_AC: @@ -2678,7 +2258,13 @@ void BLO_write_struct_at_address_by_id(BlendWriter *writer, const void *address, const void *data_ptr) { - writestruct_at_address_nr(writer->wd, DATA, struct_id, 1, address, data_ptr); + BLO_write_struct_at_address_by_id_with_filecode(writer, DATA, struct_id, address, data_ptr); +} + +void BLO_write_struct_at_address_by_id_with_filecode( + BlendWriter *writer, int filecode, int struct_id, const void *address, const void *data_ptr) +{ + writestruct_at_address_nr(writer->wd, filecode, struct_id, 1, address, data_ptr); } void BLO_write_struct_array_by_id(BlendWriter *writer, diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc index e34be68abbf..cb5fcdbe3c6 100644 --- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc +++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc @@ -73,7 +73,7 @@ void BlendfileLoadingBaseTest::SetUpTestCase() BKE_modifier_init(); DEG_register_node_types(); RNA_init(); - init_nodesystem(); + BKE_node_system_init(); G.background = true; G.factory_startup = true; diff --git a/source/blender/blentranslation/intern/blt_lang.c b/source/blender/blentranslation/intern/blt_lang.c index 078ded7e5c2..bd0352d3e80 100644 --- a/source/blender/blentranslation/intern/blt_lang.c +++ b/source/blender/blentranslation/intern/blt_lang.c @@ -105,7 +105,7 @@ static void fill_locales(void) while (line) { int t; str = (char *)line->link; - if (str[0] == '#' || str[0] == '\0') { + if (ELEM(str[0], '#', '\0')) { line = line->next; continue; /* Comment or void... */ } @@ -130,7 +130,7 @@ static void fill_locales(void) char *loc, *sep1, *sep2, *sep3; str = (char *)line->link; - if (str[0] == '#' || str[0] == '\0') { + if (ELEM(str[0], '#', '\0')) { line = line->next; continue; } @@ -388,7 +388,7 @@ static void blt_lang_check_ime_supported(void) { #ifdef WITH_INPUT_IME const char *uilng = BLT_lang_get(); - ime_is_lang_supported = STREQ(uilng, "zh_CN") || STREQ(uilng, "zh_TW") || STREQ(uilng, "ja_JP"); + ime_is_lang_supported = STR_ELEM(uilng, "zh_CN", "zh_TW", "ja_JP"); #else ime_is_lang_supported = false; #endif diff --git a/source/blender/blentranslation/msgfmt/CMakeLists.txt b/source/blender/blentranslation/msgfmt/CMakeLists.txt index 20f5053bd29..4b8f0878c75 100644 --- a/source/blender/blentranslation/msgfmt/CMakeLists.txt +++ b/source/blender/blentranslation/msgfmt/CMakeLists.txt @@ -34,7 +34,7 @@ setup_libdirs() add_cc_flags_custom_test(msgfmt) if(WIN32) - set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /nodefaultlib:MSVCRT.lib") + string(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG " /nodefaultlib:MSVCRT.lib") endif() add_executable(msgfmt ${SRC}) diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 92c52f5d8d0..c215cf69e3a 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -183,7 +183,7 @@ set(LIB ) if(MSVC AND NOT MSVC_CLANG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX /wd4101") + string(APPEND CMAKE_C_FLAGS " /WX /wd4101") endif() if(WITH_BULLET) diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index ca5693aa5ba..8631c224ce0 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -335,7 +335,7 @@ BMFace *BM_face_create_ngon_verts(BMesh *bm, /* we want to use the reverse winding to the existing order */ BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1); winding[(vert_arr[i_prev] == test_v2)]++; - BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1); + BLI_assert(ELEM(vert_arr[i_prev], test_v2, test_v1)); } } diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index df5e7aadc64..b913bdd12e4 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -2289,6 +2289,7 @@ bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src) return true; } +/* -------------------------------------------------------------------- */ /** \name BM_vert_separate, bmesh_kernel_vert_separate and friends * \{ */ diff --git a/source/blender/bmesh/intern/bmesh_delete.c b/source/blender/bmesh/intern/bmesh_delete.c index b5ff24f6d61..f470361e5fb 100644 --- a/source/blender/bmesh/intern/bmesh_delete.c +++ b/source/blender/bmesh/intern/bmesh_delete.c @@ -28,9 +28,9 @@ #include "bmesh.h" #include "intern/bmesh_private.h" -/* -------------------------------------------------------------------- */ /* BMO functions */ +/* -------------------------------------------------------------------- */ /** \name BMesh Operator Delete Functions * \{ */ @@ -203,7 +203,6 @@ void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type) /** \} */ -/* -------------------------------------------------------------------- */ /* BM functions * * note! this is just a duplicate of the code above (bad!) @@ -211,6 +210,7 @@ void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type) * each time we need to remove some geometry. */ +/* -------------------------------------------------------------------- */ /** \name BMesh Delete Functions (no oflags) * \{ */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 0bbe86d2d2f..a15408d43be 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -1027,6 +1027,7 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float } } +/* -------------------------------------------------------------------- */ /** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_*** * * Handling loop custom-data such as UV's, while keeping contiguous fans is rather tedious. diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index a5d02cdc4e5..4fe6e6aee58 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -66,6 +66,7 @@ static void recount_totsels(BMesh *bm) } } +/* -------------------------------------------------------------------- */ /** \name BMesh helper functions for selection & hide flushing. * \{ */ @@ -540,7 +541,8 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select) } } -/** \name Non flushing versions element selection. +/* -------------------------------------------------------------------- */ +/** \name Non Flushing Versions Element Selection * \{ */ void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select) diff --git a/source/blender/bmesh/intern/bmesh_mesh_duplicate.c b/source/blender/bmesh/intern/bmesh_mesh_duplicate.c index 51f9d2eab1d..1d393abcd56 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_duplicate.c +++ b/source/blender/bmesh/intern/bmesh_mesh_duplicate.c @@ -50,9 +50,7 @@ static BMEdge *bm_edge_copy_with_arrays(BMesh *bm_src, } static BMFace *bm_face_copy_with_arrays( - BMesh *bm_src, BMesh *bm_dst, BMFace *f_src, BMVert **verts_dst, BMEdge **edges_dst - -) + BMesh *bm_src, BMesh *bm_dst, BMFace *f_src, BMVert **verts_dst, BMEdge **edges_dst) { BMFace *f_dst; BMVert **vtar = BLI_array_alloca(vtar, f_src->len); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index c5e030c436a..c2421939aa8 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -963,7 +963,7 @@ void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele) BMO_ASSERT_SLOT_IN_OP(slot, op); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE); - BLI_assert(slot->len == 0 || slot->len == 1); + BLI_assert(ELEM(slot->len, 0, 1)); BLI_assert(slot->slot_subtype.elem & ele->htype); @@ -979,7 +979,7 @@ void BMO_slot_buffer_from_array(BMOperator *op, { BMO_ASSERT_SLOT_IN_OP(slot, op); BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); - BLI_assert(slot->len == 0 || slot->len == ele_buffer_len); + BLI_assert(ELEM(slot->len, 0, ele_buffer_len)); if (slot->data.buf == NULL) { slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(*slot->data.buf) * ele_buffer_len); @@ -993,7 +993,7 @@ void *BMO_slot_buffer_get_single(BMOpSlot *slot) { BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF); BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE); - BLI_assert(slot->len == 0 || slot->len == 1); + BLI_assert(ELEM(slot->len, 0, 1)); return slot->len ? (BMHeader *)slot->data.buf[0] : NULL; } diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c index 09c0f48c2f6..1d000b3b232 100644 --- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c +++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c @@ -39,9 +39,9 @@ #include "intern/bmesh_private.h" /* -------------------------------------------------------------------- */ -/* Face Split Edge-Net */ - -/** \name BM_face_split_edgenet and helper functions. +/** \name Face Split Edge-Net + * + * #BM_face_split_edgenet and helper functions. * * \note Don't use #BM_edge_is_wire or #BM_edge_is_boundary * since we need to take flagged faces into account. @@ -702,9 +702,9 @@ bool BM_face_split_edgenet(BMesh *bm, /** \} */ /* -------------------------------------------------------------------- */ -/* Face Split Edge-Net Connect Islands */ - -/** \name BM_face_split_edgenet_connect_islands and helper functions. +/** \name Face Split Edge-Net Connect Islands + * + * #BM_face_split_edgenet_connect_islands and helper functions. * * Connect isolated mesh 'islands' so they form legal regions from which we can create faces. * diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c index 791fa64ae7d..0d8b5cf4590 100644 --- a/source/blender/bmesh/intern/bmesh_query.c +++ b/source/blender/bmesh/intern/bmesh_query.c @@ -1605,7 +1605,7 @@ float BM_loop_calc_face_normal_safe_vcos_ex(const BMLoop *l, } /** - * #BM_loop_calc_face_normal_safe_ex with pre-defined sane epsilon. + * #BM_loop_calc_face_normal_safe_ex with predefined sane epsilon. * * Since this doesn't scale based on triangle size, fixed value works well. */ diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index d9f68f8aa62..ef4a9c9de1c 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -402,7 +402,7 @@ bool bmesh_radial_validate(int radlen, BMLoop *l) if (l_iter->e != l->e) { return false; } - if (l_iter->v != l->e->v1 && l_iter->v != l->e->v2) { + if (!ELEM(l_iter->v, l->e->v1, l->e->v2)) { return false; } diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index dc9107a1616..7d56e560275 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -37,6 +37,7 @@ } \ (void)0 +/* -------------------------------------------------------------------- */ /** \name Mask Flag Checks * \{ */ @@ -75,6 +76,7 @@ static bool bmw_mask_check_face(BMWalker *walker, BMFace *f) /** \} */ +/* -------------------------------------------------------------------- */ /** \name BMesh Queries (modified to check walker flags) * \{ */ @@ -94,8 +96,8 @@ static bool bmw_edge_is_wire(const BMWalker *walker, const BMEdge *e) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Shell Walker - * \{ * * Starts at a vertex on the mesh and walks over the 'shell' it belongs * to via visiting connected edges. @@ -104,7 +106,7 @@ static bool bmw_edge_is_wire(const BMWalker *walker, const BMEdge *e) * restrict flag acts on the edges as well. * * \todo Add restriction flag/callback for wire edges. - */ + * \{ */ static void bmw_VertShellWalker_visitEdge(BMWalker *walker, BMEdge *e) { BMwShellWalker *shellWalk = NULL; @@ -228,14 +230,14 @@ static void *bmw_VertShellWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name LoopShell Walker - * \{ * * Starts at any element on the mesh and walks over the 'shell' it belongs * to via visiting connected loops. * * \note this is mainly useful to loop over a shell delimited by edges. - */ + * \{ */ static void bmw_LoopShellWalker_visitLoop(BMWalker *walker, BMLoop *l) { BMwLoopShellWalker *shellWalk = NULL; @@ -352,10 +354,10 @@ static void *bmw_LoopShellWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name LoopShell & 'Wire' Walker - * \{ * - * Piggyback ontop of #BMwLoopShellWalker, but also walk over wire edges + * Piggyback on top of #BMwLoopShellWalker, but also walk over wire edges * This isn't elegant but users expect it when selecting linked, * so we can support delimiters _and_ walking over wire edges. * @@ -363,7 +365,7 @@ static void *bmw_LoopShellWalker_step(BMWalker *walker) * - can yield edges (as well as loops) * - only step over wire edges. * - verts and edges are stored in `visit_set_alt`. - */ + * \{ */ static void bmw_LoopShellWalker_visitEdgeWire(BMWalker *walker, BMEdge *e) { @@ -504,12 +506,12 @@ static void *bmw_LoopShellWireWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name FaceShell Walker - * \{ * * Starts at an edge on the mesh and walks over the 'shell' it belongs * to via visiting connected faces. - */ + * \{ */ static void bmw_FaceShellWalker_visitEdge(BMWalker *walker, BMEdge *e) { BMwShellWalker *shellWalk = NULL; @@ -567,13 +569,13 @@ static void *bmw_FaceShellWalker_step(BMWalker *walker) } /** \} */ +/* -------------------------------------------------------------------- */ /** \name Connected Vertex Walker - * \{ * * Similar to shell walker, but visits vertices instead of edges. * * Walk from a vertex to all connected vertices. - */ + * \{ */ static void bmw_ConnectedVertexWalker_visitVertex(BMWalker *walker, BMVert *v) { BMwConnectedVertexWalker *vwalk; @@ -629,8 +631,8 @@ static void *bmw_ConnectedVertexWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Island Boundary Walker - * \{ * * Starts at a edge on the mesh and walks over the boundary of an island it belongs to. * @@ -640,7 +642,7 @@ static void *bmw_ConnectedVertexWalker_step(BMWalker *walker) * over the boundary. raises an error if it encounters non-manifold geometry. * * \todo Add restriction flag/callback for wire edges. - */ + * \{ */ static void bmw_IslandboundWalker_begin(BMWalker *walker, void *data) { BMLoop *l = data; @@ -723,13 +725,13 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker) return owalk.curloop; } +/* -------------------------------------------------------------------- */ /** \name Island Walker - * \{ * * Starts at a tool flagged-face and walks over the face region * * \todo Add restriction flag/callback for wire edges. - */ + * \{ */ static void bmw_IslandWalker_begin(BMWalker *walker, void *data) { BMwIslandWalker *iwalk = NULL; @@ -828,11 +830,11 @@ static void *bmw_IslandManifoldWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Edge Loop Walker - * \{ * * Starts at a tool-flagged edge and walks over the edge loop - */ + * \{ */ /* utility function to see if an edge is a part of an ngon boundary */ static bool bm_edge_is_single(BMEdge *e) @@ -981,7 +983,7 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker) /* Typical loopiong over edges in the middle of a mesh */ /* However, why use 2 here at all? * I guess for internal ngon loops it can be useful. Antony R. */ - if (vert_edge_tot == 4 || vert_edge_tot == 2) { + if (ELEM(vert_edge_tot, 4, 2)) { int i_opposite = vert_edge_tot / 2; int i = 0; do { @@ -1070,13 +1072,13 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Face Loop Walker - * \{ * * Starts at a tool-flagged face and walks over the face loop * Conditions for starting and stepping the face loop have been * tuned in an attempt to match the face loops built by EditMesh - */ + * \{ */ /* Check whether the face loop should includes the face specified * by the given BMLoop */ @@ -1216,13 +1218,13 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker) // #define BMW_EDGERING_NGON +/* -------------------------------------------------------------------- */ /** \name Edge Ring Walker - * \{ * * Starts at a tool-flagged edge and walks over the edge ring * Conditions for starting and stepping the edge ring have been * tuned to match behavior users expect (dating back to v2.4x). - */ + * \{ */ static void bmw_EdgeringWalker_begin(BMWalker *walker, void *data) { BMwEdgeringWalker *lwalk, owalk, *owalk_pt; @@ -1349,6 +1351,7 @@ static void *bmw_EdgeringWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Boundary Edge Walker * \{ */ @@ -1420,14 +1423,14 @@ static void *bmw_EdgeboundaryWalker_step(BMWalker *walker) /** \} */ +/* -------------------------------------------------------------------- */ /** \name UV Edge Walker * * walk over uv islands; takes a loop as input. restrict flag * restricts the walking to loops whose vert has restrict flag set as a * tool flag. * - * the flag parameter to BMW_init maps to a loop customdata layer index. - * + * The flag parameter to BMW_init maps to a loop customdata layer index. * \{ */ static void bmw_UVEdgeWalker_begin(BMWalker *walker, void *data) diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c index c97e855aa67..3aad37b3b02 100644 --- a/source/blender/bmesh/operators/bmo_fill_grid.c +++ b/source/blender/bmesh/operators/bmo_fill_grid.c @@ -96,9 +96,7 @@ static void quad_verts_to_barycentric_tri(float tri[3][3], #endif /* -------------------------------------------------------------------- */ -/* Handle Loop Pairs */ - -/** \name Loop Pairs +/** \name Handle Loop Pairs * \{ */ /** diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 46dff99898c..8b2f9478aab 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -338,9 +338,9 @@ static void alter_co(BMVert *v, add_v3_v3v3(co2, v->co, params->fractal_ofs); mul_v3_fl(co2, 10.0f); - tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f); - tvec[1] = fac * (BLI_gTurbulence(1.0, co2[1], co2[0], co2[2], 15, 0, 2) - 0.5f); - tvec[2] = fac * (BLI_gTurbulence(1.0, co2[1], co2[2], co2[0], 15, 0, 2) - 0.5f); + tvec[0] = fac * (BLI_noise_generic_turbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f); + tvec[1] = fac * (BLI_noise_generic_turbulence(1.0, co2[1], co2[0], co2[2], 15, 0, 2) - 0.5f); + tvec[2] = fac * (BLI_noise_generic_turbulence(1.0, co2[1], co2[2], co2[0], 15, 0, 2) - 0.5f); /* add displacement */ madd_v3_v3fl(co, normal, tvec[0]); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index e8ded83dfbe..ce58b8b8382 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -303,14 +303,14 @@ typedef enum { } FKind; /** Helper for keeping track of angle kind. */ -enum { +typedef enum AngleKind { /** Angle less than 180 degrees. */ ANGLE_SMALLER = -1, /** 180 degree angle. */ ANGLE_STRAIGHT = 0, /** Angle greater than 180 degrees. */ ANGLE_LARGER = 1, -}; +} AngleKind; /** Bevel parameters and state. */ typedef struct BevelParams { @@ -1101,7 +1101,7 @@ static bool is_outside_edge(EdgeHalf *e, const float co[3], BMVert **ret_closer_ } /* Return whether the angle is less than, equal to, or larger than 180 degrees. */ -static int edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v) +static AngleKind edges_angle_kind(EdgeHalf *e1, EdgeHalf *e2, BMVert *v) { BMVert *v1 = BM_edge_other_vert(e1->e, v); BMVert *v2 = BM_edge_other_vert(e2->e, v); @@ -1399,7 +1399,7 @@ static void offset_meet(BevelParams *bp, normalize_v3(norm_perp2); float off1a[3], off1b[3], off2a[3], off2b[3]; - if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { + if (ELEM(bp->offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE)) { offset_meet_lines_percent_or_absolute(bp, e1, e2, v, off1a, off1b, off2a, off2b); } else { @@ -1556,7 +1556,7 @@ static bool offset_on_edge_between(BevelParams *bp, float meet1[3], meet2[3]; bool ok1 = offset_meet_edge(e1, emid, v, meet1, &ang1); bool ok2 = offset_meet_edge(emid, e2, v, meet2, &ang2); - if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { + if (ELEM(bp->offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE)) { BMVert *v2 = BM_edge_other_vert(emid->e, v); if (bp->offset_type == BEVEL_AMT_PERCENT) { interp_v3_v3v3(meetco, v->co, v2->co, bp->offset / 100.0f); @@ -2158,7 +2158,7 @@ static void snap_to_superellipsoid(float co[3], const float super_r, bool midlin float x = a; float y = b; float z = c; - if (r == PRO_SQUARE_R || r == PRO_SQUARE_IN_R) { + if (ELEM(r, PRO_SQUARE_R, PRO_SQUARE_IN_R)) { /* Will only be called for 2d profile. */ BLI_assert(fabsf(z) < BEVEL_EPSILON); z = 0.0f; @@ -2441,7 +2441,7 @@ static void bevel_harden_normals(BevelParams *bp, BMesh *bm) BMFace *f; BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { FKind fkind = get_face_kind(bp, f); - if (fkind == F_ORIG || fkind == F_RECON) { + if (ELEM(fkind, F_ORIG, F_RECON)) { continue; } BMIter liter; @@ -3027,7 +3027,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) for (EdgeHalf *e3 = e->next; e3 != e2; e3 = e3->next) { e3->leftv = e3->rightv = v; } - int ang_kind = edges_angle_kind(e, e2, bv->v); + AngleKind ang_kind = edges_angle_kind(e, e2, bv->v); /* Are we doing special mitering? * There can only be one outer reflex angle, so only one outer miter, @@ -3105,7 +3105,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv, bool construct) } } else { /* construct == false. */ - int ang_kind = edges_angle_kind(e, e2, bv->v); + AngleKind ang_kind = edges_angle_kind(e, e2, bv->v); if ((miter_outer != BEVEL_MITER_SHARP && !emiter && ang_kind == ANGLE_LARGER) || (miter_inner != BEVEL_MITER_SHARP && ang_kind == ANGLE_SMALLER)) { if (ang_kind == ANGLE_LARGER) { @@ -4568,13 +4568,13 @@ static void snap_to_pipe_profile(BoundVert *vpipe, bool midline, float co[3]) sub_v3_v3v3(edir, e->e->v1->co, e->e->v2->co); plane_from_point_normal_v3(plane, co, edir); - float va0[3], vb0[3], vmid0[3]; - closest_to_plane_v3(va0, plane, pro->start); - closest_to_plane_v3(vb0, plane, pro->end); - closest_to_plane_v3(vmid0, plane, pro->middle); + float start_plane[3], end_plane[3], middle_plane[3]; + closest_to_plane_v3(start_plane, plane, pro->start); + closest_to_plane_v3(end_plane, plane, pro->end); + closest_to_plane_v3(middle_plane, plane, pro->middle); float m[4][4], minv[4][4]; - if (make_unit_square_map(va0, vmid0, vb0, m) && invert_m4_m4(minv, m)) { + if (make_unit_square_map(start_plane, middle_plane, end_plane, m) && invert_m4_m4(minv, m)) { /* Transform co and project it onto superellipse. */ float p[3]; mul_v3_m4v3(p, minv, co); @@ -4585,9 +4585,9 @@ static void snap_to_pipe_profile(BoundVert *vpipe, bool midline, float co[3]) copy_v3_v3(co, snap); } else { - /* Planar case: just snap to line va0--vb0. */ + /* Planar case: just snap to line start_plane--end_plane. */ float p[3]; - closest_to_line_segment_v3(p, co, va0, vb0); + closest_to_line_segment_v3(p, co, start_plane, end_plane); copy_v3_v3(co, p); } } @@ -4619,7 +4619,7 @@ static VMesh *pipe_adj_vmesh(BevelParams *bp, BevVert *bv, BoundVert *vpipe) if (bp->profile_type == BEVEL_PROFILE_CUSTOM) { /* Find both profile vertices that correspond to this point. */ float *profile_point_pipe1, *profile_point_pipe2, f; - if (i == ipipe1 || i == ipipe2) { + if (ELEM(i, ipipe1, ipipe2)) { if (n_bndv == 3 && i == ipipe1) { /* This part of the vmesh is the triangular corner between the two pipe profiles. */ int ring = max_ii(j, k); @@ -4928,7 +4928,7 @@ static VMesh *square_out_adj_vmesh(BevelParams *bp, BevVert *bv) copy_v3_v3(bndco, bndv->nv.co); EdgeHalf *e1 = bndv->efirst; EdgeHalf *e2 = bndv->elast; - int ang_kind = ANGLE_STRAIGHT; + AngleKind ang_kind = ANGLE_STRAIGHT; if (e1 && e2) { ang_kind = edges_angle_kind(e1, e2, bv->v); } @@ -6229,7 +6229,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) break; } } - if (bp->offset_type != BEVEL_AMT_PERCENT && bp->offset_type != BEVEL_AMT_ABSOLUTE) { + if (!ELEM(bp->offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE)) { e->offset_r_spec = e->offset_l_spec; } if (bp->use_weights) { @@ -6771,7 +6771,7 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) BMIter iter; BMLoop *l; BM_ITER_ELEM (l, &iter, r_f, BM_LOOPS_OF_FACE) { - if (l->v == verts[0] || l->v == verts[2]) { + if (ELEM(l->v, verts[0], verts[2])) { BM_elem_flag_enable(l, BM_ELEM_LONG_TAG); } } @@ -7232,7 +7232,7 @@ static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb) EdgeHalf *ec; BMVert *vd; float kc; - if (bp->offset_type == BEVEL_AMT_PERCENT || bp->offset_type == BEVEL_AMT_ABSOLUTE) { + if (ELEM(bp->offset_type, BEVEL_AMT_PERCENT, BEVEL_AMT_ABSOLUTE)) { if (ea->is_bev && ebother != NULL && ebother->prev->is_bev) { if (bp->offset_type == BEVEL_AMT_PERCENT) { return 50.0f; diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c index 9f4327fd1e3..c332d88e83b 100644 --- a/source/blender/bmesh/tools/bmesh_edgenet.c +++ b/source/blender/bmesh/tools/bmesh_edgenet.c @@ -51,7 +51,7 @@ enum { */ static bool bm_edge_step_ok(BMEdge *e) { - return BM_elem_flag_test(e, BM_ELEM_TAG) && ((e->l == NULL) || (e->l->radial_next == e->l)); + return BM_elem_flag_test(e, BM_ELEM_TAG) && (ELEM(e->l, NULL, e->l->radial_next)); } static int bm_edge_face(BMEdge *e) diff --git a/source/blender/bmesh/tools/bmesh_path_region.c b/source/blender/bmesh/tools/bmesh_path_region.c index f8e981bbd58..23be3cdf117 100644 --- a/source/blender/bmesh/tools/bmesh_path_region.c +++ b/source/blender/bmesh/tools/bmesh_path_region.c @@ -74,6 +74,7 @@ static bool bm_vert_pair_ends(BMVert *v_pivot, BMVert *v_end_pair[2]) } #endif /* USE_EDGE_CHAIN */ +/* -------------------------------------------------------------------- */ /** \name Vertex in Region Checks * \{ */ @@ -386,6 +387,7 @@ static LinkNode *mesh_calc_path_region_elem(BMesh *bm, #undef USE_EDGE_CHAIN +/* -------------------------------------------------------------------- */ /** \name Main Functions (exposed externally). * \{ */ diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.c b/source/blender/bmesh/tools/bmesh_path_region_uv.c index d036c20d0e4..517913b5b56 100644 --- a/source/blender/bmesh/tools/bmesh_path_region_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_region_uv.c @@ -72,6 +72,7 @@ static bool bm_loop_pair_ends(BMLoop *l_pivot, BMLoop *l_end_pair[2]) } #endif /* USE_EDGE_CHAIN */ +/* -------------------------------------------------------------------- */ /** \name Loop Vertex in Region Checks * \{ */ @@ -403,6 +404,7 @@ static LinkNode *mesh_calc_path_region_elem(BMesh *bm, #undef USE_EDGE_CHAIN +/* -------------------------------------------------------------------- */ /** \name Main Functions (exposed externally). * \{ */ diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c index d222ea214c4..561b00544b5 100644 --- a/source/blender/bmesh/tools/bmesh_region_match.c +++ b/source/blender/bmesh/tools/bmesh_region_match.c @@ -67,8 +67,6 @@ #include "BLI_strict_flags.h" /* -------------------------------------------------------------------- */ -/* UUID-Walk API */ - /** \name Internal UUIDWalk API * \{ */ @@ -615,6 +613,7 @@ static uint bm_uuidwalk_init_from_edge(UUIDWalk *uuidwalk, BMEdge *e) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Internal UUIDFaceStep API * \{ */ @@ -907,6 +906,7 @@ static void bm_face_array_visit(BMFace **faces, #ifdef USE_PIVOT_SEARCH +/* -------------------------------------------------------------------- */ /** \name Internal UUIDWalk API * \{ */ @@ -1226,11 +1226,11 @@ static BMEdge *bm_face_region_pivot_edge_find(BMFace **faces_region, #endif /* USE_PIVOT_SEARCH */ -/* -------------------------------------------------------------------- */ /* Quick UUID pass - identify candidates */ #ifdef USE_PIVOT_FASTMATCH +/* -------------------------------------------------------------------- */ /** \name Fast Match * \{ */ diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index d524f4a0e1e..54dd121952b 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -353,6 +353,8 @@ set(SRC operations/COM_KeyingDespillOperation.h operations/COM_KeyingOperation.cpp operations/COM_KeyingOperation.h + operations/COM_KeyingSetAlphaOperation.cpp + operations/COM_KeyingSetAlphaOperation.h operations/COM_ColorSpillOperation.cpp operations/COM_ColorSpillOperation.h diff --git a/source/blender/compositor/intern/COM_CPUDevice.cpp b/source/blender/compositor/intern/COM_CPUDevice.cpp index bcb14e4dbb2..26fe1ba0bc3 100644 --- a/source/blender/compositor/intern/COM_CPUDevice.cpp +++ b/source/blender/compositor/intern/COM_CPUDevice.cpp @@ -18,7 +18,7 @@ #include "COM_CPUDevice.h" -CPUDevice::CPUDevice(int thread_id) : Device(), m_thread_id(thread_id) +CPUDevice::CPUDevice(int thread_id) : m_thread_id(thread_id) { } diff --git a/source/blender/compositor/intern/COM_Converter.cpp b/source/blender/compositor/intern/COM_Converter.cpp index 60676ee42b7..15a52d10071 100644 --- a/source/blender/compositor/intern/COM_Converter.cpp +++ b/source/blender/compositor/intern/COM_Converter.cpp @@ -116,12 +116,19 @@ bool Converter::is_fast_node(bNode *b_node) { - return !(b_node->type == CMP_NODE_BLUR || b_node->type == CMP_NODE_VECBLUR || - b_node->type == CMP_NODE_BILATERALBLUR || b_node->type == CMP_NODE_DEFOCUS || - b_node->type == CMP_NODE_BOKEHBLUR || b_node->type == CMP_NODE_GLARE || - b_node->type == CMP_NODE_DBLUR || b_node->type == CMP_NODE_MOVIEDISTORTION || - b_node->type == CMP_NODE_LENSDIST || b_node->type == CMP_NODE_DOUBLEEDGEMASK || - b_node->type == CMP_NODE_DILATEERODE || b_node->type == CMP_NODE_DENOISE); + return !ELEM(b_node->type, + CMP_NODE_BLUR, + CMP_NODE_VECBLUR, + CMP_NODE_BILATERALBLUR, + CMP_NODE_DEFOCUS, + CMP_NODE_BOKEHBLUR, + CMP_NODE_GLARE, + CMP_NODE_DBLUR, + CMP_NODE_MOVIEDISTORTION, + CMP_NODE_LENSDIST, + CMP_NODE_DOUBLEEDGEMASK, + CMP_NODE_DILATEERODE, + CMP_NODE_DENOISE); } Node *Converter::convert(bNode *b_node) diff --git a/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp index 029be6d44b1..98239166860 100644 --- a/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp +++ b/source/blender/compositor/intern/COM_SingleThreadedOperation.cpp @@ -18,7 +18,7 @@ #include "COM_SingleThreadedOperation.h" -SingleThreadedOperation::SingleThreadedOperation() : NodeOperation() +SingleThreadedOperation::SingleThreadedOperation() { this->m_cachedInstance = NULL; setComplex(true); diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index b75d06763b7..53cf64c5c3f 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -32,7 +32,7 @@ #include "COM_DilateErodeOperation.h" -#include "COM_SetAlphaOperation.h" +#include "COM_KeyingSetAlphaOperation.h" #include "COM_GaussianAlphaXBlurOperation.h" #include "COM_GaussianAlphaYBlurOperation.h" @@ -63,7 +63,7 @@ NodeOperationOutput *KeyingNode::setupPreBlur(NodeConverter &converter, converter.addLink(convertRGBToYCCOperation->getOutputSocket(0), separateOperation->getInputSocket(0)); - if (channel == 0 || channel == 3) { + if (ELEM(channel, 0, 3)) { converter.addLink(separateOperation->getOutputSocket(0), combineOperation->getInputSocket(channel)); } @@ -322,7 +322,7 @@ void KeyingNode::convertToOperations(NodeConverter &converter, } /* set alpha channel to output image */ - SetAlphaOperation *alphaOperation = new SetAlphaOperation(); + KeyingSetAlphaOperation *alphaOperation = new KeyingSetAlphaOperation(); converter.addOperation(alphaOperation); converter.mapInputSocket(inputImage, alphaOperation->getInputSocket(0)); diff --git a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp index 1be5ef1f2df..668d07c7c3d 100644 --- a/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverKeyOperation.cpp @@ -18,7 +18,7 @@ #include "COM_AlphaOverKeyOperation.h" -AlphaOverKeyOperation::AlphaOverKeyOperation() : MixBaseOperation() +AlphaOverKeyOperation::AlphaOverKeyOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp index 513158dcff6..b8465ab7ccf 100644 --- a/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverMixedOperation.cpp @@ -18,7 +18,7 @@ #include "COM_AlphaOverMixedOperation.h" -AlphaOverMixedOperation::AlphaOverMixedOperation() : MixBaseOperation() +AlphaOverMixedOperation::AlphaOverMixedOperation() { this->m_x = 0.0f; } diff --git a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp index 8e5bce7221f..4510c027d46 100644 --- a/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp +++ b/source/blender/compositor/operations/COM_AlphaOverPremultiplyOperation.cpp @@ -18,7 +18,7 @@ #include "COM_AlphaOverPremultiplyOperation.h" -AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation() : MixBaseOperation() +AlphaOverPremultiplyOperation::AlphaOverPremultiplyOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp index 3d5e53feb39..e1e58c9521a 100644 --- a/source/blender/compositor/operations/COM_AntiAliasOperation.cpp +++ b/source/blender/compositor/operations/COM_AntiAliasOperation.cpp @@ -112,7 +112,7 @@ static int extrapolate9(float *E0, #undef PCPY } -AntiAliasOperation::AntiAliasOperation() : NodeOperation() +AntiAliasOperation::AntiAliasOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp index 8168867a522..93193aef360 100644 --- a/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BilateralBlurOperation.cpp @@ -21,7 +21,7 @@ #include "RE_pipeline.h" -BilateralBlurOperation::BilateralBlurOperation() : NodeOperation() +BilateralBlurOperation::BilateralBlurOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp index ef0f259c592..0d9a1a184d6 100644 --- a/source/blender/compositor/operations/COM_BlurBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_BlurBaseOperation.cpp @@ -22,7 +22,7 @@ #include "RE_pipeline.h" -BlurBaseOperation::BlurBaseOperation(DataType data_type) : NodeOperation() +BlurBaseOperation::BlurBaseOperation(DataType data_type) { /* data_type is almost always COM_DT_COLOR except for alpha-blur */ this->addInputSocket(data_type); diff --git a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp index c00ef2468c0..987c5946e48 100644 --- a/source/blender/compositor/operations/COM_BokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehBlurOperation.cpp @@ -22,7 +22,7 @@ #include "RE_pipeline.h" -BokehBlurOperation::BokehBlurOperation() : NodeOperation() +BokehBlurOperation::BokehBlurOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); diff --git a/source/blender/compositor/operations/COM_BokehImageOperation.cpp b/source/blender/compositor/operations/COM_BokehImageOperation.cpp index 3fd9a77d879..be3f637e4bb 100644 --- a/source/blender/compositor/operations/COM_BokehImageOperation.cpp +++ b/source/blender/compositor/operations/COM_BokehImageOperation.cpp @@ -19,7 +19,7 @@ #include "COM_BokehImageOperation.h" #include "BLI_math.h" -BokehImageOperation::BokehImageOperation() : NodeOperation() +BokehImageOperation::BokehImageOperation() { this->addOutputSocket(COM_DT_COLOR); this->m_deleteData = false; diff --git a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp index c5f0108bf5a..d7d779ed0bb 100644 --- a/source/blender/compositor/operations/COM_BoxMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_BoxMaskOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #include "DNA_node_types.h" -BoxMaskOperation::BoxMaskOperation() : NodeOperation() +BoxMaskOperation::BoxMaskOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cpp b/source/blender/compositor/operations/COM_BrightnessOperation.cpp index b6c22029899..c72d227138d 100644 --- a/source/blender/compositor/operations/COM_BrightnessOperation.cpp +++ b/source/blender/compositor/operations/COM_BrightnessOperation.cpp @@ -18,7 +18,7 @@ #include "COM_BrightnessOperation.h" -BrightnessOperation::BrightnessOperation() : NodeOperation() +BrightnessOperation::BrightnessOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp index ecd61e95f43..115d415a8f8 100644 --- a/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateMeanOperation.cpp @@ -22,7 +22,7 @@ #include "IMB_colormanagement.h" -CalculateMeanOperation::CalculateMeanOperation() : NodeOperation() +CalculateMeanOperation::CalculateMeanOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp index 059040d6f05..476626ffcb6 100644 --- a/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp +++ b/source/blender/compositor/operations/COM_CalculateStandardDeviationOperation.cpp @@ -23,7 +23,6 @@ #include "IMB_colormanagement.h" CalculateStandardDeviationOperation::CalculateStandardDeviationOperation() - : CalculateMeanOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp index ddbc400777f..b7ee3ad6de3 100644 --- a/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp +++ b/source/blender/compositor/operations/COM_ChangeHSVOperation.cpp @@ -18,7 +18,7 @@ #include "COM_ChangeHSVOperation.h" -ChangeHSVOperation::ChangeHSVOperation() : NodeOperation() +ChangeHSVOperation::ChangeHSVOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp index cbd46ea71f8..8dcee8c6070 100644 --- a/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChannelMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_ChannelMatteOperation.h" #include "BLI_math.h" -ChannelMatteOperation::ChannelMatteOperation() : NodeOperation() +ChannelMatteOperation::ChannelMatteOperation() { addInputSocket(COM_DT_COLOR); addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp index 62dc74d2092..c55f434801d 100644 --- a/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ChromaMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_ChromaMatteOperation.h" #include "BLI_math.h" -ChromaMatteOperation::ChromaMatteOperation() : NodeOperation() +ChromaMatteOperation::ChromaMatteOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp index a515b9a6a67..91418c47665 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceASCCDLOperation.cpp @@ -31,7 +31,7 @@ inline float colorbalance_cdl(float in, float offset, float power, float slope) return powf(x, power); } -ColorBalanceASCCDLOperation::ColorBalanceASCCDLOperation() : NodeOperation() +ColorBalanceASCCDLOperation::ColorBalanceASCCDLOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp index 1578a805d1e..849540db1fc 100644 --- a/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorBalanceLGGOperation.cpp @@ -36,7 +36,7 @@ inline float colorbalance_lgg(float in, float lift_lgg, float gamma_inv, float g return powf(srgb_to_linearrgb(x), gamma_inv); } -ColorBalanceLGGOperation::ColorBalanceLGGOperation() : NodeOperation() +ColorBalanceLGGOperation::ColorBalanceLGGOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp index 893c052831c..d99444344bd 100644 --- a/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCorrectionOperation.cpp @@ -21,7 +21,7 @@ #include "IMB_colormanagement.h" -ColorCorrectionOperation::ColorCorrectionOperation() : NodeOperation() +ColorCorrectionOperation::ColorCorrectionOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp index 9d514c872f7..8bdaa8ec28b 100644 --- a/source/blender/compositor/operations/COM_ColorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorCurveOperation.cpp @@ -22,7 +22,7 @@ #include "MEM_guardedalloc.h" -ColorCurveOperation::ColorCurveOperation() : CurveBaseOperation() +ColorCurveOperation::ColorCurveOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -98,7 +98,7 @@ void ColorCurveOperation::deinitExecution() // Constant level curve mapping -ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation() : CurveBaseOperation() +ConstantLevelColorCurveOperation::ConstantLevelColorCurveOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp index 90b7f4a63b5..e3aa3aef5a4 100644 --- a/source/blender/compositor/operations/COM_ColorMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_ColorMatteOperation.h" #include "BLI_math.h" -ColorMatteOperation::ColorMatteOperation() : NodeOperation() +ColorMatteOperation::ColorMatteOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorRampOperation.cpp b/source/blender/compositor/operations/COM_ColorRampOperation.cpp index 95e0bd2d82b..e7f5ca1af5e 100644 --- a/source/blender/compositor/operations/COM_ColorRampOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorRampOperation.cpp @@ -20,7 +20,7 @@ #include "BKE_colorband.h" -ColorRampOperation::ColorRampOperation() : NodeOperation() +ColorRampOperation::ColorRampOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp index 99ab6105934..4356eb4b745 100644 --- a/source/blender/compositor/operations/COM_ColorSpillOperation.cpp +++ b/source/blender/compositor/operations/COM_ColorSpillOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #define AVG(a, b) ((a + b) / 2) -ColorSpillOperation::ColorSpillOperation() : NodeOperation() +ColorSpillOperation::ColorSpillOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_CompositorOperation.cpp b/source/blender/compositor/operations/COM_CompositorOperation.cpp index 8d55fe53aa7..63e7817606f 100644 --- a/source/blender/compositor/operations/COM_CompositorOperation.cpp +++ b/source/blender/compositor/operations/COM_CompositorOperation.cpp @@ -32,7 +32,7 @@ #include "PIL_time.h" -CompositorOperation::CompositorOperation() : NodeOperation() +CompositorOperation::CompositorOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp index 6a4c5db856c..39143aaf3b8 100644 --- a/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertColorProfileOperation.cpp @@ -20,7 +20,7 @@ #include "IMB_imbuf.h" -ConvertColorProfileOperation::ConvertColorProfileOperation() : NodeOperation() +ConvertColorProfileOperation::ConvertColorProfileOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 1a1ea794d24..56c4fb44d4f 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -21,7 +21,7 @@ #include "BLI_math.h" #include "DNA_camera_types.h" -ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation() : NodeOperation() +ConvertDepthToRadiusOperation::ConvertDepthToRadiusOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ConvertOperation.cpp b/source/blender/compositor/operations/COM_ConvertOperation.cpp index 0bd3f5b8796..dae4a9f1bab 100644 --- a/source/blender/compositor/operations/COM_ConvertOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertOperation.cpp @@ -397,7 +397,7 @@ void ConvertStraightToPremulOperation::executePixelSampled(float output[4], /* ******** Separate Channels ******** */ -SeparateChannelOperation::SeparateChannelOperation() : NodeOperation() +SeparateChannelOperation::SeparateChannelOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_VALUE); @@ -425,7 +425,7 @@ void SeparateChannelOperation::executePixelSampled(float output[4], /* ******** Combine Channels ******** */ -CombineChannelsOperation::CombineChannelsOperation() : NodeOperation() +CombineChannelsOperation::CombineChannelsOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp index 1439c7abb45..1932098fd30 100644 --- a/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionEdgeFilterOperation.cpp @@ -19,7 +19,7 @@ #include "COM_ConvolutionEdgeFilterOperation.h" #include "BLI_math.h" -ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() : ConvolutionFilterOperation() +ConvolutionEdgeFilterOperation::ConvolutionEdgeFilterOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp index 3f47bfda618..fabde28d7a2 100644 --- a/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvolutionFilterOperation.cpp @@ -22,7 +22,7 @@ #include "MEM_guardedalloc.h" -ConvolutionFilterOperation::ConvolutionFilterOperation() : NodeOperation() +ConvolutionFilterOperation::ConvolutionFilterOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_CropOperation.cpp b/source/blender/compositor/operations/COM_CropOperation.cpp index 625490dd3ab..3dda1a94989 100644 --- a/source/blender/compositor/operations/COM_CropOperation.cpp +++ b/source/blender/compositor/operations/COM_CropOperation.cpp @@ -19,7 +19,7 @@ #include "COM_CropOperation.h" #include "BLI_math.h" -CropBaseOperation::CropBaseOperation() : NodeOperation() +CropBaseOperation::CropBaseOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp index 085db6a9dea..07466cdeccd 100644 --- a/source/blender/compositor/operations/COM_CryptomatteOperation.cpp +++ b/source/blender/compositor/operations/COM_CryptomatteOperation.cpp @@ -18,7 +18,7 @@ #include "COM_CryptomatteOperation.h" -CryptomatteOperation::CryptomatteOperation(size_t num_inputs) : NodeOperation() +CryptomatteOperation::CryptomatteOperation(size_t num_inputs) { for (size_t i = 0; i < num_inputs; i++) { this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp index da62928ce7f..5cfea97475a 100644 --- a/source/blender/compositor/operations/COM_CurveBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_CurveBaseOperation.cpp @@ -20,7 +20,7 @@ #include "BKE_colortools.h" -CurveBaseOperation::CurveBaseOperation() : NodeOperation() +CurveBaseOperation::CurveBaseOperation() { this->m_curveMapping = NULL; } diff --git a/source/blender/compositor/operations/COM_DenoiseOperation.cpp b/source/blender/compositor/operations/COM_DenoiseOperation.cpp index 4087056a79d..97e2dba5e18 100644 --- a/source/blender/compositor/operations/COM_DenoiseOperation.cpp +++ b/source/blender/compositor/operations/COM_DenoiseOperation.cpp @@ -26,7 +26,7 @@ static pthread_mutex_t oidn_lock = BLI_MUTEX_INITIALIZER; #endif #include <iostream> -DenoiseOperation::DenoiseOperation() : SingleThreadedOperation() +DenoiseOperation::DenoiseOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_DespeckleOperation.cpp b/source/blender/compositor/operations/COM_DespeckleOperation.cpp index 9b8d72da26d..5d8481562ab 100644 --- a/source/blender/compositor/operations/COM_DespeckleOperation.cpp +++ b/source/blender/compositor/operations/COM_DespeckleOperation.cpp @@ -22,7 +22,7 @@ #include "BLI_utildefines.h" -DespeckleOperation::DespeckleOperation() : NodeOperation() +DespeckleOperation::DespeckleOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp index ea3526eb7e0..92a804ec3ec 100644 --- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_DifferenceMatteOperation.h" #include "BLI_math.h" -DifferenceMatteOperation::DifferenceMatteOperation() : NodeOperation() +DifferenceMatteOperation::DifferenceMatteOperation() { addInputSocket(COM_DT_COLOR); addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp index 52bc00e9b84..0fbdb37081b 100644 --- a/source/blender/compositor/operations/COM_DilateErodeOperation.cpp +++ b/source/blender/compositor/operations/COM_DilateErodeOperation.cpp @@ -23,7 +23,7 @@ #include "MEM_guardedalloc.h" // DilateErode Distance Threshold -DilateErodeThresholdOperation::DilateErodeThresholdOperation() : NodeOperation() +DilateErodeThresholdOperation::DilateErodeThresholdOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -159,7 +159,7 @@ bool DilateErodeThresholdOperation::determineDependingAreaOfInterest( } // Dilate Distance -DilateDistanceOperation::DilateDistanceOperation() : NodeOperation() +DilateDistanceOperation::DilateDistanceOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); @@ -317,7 +317,7 @@ void ErodeDistanceOperation::executeOpenCL(OpenCLDevice *device, } // Dilate step -DilateStepOperation::DilateStepOperation() : NodeOperation() +DilateStepOperation::DilateStepOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp index 31eb74fbc42..efe40cc8b58 100644 --- a/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_DirectionalBlurOperation.cpp @@ -23,7 +23,7 @@ #include "RE_pipeline.h" -DirectionalBlurOperation::DirectionalBlurOperation() : NodeOperation() +DirectionalBlurOperation::DirectionalBlurOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_DisplaceOperation.cpp b/source/blender/compositor/operations/COM_DisplaceOperation.cpp index 73790447216..31b4d41320f 100644 --- a/source/blender/compositor/operations/COM_DisplaceOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -DisplaceOperation::DisplaceOperation() : NodeOperation() +DisplaceOperation::DisplaceOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp index 32eb5679d9d..10d274b6fc5 100644 --- a/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp +++ b/source/blender/compositor/operations/COM_DisplaceSimpleOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -DisplaceSimpleOperation::DisplaceSimpleOperation() : NodeOperation() +DisplaceSimpleOperation::DisplaceSimpleOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp index ff337455658..23e133ad711 100644 --- a/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DistanceRGBMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_DistanceRGBMatteOperation.h" #include "BLI_math.h" -DistanceRGBMatteOperation::DistanceRGBMatteOperation() : NodeOperation() +DistanceRGBMatteOperation::DistanceRGBMatteOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp index 6ad1a7e440a..f333cc1ecd9 100644 --- a/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_DistanceYCCMatteOperation.cpp @@ -19,7 +19,7 @@ #include "COM_DistanceYCCMatteOperation.h" #include "BLI_math.h" -DistanceYCCMatteOperation::DistanceYCCMatteOperation() : DistanceRGBMatteOperation() +DistanceYCCMatteOperation::DistanceYCCMatteOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_DotproductOperation.cpp b/source/blender/compositor/operations/COM_DotproductOperation.cpp index da6ce510a25..263a7060a49 100644 --- a/source/blender/compositor/operations/COM_DotproductOperation.cpp +++ b/source/blender/compositor/operations/COM_DotproductOperation.cpp @@ -18,7 +18,7 @@ #include "COM_DotproductOperation.h" -DotproductOperation::DotproductOperation() : NodeOperation() +DotproductOperation::DotproductOperation() { this->addInputSocket(COM_DT_VECTOR); this->addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp index 95ccb462ade..de60e53d3d0 100644 --- a/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_DoubleEdgeMaskOperation.cpp @@ -1306,7 +1306,7 @@ void DoubleEdgeMaskOperation::doDoubleEdgeMask(float *imask, float *omask, float } } -DoubleEdgeMaskOperation::DoubleEdgeMaskOperation() : NodeOperation() +DoubleEdgeMaskOperation::DoubleEdgeMaskOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp index 0dc42b3457f..1dc1b0e2be6 100644 --- a/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_EllipseMaskOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #include "DNA_node_types.h" -EllipseMaskOperation::EllipseMaskOperation() : NodeOperation() +EllipseMaskOperation::EllipseMaskOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 0ccb959712f..0387f495f0c 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -256,7 +256,7 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, } /// -FastGaussianBlurValueOperation::FastGaussianBlurValueOperation() : NodeOperation() +FastGaussianBlurValueOperation::FastGaussianBlurValueOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_FlipOperation.cpp b/source/blender/compositor/operations/COM_FlipOperation.cpp index 57b686986b7..f248133d389 100644 --- a/source/blender/compositor/operations/COM_FlipOperation.cpp +++ b/source/blender/compositor/operations/COM_FlipOperation.cpp @@ -18,7 +18,7 @@ #include "COM_FlipOperation.h" -FlipOperation::FlipOperation() : NodeOperation() +FlipOperation::FlipOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp index 36272c05774..a333ca18fc2 100644 --- a/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaCorrectOperation.cpp @@ -19,7 +19,7 @@ #include "COM_GammaCorrectOperation.h" #include "BLI_math.h" -GammaCorrectOperation::GammaCorrectOperation() : NodeOperation() +GammaCorrectOperation::GammaCorrectOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); @@ -61,7 +61,7 @@ void GammaCorrectOperation::deinitExecution() this->m_inputProgram = NULL; } -GammaUncorrectOperation::GammaUncorrectOperation() : NodeOperation() +GammaUncorrectOperation::GammaUncorrectOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_GammaOperation.cpp b/source/blender/compositor/operations/COM_GammaOperation.cpp index ee6b42c349f..af483e612f0 100644 --- a/source/blender/compositor/operations/COM_GammaOperation.cpp +++ b/source/blender/compositor/operations/COM_GammaOperation.cpp @@ -19,7 +19,7 @@ #include "COM_GammaOperation.h" #include "BLI_math.h" -GammaOperation::GammaOperation() : NodeOperation() +GammaOperation::GammaOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp index 278e65a7dfd..633b4821358 100644 --- a/source/blender/compositor/operations/COM_GlareBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareBaseOperation.cpp @@ -19,7 +19,7 @@ #include "COM_GlareBaseOperation.h" #include "BLI_math.h" -GlareBaseOperation::GlareBaseOperation() : SingleThreadedOperation() +GlareBaseOperation::GlareBaseOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp index d050d9b58a9..e61d4e8d8a7 100644 --- a/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareThresholdOperation.cpp @@ -21,7 +21,7 @@ #include "IMB_colormanagement.h" -GlareThresholdOperation::GlareThresholdOperation() : NodeOperation() +GlareThresholdOperation::GlareThresholdOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_FIT); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp index 8292413f6f1..1d9c493d52b 100644 --- a/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp +++ b/source/blender/compositor/operations/COM_HueSaturationValueCorrectOperation.cpp @@ -22,7 +22,7 @@ #include "BKE_colortools.h" -HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation() : CurveBaseOperation() +HueSaturationValueCorrectOperation::HueSaturationValueCorrectOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_IDMaskOperation.cpp b/source/blender/compositor/operations/COM_IDMaskOperation.cpp index ef321157320..8113adb9bbc 100644 --- a/source/blender/compositor/operations/COM_IDMaskOperation.cpp +++ b/source/blender/compositor/operations/COM_IDMaskOperation.cpp @@ -18,7 +18,7 @@ #include "COM_IDMaskOperation.h" -IDMaskOperation::IDMaskOperation() : NodeOperation() +IDMaskOperation::IDMaskOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ImageOperation.cpp b/source/blender/compositor/operations/COM_ImageOperation.cpp index 38d2fbf9ed4..73c560ca473 100644 --- a/source/blender/compositor/operations/COM_ImageOperation.cpp +++ b/source/blender/compositor/operations/COM_ImageOperation.cpp @@ -31,7 +31,7 @@ #include "RE_render_ext.h" #include "RE_shader_ext.h" -BaseImageOperation::BaseImageOperation() : NodeOperation() +BaseImageOperation::BaseImageOperation() { this->m_image = NULL; this->m_buffer = NULL; diff --git a/source/blender/compositor/operations/COM_InpaintOperation.cpp b/source/blender/compositor/operations/COM_InpaintOperation.cpp index 0555ee24b9b..335af3a8287 100644 --- a/source/blender/compositor/operations/COM_InpaintOperation.cpp +++ b/source/blender/compositor/operations/COM_InpaintOperation.cpp @@ -27,7 +27,7 @@ BLI_assert(x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight()) // Inpaint (simple convolve using average of known pixels) -InpaintSimpleOperation::InpaintSimpleOperation() : NodeOperation() +InpaintSimpleOperation::InpaintSimpleOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_InvertOperation.cpp b/source/blender/compositor/operations/COM_InvertOperation.cpp index bfd9d14a1ef..f0d677d3d2f 100644 --- a/source/blender/compositor/operations/COM_InvertOperation.cpp +++ b/source/blender/compositor/operations/COM_InvertOperation.cpp @@ -18,7 +18,7 @@ #include "COM_InvertOperation.h" -InvertOperation::InvertOperation() : NodeOperation() +InvertOperation::InvertOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp index 83dd90ef08b..72bf86facfb 100644 --- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -KeyingBlurOperation::KeyingBlurOperation() : NodeOperation() +KeyingBlurOperation::KeyingBlurOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp index eafd1e671f8..592f116c451 100644 --- a/source/blender/compositor/operations/COM_KeyingClipOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingClipOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -KeyingClipOperation::KeyingClipOperation() : NodeOperation() +KeyingClipOperation::KeyingClipOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp index a1ba49a69b2..97eea6267b0 100644 --- a/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingDespillOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -KeyingDespillOperation::KeyingDespillOperation() : NodeOperation() +KeyingDespillOperation::KeyingDespillOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_KeyingOperation.cpp b/source/blender/compositor/operations/COM_KeyingOperation.cpp index 50562143ce6..dfc433dcfc6 100644 --- a/source/blender/compositor/operations/COM_KeyingOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingOperation.cpp @@ -39,7 +39,7 @@ static float get_pixel_saturation(const float pixelColor[4], return (pixelColor[primary_channel] - val) * fabsf(1.0f - val); } -KeyingOperation::KeyingOperation() : NodeOperation() +KeyingOperation::KeyingOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp index 082091411fb..36093a931d0 100644 --- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp +++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp @@ -30,7 +30,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -KeyingScreenOperation::KeyingScreenOperation() : NodeOperation() +KeyingScreenOperation::KeyingScreenOperation() { this->addOutputSocket(COM_DT_COLOR); this->m_movieClip = NULL; diff --git a/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp new file mode 100644 index 00000000000..8e501838d7b --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.cpp @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +#include "COM_KeyingSetAlphaOperation.h" + +KeyingSetAlphaOperation::KeyingSetAlphaOperation() +{ + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_VALUE); + this->addOutputSocket(COM_DT_COLOR); + + this->m_inputColor = NULL; + this->m_inputAlpha = NULL; +} + +void KeyingSetAlphaOperation::initExecution() +{ + this->m_inputColor = getInputSocketReader(0); + this->m_inputAlpha = getInputSocketReader(1); +} + +void KeyingSetAlphaOperation::executePixelSampled(float output[4], + float x, + float y, + PixelSampler sampler) +{ + float color_input[4]; + float alpha_input[4]; + + this->m_inputColor->readSampled(color_input, x, y, sampler); + this->m_inputAlpha->readSampled(alpha_input, x, y, sampler); + + mul_v4_v4fl(output, color_input, alpha_input[0]); +} + +void KeyingSetAlphaOperation::deinitExecution() +{ + this->m_inputColor = NULL; + this->m_inputAlpha = NULL; +} diff --git a/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h new file mode 100644 index 00000000000..b786240f215 --- /dev/null +++ b/source/blender/compositor/operations/COM_KeyingSetAlphaOperation.h @@ -0,0 +1,39 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2020, Blender Foundation. + */ + +#pragma once + +#include "COM_NodeOperation.h" + +/** + * Operation which is used by keying node to modify image's alpha channels. + * It keeps color properly pre-multiplied. + */ +class KeyingSetAlphaOperation : public NodeOperation { + private: + SocketReader *m_inputColor; + SocketReader *m_inputAlpha; + + public: + KeyingSetAlphaOperation(); + + void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + + void initExecution(); + void deinitExecution(); +}; diff --git a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp index 936ac00a0e8..50de043b641 100644 --- a/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp +++ b/source/blender/compositor/operations/COM_LuminanceMatteOperation.cpp @@ -21,7 +21,7 @@ #include "IMB_colormanagement.h" -LuminanceMatteOperation::LuminanceMatteOperation() : NodeOperation() +LuminanceMatteOperation::LuminanceMatteOperation() { addInputSocket(COM_DT_COLOR); addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_MapRangeOperation.cpp b/source/blender/compositor/operations/COM_MapRangeOperation.cpp index ff5804a63a4..e4fe6065164 100644 --- a/source/blender/compositor/operations/COM_MapRangeOperation.cpp +++ b/source/blender/compositor/operations/COM_MapRangeOperation.cpp @@ -18,7 +18,7 @@ #include "COM_MapRangeOperation.h" -MapRangeOperation::MapRangeOperation() : NodeOperation() +MapRangeOperation::MapRangeOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp index 9101b82202a..ed250bc28b6 100644 --- a/source/blender/compositor/operations/COM_MapUVOperation.cpp +++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp @@ -19,7 +19,7 @@ #include "COM_MapUVOperation.h" #include "BLI_math.h" -MapUVOperation::MapUVOperation() : NodeOperation() +MapUVOperation::MapUVOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_MapValueOperation.cpp b/source/blender/compositor/operations/COM_MapValueOperation.cpp index 45104d11210..908ad7f1317 100644 --- a/source/blender/compositor/operations/COM_MapValueOperation.cpp +++ b/source/blender/compositor/operations/COM_MapValueOperation.cpp @@ -18,7 +18,7 @@ #include "COM_MapValueOperation.h" -MapValueOperation::MapValueOperation() : NodeOperation() +MapValueOperation::MapValueOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 9fc7448ce42..7c21ee5d757 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -26,7 +26,7 @@ #include "BKE_lib_id.h" #include "BKE_mask.h" -MaskOperation::MaskOperation() : NodeOperation() +MaskOperation::MaskOperation() { this->addOutputSocket(COM_DT_VALUE); this->m_mask = NULL; diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.cpp b/source/blender/compositor/operations/COM_MathBaseOperation.cpp index 1363b75433a..c37874c7c9b 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_MathBaseOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" -MathBaseOperation::MathBaseOperation() : NodeOperation() +MathBaseOperation::MathBaseOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_MixOperation.cpp b/source/blender/compositor/operations/COM_MixOperation.cpp index 371da20044f..376e27b1f30 100644 --- a/source/blender/compositor/operations/COM_MixOperation.cpp +++ b/source/blender/compositor/operations/COM_MixOperation.cpp @@ -22,7 +22,7 @@ /* ******** Mix Base Operation ******** */ -MixBaseOperation::MixBaseOperation() : NodeOperation() +MixBaseOperation::MixBaseOperation() { this->addInputSocket(COM_DT_VALUE); this->addInputSocket(COM_DT_COLOR); @@ -97,7 +97,7 @@ void MixBaseOperation::deinitExecution() /* ******** Mix Add Operation ******** */ -MixAddOperation::MixAddOperation() : MixBaseOperation() +MixAddOperation::MixAddOperation() { /* pass */ } @@ -126,7 +126,7 @@ void MixAddOperation::executePixelSampled(float output[4], float x, float y, Pix /* ******** Mix Blend Operation ******** */ -MixBlendOperation::MixBlendOperation() : MixBaseOperation() +MixBlendOperation::MixBlendOperation() { /* pass */ } @@ -160,7 +160,7 @@ void MixBlendOperation::executePixelSampled(float output[4], /* ******** Mix Burn Operation ******** */ -MixColorBurnOperation::MixColorBurnOperation() : MixBaseOperation() +MixColorBurnOperation::MixColorBurnOperation() { /* pass */ } @@ -243,7 +243,7 @@ void MixColorBurnOperation::executePixelSampled(float output[4], /* ******** Mix Color Operation ******** */ -MixColorOperation::MixColorOperation() : MixBaseOperation() +MixColorOperation::MixColorOperation() { /* pass */ } @@ -288,7 +288,7 @@ void MixColorOperation::executePixelSampled(float output[4], /* ******** Mix Darken Operation ******** */ -MixDarkenOperation::MixDarkenOperation() : MixBaseOperation() +MixDarkenOperation::MixDarkenOperation() { /* pass */ } @@ -321,7 +321,7 @@ void MixDarkenOperation::executePixelSampled(float output[4], /* ******** Mix Difference Operation ******** */ -MixDifferenceOperation::MixDifferenceOperation() : MixBaseOperation() +MixDifferenceOperation::MixDifferenceOperation() { /* pass */ } @@ -354,7 +354,7 @@ void MixDifferenceOperation::executePixelSampled(float output[4], /* ******** Mix Difference Operation ******** */ -MixDivideOperation::MixDivideOperation() : MixBaseOperation() +MixDivideOperation::MixDivideOperation() { /* pass */ } @@ -404,7 +404,7 @@ void MixDivideOperation::executePixelSampled(float output[4], /* ******** Mix Dodge Operation ******** */ -MixDodgeOperation::MixDodgeOperation() : MixBaseOperation() +MixDodgeOperation::MixDodgeOperation() { /* pass */ } @@ -492,7 +492,7 @@ void MixDodgeOperation::executePixelSampled(float output[4], /* ******** Mix Glare Operation ******** */ -MixGlareOperation::MixGlareOperation() : MixBaseOperation() +MixGlareOperation::MixGlareOperation() { /* pass */ } @@ -533,7 +533,7 @@ void MixGlareOperation::executePixelSampled(float output[4], /* ******** Mix Hue Operation ******** */ -MixHueOperation::MixHueOperation() : MixBaseOperation() +MixHueOperation::MixHueOperation() { /* pass */ } @@ -575,7 +575,7 @@ void MixHueOperation::executePixelSampled(float output[4], float x, float y, Pix /* ******** Mix Lighten Operation ******** */ -MixLightenOperation::MixLightenOperation() : MixBaseOperation() +MixLightenOperation::MixLightenOperation() { /* pass */ } @@ -626,7 +626,7 @@ void MixLightenOperation::executePixelSampled(float output[4], /* ******** Mix Linear Light Operation ******** */ -MixLinearLightOperation::MixLinearLightOperation() : MixBaseOperation() +MixLinearLightOperation::MixLinearLightOperation() { /* pass */ } @@ -674,7 +674,7 @@ void MixLinearLightOperation::executePixelSampled(float output[4], /* ******** Mix Multiply Operation ******** */ -MixMultiplyOperation::MixMultiplyOperation() : MixBaseOperation() +MixMultiplyOperation::MixMultiplyOperation() { /* pass */ } @@ -707,7 +707,7 @@ void MixMultiplyOperation::executePixelSampled(float output[4], /* ******** Mix Ovelray Operation ******** */ -MixOverlayOperation::MixOverlayOperation() : MixBaseOperation() +MixOverlayOperation::MixOverlayOperation() { /* pass */ } @@ -757,7 +757,7 @@ void MixOverlayOperation::executePixelSampled(float output[4], /* ******** Mix Saturation Operation ******** */ -MixSaturationOperation::MixSaturationOperation() : MixBaseOperation() +MixSaturationOperation::MixSaturationOperation() { /* pass */ } @@ -799,7 +799,7 @@ void MixSaturationOperation::executePixelSampled(float output[4], /* ******** Mix Screen Operation ******** */ -MixScreenOperation::MixScreenOperation() : MixBaseOperation() +MixScreenOperation::MixScreenOperation() { /* pass */ } @@ -833,7 +833,7 @@ void MixScreenOperation::executePixelSampled(float output[4], /* ******** Mix Soft Light Operation ******** */ -MixSoftLightOperation::MixSoftLightOperation() : MixBaseOperation() +MixSoftLightOperation::MixSoftLightOperation() { /* pass */ } @@ -879,7 +879,7 @@ void MixSoftLightOperation::executePixelSampled(float output[4], /* ******** Mix Subtract Operation ******** */ -MixSubtractOperation::MixSubtractOperation() : MixBaseOperation() +MixSubtractOperation::MixSubtractOperation() { /* pass */ } @@ -911,7 +911,7 @@ void MixSubtractOperation::executePixelSampled(float output[4], /* ******** Mix Value Operation ******** */ -MixValueOperation::MixValueOperation() : MixBaseOperation() +MixValueOperation::MixValueOperation() { /* pass */ } diff --git a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp index 34773a1e4f8..f4e860316b3 100644 --- a/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipAttributeOperation.cpp @@ -21,7 +21,7 @@ #include "BKE_movieclip.h" #include "BKE_tracking.h" -MovieClipAttributeOperation::MovieClipAttributeOperation() : NodeOperation() +MovieClipAttributeOperation::MovieClipAttributeOperation() { this->addOutputSocket(COM_DT_VALUE); this->m_framenumber = 0; diff --git a/source/blender/compositor/operations/COM_MovieClipOperation.cpp b/source/blender/compositor/operations/COM_MovieClipOperation.cpp index 17794ae879e..9d1779b3573 100644 --- a/source/blender/compositor/operations/COM_MovieClipOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieClipOperation.cpp @@ -26,7 +26,7 @@ #include "IMB_imbuf.h" -MovieClipBaseOperation::MovieClipBaseOperation() : NodeOperation() +MovieClipBaseOperation::MovieClipBaseOperation() { this->m_movieClip = NULL; this->m_movieClipBuffer = NULL; diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 67491d51547..5accf9a2dc3 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -23,7 +23,7 @@ #include "BLI_linklist.h" -MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation() +MovieDistortionOperation::MovieDistortionOperation(bool distortion) { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp index 8878b05ade7..952225d5fb7 100644 --- a/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp +++ b/source/blender/compositor/operations/COM_MultilayerImageOperation.cpp @@ -21,7 +21,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -MultilayerBaseOperation::MultilayerBaseOperation(int passindex, int view) : BaseImageOperation() +MultilayerBaseOperation::MultilayerBaseOperation(int passindex, int view) { this->m_passId = passindex; this->m_view = view; diff --git a/source/blender/compositor/operations/COM_NormalizeOperation.cpp b/source/blender/compositor/operations/COM_NormalizeOperation.cpp index 55faa480b83..1e7986c6009 100644 --- a/source/blender/compositor/operations/COM_NormalizeOperation.cpp +++ b/source/blender/compositor/operations/COM_NormalizeOperation.cpp @@ -18,7 +18,7 @@ #include "COM_NormalizeOperation.h" -NormalizeOperation::NormalizeOperation() : NodeOperation() +NormalizeOperation::NormalizeOperation() { this->addInputSocket(COM_DT_VALUE); this->addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_PixelateOperation.cpp b/source/blender/compositor/operations/COM_PixelateOperation.cpp index 18e691d3c34..01cd7fcfd97 100644 --- a/source/blender/compositor/operations/COM_PixelateOperation.cpp +++ b/source/blender/compositor/operations/COM_PixelateOperation.cpp @@ -18,7 +18,7 @@ #include "COM_PixelateOperation.h" -PixelateOperation::PixelateOperation(DataType datatype) : NodeOperation() +PixelateOperation::PixelateOperation(DataType datatype) { this->addInputSocket(datatype); this->addOutputSocket(datatype); diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp index eae576ceb56..d4f2ca7bbe8 100644 --- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp @@ -87,8 +87,7 @@ static void readCornersFromSockets(rcti *rect, SocketReader *readers[4], float c /* ******** PlaneCornerPinMaskOperation ******** */ -PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() - : PlaneDistortMaskOperation(), m_corners_ready(false) +PlaneCornerPinMaskOperation::PlaneCornerPinMaskOperation() : m_corners_ready(false) { addInputSocket(COM_DT_VECTOR); addInputSocket(COM_DT_VECTOR); @@ -152,8 +151,7 @@ void PlaneCornerPinMaskOperation::determineResolution(unsigned int resolution[2] /* ******** PlaneCornerPinWarpImageOperation ******** */ -PlaneCornerPinWarpImageOperation::PlaneCornerPinWarpImageOperation() - : PlaneDistortWarpImageOperation(), m_corners_ready(false) +PlaneCornerPinWarpImageOperation::PlaneCornerPinWarpImageOperation() : m_corners_ready(false) { addInputSocket(COM_DT_VECTOR); addInputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp index e7574e80c2f..0f6d5d0d4d7 100644 --- a/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp +++ b/source/blender/compositor/operations/COM_PlaneDistortCommonOperation.cpp @@ -44,7 +44,7 @@ BLI_INLINE void warpCoord(float x, float y, float matrix[3][3], float uv[2], flo deriv[1][1] = (matrix[1][1] - matrix[1][2] * uv[1]) / vec[2]; } -PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() : NodeOperation() +PlaneDistortWarpImageOperation::PlaneDistortWarpImageOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); @@ -145,7 +145,7 @@ bool PlaneDistortWarpImageOperation::determineDependingAreaOfInterest( /* ******** PlaneDistort Mask ******** */ -PlaneDistortMaskOperation::PlaneDistortMaskOperation() : NodeOperation() +PlaneDistortMaskOperation::PlaneDistortMaskOperation() { addOutputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.h b/source/blender/compositor/operations/COM_PlaneTrackOperation.h index fc0a0873d5f..fc325c7db7d 100644 --- a/source/blender/compositor/operations/COM_PlaneTrackOperation.h +++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.h @@ -64,7 +64,7 @@ class PlaneTrackCommon { class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTrackCommon { public: - PlaneTrackMaskOperation() : PlaneDistortMaskOperation(), PlaneTrackCommon() + PlaneTrackMaskOperation() { } @@ -82,7 +82,7 @@ class PlaneTrackMaskOperation : public PlaneDistortMaskOperation, public PlaneTr class PlaneTrackWarpImageOperation : public PlaneDistortWarpImageOperation, public PlaneTrackCommon { public: - PlaneTrackWarpImageOperation() : PlaneDistortWarpImageOperation(), PlaneTrackCommon() + PlaneTrackWarpImageOperation() : PlaneTrackCommon() { } diff --git a/source/blender/compositor/operations/COM_PreviewOperation.cpp b/source/blender/compositor/operations/COM_PreviewOperation.cpp index 43d20271141..46ac466fd19 100644 --- a/source/blender/compositor/operations/COM_PreviewOperation.cpp +++ b/source/blender/compositor/operations/COM_PreviewOperation.cpp @@ -35,7 +35,7 @@ PreviewOperation::PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings) - : NodeOperation() + { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->m_preview = NULL; diff --git a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp index 32933f1b966..921b7ed474c 100644 --- a/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ProjectorLensDistortionOperation.cpp @@ -20,7 +20,7 @@ #include "BLI_math.h" #include "BLI_utildefines.h" -ProjectorLensDistortionOperation::ProjectorLensDistortionOperation() : NodeOperation() +ProjectorLensDistortionOperation::ProjectorLensDistortionOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp index 99cc9f5dd01..9139ac200c8 100644 --- a/source/blender/compositor/operations/COM_ReadBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_ReadBufferOperation.cpp @@ -20,7 +20,7 @@ #include "COM_WriteBufferOperation.h" #include "COM_defines.h" -ReadBufferOperation::ReadBufferOperation(DataType datatype) : NodeOperation() +ReadBufferOperation::ReadBufferOperation(DataType datatype) { this->addOutputSocket(datatype); this->m_single_value = false; diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp index c8a68c70c4d..b7b1da1bb89 100644 --- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp +++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp @@ -29,7 +29,7 @@ /* ******** Render Layers Base Prog ******** */ RenderLayersProg::RenderLayersProg(const char *passName, DataType type, int elementsize) - : NodeOperation(), m_passName(passName) + : m_passName(passName) { this->setScene(NULL); this->m_inputBuffer = NULL; diff --git a/source/blender/compositor/operations/COM_RotateOperation.cpp b/source/blender/compositor/operations/COM_RotateOperation.cpp index 3ccf36cec2c..e25d5af1aed 100644 --- a/source/blender/compositor/operations/COM_RotateOperation.cpp +++ b/source/blender/compositor/operations/COM_RotateOperation.cpp @@ -19,7 +19,7 @@ #include "COM_RotateOperation.h" #include "BLI_math.h" -RotateOperation::RotateOperation() : NodeOperation() +RotateOperation::RotateOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index b7731a34c91..4b92be65b3e 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -24,7 +24,7 @@ #include "PIL_time.h" -ScreenLensDistortionOperation::ScreenLensDistortionOperation() : NodeOperation() +ScreenLensDistortionOperation::ScreenLensDistortionOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp index 68c165411b2..cc4e4a562db 100644 --- a/source/blender/compositor/operations/COM_SetAlphaOperation.cpp +++ b/source/blender/compositor/operations/COM_SetAlphaOperation.cpp @@ -18,7 +18,7 @@ #include "COM_SetAlphaOperation.h" -SetAlphaOperation::SetAlphaOperation() : NodeOperation() +SetAlphaOperation::SetAlphaOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_SetColorOperation.cpp b/source/blender/compositor/operations/COM_SetColorOperation.cpp index 58bfcb44afd..ffbc20fde9c 100644 --- a/source/blender/compositor/operations/COM_SetColorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetColorOperation.cpp @@ -18,7 +18,7 @@ #include "COM_SetColorOperation.h" -SetColorOperation::SetColorOperation() : NodeOperation() +SetColorOperation::SetColorOperation() { this->addOutputSocket(COM_DT_COLOR); } diff --git a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp index f3b3ed217f9..3c6a5104352 100644 --- a/source/blender/compositor/operations/COM_SetSamplerOperation.cpp +++ b/source/blender/compositor/operations/COM_SetSamplerOperation.cpp @@ -18,7 +18,7 @@ #include "COM_SetSamplerOperation.h" -SetSamplerOperation::SetSamplerOperation() : NodeOperation() +SetSamplerOperation::SetSamplerOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_SetValueOperation.cpp b/source/blender/compositor/operations/COM_SetValueOperation.cpp index e49b6941f49..d72a2dfe23d 100644 --- a/source/blender/compositor/operations/COM_SetValueOperation.cpp +++ b/source/blender/compositor/operations/COM_SetValueOperation.cpp @@ -18,7 +18,7 @@ #include "COM_SetValueOperation.h" -SetValueOperation::SetValueOperation() : NodeOperation() +SetValueOperation::SetValueOperation() { this->addOutputSocket(COM_DT_VALUE); } diff --git a/source/blender/compositor/operations/COM_SetVectorOperation.cpp b/source/blender/compositor/operations/COM_SetVectorOperation.cpp index d3a0329c9b9..a0341dbc4df 100644 --- a/source/blender/compositor/operations/COM_SetVectorOperation.cpp +++ b/source/blender/compositor/operations/COM_SetVectorOperation.cpp @@ -19,7 +19,7 @@ #include "COM_SetVectorOperation.h" #include "COM_defines.h" -SetVectorOperation::SetVectorOperation() : NodeOperation() +SetVectorOperation::SetVectorOperation() { this->addOutputSocket(COM_DT_VECTOR); } diff --git a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp index 2d54d6ae45d..baeb2f44303 100644 --- a/source/blender/compositor/operations/COM_SocketProxyOperation.cpp +++ b/source/blender/compositor/operations/COM_SocketProxyOperation.cpp @@ -19,7 +19,7 @@ #include "COM_SocketProxyOperation.h" SocketProxyOperation::SocketProxyOperation(DataType type, bool use_conversion) - : NodeOperation(), m_use_conversion(use_conversion) + : m_use_conversion(use_conversion) { this->addInputSocket(type); this->addOutputSocket(type); diff --git a/source/blender/compositor/operations/COM_SplitOperation.cpp b/source/blender/compositor/operations/COM_SplitOperation.cpp index 3eddf033cf4..cace3b40b44 100644 --- a/source/blender/compositor/operations/COM_SplitOperation.cpp +++ b/source/blender/compositor/operations/COM_SplitOperation.cpp @@ -27,7 +27,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -SplitOperation::SplitOperation() : NodeOperation() +SplitOperation::SplitOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp index 4a7139537c1..ef3c0700119 100644 --- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp +++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp @@ -19,7 +19,7 @@ #include "COM_SunBeamsOperation.h" -SunBeamsOperation::SunBeamsOperation() : NodeOperation() +SunBeamsOperation::SunBeamsOperation() { this->addInputSocket(COM_DT_COLOR); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp index 07316280bbc..5a8c40d8c8c 100644 --- a/source/blender/compositor/operations/COM_TextureOperation.cpp +++ b/source/blender/compositor/operations/COM_TextureOperation.cpp @@ -25,7 +25,7 @@ #include "BLI_listbase.h" #include "BLI_threads.h" -TextureBaseOperation::TextureBaseOperation() : NodeOperation() +TextureBaseOperation::TextureBaseOperation() { this->addInputSocket(COM_DT_VECTOR); // offset this->addInputSocket(COM_DT_VECTOR); // size diff --git a/source/blender/compositor/operations/COM_TonemapOperation.cpp b/source/blender/compositor/operations/COM_TonemapOperation.cpp index 59354ff7581..2e330e287b2 100644 --- a/source/blender/compositor/operations/COM_TonemapOperation.cpp +++ b/source/blender/compositor/operations/COM_TonemapOperation.cpp @@ -22,7 +22,7 @@ #include "IMB_colormanagement.h" -TonemapOperation::TonemapOperation() : NodeOperation() +TonemapOperation::TonemapOperation() { this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp index 5c4f3b99f58..eca87a7b5a3 100644 --- a/source/blender/compositor/operations/COM_TrackPositionOperation.cpp +++ b/source/blender/compositor/operations/COM_TrackPositionOperation.cpp @@ -28,7 +28,7 @@ #include "BKE_node.h" #include "BKE_tracking.h" -TrackPositionOperation::TrackPositionOperation() : NodeOperation() +TrackPositionOperation::TrackPositionOperation() { this->addOutputSocket(COM_DT_VALUE); this->m_movieClip = NULL; diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp index b45e6a2b6a1..e92d1034e25 100644 --- a/source/blender/compositor/operations/COM_TranslateOperation.cpp +++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp @@ -18,7 +18,7 @@ #include "COM_TranslateOperation.h" -TranslateOperation::TranslateOperation() : NodeOperation() +TranslateOperation::TranslateOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 057dc553f7f..afc318a0c5b 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -22,7 +22,7 @@ #include "RE_pipeline.h" -VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() : NodeOperation() +VariableSizeBokehBlurOperation::VariableSizeBokehBlurOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_COLOR, COM_SC_NO_RESIZE); // do not resize the bokeh image. @@ -276,7 +276,7 @@ bool VariableSizeBokehBlurOperation::determineDependingAreaOfInterest( #ifdef COM_DEFOCUS_SEARCH // InverseSearchRadiusOperation -InverseSearchRadiusOperation::InverseSearchRadiusOperation() : NodeOperation() +InverseSearchRadiusOperation::InverseSearchRadiusOperation() { this->addInputSocket(COM_DT_VALUE, COM_SC_NO_RESIZE); // radius this->addOutputSocket(COM_DT_COLOR); diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp index 1e392b1f991..4f41a60f3c3 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cpp @@ -43,7 +43,7 @@ void zbuf_free_span(ZSpan *zspan); void antialias_tagbuf(int xsize, int ysize, char *rectmove); /* VectorBlurOperation */ -VectorBlurOperation::VectorBlurOperation() : NodeOperation() +VectorBlurOperation::VectorBlurOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); // ZBUF diff --git a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp index 61312355a39..a78a8c47ea3 100644 --- a/source/blender/compositor/operations/COM_VectorCurveOperation.cpp +++ b/source/blender/compositor/operations/COM_VectorCurveOperation.cpp @@ -20,7 +20,7 @@ #include "BKE_colortools.h" -VectorCurveOperation::VectorCurveOperation() : CurveBaseOperation() +VectorCurveOperation::VectorCurveOperation() { this->addInputSocket(COM_DT_VECTOR); this->addOutputSocket(COM_DT_VECTOR); diff --git a/source/blender/compositor/operations/COM_ViewerOperation.cpp b/source/blender/compositor/operations/COM_ViewerOperation.cpp index e1d891559a7..254d6975bee 100644 --- a/source/blender/compositor/operations/COM_ViewerOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerOperation.cpp @@ -32,7 +32,7 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -ViewerOperation::ViewerOperation() : NodeOperation() +ViewerOperation::ViewerOperation() { this->setImage(NULL); this->setImageUser(NULL); diff --git a/source/blender/compositor/operations/COM_WrapOperation.cpp b/source/blender/compositor/operations/COM_WrapOperation.cpp index 952f69c3787..7f7c1b7b639 100644 --- a/source/blender/compositor/operations/COM_WrapOperation.cpp +++ b/source/blender/compositor/operations/COM_WrapOperation.cpp @@ -89,7 +89,7 @@ bool WrapOperation::determineDependingAreaOfInterest(rcti *input, newInput.ymin = input->ymin; newInput.ymax = input->ymax; - if (m_wrappingType == CMP_NODE_WRAP_X || m_wrappingType == CMP_NODE_WRAP_XY) { + if (ELEM(m_wrappingType, CMP_NODE_WRAP_X, CMP_NODE_WRAP_XY)) { // wrap only on the x-axis if tile is wrapping newInput.xmin = getWrappedOriginalXPos(input->xmin); newInput.xmax = roundf(getWrappedOriginalXPos(input->xmax)); @@ -98,7 +98,7 @@ bool WrapOperation::determineDependingAreaOfInterest(rcti *input, newInput.xmax = this->getWidth(); } } - if (m_wrappingType == CMP_NODE_WRAP_Y || m_wrappingType == CMP_NODE_WRAP_XY) { + if (ELEM(m_wrappingType, CMP_NODE_WRAP_Y, CMP_NODE_WRAP_XY)) { // wrap only on the y-axis if tile is wrapping newInput.ymin = getWrappedOriginalYPos(input->ymin); newInput.ymax = roundf(getWrappedOriginalYPos(input->ymax)); diff --git a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp index 640e3e3d381..883dd48ccfe 100644 --- a/source/blender/compositor/operations/COM_WriteBufferOperation.cpp +++ b/source/blender/compositor/operations/COM_WriteBufferOperation.cpp @@ -21,7 +21,7 @@ #include "COM_defines.h" #include <stdio.h> -WriteBufferOperation::WriteBufferOperation(DataType datatype) : NodeOperation() +WriteBufferOperation::WriteBufferOperation(DataType datatype) { this->addInputSocket(datatype); this->m_memoryProxy = new MemoryProxy(datatype); diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 767280e2cd2..935272e0dbe 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -19,7 +19,7 @@ #include "COM_ZCombineOperation.h" #include "BLI_utildefines.h" -ZCombineOperation::ZCombineOperation() : NodeOperation() +ZCombineOperation::ZCombineOperation() { this->addInputSocket(COM_DT_COLOR); this->addInputSocket(COM_DT_VALUE); @@ -95,7 +95,7 @@ void ZCombineOperation::deinitExecution() } // MASK combine -ZCombineMaskOperation::ZCombineMaskOperation() : NodeOperation() +ZCombineMaskOperation::ZCombineMaskOperation() { this->addInputSocket(COM_DT_VALUE); // mask this->addInputSocket(COM_DT_COLOR); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 7f9a745c1a4..a04a33d8cfa 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -96,7 +96,6 @@ #include "BKE_pointcache.h" #include "BKE_rigidbody.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_shader_fx.h" #include "BKE_simulation.h" #include "BKE_sound.h" @@ -110,6 +109,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" +#include "SEQ_sequencer.h" + #include "intern/builder/deg_builder.h" #include "intern/depsgraph.h" #include "intern/depsgraph_type.h" @@ -1199,7 +1200,7 @@ void DepsgraphNodeBuilder::build_particle_systems(Object *object, bool is_object /* Keyed particle targets. */ if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) { LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) { - if (particle_target->ob == nullptr || particle_target->ob == object) { + if (ELEM(particle_target->ob, nullptr, object)) { continue; } build_object(-1, particle_target->ob, DEG_ID_LINKED_INDIRECTLY, is_object_visible); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index bac36885dfc..40b856b1896 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -89,7 +89,6 @@ #include "BKE_particle.h" #include "BKE_pointcache.h" #include "BKE_rigidbody.h" -#include "BKE_sequencer.h" #include "BKE_shader_fx.h" #include "BKE_shrinkwrap.h" #include "BKE_sound.h" @@ -99,6 +98,8 @@ #include "RNA_access.h" #include "RNA_types.h" +#include "SEQ_sequencer.h" + #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -742,7 +743,7 @@ void DepsgraphRelationBuilder::build_object_proxy_from(Object *object) void DepsgraphRelationBuilder::build_object_proxy_group(Object *object) { - if (object->proxy_group == nullptr || object->proxy_group == object->proxy) { + if (ELEM(object->proxy_group, nullptr, object->proxy)) { return; } /* Object is local here (local in .blend file, users interacts with it). */ @@ -1853,7 +1854,7 @@ void DepsgraphRelationBuilder::build_particle_systems(Object *object) /* Keyed particle targets. */ if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) { LISTBASE_FOREACH (ParticleTarget *, particle_target, &psys->targets) { - if (particle_target->ob == nullptr || particle_target->ob == object) { + if (ELEM(particle_target->ob, nullptr, object)) { continue; } /* Make sure target object is pulled into the graph. */ @@ -2813,8 +2814,7 @@ void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) * to preserve that cache in copy-on-write, but for the time being * we allow flush to layer collections component which will ensure * that cached array of bases exists and is up-to-date. */ - if (comp_node->type == NodeType::PARAMETERS || - comp_node->type == NodeType::LAYER_COLLECTIONS) { + if (ELEM(comp_node->type, NodeType::PARAMETERS, NodeType::LAYER_COLLECTIONS)) { rel_flag &= ~RELATION_FLAG_NO_FLUSH; } /* All entry operations of each component should wait for a proper diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc index 717c8300f9b..17f364118ae 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_drivers.cc @@ -39,9 +39,7 @@ namespace blender { namespace deg { DriverDescriptor::DriverDescriptor(PointerRNA *id_ptr, FCurve *fcu) - : rna_prefix(), - rna_suffix(), - id_ptr_(id_ptr), + : id_ptr_(id_ptr), fcu_(fcu), driver_relations_needed_(false), pointer_rna_(), diff --git a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc index 18b24179edf..442537bd79a 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_rna.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_rna.cc @@ -209,8 +209,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, } } /* Final transform properties go to the Done node for the exit. */ - else if (STREQ(prop_name, "head") || STREQ(prop_name, "tail") || - STREQ(prop_name, "length") || STRPREFIX(prop_name, "matrix")) { + else if (STR_ELEM(prop_name, "head", "tail", "length") || STRPREFIX(prop_name, "matrix")) { if (source == RNAPointerSource::EXIT) { node_identifier.operation_code = OperationCode::BONE_DONE; } @@ -325,7 +324,7 @@ RNANodeIdentifier RNANodeQuery::construct_node_identifier(const PointerRNA *ptr, node_identifier.type = NodeType::GEOMETRY; return node_identifier; } - if (STREQ(prop_identifier, "hide_viewport") || STREQ(prop_identifier, "hide_render")) { + if (STR_ELEM(prop_identifier, "hide_viewport", "hide_render")) { node_identifier.type = NodeType::OBJECT_FROM_LAYER; return node_identifier; } diff --git a/source/blender/depsgraph/intern/builder/pipeline.cc b/source/blender/depsgraph/intern/builder/pipeline.cc index b13077e4792..76b6f17a243 100644 --- a/source/blender/depsgraph/intern/builder/pipeline.cc +++ b/source/blender/depsgraph/intern/builder/pipeline.cc @@ -37,8 +37,7 @@ AbstractBuilderPipeline::AbstractBuilderPipeline(::Depsgraph *graph) : deg_graph_(reinterpret_cast<Depsgraph *>(graph)), bmain_(deg_graph_->bmain), scene_(deg_graph_->scene), - view_layer_(deg_graph_->view_layer), - builder_cache_() + view_layer_(deg_graph_->view_layer) { } diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc index 868f88d8fcd..8055e65595b 100644 --- a/source/blender/depsgraph/intern/depsgraph_tag.cc +++ b/source/blender/depsgraph/intern/depsgraph_tag.cc @@ -308,7 +308,7 @@ void depsgraph_tag_component(Depsgraph *graph, void deg_graph_id_tag_legacy_compat( Main *bmain, Depsgraph *depsgraph, ID *id, IDRecalcFlag tag, eUpdateSource update_source) { - if (tag == ID_RECALC_GEOMETRY || tag == 0) { + if (ELEM(tag, ID_RECALC_GEOMETRY, 0)) { switch (GS(id->name)) { case ID_OB: { Object *object = (Object *)id; diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 477dd316768..0a92cdb2e64 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -90,9 +90,10 @@ #include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_pointcache.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" +#include "SEQ_sequencer.h" + #include "intern/builder/deg_builder.h" #include "intern/builder/deg_builder_nodes.h" #include "intern/depsgraph.h" diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index 5ccdcbec858..73e35b4c77a 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -145,8 +145,7 @@ inline void flush_handle_component_node(IDNode *id_node, * special component where we don't want all operations to be tagged. * * TODO(sergey): Make this a more generic solution. */ - if (comp_node->type != NodeType::PARTICLE_SETTINGS && - comp_node->type != NodeType::PARTICLE_SYSTEM) { + if (!ELEM(comp_node->type, NodeType::PARTICLE_SETTINGS, NodeType::PARTICLE_SYSTEM)) { for (OperationNode *op : comp_node->operations) { op->flag |= DEPSOP_FLAG_NEEDS_UPDATE; } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc index 4d79480a5ad..314254c0cf6 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_sequencer.cc @@ -28,9 +28,10 @@ #include "BLI_assert.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" +#include "SEQ_sequencer.h" + namespace blender { namespace deg { diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 8d19949adc8..53269544afa 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -137,7 +137,7 @@ void IDNode::destroy() } /* Free memory used by this CoW ID. */ - if (id_cow != id_orig && id_cow != nullptr) { + if (!ELEM(id_cow, id_orig, nullptr)) { deg_free_copy_on_write_datablock(id_cow); MEM_freeN(id_cow); id_cow = nullptr; diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index ca5c2c94b40..2d5b93f4272 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -36,6 +36,7 @@ struct ARegion; struct DRWInstanceDataList; struct Depsgraph; struct DrawEngineType; +struct GHash; struct GPUMaterial; struct GPUOffScreen; struct GPUViewport; @@ -140,6 +141,7 @@ void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph /* This is here because GPUViewport needs it */ struct DRWInstanceDataList *DRW_instance_data_list_create(void); void DRW_instance_data_list_free(struct DRWInstanceDataList *idatalist); +void DRW_uniform_attrs_pool_free(struct GHash *table); void DRW_render_context_enable(struct Render *render); void DRW_render_context_disable(struct Render *render); diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 355d156a083..7d1f40ba5d8 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -401,7 +401,7 @@ static void eevee_id_world_update(void *vedata, World *wo) EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; LightCache *lcache = stl->g_data->light_cache; - if (lcache == NULL || lcache == stl->lookdev_lightcache) { + if (ELEM(lcache, NULL, stl->lookdev_lightcache)) { /* Avoid Lookdev viewport clearing the update flag (see T67741). */ return; } diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index b7112c07cab..b773049f6f7 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -97,7 +97,7 @@ static float light_shape_power_get(const Light *la, const EEVEE_Light *evli) power *= 4.0f / M_PI; } } - else if (la->type == LA_SPOT || la->type == LA_LOCAL) { + else if (ELEM(la->type, LA_SPOT, LA_LOCAL)) { power = 1.0f / (4.0f * evli->radius * evli->radius * M_PI * M_PI); /* 1/(4*r²*Pi²) */ /* for point lights (a.k.a radius == 0.0) */ diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index 3b525ba0742..58f182ecf8d 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -881,7 +881,6 @@ void EEVEE_materials_free(void) } /* -------------------------------------------------------------------- */ - /** \name Render Passes * \{ */ diff --git a/source/blender/draw/engines/eevee/eevee_motion_blur.c b/source/blender/draw/engines/eevee/eevee_motion_blur.c index fe3705f1fbb..530becfe771 100644 --- a/source/blender/draw/engines/eevee/eevee_motion_blur.c +++ b/source/blender/draw/engines/eevee/eevee_motion_blur.c @@ -521,8 +521,7 @@ void EEVEE_motion_blur_swap_data(EEVEE_Data *vedata) case EEVEE_MOTION_DATA_MESH: if (mb_geom->batch != NULL) { for (int i = 0; i < GPU_BATCH_VBO_MAX_LEN; i++) { - if (mb_geom->batch->verts[i] == mb_geom->vbo[MB_PREV] || - mb_geom->batch->verts[i] == mb_geom->vbo[MB_NEXT]) { + if (ELEM(mb_geom->batch->verts[i], mb_geom->vbo[MB_PREV], mb_geom->vbo[MB_NEXT])) { /* Avoid double reference of the VBOs. */ mb_geom->batch->verts[i] = NULL; } diff --git a/source/blender/draw/engines/eevee/eevee_shadows.c b/source/blender/draw/engines/eevee/eevee_shadows.c index 2f8eb482882..fa5afd60235 100644 --- a/source/blender/draw/engines/eevee/eevee_shadows.c +++ b/source/blender/draw/engines/eevee/eevee_shadows.c @@ -349,7 +349,6 @@ void EEVEE_shadows_draw(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata, DRWView } /* -------------------------------------------------------------------- */ - /** \name Render Passes * \{ */ diff --git a/source/blender/draw/engines/eevee/eevee_volumes.c b/source/blender/draw/engines/eevee/eevee_volumes.c index 9527c0f47b0..1e75968f1de 100644 --- a/source/blender/draw/engines/eevee/eevee_volumes.c +++ b/source/blender/draw/engines/eevee/eevee_volumes.c @@ -453,7 +453,7 @@ static bool eevee_volume_object_mesh_init(Scene *scene, DRW_shgroup_uniform_texture_ref( grp, gpu_grid->sampler_name, fds->tex_color ? &fds->tex_color : &e_data.dummy_one); } - else if (STREQ(gpu_grid->name, "flame") || STREQ(gpu_grid->name, "temperature")) { + else if (STR_ELEM(gpu_grid->name, "flame", "temperature")) { DRW_shgroup_uniform_texture_ref( grp, gpu_grid->sampler_name, fds->tex_flame ? &fds->tex_flame : &e_data.dummy_flame); } @@ -788,7 +788,6 @@ void EEVEE_volumes_free(void) } /* -------------------------------------------------------------------- */ - /** \name Render Passes * \{ */ diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c index 52b41726276..18ca2e4ccc9 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c @@ -247,6 +247,10 @@ GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Obje gp_style = gpencil_viewport_material_overrides(pd, ob, color_type, gp_style); + /* Dots or Squares rotation. */ + mat_data->alignment_rot_cos = cosf(gp_style->alignment_rotation); + mat_data->alignment_rot_sin = sinf(gp_style->alignment_rotation); + /* Stroke Style */ if ((gp_style->stroke_style == GP_MATERIAL_STROKE_STYLE_TEXTURE) && (gp_style->sima)) { bool premul; @@ -367,7 +371,7 @@ static float light_power_get(const Light *la) if (la->type == LA_AREA) { return 1.0f / (4.0f * M_PI); } - if (la->type == LA_SPOT || la->type == LA_LOCAL) { + if (ELEM(la->type, LA_SPOT, LA_LOCAL)) { return 1.0f / (4.0f * M_PI * M_PI); } diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index 0922ab6552c..04128dc157e 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -62,7 +62,7 @@ typedef struct gpMaterial { float stroke_color[4]; float fill_color[4]; float fill_mix_color[4]; - float fill_uv_transform[3][2], _pad0[2]; + float fill_uv_transform[3][2], alignment_rot_cos, alignment_rot_sin; float stroke_texture_mix; float stroke_u_scale; float fill_texture_mix; diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl index 5e930af7bd7..94b066c12e5 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_common_lib.glsl @@ -461,6 +461,14 @@ void stroke_vertex() float rot_cos = abs(uv_rot); x_axis = mat2(rot_cos, -rot_sin, rot_sin, rot_cos) * x_axis; +# ifdef GP_MATERIAL_BUFFER_LEN + if (is_dot) { + float alignment_cos = MATERIAL(m).fill_uv_offset.z; + float alignment_sin = MATERIAL(m).fill_uv_offset.w; + x_axis = mat2(alignment_cos, -alignment_sin, alignment_sin, alignment_cos) * x_axis; + } +# endif + vec2 y_axis = rotate_90deg(x_axis); strokeAspect = decode_aspect(aspect1); diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 336e6e75659..fbe71900915 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -349,7 +349,6 @@ typedef enum { DRW_STATE_LOGIC_INVERT = (10 << 11), DRW_STATE_BLEND_ALPHA_UNDER_PREMUL = (11 << 11), - DRW_STATE_IN_FRONT_SELECT = (1 << 27), DRW_STATE_SHADOW_OFFSET = (1 << 28), DRW_STATE_CLIP_PLANES = (1 << 29), diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 52e7e91a995..dd2617342e1 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -1694,8 +1694,8 @@ GPUBatch *DRW_cache_speaker_get(void) copy_v3_fl3(v, r, 0.0f, z); GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); for (int i = 1; i < segments; i++) { - float x = cosf(2.f * (float)M_PI * i / segments) * r; - float y = sinf(2.f * (float)M_PI * i / segments) * r; + float x = cosf(2.0f * (float)M_PI * i / segments) * r; + float y = sinf(2.0f * (float)M_PI * i / segments) * r; copy_v3_fl3(v, x, y, z); GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); GPU_vertbuf_attr_set(vbo, attr_id.pos, vidx++, v); @@ -2389,7 +2389,7 @@ GPUBatch *DRW_cache_bone_stick_get(void) /* Bone rectangle */ pos[0] = 0.0f; for (int i = 0; i < 6; i++) { - pos[1] = (i == 0 || i == 3) ? 0.0f : ((i < 3) ? 1.0f : -1.0f); + pos[1] = (ELEM(i, 0, 3)) ? 0.0f : ((i < 3) ? 1.0f : -1.0f); flag = ((i < 2 || i > 4) ? POS_HEAD : POS_TAIL) | ((i == 0 || i == 3) ? 0 : COL_WIRE) | COL_BONE | POS_BONE; GPU_vertbuf_attr_set(vbo, attr_id.pos, v, pos); @@ -2463,14 +2463,14 @@ static float axis_marker[8][2] = { {-1.0f * S_X, -1.0f * S_Y}, {-1.0f * S_X, 1.0f * S_Y} #else /* diamond */ - {-S_X, 0.f}, - {0.f, S_Y}, - {0.f, S_Y}, - {S_X, 0.f}, - {S_X, 0.f}, - {0.f, -S_Y}, - {0.f, -S_Y}, - {-S_X, 0.f} + {-S_X, 0.0f}, + {0.0f, S_Y}, + {0.0f, S_Y}, + {S_X, 0.0f}, + {S_X, 0.0f}, + {0.0f, -S_Y}, + {0.0f, -S_Y}, + {-S_X, 0.0f} #endif }; #define MARKER_LEN (sizeof(axis_marker) / (sizeof(float[2]))) diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index ce3a89ae45c..7766ce906b8 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -2804,8 +2804,6 @@ static void *extract_vcol_init(const MeshRenderData *mr, struct MeshBatchCache * vcol_data->a = unit_float_to_ushort_clamp(vcol[loops[ml_index].v].color[3]); } } - - vcol_data += mr->loop_len; } } return NULL; diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c index 0f80b5159a7..e6c7341759b 100644 --- a/source/blender/draw/intern/draw_cache_impl_lattice.c +++ b/source/blender/draw/intern/draw_cache_impl_lattice.c @@ -389,11 +389,11 @@ static GPUIndexBuf *lattice_batch_cache_get_edges(LatticeRenderData *rdata, #define LATT_INDEX(u, v, w) ((((w)*rdata->dims.v_len + (v)) * rdata->dims.u_len) + (u)) for (int w = 0; w < rdata->dims.w_len; w++) { - int wxt = (w == 0 || w == rdata->dims.w_len - 1); + int wxt = (ELEM(w, 0, rdata->dims.w_len - 1)); for (int v = 0; v < rdata->dims.v_len; v++) { - int vxt = (v == 0 || v == rdata->dims.v_len - 1); + int vxt = (ELEM(v, 0, rdata->dims.v_len - 1)); for (int u = 0; u < rdata->dims.u_len; u++) { - int uxt = (u == 0 || u == rdata->dims.u_len - 1); + int uxt = (ELEM(u, 0, rdata->dims.u_len - 1)); if (w && ((uxt || vxt) || !rdata->show_only_outside)) { GPU_indexbuf_add_line_verts(&elb, LATT_INDEX(u, v, w - 1), LATT_INDEX(u, v, w)); diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 52d1fcfdb80..75685c7e2f0 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -301,12 +301,12 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, } ParticleData *particle = &psys->particles[parent_index]; int num = particle->num_dmcache; - if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { + if (ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } - if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { + if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); @@ -330,12 +330,12 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, } ParticleData *particle = &psys->particles[parent_index]; int num = particle->num_dmcache; - if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { + if (ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { if (particle->num < psmd->mesh_final->totface) { num = particle->num; } } - if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { + if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { MFace *mface = &psmd->mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ diff --git a/source/blender/draw/intern/draw_instance_data.c b/source/blender/draw/intern/draw_instance_data.c index 4050a5f8b69..f1598ea2fff 100644 --- a/source/blender/draw/intern/draw_instance_data.c +++ b/source/blender/draw/intern/draw_instance_data.c @@ -30,9 +30,20 @@ */ #include "draw_instance_data.h" +#include "draw_manager.h" + #include "DRW_engine.h" #include "DRW_render.h" /* For DRW_shgroup_get_instance_count() */ +#include "GPU_material.h" + +#include "DNA_particle_types.h" + +#include "BKE_duplilist.h" + +#include "RNA_access.h" + +#include "BLI_bitmap.h" #include "BLI_memblock.h" #include "BLI_mempool.h" #include "BLI_utildefines.h" @@ -408,3 +419,362 @@ void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist) } /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Sparse Uniform Buffer + * \{ */ + +#define CHUNK_LIST_STEP (1 << 4) + +/** A chunked UBO manager that doesn't actually allocate unneeded chunks. */ +typedef struct DRWSparseUniformBuf { + /* Memory buffers used to stage chunk data before transfer to UBOs. */ + char **chunk_buffers; + /* Uniform buffer objects with flushed data. */ + struct GPUUniformBuf **chunk_ubos; + /* True if the relevant chunk contains data (distinct from simply being allocated). */ + BLI_bitmap *chunk_used; + + int num_chunks; + unsigned int item_size, chunk_size, chunk_bytes; +} DRWSparseUniformBuf; + +static void drw_sparse_uniform_buffer_init(DRWSparseUniformBuf *buffer, + unsigned int item_size, + unsigned int chunk_size) +{ + buffer->chunk_buffers = NULL; + buffer->chunk_used = NULL; + buffer->chunk_ubos = NULL; + buffer->num_chunks = 0; + buffer->item_size = item_size; + buffer->chunk_size = chunk_size; + buffer->chunk_bytes = item_size * chunk_size; +} + +/** Allocate a chunked UBO with the specified item and chunk size. */ +DRWSparseUniformBuf *DRW_sparse_uniform_buffer_new(unsigned int item_size, unsigned int chunk_size) +{ + DRWSparseUniformBuf *buf = MEM_mallocN(sizeof(DRWSparseUniformBuf), __func__); + drw_sparse_uniform_buffer_init(buf, item_size, chunk_size); + return buf; +} + +/** Flush data from ordinary memory to UBOs. */ +void DRW_sparse_uniform_buffer_flush(DRWSparseUniformBuf *buffer) +{ + for (int i = 0; i < buffer->num_chunks; i++) { + if (BLI_BITMAP_TEST(buffer->chunk_used, i)) { + if (buffer->chunk_ubos[i] == NULL) { + buffer->chunk_ubos[i] = GPU_uniformbuf_create(buffer->chunk_bytes); + } + GPU_uniformbuf_update(buffer->chunk_ubos[i], buffer->chunk_buffers[i]); + } + } +} + +/** Clean all buffers and free unused ones. */ +void DRW_sparse_uniform_buffer_clear(DRWSparseUniformBuf *buffer, bool free_all) +{ + int max_used_chunk = 0; + + for (int i = 0; i < buffer->num_chunks; i++) { + /* Delete buffers that were not used since the last clear call. */ + if (free_all || !BLI_BITMAP_TEST(buffer->chunk_used, i)) { + MEM_SAFE_FREE(buffer->chunk_buffers[i]); + + if (buffer->chunk_ubos[i]) { + GPU_uniformbuf_free(buffer->chunk_ubos[i]); + buffer->chunk_ubos[i] = NULL; + } + } + else { + max_used_chunk = i + 1; + } + } + + /* Shrink the chunk array if appropriate. */ + const int old_num_chunks = buffer->num_chunks; + + buffer->num_chunks = (max_used_chunk + CHUNK_LIST_STEP - 1) & ~(CHUNK_LIST_STEP - 1); + + if (buffer->num_chunks == 0) { + /* Ensure that an empty pool holds no memory allocations. */ + MEM_SAFE_FREE(buffer->chunk_buffers); + MEM_SAFE_FREE(buffer->chunk_used); + MEM_SAFE_FREE(buffer->chunk_ubos); + return; + } + + if (buffer->num_chunks != old_num_chunks) { + buffer->chunk_buffers = MEM_recallocN(buffer->chunk_buffers, + buffer->num_chunks * sizeof(void *)); + buffer->chunk_ubos = MEM_recallocN(buffer->chunk_ubos, buffer->num_chunks * sizeof(void *)); + BLI_BITMAP_RESIZE(buffer->chunk_used, buffer->num_chunks); + } + + BLI_bitmap_set_all(buffer->chunk_used, false, buffer->num_chunks); +} + +/** Frees the buffer. */ +void DRW_sparse_uniform_buffer_free(DRWSparseUniformBuf *buffer) +{ + DRW_sparse_uniform_buffer_clear(buffer, true); + MEM_freeN(buffer); +} + +/** Checks if the buffer contains any allocated chunks. */ +bool DRW_sparse_uniform_buffer_is_empty(DRWSparseUniformBuf *buffer) +{ + return buffer->num_chunks == 0; +} + +static GPUUniformBuf *drw_sparse_uniform_buffer_get_ubo(DRWSparseUniformBuf *buffer, int chunk) +{ + if (buffer && chunk < buffer->num_chunks && BLI_BITMAP_TEST(buffer->chunk_used, chunk)) { + return buffer->chunk_ubos[chunk]; + } + return NULL; +} + +/** Bind the UBO for the given chunk, if present. A NULL buffer pointer is handled as empty. */ +void DRW_sparse_uniform_buffer_bind(DRWSparseUniformBuf *buffer, int chunk, int location) +{ + GPUUniformBuf *ubo = drw_sparse_uniform_buffer_get_ubo(buffer, chunk); + if (ubo) { + GPU_uniformbuf_bind(ubo, location); + } +} + +/** Unbind the UBO for the given chunk, if present. A NULL buffer pointer is handled as empty. */ +void DRW_sparse_uniform_buffer_unbind(DRWSparseUniformBuf *buffer, int chunk) +{ + GPUUniformBuf *ubo = drw_sparse_uniform_buffer_get_ubo(buffer, chunk); + if (ubo) { + GPU_uniformbuf_unbind(ubo); + } +} + +/** Returns a pointer to the given item of the given chunk, allocating memory if necessary. */ +void *DRW_sparse_uniform_buffer_ensure_item(DRWSparseUniformBuf *buffer, int chunk, int item) +{ + if (chunk >= buffer->num_chunks) { + buffer->num_chunks = (chunk + CHUNK_LIST_STEP) & ~(CHUNK_LIST_STEP - 1); + buffer->chunk_buffers = MEM_recallocN(buffer->chunk_buffers, + buffer->num_chunks * sizeof(void *)); + buffer->chunk_ubos = MEM_recallocN(buffer->chunk_ubos, buffer->num_chunks * sizeof(void *)); + BLI_BITMAP_RESIZE(buffer->chunk_used, buffer->num_chunks); + } + + char *chunk_buffer = buffer->chunk_buffers[chunk]; + + if (chunk_buffer == NULL) { + buffer->chunk_buffers[chunk] = chunk_buffer = MEM_callocN(buffer->chunk_bytes, __func__); + } + else if (!BLI_BITMAP_TEST(buffer->chunk_used, chunk)) { + memset(chunk_buffer, 0, buffer->chunk_bytes); + } + + BLI_BITMAP_ENABLE(buffer->chunk_used, chunk); + + return chunk_buffer + buffer->item_size * item; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Uniform Attribute Buffers + * \{ */ + +/** Sparse UBO buffer for a specific uniform attribute list. */ +typedef struct DRWUniformAttrBuf { + /* Attribute list (also used as hash table key) handled by this buffer. */ + GPUUniformAttrList key; + /* Sparse UBO buffer containing the attribute values. */ + DRWSparseUniformBuf ubos; + /* Last handle used to update the buffer, checked for avoiding redundant updates. */ + DRWResourceHandle last_handle; + /* Linked list pointer used for freeing the empty unneeded buffers. */ + struct DRWUniformAttrBuf *next_empty; +} DRWUniformAttrBuf; + +static DRWUniformAttrBuf *drw_uniform_attrs_pool_ensure(GHash *table, GPUUniformAttrList *key) +{ + void **pkey, **pval; + + if (!BLI_ghash_ensure_p_ex(table, key, &pkey, &pval)) { + DRWUniformAttrBuf *buffer = MEM_callocN(sizeof(*buffer), __func__); + + *pkey = &buffer->key; + *pval = buffer; + + GPU_uniform_attr_list_copy(&buffer->key, key); + drw_sparse_uniform_buffer_init( + &buffer->ubos, key->count * sizeof(float[4]), DRW_RESOURCE_CHUNK_LEN); + + buffer->last_handle = (DRWResourceHandle)-1; + } + + return (DRWUniformAttrBuf *)*pval; +} + +/* This function mirrors lookup_property in cycles/blender/blender_object.cpp */ +static bool drw_uniform_property_lookup(ID *id, const char *name, float r_data[4]) +{ + PointerRNA ptr, id_ptr; + PropertyRNA *prop; + + if (!id) { + return false; + } + + RNA_id_pointer_create(id, &id_ptr); + + if (!RNA_path_resolve(&id_ptr, name, &ptr, &prop)) { + return false; + } + + PropertyType type = RNA_property_type(prop); + int arraylen = RNA_property_array_length(&ptr, prop); + + if (arraylen == 0) { + float value; + + if (type == PROP_FLOAT) { + value = RNA_property_float_get(&ptr, prop); + } + else if (type == PROP_INT) { + value = RNA_property_int_get(&ptr, prop); + } + else { + return false; + } + + copy_v4_fl4(r_data, value, value, value, 1); + return true; + } + + if (type == PROP_FLOAT && arraylen <= 4) { + copy_v4_fl4(r_data, 0, 0, 0, 1); + RNA_property_float_get_array(&ptr, prop, r_data); + return true; + } + + return false; +} + +/* This function mirrors lookup_instance_property in cycles/blender/blender_object.cpp */ +static void drw_uniform_attribute_lookup(GPUUniformAttr *attr, + Object *ob, + Object *dupli_parent, + DupliObject *dupli_source, + float r_data[4]) +{ + char idprop_name[sizeof(attr->name) + 4]; + + copy_v4_fl(r_data, 0); + sprintf(idprop_name, "[\"%s\"]", attr->name); + + /* If requesting instance data, check the parent particle system and object. */ + if (attr->use_dupli) { + if (dupli_source && dupli_source->particle_system) { + ParticleSettings *settings = dupli_source->particle_system->part; + if (drw_uniform_property_lookup((ID *)settings, idprop_name, r_data) || + drw_uniform_property_lookup((ID *)settings, attr->name, r_data)) { + return; + } + } + if (drw_uniform_property_lookup((ID *)dupli_parent, idprop_name, r_data) || + drw_uniform_property_lookup((ID *)dupli_parent, attr->name, r_data)) { + return; + } + } + + /* Check the object and mesh. */ + if (ob) { + if (drw_uniform_property_lookup((ID *)ob, idprop_name, r_data) || + drw_uniform_property_lookup((ID *)ob, attr->name, r_data) || + drw_uniform_property_lookup((ID *)ob->data, idprop_name, r_data) || + drw_uniform_property_lookup((ID *)ob->data, attr->name, r_data)) { + return; + } + } +} + +void drw_uniform_attrs_pool_update(GHash *table, + GPUUniformAttrList *key, + DRWResourceHandle *handle, + Object *ob, + Object *dupli_parent, + DupliObject *dupli_source) +{ + DRWUniformAttrBuf *buffer = drw_uniform_attrs_pool_ensure(table, key); + + if (buffer->last_handle != *handle) { + buffer->last_handle = *handle; + + int chunk = DRW_handle_chunk_get(handle); + int item = DRW_handle_id_get(handle); + float(*values)[4] = DRW_sparse_uniform_buffer_ensure_item(&buffer->ubos, chunk, item); + + LISTBASE_FOREACH (GPUUniformAttr *, attr, &buffer->key.list) { + drw_uniform_attribute_lookup(attr, ob, dupli_parent, dupli_source, *values++); + } + } +} + +DRWSparseUniformBuf *DRW_uniform_attrs_pool_find_ubo(GHash *table, struct GPUUniformAttrList *key) +{ + DRWUniformAttrBuf *buffer = BLI_ghash_lookup(table, key); + return buffer ? &buffer->ubos : NULL; +} + +GHash *DRW_uniform_attrs_pool_new() +{ + return GPU_uniform_attr_list_hash_new("obattr_hash"); +} + +void DRW_uniform_attrs_pool_flush_all(GHash *table) +{ + GHASH_FOREACH_BEGIN (DRWUniformAttrBuf *, buffer, table) { + DRW_sparse_uniform_buffer_flush(&buffer->ubos); + } + GHASH_FOREACH_END(); +} + +static void drw_uniform_attrs_pool_free_cb(void *ptr) +{ + DRWUniformAttrBuf *buffer = ptr; + + GPU_uniform_attr_list_free(&buffer->key); + DRW_sparse_uniform_buffer_clear(&buffer->ubos, true); + MEM_freeN(buffer); +} + +void DRW_uniform_attrs_pool_clear_all(GHash *table) +{ + DRWUniformAttrBuf *remove_list = NULL; + + GHASH_FOREACH_BEGIN (DRWUniformAttrBuf *, buffer, table) { + buffer->last_handle = (DRWResourceHandle)-1; + DRW_sparse_uniform_buffer_clear(&buffer->ubos, false); + + if (DRW_sparse_uniform_buffer_is_empty(&buffer->ubos)) { + buffer->next_empty = remove_list; + remove_list = buffer; + } + } + GHASH_FOREACH_END(); + + while (remove_list) { + DRWUniformAttrBuf *buffer = remove_list; + remove_list = buffer->next_empty; + BLI_ghash_remove(table, &buffer->key, NULL, drw_uniform_attrs_pool_free_cb); + } +} + +void DRW_uniform_attrs_pool_free(GHash *table) +{ + BLI_ghash_free(table, NULL, drw_uniform_attrs_pool_free_cb); +} + +/** \} */ diff --git a/source/blender/draw/intern/draw_instance_data.h b/source/blender/draw/intern/draw_instance_data.h index e562d99097e..c959a9e19d6 100644 --- a/source/blender/draw/intern/draw_instance_data.h +++ b/source/blender/draw/intern/draw_instance_data.h @@ -31,8 +31,12 @@ #define DRW_BUFFER_VERTS_CHUNK 128 +struct GHash; +struct GPUUniformAttrList; + typedef struct DRWInstanceData DRWInstanceData; typedef struct DRWInstanceDataList DRWInstanceDataList; +typedef struct DRWSparseUniformBuf DRWSparseUniformBuf; void *DRW_instance_data_next(DRWInstanceData *idata); DRWInstanceData *DRW_instance_data_request(DRWInstanceDataList *idatalist, uint attr_size); @@ -54,3 +58,21 @@ void DRW_instance_buffer_finish(DRWInstanceDataList *idatalist); void DRW_instance_data_list_reset(DRWInstanceDataList *idatalist); void DRW_instance_data_list_free_unused(DRWInstanceDataList *idatalist); void DRW_instance_data_list_resize(DRWInstanceDataList *idatalist); + +/* Sparse chunked UBO manager. */ +DRWSparseUniformBuf *DRW_sparse_uniform_buffer_new(unsigned int item_size, + unsigned int chunk_size); +void DRW_sparse_uniform_buffer_flush(DRWSparseUniformBuf *buffer); +void DRW_sparse_uniform_buffer_clear(DRWSparseUniformBuf *buffer, bool free_all); +void DRW_sparse_uniform_buffer_free(DRWSparseUniformBuf *buffer); +bool DRW_sparse_uniform_buffer_is_empty(DRWSparseUniformBuf *buffer); +void DRW_sparse_uniform_buffer_bind(DRWSparseUniformBuf *buffer, int chunk, int location); +void DRW_sparse_uniform_buffer_unbind(DRWSparseUniformBuf *buffer, int chunk); +void *DRW_sparse_uniform_buffer_ensure_item(DRWSparseUniformBuf *buffer, int chunk, int item); + +/* Uniform attribute UBO management. */ +struct GHash *DRW_uniform_attrs_pool_new(void); +void DRW_uniform_attrs_pool_flush_all(struct GHash *table); +void DRW_uniform_attrs_pool_clear_all(struct GHash *table); +struct DRWSparseUniformBuf *DRW_uniform_attrs_pool_find_ubo(struct GHash *table, + struct GPUUniformAttrList *key); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index f995582149a..f51328e9bc9 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -467,6 +467,8 @@ static void drw_viewport_cache_resize(void) BLI_memblock_clear(DST.vmempool->passes, NULL); BLI_memblock_clear(DST.vmempool->views, NULL); BLI_memblock_clear(DST.vmempool->images, NULL); + + DRW_uniform_attrs_pool_clear_all(DST.vmempool->obattrs_ubo_pool); } DRW_instance_data_list_free_unused(DST.idatalist); @@ -593,6 +595,9 @@ static void drw_viewport_var_init(void) if (DST.vmempool->images == NULL) { DST.vmempool->images = BLI_memblock_create(sizeof(GPUTexture *)); } + if (DST.vmempool->obattrs_ubo_pool == NULL) { + DST.vmempool->obattrs_ubo_pool = DRW_uniform_attrs_pool_new(); + } DST.resource_handle = 0; DST.pass_handle = 0; @@ -3026,6 +3031,7 @@ void DRW_render_context_disable(Render *render) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Init/Exit (DRW_opengl_ctx) * \{ */ @@ -3172,6 +3178,7 @@ void DRW_xr_drawing_end(void) #endif +/* -------------------------------------------------------------------- */ /** \name Internal testing API for gtests * \{ */ diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index 8e505d5df71..4f4e03938c0 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -43,6 +43,9 @@ #include "draw_instance_data.h" +struct DupliObject; +struct Object; + /* Use draw manager to call GPU_select, see: DRW_draw_select_loop */ #define USE_GPU_SELECT @@ -286,6 +289,7 @@ typedef enum { /** Per drawcall uniforms/UBO */ DRW_UNIFORM_BLOCK_OBMATS, DRW_UNIFORM_BLOCK_OBINFOS, + DRW_UNIFORM_BLOCK_OBATTRS, DRW_UNIFORM_RESOURCE_CHUNK, DRW_UNIFORM_RESOURCE_ID, /** Legacy / Fallback */ @@ -317,6 +321,8 @@ struct DRWUniform { float fvalue[4]; /* DRW_UNIFORM_INT_COPY */ int ivalue[4]; + /* DRW_UNIFORM_BLOCK_OBATTRS */ + struct GPUUniformAttrList *uniform_attrs; }; int location; /* Uniform location or binding point for textures and ubos. */ uint8_t type; /* DRWUniformType */ @@ -340,6 +346,9 @@ struct DRWShadingGroup { struct { int objectinfo; /* Equal to 1 if the shader needs obinfos. */ DRWResourceHandle pass_handle; /* Memblock key to parent pass. */ + + /* Set of uniform attributes used by this shader. */ + struct GPUUniformAttrList *uniform_attrs; }; /* This struct is used after cache populate if using the Z sorting. * It will not conflict with the above struct. */ @@ -598,3 +607,10 @@ void drw_resource_buffer_finish(ViewportMemoryPool *vmempool); GPUBatch *drw_cache_procedural_points_get(void); GPUBatch *drw_cache_procedural_lines_get(void); GPUBatch *drw_cache_procedural_triangles_get(void); + +void drw_uniform_attrs_pool_update(struct GHash *table, + struct GPUUniformAttrList *key, + DRWResourceHandle *handle, + struct Object *ob, + struct Object *dupli_parent, + struct DupliObject *dupli_source); diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 5f394804bcf..f1d3f8c8d5a 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -128,6 +128,8 @@ void drw_resource_buffer_finish(ViewportMemoryPool *vmempool) GPU_uniformbuf_update(vmempool->obinfos_ubo[i], data_infos); } + DRW_uniform_attrs_pool_flush_all(vmempool->obattrs_ubo_pool); + /* Aligned alloc to avoid unaligned memcpy. */ DRWCommandChunk *chunk_tmp = MEM_mallocN_aligned(sizeof(DRWCommandChunk), 16, "tmp call chunk"); DRWCommandChunk *chunk; @@ -209,6 +211,9 @@ static void drw_shgroup_uniform_create_ex(DRWShadingGroup *shgroup, uni->texture_ref = (GPUTexture **)value; uni->sampler_state = sampler_state; break; + case DRW_UNIFORM_BLOCK_OBATTRS: + uni->uniform_attrs = (GPUUniformAttrList *)value; + break; default: uni->pvalue = (const float *)value; break; @@ -611,6 +616,15 @@ static DRWResourceHandle drw_resource_handle(DRWShadingGroup *shgroup, } } + if (shgroup->uniform_attrs) { + drw_uniform_attrs_pool_update(DST.vmempool->obattrs_ubo_pool, + shgroup->uniform_attrs, + &DST.ob_handle, + ob, + DST.dupli_parent, + DST.dupli_source); + } + return DST.ob_handle; } @@ -1184,6 +1198,7 @@ void DRW_buffer_add_entry_array(DRWCallBuffer *callbuf, const void *attr[], uint static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) { shgroup->uniforms = NULL; + shgroup->uniform_attrs = NULL; int view_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_VIEW); int model_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_MODEL); @@ -1329,6 +1344,13 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial if (ubo != NULL) { DRW_shgroup_uniform_block(grp, GPU_UBO_BLOCK_NAME, ubo); } + + GPUUniformAttrList *uattrs = GPU_material_uniform_attributes(material); + if (uattrs != NULL) { + int loc = GPU_shader_get_uniform_block_binding(grp->shader, GPU_ATTRIBUTE_UBO_BLOCK_NAME); + drw_shgroup_uniform_create_ex(grp, loc, DRW_UNIFORM_BLOCK_OBATTRS, uattrs, 0, 0, 1); + grp->uniform_attrs = uattrs; + } } GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat attrs[], diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 8cf96251e84..749e9e6bafb 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -57,12 +57,15 @@ typedef struct DRWCommandsState { /* Resource location. */ int obmats_loc; int obinfos_loc; + int obattrs_loc; int baseinst_loc; int chunkid_loc; int resourceid_loc; /* Legacy matrix support. */ int obmat_loc; int obinv_loc; + /* Uniform Attributes. */ + DRWSparseUniformBuf *obattrs_ubo; /* Selection ID state. */ GPUVertBuf *select_buf; uint select_id; @@ -651,6 +654,12 @@ static void draw_update_uniforms(DRWShadingGroup *shgroup, state->obinfos_loc = uni->location; GPU_uniformbuf_bind(DST.vmempool->obinfos_ubo[0], uni->location); break; + case DRW_UNIFORM_BLOCK_OBATTRS: + state->obattrs_loc = uni->location; + state->obattrs_ubo = DRW_uniform_attrs_pool_find_ubo(DST.vmempool->obattrs_ubo_pool, + uni->uniform_attrs); + DRW_sparse_uniform_buffer_bind(state->obattrs_ubo, 0, uni->location); + break; case DRW_UNIFORM_RESOURCE_CHUNK: state->chunkid_loc = uni->location; GPU_shader_uniform_int(shgroup->shader, uni->location, 0); @@ -765,6 +774,10 @@ static void draw_call_resource_bind(DRWCommandsState *state, const DRWResourceHa GPU_uniformbuf_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]); GPU_uniformbuf_bind(DST.vmempool->obinfos_ubo[chunk], state->obinfos_loc); } + if (state->obattrs_loc != -1) { + DRW_sparse_uniform_buffer_unbind(state->obattrs_ubo, state->resource_chunk); + DRW_sparse_uniform_buffer_bind(state->obattrs_ubo, chunk, state->obattrs_loc); + } state->resource_chunk = chunk; } @@ -887,6 +900,9 @@ static void draw_call_batching_finish(DRWShadingGroup *shgroup, DRWCommandsState if (state->obinfos_loc != -1) { GPU_uniformbuf_unbind(DST.vmempool->obinfos_ubo[state->resource_chunk]); } + if (state->obattrs_loc != -1) { + DRW_sparse_uniform_buffer_unbind(state->obattrs_ubo, state->resource_chunk); + } } static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) @@ -896,11 +912,13 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) DRWCommandsState state = { .obmats_loc = -1, .obinfos_loc = -1, + .obattrs_loc = -1, .baseinst_loc = -1, .chunkid_loc = -1, .resourceid_loc = -1, .obmat_loc = -1, .obinv_loc = -1, + .obattrs_ubo = NULL, .drw_state_enabled = 0, .drw_state_disabled = 0, }; diff --git a/source/blender/draw/intern/draw_manager_shader.c b/source/blender/draw/intern/draw_manager_shader.c index 85c04b73529..c93cbf16a30 100644 --- a/source/blender/draw/intern/draw_manager_shader.c +++ b/source/blender/draw/intern/draw_manager_shader.c @@ -549,7 +549,6 @@ void DRW_shader_free(GPUShader *shader) /** \} */ /* -------------------------------------------------------------------- */ - /** \name Shader Library * * Simple include system for glsl files. diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 1f1b52e9577..8ba3ee097df 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -198,7 +198,6 @@ void DRW_draw_cursor(void) } /* -------------------------------------------------------------------- */ - /** \name 2D Cursor * \{ */ diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c index b2225ec138f..e552a321bca 100644 --- a/source/blender/editors/animation/anim_deps.c +++ b/source/blender/editors/animation/anim_deps.c @@ -44,12 +44,13 @@ #include "BKE_gpencil.h" #include "BKE_main.h" #include "BKE_node.h" -#include "BKE_sequencer.h" #include "DEG_depsgraph.h" #include "RNA_access.h" +#include "SEQ_sequencer.h" + #include "ED_anim_api.h" /* **************************** depsgraph tagging ******************************** */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 5dff62459ac..2e65fff69f1 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -96,11 +96,12 @@ #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_node.h" -#include "BKE_sequencer.h" #include "ED_anim_api.h" #include "ED_markers.h" +#include "SEQ_sequencer.h" + #include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */ /* ************************************************************ */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index b52ff131b43..9e622aea6ab 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -37,7 +37,6 @@ #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "UI_view2d.h" @@ -56,6 +55,8 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "SEQ_sequencer.h" + #include "anim_intern.h" /* ********************** frame change operator ***************************/ diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index fc622c7a52e..deebf1d1efc 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -21,13 +21,11 @@ * \ingroup edanimation */ -/* User-Interface Stuff for F-Modifiers: - * This file defines the (C-Coded) templates + editing callbacks needed - * by the interface stuff or F-Modifiers, as used by F-Curves in the Graph Editor, - * and NLA-Strips in the NLA Editor. +/** + * User Interface for F-Modifiers * - * Copy/Paste Buffer for F-Modifiers: - * For now, this is also defined in this file so that it can be shared between the + * This file defines templates and some editing callbacks needed by the interface for + * F-Modifiers, as used by F-Curves in the Graph Editor and NLA-Strips in the NLA Editor. */ #include <string.h> @@ -1047,8 +1045,12 @@ void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, } } -/* ********************************************** */ -/* COPY/PASTE BUFFER STUFF */ +/* -------------------------------------------------------------------- */ +/** \name Copy / Paste Buffer Code + * + * For now, this is also defined in this file so that it can be shared between the graph editor + * and the NLA editor. + * \{ */ /* Copy/Paste Buffer itself (list of FModifier 's) */ static ListBase fmodifier_copypaste_buf = {NULL, NULL}; @@ -1139,4 +1141,4 @@ bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *c return ok; } -/* ********************************************** */ +/** \} */ diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c index 60a1434ed42..8bcaf72f678 100644 --- a/source/blender/editors/armature/armature_naming.c +++ b/source/blender/editors/armature/armature_naming.c @@ -606,7 +606,7 @@ void ARMATURE_OT_autoside_names(wmOperatorType *ot) }; /* identifiers */ - ot->name = "AutoName by Axis"; + ot->name = "Auto-Name by Axis"; ot->idname = "ARMATURE_OT_autoside_names"; ot->description = "Automatically renames the selected bones according to which side of the target axis they " diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 27718b61d70..60fe8ee7dee 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -1550,10 +1550,10 @@ enum { static const EnumPropertyItem prop_similar_types[] = { {SIMEDBONE_CHILDREN, "CHILDREN", 0, "Children", ""}, - {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate children", ""}, + {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate Children", ""}, {SIMEDBONE_SIBLINGS, "SIBLINGS", 0, "Siblings", ""}, {SIMEDBONE_LENGTH, "LENGTH", 0, "Length", ""}, - {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y axis)", ""}, + {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y Axis)", ""}, {SIMEDBONE_PREFIX, "PREFIX", 0, "Prefix", ""}, {SIMEDBONE_SUFFIX, "SUFFIX", 0, "Suffix", ""}, {SIMEDBONE_LAYER, "LAYER", 0, "Layer", ""}, @@ -1806,11 +1806,11 @@ static void select_similar_data_pchan(bContext *C, const size_t bytes_size, cons static void is_ancestor(EditBone *bone, EditBone *ancestor) { - if (bone->temp.ebone == ancestor || bone->temp.ebone == NULL) { + if (ELEM(bone->temp.ebone, ancestor, NULL)) { return; } - if (bone->temp.ebone->temp.ebone != NULL && bone->temp.ebone->temp.ebone != ancestor) { + if (!ELEM(bone->temp.ebone->temp.ebone, NULL, ancestor)) { is_ancestor(bone->temp.ebone, ancestor); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index e51e5ec5cef..3c0b6dacbf6 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1547,7 +1547,8 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind } } else { - BKE_modifier_set_error(&mmd->modifier, "Failed to find bind solution (increase precision?)"); + BKE_modifier_set_error( + mmd->object, &mmd->modifier, "Failed to find bind solution (increase precision?)"); error("Mesh Deform: failed to find bind solution."); break; } diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 8a1c2a4afa8..91893af003f 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -638,7 +638,7 @@ void POSE_OT_autoside_names(wmOperatorType *ot) }; /* identifiers */ - ot->name = "AutoName by Axis"; + ot->name = "Auto-Name by Axis"; ot->idname = "POSE_OT_autoside_names"; ot->description = "Automatically renames the selected bones according to which side of the target axis they " diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index eb2a0d7a073..3781b2e318b 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -961,7 +961,7 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p /* initial apply for operator... */ /* TODO: need to calculate percentage for initial round too... */ - if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) { + if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) { pose_slide_apply(C, pso); } else { @@ -1200,7 +1200,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) pose_slide_reset(pso); /* apply... */ - if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) { + if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) { pose_slide_apply(C, pso); } else { @@ -1223,7 +1223,7 @@ static void pose_slide_cancel(bContext *UNUSED(C), wmOperator *op) static int pose_slide_exec_common(bContext *C, wmOperator *op, tPoseSlideOp *pso) { /* settings should have been set up ok for applying, so just apply! */ - if (pso->mode != POSESLIDE_PUSH_REST && pso->mode != POSESLIDE_RELAX_REST) { + if (!ELEM(pso->mode, POSESLIDE_PUSH_REST, POSESLIDE_RELAX_REST)) { pose_slide_apply(C, pso); } else { diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 85d86849140..db472c9ffa7 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -307,12 +307,8 @@ static void keyIndex_delNurb(EditNurb *editnurb, Nurb *nu) static void keyIndex_delNurbList(EditNurb *editnurb, ListBase *nubase) { - Nurb *nu = nubase->first; - - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { keyIndex_delNurb(editnurb, nu); - - nu = nu->next; } } @@ -476,19 +472,15 @@ static void keyIndex_switchDirection(EditNurb *editnurb, Nurb *nu) static void switch_keys_direction(Curve *cu, Nurb *actnu) { - KeyBlock *currkey; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs; - Nurb *nu; float *fp; int a; - currkey = cu->key->block.first; - while (currkey) { + LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) { fp = currkey->data; - nu = nubase->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { if (nu->bezt) { BezTriple *bezt = nu->bezt; a = nu->pntsu; @@ -522,11 +514,7 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu) fp += a * KEYELEM_FLOAT_LEN_BPOINT; } } - - nu = nu->next; } - - currkey = currkey->next; } } @@ -583,13 +571,11 @@ static void bezt_to_key(BezTriple *bezt, float *key) static void calc_keyHandles(ListBase *nurb, float *key) { - Nurb *nu; int a; float *fp = key; BezTriple *bezt; - nu = nurb->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurb) { if (nu->bezt) { BezTriple *prevp, *nextp; BezTriple cur, prev, next; @@ -649,8 +635,6 @@ static void calc_keyHandles(ListBase *nurb, float *key) a = nu->pntsu * nu->pntsv; fp += a * KEYELEM_FLOAT_LEN_BPOINT; } - - nu = nu->next; } } @@ -658,255 +642,247 @@ static void calc_shapeKeys(Object *obedit, ListBase *newnurbs) { Curve *cu = (Curve *)obedit->data; - /* are there keys? */ - if (cu->key) { - int a, i; - EditNurb *editnurb = cu->editnurb; - KeyBlock *currkey; - KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1); - BezTriple *bezt, *oldbezt; - BPoint *bp, *oldbp; - Nurb *nu, *newnu; - int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs); - - float(*ofs)[3] = NULL; - float *oldkey, *newkey, *ofp; - - /* editing the base key should update others */ - if (cu->key->type == KEY_RELATIVE) { - if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */ - int totvec = 0; - - /* Calculate needed memory to store offset */ - nu = editnurb->nurbs.first; - while (nu) { - if (nu->bezt) { - /* Three vects to store handles and one for tilt. */ - totvec += nu->pntsu * 4; - } - else { - totvec += 2 * nu->pntsu * nu->pntsv; - } + if (cu->key == NULL) { + return; + } - nu = nu->next; + int a, i; + EditNurb *editnurb = cu->editnurb; + KeyBlock *actkey = BLI_findlink(&cu->key->block, editnurb->shapenr - 1); + BezTriple *bezt, *oldbezt; + BPoint *bp, *oldbp; + Nurb *newnu; + int totvert = BKE_keyblock_curve_element_count(&editnurb->nurbs); + + float(*ofs)[3] = NULL; + float *oldkey, *newkey, *ofp; + + /* editing the base key should update others */ + if (cu->key->type == KEY_RELATIVE) { + if (BKE_keyblock_is_basis(cu->key, editnurb->shapenr - 1)) { /* active key is a base */ + int totvec = 0; + + /* Calculate needed memory to store offset */ + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { + + if (nu->bezt) { + /* Three vects to store handles and one for tilt. */ + totvec += nu->pntsu * 4; } + else { + totvec += 2 * nu->pntsu * nu->pntsv; + } + } - ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data"); - nu = editnurb->nurbs.first; - i = 0; - while (nu) { - if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - while (a--) { - oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); + ofs = MEM_callocN(sizeof(float[3]) * totvec, "currkey->data"); + i = 0; + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { + if (nu->bezt) { + bezt = nu->bezt; + a = nu->pntsu; + while (a--) { + oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); - if (oldbezt) { - int j; - for (j = 0; j < 3; j++) { - sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]); - i++; - } - ofs[i][0] = bezt->tilt - oldbezt->tilt; - ofs[i][1] = bezt->radius - oldbezt->radius; + if (oldbezt) { + int j; + for (j = 0; j < 3; j++) { + sub_v3_v3v3(ofs[i], bezt->vec[j], oldbezt->vec[j]); i++; } - else { - i += 4; - } - bezt++; + ofs[i][0] = bezt->tilt - oldbezt->tilt; + ofs[i][1] = bezt->radius - oldbezt->radius; + i++; } + else { + i += 4; + } + bezt++; } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - oldbp = getKeyIndexOrig_bp(editnurb, bp); - if (oldbp) { - sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec); - ofs[i + 1][0] = bp->tilt - oldbp->tilt; - ofs[i + 1][1] = bp->radius - oldbp->radius; - } - i += 2; - bp++; + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + while (a--) { + oldbp = getKeyIndexOrig_bp(editnurb, bp); + if (oldbp) { + sub_v3_v3v3(ofs[i], bp->vec, oldbp->vec); + ofs[i + 1][0] = bp->tilt - oldbp->tilt; + ofs[i + 1][1] = bp->radius - oldbp->radius; } + i += 2; + bp++; } - - nu = nu->next; } } } + } - currkey = cu->key->block.first; - while (currkey) { - const bool apply_offset = (ofs && (currkey != actkey) && - (editnurb->shapenr - 1 == currkey->relative)); - - float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); - ofp = oldkey = currkey->data; + LISTBASE_FOREACH (KeyBlock *, currkey, &cu->key->block) { + const bool apply_offset = (ofs && (currkey != actkey) && + (editnurb->shapenr - 1 == currkey->relative)); - nu = editnurb->nurbs.first; - /* We need to restore to original curve into newnurb, *not* editcurve's nurbs. - * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), - * we would invalidate editcurve. */ - newnu = newnurbs->first; - i = 0; - while (nu) { - if (currkey == actkey) { - const bool restore = actkey != cu->key->refkey; + float *fp = newkey = MEM_callocN(cu->key->elemsize * totvert, "currkey->data"); + ofp = oldkey = currkey->data; - if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; - BezTriple *newbezt = newnu->bezt; - while (a--) { - int j; - oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); + Nurb *nu = editnurb->nurbs.first; + /* We need to restore to original curve into newnurb, *not* editcurve's nurbs. + * Otherwise, in case we update obdata *without* leaving editmode (e.g. viewport render), + * we would invalidate editcurve. */ + newnu = newnurbs->first; + i = 0; + while (nu) { + if (currkey == actkey) { + const bool restore = actkey != cu->key->refkey; - for (j = 0; j < 3; j++, i++) { - copy_v3_v3(&fp[j * 3], bezt->vec[j]); + if (nu->bezt) { + bezt = nu->bezt; + a = nu->pntsu; + BezTriple *newbezt = newnu->bezt; + while (a--) { + int j; + oldbezt = getKeyIndexOrig_bezt(editnurb, bezt); - if (restore && oldbezt) { - copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]); - } - } - fp[9] = bezt->tilt; - fp[10] = bezt->radius; + for (j = 0; j < 3; j++, i++) { + copy_v3_v3(&fp[j * 3], bezt->vec[j]); if (restore && oldbezt) { - newbezt->tilt = oldbezt->tilt; - newbezt->radius = oldbezt->radius; + copy_v3_v3(newbezt->vec[j], oldbezt->vec[j]); } + } + fp[9] = bezt->tilt; + fp[10] = bezt->radius; - fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; - i++; - bezt++; - newbezt++; + if (restore && oldbezt) { + newbezt->tilt = oldbezt->tilt; + newbezt->radius = oldbezt->radius; } - } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - BPoint *newbp = newnu->bp; - while (a--) { - oldbp = getKeyIndexOrig_bp(editnurb, bp); - copy_v3_v3(fp, bp->vec); + fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; + i++; + bezt++; + newbezt++; + } + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + BPoint *newbp = newnu->bp; + while (a--) { + oldbp = getKeyIndexOrig_bp(editnurb, bp); - fp[3] = bp->tilt; - fp[4] = bp->radius; + copy_v3_v3(fp, bp->vec); - if (restore && oldbp) { - copy_v3_v3(newbp->vec, oldbp->vec); - newbp->tilt = oldbp->tilt; - newbp->radius = oldbp->radius; - } + fp[3] = bp->tilt; + fp[4] = bp->radius; - fp += KEYELEM_FLOAT_LEN_BPOINT; - bp++; - newbp++; - i += 2; + if (restore && oldbp) { + copy_v3_v3(newbp->vec, oldbp->vec); + newbp->tilt = oldbp->tilt; + newbp->radius = oldbp->radius; } + + fp += KEYELEM_FLOAT_LEN_BPOINT; + bp++; + newbp++; + i += 2; } } - else { - int index; - const float *curofp; - - if (oldkey) { - if (nu->bezt) { - bezt = nu->bezt; - a = nu->pntsu; + } + else { + int index; + const float *curofp; - while (a--) { - index = getKeyIndexOrig_keyIndex(editnurb, bezt); - if (index >= 0) { - int j; - curofp = ofp + index; + if (oldkey) { + if (nu->bezt) { + bezt = nu->bezt; + a = nu->pntsu; - for (j = 0; j < 3; j++, i++) { - copy_v3_v3(&fp[j * 3], &curofp[j * 3]); + while (a--) { + index = getKeyIndexOrig_keyIndex(editnurb, bezt); + if (index >= 0) { + int j; + curofp = ofp + index; - if (apply_offset) { - add_v3_v3(&fp[j * 3], ofs[i]); - } - } - fp[9] = curofp[9]; - fp[10] = curofp[10]; + for (j = 0; j < 3; j++, i++) { + copy_v3_v3(&fp[j * 3], &curofp[j * 3]); if (apply_offset) { - /* Apply tilt offsets. */ - add_v3_v3(fp + 9, ofs[i]); - i++; + add_v3_v3(&fp[j * 3], ofs[i]); } + } + fp[9] = curofp[9]; + fp[10] = curofp[10]; - fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; + if (apply_offset) { + /* Apply tilt offsets. */ + add_v3_v3(fp + 9, ofs[i]); + i++; } - else { - int j; - for (j = 0; j < 3; j++, i++) { - copy_v3_v3(&fp[j * 3], bezt->vec[j]); - } - fp[9] = bezt->tilt; - fp[10] = bezt->radius; - fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; + fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; + } + else { + int j; + for (j = 0; j < 3; j++, i++) { + copy_v3_v3(&fp[j * 3], bezt->vec[j]); } - bezt++; + fp[9] = bezt->tilt; + fp[10] = bezt->radius; + + fp += KEYELEM_FLOAT_LEN_BEZTRIPLE; } + bezt++; } - else { - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - index = getKeyIndexOrig_keyIndex(editnurb, bp); + } + else { + bp = nu->bp; + a = nu->pntsu * nu->pntsv; + while (a--) { + index = getKeyIndexOrig_keyIndex(editnurb, bp); - if (index >= 0) { - curofp = ofp + index; - copy_v3_v3(fp, curofp); - fp[3] = curofp[3]; - fp[4] = curofp[4]; + if (index >= 0) { + curofp = ofp + index; + copy_v3_v3(fp, curofp); + fp[3] = curofp[3]; + fp[4] = curofp[4]; - if (apply_offset) { - add_v3_v3(fp, ofs[i]); - add_v3_v3(&fp[3], ofs[i + 1]); - } - } - else { - copy_v3_v3(fp, bp->vec); - fp[3] = bp->tilt; - fp[4] = bp->radius; + if (apply_offset) { + add_v3_v3(fp, ofs[i]); + add_v3_v3(&fp[3], ofs[i + 1]); } - - fp += KEYELEM_FLOAT_LEN_BPOINT; - bp++; - i += 2; } + else { + copy_v3_v3(fp, bp->vec); + fp[3] = bp->tilt; + fp[4] = bp->radius; + } + + fp += KEYELEM_FLOAT_LEN_BPOINT; + bp++; + i += 2; } } } - - nu = nu->next; - newnu = newnu->next; } - if (apply_offset) { - /* handles could become malicious after offsets applying */ - calc_keyHandles(&editnurb->nurbs, newkey); - } - - currkey->totelem = totvert; - if (currkey->data) { - MEM_freeN(currkey->data); - } - currkey->data = newkey; + nu = nu->next; + newnu = newnu->next; + } - currkey = currkey->next; + if (apply_offset) { + /* handles could become malicious after offsets applying */ + calc_keyHandles(&editnurb->nurbs, newkey); } - if (ofs) { - MEM_freeN(ofs); + currkey->totelem = totvert; + if (currkey->data) { + MEM_freeN(currkey->data); } + currkey->data = newkey; + } + + if (ofs) { + MEM_freeN(ofs); } } @@ -929,11 +905,10 @@ static void fcurve_path_rename(AnimData *adt, ListBase *orig_curves, ListBase *curves) { - FCurve *fcu, *nfcu, *nextfcu; + FCurve *nfcu; int len = strlen(orig_rna_path); - for (fcu = orig_curves->first; fcu; fcu = nextfcu) { - nextfcu = fcu->next; + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { if (STREQLEN(fcu->rna_path, orig_rna_path, len)) { char *spath, *suffix = fcu->rna_path + len; nfcu = BKE_fcurve_copy(fcu); @@ -977,16 +952,15 @@ static void fcurve_remove(AnimData *adt, ListBase *orig_curves, FCurve *fcu) static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) { - int nu_index = 0, a, pt_index; + int a, pt_index; EditNurb *editnurb = cu->editnurb; - Nurb *nu; CVKeyIndex *keyIndex; char rna_path[64], orig_rna_path[64]; AnimData *adt = BKE_animdata_from_id(&cu->id); ListBase curves = {NULL, NULL}; - FCurve *fcu, *next; - for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) { + int nu_index = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) { if (nu->bezt) { BezTriple *bezt = nu->bezt; a = nu->pntsu; @@ -1054,19 +1028,18 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) /* remove paths for removed control points * need this to make further step with copying non-cv related curves copying * not touching cv's f-curves */ - for (fcu = orig_curves->first; fcu; fcu = next) { - next = fcu->next; - - if (STREQLEN(fcu->rna_path, "splines", 7)) { + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { + if (STRPREFIX(fcu->rna_path, "splines")) { const char *ch = strchr(fcu->rna_path, '.'); - if (ch && (STREQLEN(ch, ".bezier_points", 14) || STREQLEN(ch, ".points", 7))) { + if (ch && (STRPREFIX(ch, ".bezier_points") || STRPREFIX(ch, ".points"))) { fcurve_remove(adt, orig_curves, fcu); } } } - for (nu = editnurb->nurbs.first, nu_index = 0; nu != NULL; nu = nu->next, nu_index++) { + nu_index = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, nu_index) { keyIndex = NULL; if (nu->pntsu) { if (nu->bezt) { @@ -1086,10 +1059,8 @@ static void curve_rename_fcurves(Curve *cu, ListBase *orig_curves) /* the remainders in orig_curves can be copied back (like follow path) */ /* (if it's not path to spline) */ - for (fcu = orig_curves->first; fcu; fcu = next) { - next = fcu->next; - - if (STREQLEN(fcu->rna_path, "splines", 7)) { + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, orig_curves) { + if (STRPREFIX(fcu->rna_path, "splines")) { fcurve_remove(adt, orig_curves, fcu); } else { @@ -1141,13 +1112,11 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) { Curve *curve = (Curve *)obedit->data; EditNurb *editnurb = curve->editnurb; - Nurb *nu; CVKeyIndex *keyIndex; int *old_to_new_map; - int old_totvert; - int vertex_index; - for (nu = curve->nurb.first, old_totvert = 0; nu != NULL; nu = nu->next) { + int old_totvert = 0; + LISTBASE_FOREACH (Nurb *, nu, &curve->nurb) { if (nu->bezt) { old_totvert += nu->pntsu * 3; } @@ -1161,7 +1130,8 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) old_to_new_map[i] = -1; } - for (nu = editnurb->nurbs.first, vertex_index = 0; nu != NULL; nu = nu->next) { + int vertex_index = 0; + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->bezt) { BezTriple *bezt = nu->bezt; int a = nu->pntsu; @@ -1205,7 +1175,6 @@ static int *init_index_map(Object *obedit, int *r_old_totvert) static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) { - Object *object; Curve *curve = (Curve *)obedit->data; EditNurb *editnurb = curve->editnurb; int *old_to_new_map = NULL; @@ -1219,8 +1188,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) return; } - for (object = bmain->objects.first; object; object = object->id.next) { - ModifierData *md; + LISTBASE_FOREACH (Object *, object, &bmain->objects) { int index; if ((object->parent) && (object->parent->data == curve) && ELEM(object->partype, PARVERT1, PARVERT3)) { @@ -1248,7 +1216,7 @@ static void remap_hooks_and_vertex_parents(Main *bmain, Object *obedit) } } if (object->data == curve) { - for (md = object->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Hook) { HookModifierData *hmd = (HookModifierData *)md; int i, j; @@ -1290,13 +1258,12 @@ void ED_curve_editnurb_load(Main *bmain, Object *obedit) if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu = obedit->data; - Nurb *nu, *newnu; ListBase newnurb = {NULL, NULL}, oldnurb = cu->nurb; remap_hooks_and_vertex_parents(bmain, obedit); - for (nu = editnurb->first; nu; nu = nu->next) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, editnurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); BLI_addtail(&newnurb, newnu); if (nu->type == CU_NURBS) { @@ -1323,7 +1290,6 @@ void ED_curve_editnurb_make(Object *obedit) { Curve *cu = (Curve *)obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu, *newnu; KeyBlock *actkey; if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { @@ -1346,12 +1312,10 @@ void ED_curve_editnurb_make(Object *obedit) cu->editnurb = editnurb; } - nu = cu->nurb.first; - while (nu) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); BKE_nurb_test_2d(newnu); /* after join, or any other creation of curve */ BLI_addtail(&editnurb->nurbs, newnu); - nu = nu->next; } /* animation could be added in editmode even if there was no animdata in @@ -1722,11 +1686,10 @@ static void rotateflagNurb(ListBase *editnurb, const float rotmat[3][3]) { /* all verts with (flag & 'flag') rotate */ - Nurb *nu; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_NURBS) { bp = nu->bp; a = nu->pntsu * nu->pntsv; @@ -1746,12 +1709,11 @@ static void rotateflagNurb(ListBase *editnurb, void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float vec[3]) { /* all verts with ('flag' & flag) translate */ - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { a = nu->pntsu; bezt = nu->bezt; @@ -1785,11 +1747,10 @@ void ed_editnurb_translate_flag(ListBase *editnurb, uint8_t flag, const float ve static void weightflagNurb(ListBase *editnurb, short flag, float w) { - Nurb *nu; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_NURBS) { a = nu->pntsu * nu->pntsv; bp = nu->bp; @@ -1808,16 +1769,12 @@ static void ed_surf_delete_selected(Object *obedit) { Curve *cu = obedit->data; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu, *next; BPoint *bp, *bpn, *newbp; int a, b, newu, newv; BLI_assert(obedit->type == OB_SURF); - nu = editnurb->first; - while (nu) { - next = nu->next; - + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, editnurb) { /* is entire nurb selected */ bp = nu->bp; a = nu->pntsu * nu->pntsv; @@ -1903,7 +1860,6 @@ static void ed_surf_delete_selected(Object *obedit) } } } - nu = next; } } @@ -1912,15 +1868,12 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs; - Nurb *nu, *next; BezTriple *bezt, *bezt1; BPoint *bp, *bp1; int a, type, nuindex = 0; /* first loop, can we remove entire pieces? */ - nu = nubase->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -1981,13 +1934,10 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) clamp_nurb_order_u(nu); } #endif - nu = next; nuindex++; } /* 2nd loop, delete small pieces: just for curves */ - nu = nubase->first; - while (nu) { - next = nu->next; + LISTBASE_FOREACH_MUTABLE (Nurb *, nu, nubase) { type = 0; if (nu->type == CU_BEZIER) { bezt = nu->bezt; @@ -2047,21 +1997,17 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) BKE_nurb_order_clamp_u(nu); BKE_nurb_knot_calc_u(nu); } - nu = next; } } /* only for OB_SURF */ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) { - Nurb *nu; BPoint *bp, *bpn, *newbp; int a, u, v, len; bool ok = false; - nu = editnurb->nurbs.first; - while (nu) { - + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->pntsv == 1) { bp = nu->bp; a = nu->pntsu; @@ -2109,7 +2055,7 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) bp++; } - if (u == 0 || u == nu->pntsv - 1) { /* row in u-direction selected */ + if (ELEM(u, 0, nu->pntsv - 1)) { /* row in u-direction selected */ ok = true; newbp = (BPoint *)MEM_mallocN(nu->pntsu * (nu->pntsv + 1) * sizeof(BPoint), "extrudeNurb1"); @@ -2137,7 +2083,7 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) nu->pntsv++; BKE_nurb_knot_calc_v(nu); } - else if (v == 0 || v == nu->pntsu - 1) { /* column in v-direction selected */ + else if (ELEM(v, 0, nu->pntsu - 1)) { /* column in v-direction selected */ ok = true; bpn = newbp = (BPoint *)MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint), "extrudeNurb1"); @@ -2166,7 +2112,6 @@ bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) } } } - nu = nu->next; } return ok; @@ -2197,14 +2142,15 @@ static void adduplicateflagNurb( Object *obedit, View3D *v3d, ListBase *newnurb, const uint8_t flag, const bool split) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu, *newnu; + Nurb *newnu; BezTriple *bezt, *bezt1; BPoint *bp, *bp1, *bp2, *bp3; Curve *cu = (Curve *)obedit->data; - int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv, i; + int a, b, c, starta, enda, diffa, cyclicu, cyclicv, newu, newv; char *usel; - for (i = 0, nu = editnurb->first; nu; i++, nu = nu->next) { + int i = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, editnurb, i) { cyclicu = cyclicv = 0; if (nu->type == CU_BEZIER) { for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) { @@ -2363,7 +2309,7 @@ static void adduplicateflagNurb( newv = 0; for (a = 0; a < nu->pntsu; a++) { if (usel[a]) { - if (newv == 0 || usel[a] == newv) { + if (ELEM(newv, 0, usel[a])) { newv = usel[a]; newu++; } @@ -2569,7 +2515,7 @@ static void adduplicateflagNurb( } if (BLI_listbase_is_empty(newnurb) == false) { - for (nu = newnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, newnurb) { if (nu->type == CU_BEZIER) { if (split) { /* recalc first and last */ @@ -2619,10 +2565,9 @@ static int switch_direction_exec(bContext *C, wmOperator *UNUSED(op)) } EditNurb *editnurb = cu->editnurb; - Nurb *nu; - int i; - for (nu = editnurb->nurbs.first, i = 0; nu; nu = nu->next, i++) { + int i = 0; + LISTBASE_FOREACH_INDEX (Nurb *, nu, &editnurb->nurbs, i) { if (ED_curve_nurb_select_check(v3d, nu)) { BKE_nurb_direction_switch(nu); keyData_switchDirectionNurb(cu, nu); @@ -2674,13 +2619,12 @@ static int set_goal_weight_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; float weight = RNA_float_get(op->ptr, "weight"); int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { if (bezt->f2 & SELECT) { @@ -2741,13 +2685,12 @@ static int set_radius_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; float radius = RNA_float_get(op->ptr, "radius"); int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { for (bezt = nu->bezt, a = 0; a < nu->pntsu; a++, bezt++) { if (bezt->f2 & SELECT) { @@ -2853,12 +2796,11 @@ static int smooth_exec(bContext *C, wmOperator *UNUSED(op)) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; int a, a_end; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { /* duplicate the curve to use in weight calculation */ const BezTriple *bezt_orig = MEM_dupallocN(nu->bezt); @@ -2960,7 +2902,6 @@ void CURVE_OT_smooth(wmOperatorType *ot) static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, const int bp_offset) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; @@ -2970,7 +2911,7 @@ static void curve_smooth_value(ListBase *editnurb, const int bezt_offsetof, cons int start_sel, end_sel; /* selection indices, inclusive */ float start_rad, end_rad, fac, range; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { #define BEZT_VALUE(bezt) (*((float *)((char *)(bezt) + bezt_offsetof))) @@ -3289,12 +3230,11 @@ static int hide_exec(bContext *C, wmOperator *op) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int a, sel; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -3385,13 +3325,12 @@ static int reveal_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { nu->hide = 0; if (nu->type == CU_BEZIER) { bezt = nu->bezt; @@ -3462,7 +3401,6 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts) { Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu; BezTriple *bezt, *beztnew, *beztn; BPoint *bp, *prevbp, *bpnew, *bpn; float vec[15]; @@ -3471,7 +3409,7 @@ static void subdividenurb(Object *obedit, View3D *v3d, int number_cuts) // printf("*** subdivideNurb: entering subdivide\n"); - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { amount = 0; if (nu->type == CU_BEZIER) { BezTriple *nextbezt; @@ -3925,18 +3863,17 @@ static int set_spline_type_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); View3D *v3d = CTX_wm_view3d(C); ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; bool changed = false; bool changed_size = false; const bool use_handles = RNA_boolean_get(op->ptr, "use_handles"); const int type = RNA_enum_get(op->ptr, "type"); - if (type == CU_CARDINAL || type == CU_BSPLINE) { + if (ELEM(type, CU_CARDINAL, CU_BSPLINE)) { BKE_report(op->reports, RPT_ERROR, "Not yet implemented"); continue; } - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { const int pntsu_prev = nu->pntsu; const char *err_msg = NULL; @@ -4225,12 +4162,11 @@ static void make_selection_list_nurb(View3D *v3d, ListBase *editnurb, ListBase * { ListBase nbase = {NULL, NULL}; NurbSort *nus, *nustest, *headdo, *taildo; - Nurb *nu; BPoint *bp; float dist, headdist, taildist; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { nus = (NurbSort *)MEM_callocN(sizeof(NurbSort), "sort"); @@ -4472,7 +4408,7 @@ static int merge_nurb(View3D *v3d, Object *obedit) /* resolution match, to avoid uv rotations */ if (nus1->nu->pntsv == 1) { - if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) { + if (ELEM(nus1->nu->pntsu, nus2->nu->pntsu, nus2->nu->pntsv)) { /* pass */ } else { @@ -4480,7 +4416,7 @@ static int merge_nurb(View3D *v3d, Object *obedit) } } else if (nus2->nu->pntsv == 1) { - if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) { + if (ELEM(nus2->nu->pntsu, nus1->nu->pntsu, nus1->nu->pntsv)) { /* pass */ } else { @@ -4996,7 +4932,6 @@ bool ed_editnurb_spin( { Curve *cu = (Curve *)obedit->data; ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; float cmat[3][3], tmat[3][3], imat[3][3]; float bmat[3][3], rotmat[3][3], scalemat1[3][3], scalemat2[3][3]; float persmat[3][3], persinv[3][3]; @@ -5056,7 +4991,7 @@ bool ed_editnurb_spin( } if (ok) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (ED_curve_nurb_select_check(v3d, nu)) { nu->orderv = 4; nu->flagv |= CU_NURB_CYCLIC; @@ -5427,8 +5362,6 @@ static int ed_editcurve_addvert(Curve *cu, View3D *v3d, const float location_init[3]) { - Nurb *nu; - float center[3]; float temp[3]; uint verts_len; @@ -5437,7 +5370,7 @@ static int ed_editcurve_addvert(Curve *cu, zero_v3(center); verts_len = 0; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { int i; if (nu->type == CU_BEZIER) { BezTriple *bezt; @@ -5472,7 +5405,7 @@ static int ed_editcurve_addvert(Curve *cu, ofs[2] = 0.0f; } - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->type == CU_BEZIER) { BezTriple *bezt; for (i = 0, bezt = nu->bezt; i < nu->pntsu; i++, bezt++) { @@ -5511,7 +5444,7 @@ static int ed_editcurve_addvert(Curve *cu, } /* nothing selected: create a new curve */ - nu = BKE_curve_nurb_active_get(cu); + Nurb *nu = BKE_curve_nurb_active_get(cu); if (!nu || nu->type == CU_BEZIER) { Nurb *nurb_new; @@ -5764,8 +5697,7 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op)) /* First test: curve? */ if (obedit->type != OB_CURVE) { - Nurb *nu; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) == 1)) { as_curve = true; break; @@ -5819,13 +5751,12 @@ void CURVE_OT_extrude(wmOperatorType *ot) static bool curve_toggle_cyclic(View3D *v3d, ListBase *editnurb, int direction) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; bool changed = false; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->pntsu > 1 || nu->pntsv > 1) { if (nu->type == CU_POLY) { a = nu->pntsu; @@ -5932,10 +5863,9 @@ static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUS ListBase *editnurb = object_editcurve_get(obedit); uiPopupMenu *pup; uiLayout *layout; - Nurb *nu; if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->pntsu > 1 || nu->pntsv > 1) { if (nu->type == CU_NURBS) { pup = UI_popup_menu_begin(C, IFACE_("Direction"), ICON_NONE); @@ -6064,12 +5994,12 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nubase = &editnurb->nurbs, newnurb = {NULL, NULL}; - Nurb *nu, *nu1; + Nurb *nu1; BezTriple *bezt, *bezt1, *bezt2; BPoint *bp, *bp1, *bp2; int a, b, starta, enda, cut, cyclicut; - for (nu = nubase->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nubase) { nu1 = NULL; starta = enda = cut = -1; cyclicut = 0; @@ -6452,7 +6382,7 @@ static bool curve_delete_segments(Object *obedit, View3D *v3d, const bool split) } } - for (nu = newnurb.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &newnurb) { if (nu->type == CU_BEZIER) { if (split) { /* deselect for split operator */ @@ -6620,9 +6550,8 @@ static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op)) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if ((nu->type == CU_BEZIER) && (nu->pntsu > 2)) { uint span_step[2] = {nu->pntsu, nu->pntsu}; uint span_len; @@ -6766,9 +6695,8 @@ static int curve_decimate_exec(bContext *C, wmOperator *op) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { if ((nu->pntsu > 2) && nurb_bezt_flag_any(nu, SELECT)) { const int error_target_len = max_ii(2, nu->pntsu * ratio); @@ -6917,7 +6845,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob_active = CTX_data_active_object(C); Curve *cu; - Nurb *nu, *newnu; BezTriple *bezt; BPoint *bp; ListBase tempbase; @@ -6955,9 +6882,8 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) /* watch it: switch order here really goes wrong */ mul_m4_m4m4(cmat, imat, ob_iter->obmat); - nu = cu->nurb.first; - while (nu) { - newnu = BKE_nurb_duplicate(nu); + LISTBASE_FOREACH (Nurb *, nu, &cu->nurb) { + Nurb *newnu = BKE_nurb_duplicate(nu); if (ob_active->totcol) { /* TODO, merge material lists */ CLAMP(newnu->mat_nr, 0, ob_active->totcol - 1); } @@ -6983,7 +6909,6 @@ int ED_curve_join_objects_exec(bContext *C, wmOperator *op) bp++; } } - nu = nu->next; } } @@ -7035,12 +6960,11 @@ static int clear_tilt_exec(bContext *C, wmOperator *UNUSED(op)) } ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->bezt) { bezt = nu->bezt; a = nu->pntsu; diff --git a/source/blender/editors/curve/editcurve_add.c b/source/blender/editors/curve/editcurve_add.c index 684666aba13..5b66d473466 100644 --- a/source/blender/editors/curve/editcurve_add.c +++ b/source/blender/editors/curve/editcurve_add.c @@ -141,7 +141,7 @@ Nurb *ED_curve_add_nurbs_primitive( BKE_nurbList_flag_set(editnurb, SELECT, false); /* these types call this function to return a Nurb */ - if (stype != CU_PRIM_TUBE && stype != CU_PRIM_DONUT) { + if (!ELEM(stype, CU_PRIM_TUBE, CU_PRIM_DONUT)) { nu = (Nurb *)MEM_callocN(sizeof(Nurb), "addNurbprim"); nu->type = cutype; nu->resolu = cu->resolu; @@ -397,8 +397,8 @@ Nurb *ED_curve_add_nurbs_primitive( break; case CU_PRIM_SPHERE: /* sphere */ if (cutype == CU_NURBS) { - const float tmp_cent[3] = {0.f, 0.f, 0.f}; - const float tmp_vec[3] = {0.f, 0.f, 1.f}; + const float tmp_cent[3] = {0.0f, 0.0f, 0.0f}; + const float tmp_vec[3] = {0.0f, 0.0f, 1.0f}; nu->pntsu = 5; nu->pntsv = 1; @@ -451,8 +451,8 @@ Nurb *ED_curve_add_nurbs_primitive( break; case CU_PRIM_DONUT: /* torus */ if (cutype == CU_NURBS) { - const float tmp_cent[3] = {0.f, 0.f, 0.f}; - const float tmp_vec[3] = {0.f, 0.f, 1.f}; + const float tmp_cent[3] = {0.0f, 0.0f, 0.0f}; + const float tmp_vec[3] = {0.0f, 0.0f, 1.0f}; xzproj = 1; nu = ED_curve_add_nurbs_primitive(C, obedit, mat, CU_NURBS | CU_PRIM_CIRCLE, 0); diff --git a/source/blender/editors/curve/editcurve_query.c b/source/blender/editors/curve/editcurve_query.c index 48571ab2a9b..56392aab5bf 100644 --- a/source/blender/editors/curve/editcurve_query.c +++ b/source/blender/editors/curve/editcurve_query.c @@ -26,6 +26,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BKE_curve.h" @@ -170,7 +171,6 @@ void ED_curve_nurb_vert_selected_find( /* in nu and (bezt or bp) selected are written if there's 1 sel. */ /* if more points selected in 1 spline: return only nu, bezt and bp are 0 */ ListBase *editnurb = &cu->editnurb->nurbs; - Nurb *nu1; BezTriple *bezt1; BPoint *bp1; int a; @@ -179,13 +179,13 @@ void ED_curve_nurb_vert_selected_find( *r_bezt = NULL; *r_bp = NULL; - for (nu1 = editnurb->first; nu1; nu1 = nu1->next) { + LISTBASE_FOREACH (Nurb *, nu1, editnurb) { if (nu1->type == CU_BEZIER) { bezt1 = nu1->bezt; a = nu1->pntsu; while (a--) { if (BEZT_ISSEL_ANY_HIDDENHANDLES(v3d, bezt1)) { - if (*r_nu != NULL && *r_nu != nu1) { + if (!ELEM(*r_nu, NULL, nu1)) { *r_nu = NULL; *r_bp = NULL; *r_bezt = NULL; @@ -209,7 +209,7 @@ void ED_curve_nurb_vert_selected_find( a = nu1->pntsu * nu1->pntsv; while (a--) { if (bp1->f1 & SELECT) { - if (*r_nu != NULL && *r_nu != nu1) { + if (!ELEM(*r_nu, NULL, nu1)) { *r_bp = NULL; *r_bezt = NULL; *r_nu = NULL; diff --git a/source/blender/editors/curve/editcurve_select.c b/source/blender/editors/curve/editcurve_select.c index aa4ba332b66..4097275a2b9 100644 --- a/source/blender/editors/curve/editcurve_select.c +++ b/source/blender/editors/curve/editcurve_select.c @@ -237,9 +237,7 @@ int ED_curve_select_count(View3D *v3d, struct EditNurb *editnurb) bool ED_curve_select_check(View3D *v3d, struct EditNurb *editnurb) { - Nurb *nu; - - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (ED_curve_nurb_select_check(v3d, nu)) { return true; } @@ -284,13 +282,12 @@ bool ED_curve_deselect_all_multi(struct bContext *C) bool ED_curve_select_swap(EditNurb *editnurb, bool hide_handles) { - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; bool changed = false; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -331,7 +328,6 @@ static void select_adjacent_cp(ListBase *editnurb, const bool cont, const bool selstatus) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; @@ -341,7 +337,7 @@ static void select_adjacent_cp(ListBase *editnurb, return; } - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { lastsel = false; if (nu->type == CU_BEZIER) { a = nu->pntsu; @@ -412,7 +408,6 @@ static void select_adjacent_cp(ListBase *editnurb, static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap, bool selstatus) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; Curve *cu; @@ -425,7 +420,7 @@ static void selectend_nurb(Object *obedit, eEndPoint_Types selfirst, bool doswap cu = (Curve *)obedit->data; cu->actvert = CU_ACT_NONE; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { a = nu->pntsu; @@ -632,10 +627,9 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op)) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; ListBase *nurbs = &editnurb->nurbs; - Nurb *nu; bool changed = false; - for (nu = nurbs->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { if (ED_curve_nurb_select_check(v3d, nu)) { changed |= ED_curve_nurb_select_all(nu); } @@ -887,7 +881,6 @@ void CURVE_OT_select_previous(wmOperatorType *ot) static void curve_select_more(Object *obedit) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp, *tempbp; int a; short sel = 0; @@ -897,7 +890,7 @@ static void curve_select_more(Object *obedit) /* The algorithm is designed to work in planar cases so it */ /* may not be optimal always (example: end of NURBS sphere) */ if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; @@ -997,7 +990,6 @@ void CURVE_OT_select_more(wmOperatorType *ot) static void curve_select_less(Object *obedit) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; @@ -1005,7 +997,7 @@ static void curve_select_less(Object *obedit) bool lastsel = false; if (obedit->type == OB_SURF) { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { BLI_bitmap *selbpoints; a = nu->pntsu * nu->pntsv; bp = nu->bp; @@ -1077,7 +1069,7 @@ static void curve_select_less(Object *obedit) } } else { - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { lastsel = false; /* check what type of curve/nurb it is */ if (nu->type == CU_BEZIER) { @@ -1210,14 +1202,13 @@ void CURVE_OT_select_less(wmOperatorType *ot) static void curve_select_random(ListBase *editnurb, float randfac, int seed, bool select) { - Nurb *nu; BezTriple *bezt; BPoint *bp; int a; RNG *rng = BLI_rng_new_srandom(seed); - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -1431,9 +1422,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot) } /* -------------------------------------------------------------------- */ -/* Select Similar */ - -/** \name Select Similar +/** \name Select Similar Operator * \{ */ static const EnumPropertyItem curve_prop_similar_compare_types[] = { @@ -1702,8 +1691,7 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; - Nurb *nu; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { if (!ED_curve_nurb_select_check(v3d, nu)) { continue; } @@ -1736,9 +1724,8 @@ static int curve_select_similar_exec(bContext *C, wmOperator *op) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; bool changed = false; - Nurb *nu; - for (nu = editnurb->nurbs.first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { switch (optype) { case SIMCURHAND_TYPE: { if (nu->type & type_ref) { @@ -1797,9 +1784,7 @@ void CURVE_OT_select_similar(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/* Select Shortest Path */ - -/** \name Select Path +/** \name Select Shortest Path Operator * \{ */ static float curve_calc_dist_pair(const Nurb *nu, int a, int b) diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index 2a880c11afb..d6744472c0e 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -626,7 +626,7 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ @@ -635,7 +635,10 @@ void FONT_OT_text_paste_from_file(wmOperatorType *ot) /** \name Text To Object * \{ */ -static void txt_add_object(bContext *C, TextLine *firstline, int totline, const float offset[3]) +static void txt_add_object(bContext *C, + const TextLine *firstline, + int totline, + const float offset[3]) { Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -644,11 +647,11 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const Curve *cu; Object *obedit; Base *base; - struct TextLine *tmp; + const struct TextLine *tmp; int nchars = 0, nbytes = 0; char *s; int a; - const float rot[3] = {0.f, 0.f, 0.f}; + const float rot[3] = {0.0f, 0.0f, 0.0f}; obedit = BKE_object_add(bmain, view_layer, OB_FONT, NULL); base = view_layer->basact; @@ -709,10 +712,10 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, const WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, obedit); } -void ED_text_to_object(bContext *C, Text *text, const bool split_lines) +void ED_text_to_object(bContext *C, const Text *text, const bool split_lines) { RegionView3D *rv3d = CTX_wm_region_view3d(C); - TextLine *line; + const TextLine *line; float offset[3]; int linenum = 0; @@ -1692,8 +1695,8 @@ static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event) if (event_val && (ascii || event->utf8_buf[0])) { /* handle case like TAB (== 9) */ - if ((ascii > 31 && ascii < 254 && ascii != 127) || (ascii == 13) || (ascii == 10) || - (ascii == 8) || (event->utf8_buf[0])) { + if ((ascii > 31 && ascii < 254 && ascii != 127) || (ELEM(ascii, 13, 10)) || (ascii == 8) || + (event->utf8_buf[0])) { if (accentcode) { if (ef->pos > 0) { @@ -2157,7 +2160,7 @@ void FONT_OT_open(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ diff --git a/source/blender/editors/curve/editfont_undo.c b/source/blender/editors/curve/editfont_undo.c index ef9bb7e0c88..61c05f62af7 100644 --- a/source/blender/editors/curve/editfont_undo.c +++ b/source/blender/editors/curve/editfont_undo.c @@ -74,6 +74,7 @@ typedef struct UndoFont { #ifdef USE_ARRAY_STORE +/* -------------------------------------------------------------------- */ /** \name Array Store * \{ */ diff --git a/source/blender/editors/gpencil/annotate_paint.c b/source/blender/editors/gpencil/annotate_paint.c index c06a2f06a98..a9f9625db7a 100644 --- a/source/blender/editors/gpencil/annotate_paint.c +++ b/source/blender/editors/gpencil/annotate_paint.c @@ -1432,6 +1432,41 @@ static bool annotation_session_initdata(bContext *C, tGPsdata *p) return 1; } +/* Enable the annotations in the current space. */ +static void annotation_visible_on_space(tGPsdata *p) +{ + ScrArea *area = p->area; + switch (area->spacetype) { + case SPACE_VIEW3D: { + View3D *v3d = (View3D *)area->spacedata.first; + v3d->flag2 |= V3D_SHOW_ANNOTATION; + break; + } + case SPACE_SEQ: { + SpaceSeq *sseq = (SpaceSeq *)area->spacedata.first; + sseq->flag |= SEQ_SHOW_GPENCIL; + break; + } + case SPACE_IMAGE: { + SpaceImage *sima = (SpaceImage *)area->spacedata.first; + sima->flag |= SI_SHOW_GPENCIL; + break; + } + case SPACE_NODE: { + SpaceNode *snode = (SpaceNode *)area->spacedata.first; + snode->flag |= SNODE_SHOW_GPENCIL; + break; + } + case SPACE_CLIP: { + SpaceClip *sclip = (SpaceClip *)area->spacedata.first; + sclip->flag |= SC_SHOW_ANNOTATION; + break; + } + default: + break; + } +} + /* init new painting session */ static tGPsdata *annotation_session_initpaint(bContext *C) { @@ -1458,6 +1493,9 @@ static tGPsdata *annotation_session_initpaint(bContext *C) */ p->radius = U.gp_eraser; + /* Annotations must be always visible when use it. */ + annotation_visible_on_space(p); + /* return context data for running paint operator */ return p; } @@ -2003,7 +2041,7 @@ static void annotation_draw_apply(wmOperator *op, tGPsdata *p, Depsgraph *depsgr short ok = annotation_stroke_addpoint(p, p->mval, p->pressure, p->curtime); /* handle errors while adding point */ - if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { + if (ELEM(ok, GP_STROKEADD_FULL, GP_STROKEADD_OVERFLOW)) { /* finish off old stroke */ annotation_paint_strokeend(p); /* And start a new one!!! Else, projection errors! */ diff --git a/source/blender/editors/gpencil/gpencil_convert.c b/source/blender/editors/gpencil/gpencil_convert.c index 2d9f49fa1ed..237b5839c42 100644 --- a/source/blender/editors/gpencil/gpencil_convert.c +++ b/source/blender/editors/gpencil/gpencil_convert.c @@ -1616,9 +1616,13 @@ static bool gpencil_convert_poll_property(const bContext *UNUSED(C), const bool valid_timing = RNA_boolean_get(ptr, "use_timing_data"); /* Always show those props */ - if (STREQ(prop_id, "type") || STREQ(prop_id, "use_normalize_weights") || - STREQ(prop_id, "radius_multiplier") || STREQ(prop_id, "use_link_strokes") || - STREQ(prop_id, "bevel_depth") || STREQ(prop_id, "bevel_resolution")) { + if (STR_ELEM(prop_id, + "type", + "use_normalize_weights", + "radius_multiplier", + "use_link_strokes", + "bevel_depth", + "bevel_resolution")) { return true; } @@ -1635,7 +1639,7 @@ static bool gpencil_convert_poll_property(const bContext *UNUSED(C), if (timing_mode != GP_STROKECONVERT_TIMING_NONE) { /* Only show when link_stroke is true and stroke timing is enabled */ - if (STREQ(prop_id, "frame_range") || STREQ(prop_id, "start_frame")) { + if (STR_ELEM(prop_id, "frame_range", "start_frame")) { return true; } diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 07a1b34fa84..2cee06c36ad 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -1557,14 +1557,14 @@ static int gpencil_stroke_arrange_exec(bContext *C, wmOperator *op) continue; } /* some stroke is already at front*/ - if ((direction == GP_STROKE_MOVE_TOP) || (direction == GP_STROKE_MOVE_UP)) { + if (ELEM(direction, GP_STROKE_MOVE_TOP, GP_STROKE_MOVE_UP)) { if (gps == gpf->strokes.last) { gpf_lock = true; continue; } } /* some stroke is already at botom */ - if ((direction == GP_STROKE_MOVE_BOTTOM) || (direction == GP_STROKE_MOVE_DOWN)) { + if (ELEM(direction, GP_STROKE_MOVE_BOTTOM, GP_STROKE_MOVE_DOWN)) { if (gps == gpf->strokes.first) { gpf_lock = true; continue; @@ -3035,7 +3035,7 @@ static int gpencil_material_isolate_exec(bContext *C, wmOperator *op) for (short i = 0; i < *totcol; i++) { ma = BKE_gpencil_material(ob, i + 1); /* Skip if this is the active one */ - if ((ma == NULL) || (ma == active_ma)) { + if (ELEM(ma, NULL, active_ma)) { continue; } diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index d54bdf552eb..4ba75bcd604 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1042,7 +1042,7 @@ static void gpencil_add_move_points(bGPDframe *gpf, bGPDstroke *gps) /* review points in the middle of stroke to create new strokes */ for (int i = 0; i < gps->totpoints; i++) { /* skip first and last point */ - if ((i == 0) || (i == gps->totpoints - 1)) { + if (ELEM(i, 0, gps->totpoints - 1)) { continue; } @@ -2737,12 +2737,12 @@ static bool gpencil_snap_poll(bContext *C) static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op)) { bGPdata *gpd = ED_gpencil_data_get_active(C); - RegionView3D *rv3d = CTX_wm_region_data(C); + ARegion *region = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Object *obact = CTX_data_active_object(C); - const float gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL); + const float gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL); LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* only editable and visible layers are considered */ @@ -3152,8 +3152,8 @@ void GPENCIL_OT_stroke_cyclical_set(wmOperatorType *ot) PropertyRNA *prop; static const EnumPropertyItem cyclic_type[] = { - {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close all", ""}, - {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open all", ""}, + {GP_STROKE_CYCLIC_CLOSE, "CLOSE", 0, "Close All", ""}, + {GP_STROKE_CYCLIC_OPEN, "OPEN", 0, "Open All", ""}, {GP_STROKE_CYCLIC_TOGGLE, "TOGGLE", 0, "Toggle", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -3221,13 +3221,13 @@ static int gpencil_stroke_caps_set_exec(bContext *C, wmOperator *op) continue; } - if ((type == GP_STROKE_CAPS_TOGGLE_BOTH) || (type == GP_STROKE_CAPS_TOGGLE_START)) { + if (ELEM(type, GP_STROKE_CAPS_TOGGLE_BOTH, GP_STROKE_CAPS_TOGGLE_START)) { ++gps->caps[0]; if (gps->caps[0] >= GP_STROKE_CAP_MAX) { gps->caps[0] = GP_STROKE_CAP_ROUND; } } - if ((type == GP_STROKE_CAPS_TOGGLE_BOTH) || (type == GP_STROKE_CAPS_TOGGLE_END)) { + if (ELEM(type, GP_STROKE_CAPS_TOGGLE_BOTH, GP_STROKE_CAPS_TOGGLE_END)) { ++gps->caps[1]; if (gps->caps[1] >= GP_STROKE_CAP_MAX) { gps->caps[1] = GP_STROKE_CAP_ROUND; @@ -3398,24 +3398,50 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, } /* define start and end points of each stroke */ - float area[3], sb[3], ea[3], eb[3]; + float start_a[3], start_b[3], end_a[3], end_b[3]; pt = &gps_a->points[0]; - copy_v3_v3(area, &pt->x); + copy_v3_v3(start_a, &pt->x); pt = &gps_a->points[gps_a->totpoints - 1]; - copy_v3_v3(ea, &pt->x); + copy_v3_v3(end_a, &pt->x); pt = &gps_b->points[0]; - copy_v3_v3(sb, &pt->x); + copy_v3_v3(start_b, &pt->x); pt = &gps_b->points[gps_b->totpoints - 1]; - copy_v3_v3(eb, &pt->x); + copy_v3_v3(end_b, &pt->x); + + /* Check if need flip strokes. */ + float dist = len_squared_v3v3(end_a, start_b); + bool flip_a = false; + bool flip_b = false; + float lowest = dist; + + dist = len_squared_v3v3(end_a, end_b); + if (dist < lowest) { + lowest = dist; + flip_a = false; + flip_b = true; + } + + dist = len_squared_v3v3(start_a, start_b); + if (dist < lowest) { + lowest = dist; + flip_a = true; + flip_b = false; + } + + dist = len_squared_v3v3(start_a, end_b); + if (dist < lowest) { + lowest = dist; + flip_a = true; + flip_b = true; + } - /* review if need flip stroke B */ - float ea_sb = len_squared_v3v3(ea, sb); - float ea_eb = len_squared_v3v3(ea, eb); - /* flip if distance to end point is shorter */ - if (ea_eb < ea_sb) { + if (flip_a) { + gpencil_flip_stroke(gps_a); + } + if (flip_b) { gpencil_flip_stroke(gps_b); } @@ -3439,16 +3465,71 @@ static void gpencil_stroke_join_strokes(bGPDstroke *gps_a, } } +typedef struct tJoinStrokes { + bGPDframe *gpf; + bGPDstroke *gps; + bool used; +} tJoinStrokes; + +static int gpencil_get_nearest_stroke_index(tJoinStrokes *strokes_list, + const bGPDstroke *gps, + const int totstrokes) +{ + int index = -1; + float min_dist = FLT_MAX; + float dist, start_a[3], end_a[3], start_b[3], end_b[3]; + + bGPDspoint *pt = &gps->points[0]; + copy_v3_v3(start_a, &pt->x); + + pt = &gps->points[gps->totpoints - 1]; + copy_v3_v3(end_a, &pt->x); + + for (int i = 0; i < totstrokes; i++) { + tJoinStrokes *elem = &strokes_list[i]; + if (elem->used) { + continue; + } + pt = &elem->gps->points[0]; + copy_v3_v3(start_b, &pt->x); + + pt = &elem->gps->points[elem->gps->totpoints - 1]; + copy_v3_v3(end_b, &pt->x); + + dist = len_squared_v3v3(start_a, start_b); + if (dist < min_dist) { + min_dist = dist; + index = i; + } + dist = len_squared_v3v3(start_a, end_b); + if (dist < min_dist) { + min_dist = dist; + index = i; + } + dist = len_squared_v3v3(end_a, start_b); + if (dist < min_dist) { + min_dist = dist; + index = i; + } + dist = len_squared_v3v3(end_a, end_b); + if (dist < min_dist) { + min_dist = dist; + index = i; + } + } + + return index; +} + static int gpencil_stroke_join_exec(bContext *C, wmOperator *op) { bGPdata *gpd = ED_gpencil_data_get_active(C); bGPDlayer *activegpl = BKE_gpencil_layer_active_get(gpd); Object *ob = CTX_data_active_object(C); - - bGPDframe *gpf_a = NULL; - bGPDstroke *stroke_a = NULL; - bGPDstroke *stroke_b = NULL; - bGPDstroke *new_stroke = NULL; + /* Limit the number of strokes to join. It makes no sense to allow an very high number of strokes + * for CPU time and because to have a stroke with thousands of points is unpractical, so limit + * this number avoid to joining a full frame scene in one single stroke. */ + const int max_join_strokes = 128; const int type = RNA_enum_get(op->ptr, "type"); const bool leave_gaps = RNA_boolean_get(op->ptr, "leave_gaps"); @@ -3464,87 +3545,89 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op) BLI_assert(ELEM(type, GP_STROKE_JOIN, GP_STROKE_JOINCOPY)); - /* read all selected strokes */ - bool first = false; + int tot_strokes = 0; + /** Alloc memory */ + tJoinStrokes *strokes_list = MEM_malloc_arrayN(sizeof(tJoinStrokes), max_join_strokes, __func__); + tJoinStrokes *elem = NULL; + /* Read all selected strokes to create a list. */ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { bGPDframe *gpf = gpl->actframe; if (gpf == NULL) { continue; } - LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { + /* Add all stroke selected of the frame. */ + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { if (gps->flag & GP_STROKE_SELECT) { /* skip strokes that are invalid for current view */ if (ED_gpencil_stroke_can_use(C, gps) == false) { continue; } - /* check if the color is editable */ + /* check if the color is editable. */ if (ED_gpencil_stroke_color_use(ob, gpl, gps) == false) { continue; } - - /* to join strokes, cyclic must be disabled */ - gps->flag &= ~GP_STROKE_CYCLIC; - - /* saves first frame and stroke */ - if (!first) { - first = true; - gpf_a = gpf; - stroke_a = gps; + elem = &strokes_list[tot_strokes]; + elem->gpf = gpf; + elem->gps = gps; + elem->used = false; + + tot_strokes++; + /* Limit the number of strokes. */ + if (tot_strokes == max_join_strokes) { + BKE_reportf(op->reports, + RPT_WARNING, + "Too many strokes selected. Only joined first %d strokes.", + max_join_strokes); + break; } - else { - stroke_b = gps; - - /* create a new stroke if was not created before (only created if something to join) */ - if (new_stroke == NULL) { - new_stroke = BKE_gpencil_stroke_duplicate(stroke_a, true); + } + } + } + CTX_DATA_END; - /* if new, set current color */ - if (type == GP_STROKE_JOINCOPY) { - new_stroke->mat_nr = stroke_a->mat_nr; - } - } + /* Nothing to join. */ + if (tot_strokes < 2) { + MEM_SAFE_FREE(strokes_list); + return OPERATOR_CANCELLED; + } - /* join new_stroke and stroke B. New stroke will contain all the previous data */ - gpencil_stroke_join_strokes(new_stroke, stroke_b, leave_gaps); + /* Take first stroke. */ + elem = &strokes_list[0]; + elem->used = true; - /* if join only, delete old strokes */ - if (type == GP_STROKE_JOIN) { - if (stroke_a) { - /* Calc geometry data. */ - BKE_gpencil_stroke_geometry_update(new_stroke); + /* Create a new stroke. */ + bGPDstroke *gps_new = BKE_gpencil_stroke_duplicate(elem->gps, true); + gps_new->flag &= ~GP_STROKE_CYCLIC; + BLI_insertlinkbefore(&elem->gpf->strokes, elem->gps, gps_new); - BLI_insertlinkbefore(&gpf_a->strokes, stroke_a, new_stroke); - BLI_remlink(&gpf->strokes, stroke_a); - BKE_gpencil_free_stroke(stroke_a); - stroke_a = NULL; - } - if (stroke_b) { - BLI_remlink(&gpf->strokes, stroke_b); - BKE_gpencil_free_stroke(stroke_b); - stroke_b = NULL; - } - } - } - } + /* Join all strokes until the list is completed. */ + while (true) { + int i = gpencil_get_nearest_stroke_index(strokes_list, gps_new, tot_strokes); + if (i < 0) { + break; } + elem = &strokes_list[i]; + /* Join new_stroke and stroke B. */ + gpencil_stroke_join_strokes(gps_new, elem->gps, leave_gaps); + elem->used = true; } - CTX_DATA_END; - /* add new stroke if was not added before */ - if (type == GP_STROKE_JOINCOPY) { - if (new_stroke) { - /* Add a new frame if needed */ - if (activegpl->actframe == NULL) { - activegpl->actframe = BKE_gpencil_frame_addnew(activegpl, gpf_a->framenum); - } - /* Calc geometry data. */ - BKE_gpencil_stroke_geometry_update(new_stroke); + /* Calc geometry data for new stroke. */ + BKE_gpencil_stroke_geometry_update(gps_new); - BLI_addtail(&activegpl->actframe->strokes, new_stroke); + /* If join only, delete old strokes. */ + if (type == GP_STROKE_JOIN) { + for (int i = 0; i < tot_strokes; i++) { + elem = &strokes_list[i]; + BLI_remlink(&elem->gpf->strokes, elem->gps); + BKE_gpencil_free_stroke(elem->gps); } } + /* Free memory. */ + MEM_SAFE_FREE(strokes_list); + /* notifiers */ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); @@ -4306,7 +4389,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op) ob_dst->data = (bGPdata *)gpd_dst; /* Loop old data-block and separate parts. */ - if ((mode == GP_SEPARATE_POINT) || (mode == GP_SEPARATE_STROKE)) { + if (ELEM(mode, GP_SEPARATE_POINT, GP_SEPARATE_STROKE)) { CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { gpl_dst = NULL; bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; @@ -4678,7 +4761,9 @@ typedef bool (*GPencilTestFn)(bGPDstroke *gps, const float diff_mat[4][4], void *user_data); -static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke) +static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, + bGPDstroke *hit_stroke, + const bool flat_caps) { bGPDspoint *pt = NULL; bGPDspoint *pt1 = NULL; @@ -4722,6 +4807,17 @@ static void gpencil_cutter_dissolve(bGPDlayer *hit_layer, bGPDstroke *hit_stroke pt->flag &= ~GP_SPOINT_TAG; } } + /* If flat caps mode check extremes. */ + if (flat_caps) { + if (hit_stroke->points[0].flag & GP_SPOINT_TAG) { + hit_stroke->caps[0] = GP_STROKE_CAP_FLAT; + } + + if (hit_stroke->points[hit_stroke->totpoints - 1].flag & GP_SPOINT_TAG) { + hit_stroke->caps[1] = GP_STROKE_CAP_FLAT; + } + } + gpencil_stroke_delete_tagged_points( hit_layer->actframe, hit_stroke, gpsn, GP_SPOINT_TAG, false, 1); } @@ -4736,6 +4832,7 @@ static int gpencil_cutter_lasso_select(bContext *C, ScrArea *area = CTX_wm_area(C); ToolSettings *ts = CTX_data_tool_settings(C); const float scale = ts->gp_sculpt.isect_threshold; + const bool flat_caps = RNA_boolean_get(op->ptr, "flat_caps"); bGPDspoint *pt; GP_SpaceConversion gsc = {NULL}; @@ -4810,7 +4907,7 @@ static int gpencil_cutter_lasso_select(bContext *C, } LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) { if (gps->flag & GP_STROKE_SELECT) { - gpencil_cutter_dissolve(gpl, gps); + gpencil_cutter_dissolve(gpl, gps, flat_caps); } } } @@ -4884,6 +4981,8 @@ void GPENCIL_OT_stroke_cutter(wmOperatorType *ot) /* properties */ WM_operator_properties_gesture_lasso(ot); + + RNA_def_boolean(ot->srna, "flat_caps", 0, "Flat Caps", ""); } bool ED_object_gpencil_exit(struct Main *bmain, Object *ob) diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 3c1f538cb99..f06a1d6b6c8 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -359,14 +359,12 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4]) tgpw.custonion = true; /* normal strokes */ - if ((tgpf->fill_draw_mode == GP_FILL_DMODE_STROKE) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { + if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_STROKE, GP_FILL_DMODE_BOTH)) { ED_gpencil_draw_fill(&tgpw); } /* 3D Lines with basic shapes and invisible lines */ - if ((tgpf->fill_draw_mode == GP_FILL_DMODE_CONTROL) || - (tgpf->fill_draw_mode == GP_FILL_DMODE_BOTH)) { + if (ELEM(tgpf->fill_draw_mode, GP_FILL_DMODE_CONTROL, GP_FILL_DMODE_BOTH)) { gpencil_draw_basic_stroke(tgpf, gps, tgpw.diff_mat, diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index 2e13566402b..3a3a9bde38b 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -220,7 +220,7 @@ static bool gpencil_interpolate_check_todo(bContext *C, bGPdata *gpd) int fFrame; /* only selected */ - if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && + if ((GPENCIL_EDIT_MODE(gpd)) && (flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { continue; } @@ -305,7 +305,7 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) bool valid = true; /* only selected */ - if ((tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && + if ((GPENCIL_EDIT_MODE(gpd)) && (tgpi->flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { valid = false; } @@ -1023,7 +1023,7 @@ static int gpencil_interpolate_seq_exec(bContext *C, wmOperator *op) for (gps_from = prevFrame->strokes.first; gps_from; gps_from = gps_from->next) { /* only selected */ - if ((flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && + if ((GPENCIL_EDIT_MODE(gpd)) && (flag & GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED) && ((gps_from->flag & GP_STROKE_SELECT) == 0)) { continue; } diff --git a/source/blender/editors/gpencil/gpencil_merge.c b/source/blender/editors/gpencil/gpencil_merge.c index 3e63d644760..938f4ab26af 100644 --- a/source/blender/editors/gpencil/gpencil_merge.c +++ b/source/blender/editors/gpencil/gpencil_merge.c @@ -314,7 +314,7 @@ static int gpencil_insert_to_array(tGPencilPointCache *src_array, } src_elem = &src_array[idx]; /* check if all points or only a stroke */ - if ((gps_filter != NULL) && (gps_filter != src_elem->gps)) { + if (!ELEM(gps_filter, NULL, src_elem->gps)) { continue; } diff --git a/source/blender/editors/gpencil/gpencil_mesh.c b/source/blender/editors/gpencil/gpencil_mesh.c index e4862617d12..c136ef2070e 100644 --- a/source/blender/editors/gpencil/gpencil_mesh.c +++ b/source/blender/editors/gpencil/gpencil_mesh.c @@ -25,12 +25,15 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "BLI_math.h" +#include "DNA_anim_types.h" #include "DNA_gpencil_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BKE_anim_data.h" #include "BKE_context.h" #include "BKE_duplilist.h" #include "BKE_global.h" @@ -86,6 +89,35 @@ typedef struct GpBakeOb { Object *ob; } GpBakeOb; +/* Get list of keyframes used by selected objects. */ +static void animdata_keyframe_list_get(ListBase *ob_list, + const bool only_selected, + GHash *r_keyframes) +{ + /* Loop all objects to get the list of keyframes used. */ + LISTBASE_FOREACH (GpBakeOb *, elem, ob_list) { + Object *ob = elem->ob; + AnimData *adt = BKE_animdata_from_id(&ob->id); + if ((adt == NULL) || (adt->action == NULL)) { + continue; + } + LISTBASE_FOREACH (FCurve *, fcurve, &adt->action->curves) { + int i; + BezTriple *bezt; + for (i = 0, bezt = fcurve->bezt; i < fcurve->totvert; i++, bezt++) { + /* Keyframe number is x value of point. */ + if ((bezt->f2 & SELECT) || (!only_selected)) { + /* Insert only one key for each keyframe number. */ + int key = (int)bezt->vec[1][0]; + if (!BLI_ghash_haskey(r_keyframes, POINTER_FROM_INT(key))) { + BLI_ghash_insert(r_keyframes, POINTER_FROM_INT(key), POINTER_FROM_INT(key)); + } + } + } + } + } +} + static void gpencil_bake_duplilist(Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *list) { GpBakeOb *elem = NULL; @@ -161,13 +193,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); Object *ob_gpencil = NULL; - ListBase list = {NULL, NULL}; - gpencil_bake_ob_list(C, depsgraph, scene, &list); + ListBase ob_selected_list = {NULL, NULL}; + gpencil_bake_ob_list(C, depsgraph, scene, &ob_selected_list); /* Cannot check this in poll because the active object changes. */ - if (list.first == NULL) { + if (ob_selected_list.first == NULL) { BKE_report(op->reports, RPT_INFO, "No valid object selected"); - gpencil_bake_free_ob_list(&list); + gpencil_bake_free_ob_list(&ob_selected_list); return OPERATOR_CANCELLED; } @@ -186,29 +218,20 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) const int thickness = RNA_int_get(op->ptr, "thickness"); const bool use_seams = RNA_boolean_get(op->ptr, "seams"); const bool use_faces = RNA_boolean_get(op->ptr, "faces"); + const bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); const float offset = RNA_float_get(op->ptr, "offset"); const int frame_offset = RNA_int_get(op->ptr, "frame_target") - frame_start; - char target[64]; - RNA_string_get(op->ptr, "target", target); const int project_type = RNA_enum_get(op->ptr, "project_type"); + ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data; /* Create a new grease pencil object in origin. */ bool newob = false; - if (STREQ(target, "*NEW")) { + if (ob_gpencil == NULL) { ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0; const float loc[3] = {0.0f, 0.0f, 0.0f}; ob_gpencil = ED_gpencil_add_object(C, loc, local_view_bits); newob = true; } - else { - ob_gpencil = BLI_findstring(&bmain->objects, target, offsetof(ID, name) + 2); - } - - if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) { - BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid"); - gpencil_bake_free_ob_list(&list); - return OPERATOR_CANCELLED; - } bGPdata *gpd = (bGPdata *)ob_gpencil->data; gpd->draw_mode = (project_type == GP_REPROJECT_KEEP) ? GP_DRAWMODE_3D : GP_DRAWMODE_2D; @@ -237,6 +260,13 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) /* Loop all frame range. */ int oldframe = (int)DEG_get_ctime(depsgraph); int key = -1; + + /* Get list of keyframes. */ + GHash *keyframe_list = BLI_ghash_int_new(__func__); + if (only_selected) { + animdata_keyframe_list_get(&ob_selected_list, only_selected, keyframe_list); + } + for (int i = frame_start; i < frame_end + 1; i++) { key++; /* Jump if not step limit but include last frame always. */ @@ -244,12 +274,17 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) continue; } + /* Check if frame is in the list of frames to be exported. */ + if ((only_selected) && (!BLI_ghash_haskey(keyframe_list, POINTER_FROM_INT(i)))) { + continue; + } + /* Move scene to new frame. */ CFRA = i; BKE_scene_graph_update_for_newframe(depsgraph); /* Loop all objects in the list. */ - LISTBASE_FOREACH (GpBakeOb *, elem, &list) { + LISTBASE_FOREACH (GpBakeOb *, elem, &ob_selected_list) { Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, elem->ob); /* Generate strokes. */ @@ -270,13 +305,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) if (project_type != GP_REPROJECT_KEEP) { LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { bGPDframe *gpf = gpl->actframe; - if (gpf != NULL) { - LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { - if ((gps->flag & GP_STROKE_TAG) == 0) { - ED_gpencil_stroke_reproject( - depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false); - gps->flag |= GP_STROKE_TAG; - } + if (gpf == NULL) { + continue; + } + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + if ((gps->flag & GP_STROKE_TAG) == 0) { + ED_gpencil_stroke_reproject( + depsgraph, &gsc, sctx, gpl, gpf, gps, project_type, false); + gps->flag |= GP_STROKE_TAG; } } } @@ -314,10 +350,14 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) } /* Free memory. */ - gpencil_bake_free_ob_list(&list); + gpencil_bake_free_ob_list(&ob_selected_list); if (sctx != NULL) { ED_transform_snap_object_context_destroy(sctx); } + /* Free temp hash table. */ + if (keyframe_list != NULL) { + BLI_ghash_free(keyframe_list, NULL, NULL); + } /* notifiers */ if (newob) { @@ -334,6 +374,19 @@ static int gpencil_bake_mesh_animation_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int gpencil_bake_mesh_animation_invoke(bContext *C, + wmOperator *op, + const wmEvent *UNUSED(event)) +{ + /* Show popup dialog to allow editing. */ + /* FIXME: hard-coded dimensions here are just arbitrary. */ + return WM_operator_props_dialog_popup(C, op, 250); +} + +static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) +{ + return ((Object *)value.owner_id)->type == OB_GPENCIL; +} void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) { static const EnumPropertyItem reproject_type[] = { @@ -363,6 +416,7 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) ot->description = "Bake Mesh Animation to Grease Pencil strokes"; /* callbacks */ + ot->invoke = gpencil_bake_mesh_animation_invoke; ot->exec = gpencil_bake_mesh_animation_exec; ot->poll = gpencil_bake_mesh_animation_poll; @@ -370,7 +424,15 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_int( + ot->prop = RNA_def_pointer_runtime(ot->srna, + "target", + &RNA_Object, + "Target Object", + "Target grease pencil object. Leave empty for new object"); + RNA_def_property_poll_runtime(ot->prop, rna_GPencil_object_poll); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); + + prop = RNA_def_int( ot->srna, "frame_start", 1, 1, 100000, "Start Frame", "The start frame", 1, 100000); prop = RNA_def_int( @@ -379,6 +441,8 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) prop = RNA_def_int(ot->srna, "step", 1, 1, 100, "Step", "Step between generated frames", 1, 100); + RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100); + prop = RNA_def_float_rotation(ot->srna, "angle", 0, @@ -391,18 +455,22 @@ void GPENCIL_OT_bake_mesh_animation(wmOperatorType *ot) DEG2RADF(180.0f)); RNA_def_property_float_default(prop, DEG2RADF(70.0f)); - RNA_def_int(ot->srna, "thickness", 1, 1, 100, "Thickness", "", 1, 100); + RNA_def_float_distance(ot->srna, + "offset", + 0.001f, + 0.0, + 100.0, + "Stroke Offset", + "Offset strokes from fill", + 0.0, + 100.00); + RNA_def_boolean(ot->srna, "seams", 0, "Only Seam Edges", "Convert only seam edges"); RNA_def_boolean(ot->srna, "faces", 1, "Export Faces", "Export faces as filled strokes"); - RNA_def_float_distance( - ot->srna, "offset", 0.001f, 0.0, 100.0, "Offset", "Offset strokes from fill", 0.0, 100.00); - RNA_def_int(ot->srna, "frame_target", 1, 1, 100000, "Frame Target", "", 1, 100000); - RNA_def_string(ot->srna, - "target", - "*NEW", - 64, - "Target Object", - "Target grease pencil object name. Leave empty for new object"); + RNA_def_boolean( + ot->srna, "only_selected", 0, "Only Selected Keyframes", "Convert only selected keyframes"); + RNA_def_int( + ot->srna, "frame_target", 1, 1, 100000, "Target Frame", "Destination frame", 1, 100000); RNA_def_enum(ot->srna, "project_type", reproject_type, GP_REPROJECT_VIEW, "Projection Type", ""); } diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 543ff8e7e9a..82c30dea91d 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -1152,7 +1152,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p) /* invalidate any other point, to interpolate between * first and last contact in an imaginary line between them */ for (i = 0; i < gpd->runtime.sbuffer_used; i++) { - if ((i != first_valid) && (i != last_valid)) { + if (!ELEM(i, first_valid, last_valid)) { depth_arr[i] = FLT_MAX; } } @@ -2719,7 +2719,7 @@ static void gpencil_draw_apply(bContext *C, wmOperator *op, tGPsdata *p, Depsgra short ok = gpencil_stroke_addpoint(p, p->mval, p->pressure, p->curtime); /* handle errors while adding point */ - if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) { + if (ELEM(ok, GP_STROKEADD_FULL, GP_STROKEADD_OVERFLOW)) { /* finish off old stroke */ gpencil_paint_strokeend(p); /* And start a new one!!! Else, projection errors! */ diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c index c03ff05ac73..55180885c5d 100644 --- a/source/blender/editors/gpencil/gpencil_primitive.c +++ b/source/blender/editors/gpencil/gpencil_primitive.c @@ -849,7 +849,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi) /* invalidate any other point, to interpolate between * first and last contact in an imaginary line between them */ for (i = 0; i < gps->totpoints; i++) { - if ((i != first_valid) && (i != last_valid)) { + if (!ELEM(i, first_valid, last_valid)) { depth_arr[i] = FLT_MAX; } } diff --git a/source/blender/editors/gpencil/gpencil_trace.h b/source/blender/editors/gpencil/gpencil_trace.h index 3adde7651cd..85eb4e0609f 100644 --- a/source/blender/editors/gpencil/gpencil_trace.h +++ b/source/blender/editors/gpencil/gpencil_trace.h @@ -56,6 +56,10 @@ struct bGPDframe; #define BM_INV(bm, x, y) (bm_safe(bm, x, y) ? BM_UINV(bm, x, y) : 0) #define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0) +/* Trace modes */ +#define GPENCIL_TRACE_MODE_SINGLE 0 +#define GPENCIL_TRACE_MODE_SEQUENCE 1 + void ED_gpencil_trace_bitmap_print(FILE *f, const potrace_bitmap_t *bm); potrace_bitmap_t *ED_gpencil_trace_bitmap_new(int32_t w, int32_t h); diff --git a/source/blender/editors/gpencil/gpencil_trace_ops.c b/source/blender/editors/gpencil/gpencil_trace_ops.c index 4391abee5a1..2d04c31e60d 100644 --- a/source/blender/editors/gpencil/gpencil_trace_ops.c +++ b/source/blender/editors/gpencil/gpencil_trace_ops.c @@ -35,8 +35,10 @@ #include "BKE_context.h" #include "BKE_duplilist.h" +#include "BKE_global.h" #include "BKE_gpencil.h" #include "BKE_image.h" +#include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_object.h" @@ -45,11 +47,15 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "UI_interface.h" +#include "UI_resources.h" + #include "WM_api.h" #include "WM_types.h" #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -61,34 +67,50 @@ #include "gpencil_trace.h" #include "potracelib.h" +typedef struct TraceJob { + /* from wmJob */ + struct Object *owner; + short *stop, *do_update; + float *progress; + + bContext *C; + wmWindowManager *wm; + Main *bmain; + Scene *scene; + View3D *v3d; + Base *base_active; + Object *ob_active; + Image *image; + Object *ob_gpencil; + bGPdata *gpd; + bGPDlayer *gpl; + + bool was_ob_created; + + int32_t frame_target; + float threshold; + float scale; + float sample; + int32_t resolution; + int32_t thickness; + int32_t turnpolicy; + int32_t mode; + + bool success; + bool was_canceled; +} TraceJob; + /** * Trace a image. - * \param C: Context - * \param op: Operator - * \param ob: Grease pencil object, can be NULL - * \param ima: Image - * \param gpf: Destination frame + * \param ibuf: Image buffer. + * \param gpf: Destination frame. */ -static bool gpencil_trace_image( - bContext *C, wmOperator *op, Object *ob, Image *ima, bGPDframe *gpf) +static bool gpencil_trace_image(TraceJob *trace_job, ImBuf *ibuf, bGPDframe *gpf) { - Main *bmain = CTX_data_main(C); - potrace_bitmap_t *bm = NULL; potrace_param_t *param = NULL; potrace_state_t *st = NULL; - const float threshold = RNA_float_get(op->ptr, "threshold"); - const float scale = RNA_float_get(op->ptr, "scale"); - const float sample = RNA_float_get(op->ptr, "sample"); - const int32_t resolution = RNA_int_get(op->ptr, "resolution"); - const int32_t thickness = RNA_int_get(op->ptr, "thickness"); - const int32_t turnpolicy = RNA_enum_get(op->ptr, "turnpolicy"); - - ImBuf *ibuf; - void *lock; - ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); - /* Create an empty BW bitmap. */ bm = ED_gpencil_trace_bitmap_new(ibuf->x, ibuf->y); if (!bm) { @@ -101,10 +123,10 @@ static bool gpencil_trace_image( return false; } param->turdsize = 0; - param->turnpolicy = turnpolicy; + param->turnpolicy = trace_job->turnpolicy; /* Load BW bitmap with image. */ - ED_gpencil_trace_image_to_bitmap(ibuf, bm, threshold); + ED_gpencil_trace_image_to_bitmap(ibuf, bm, trace_job->threshold); /* Trace the bitmap. */ st = potrace_trace(param, bm); @@ -128,23 +150,26 @@ static bool gpencil_trace_image( * Really, there isn't documented in Potrace about how the scale is calculated, * but after doing a lot of tests, it looks is using a VGA resolution (640) as a base. * Maybe there are others ways to get the right scale conversion, but this solution works. */ - float scale_potrace = scale * (640.0f / (float)ibuf->x) * ((float)ibuf->x / (float)ibuf->y); + float scale_potrace = trace_job->scale * (640.0f / (float)ibuf->x) * + ((float)ibuf->x / (float)ibuf->y); if (ibuf->x > ibuf->y) { scale_potrace *= (float)ibuf->y / (float)ibuf->x; } - ED_gpencil_trace_data_to_strokes( - bmain, st, ob, gpf, offset, scale_potrace, sample, resolution, thickness); + ED_gpencil_trace_data_to_strokes(trace_job->bmain, + st, + trace_job->ob_gpencil, + gpf, + offset, + scale_potrace, + trace_job->sample, + trace_job->resolution, + trace_job->thickness); /* Free memory. */ potrace_state_free(st); potrace_param_free(param); - /* Release ibuf. */ - if (ibuf) { - BKE_image_release_ibuf(ima, ibuf, lock); - } - return true; } @@ -157,68 +182,192 @@ static bool gpencil_trace_image_poll(bContext *C) return false; } + Image *image = (Image *)ob->data; + if (!ELEM(image->source, IMA_SRC_FILE, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { + CTX_wm_operator_poll_msg_set(C, "No valid image format selected"); + return false; + } + return true; } -static int gpencil_trace_image_exec(bContext *C, wmOperator *op) +static void trace_initialize_job_data(TraceJob *trace_job) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - Base *base_active = CTX_data_active_base(C); - Object *ob_active = base_active->object; - Image *image = (Image *)ob_active->data; - bool ob_created = false; - - const int32_t frame_target = CFRA; - Object *ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data; - /* Create a new grease pencil object. */ - if (ob_gpencil == NULL) { - ushort local_view_bits = (v3d && v3d->localvd) ? v3d->local_view_uuid : 0; - ob_gpencil = ED_gpencil_add_object(C, ob_active->loc, local_view_bits); + if (trace_job->ob_gpencil == NULL) { + ushort local_view_bits = (trace_job->v3d && trace_job->v3d->localvd) ? + trace_job->v3d->local_view_uuid : + 0; + trace_job->ob_gpencil = ED_gpencil_add_object( + trace_job->C, trace_job->ob_active->loc, local_view_bits); /* Apply image rotation. */ - copy_v3_v3(ob_gpencil->rot, ob_active->rot); + copy_v3_v3(trace_job->ob_gpencil->rot, trace_job->ob_active->rot); /* Grease pencil is rotated 90 degrees in X axis by default. */ - ob_gpencil->rot[0] -= DEG2RADF(90.0f); - ob_created = true; + trace_job->ob_gpencil->rot[0] -= DEG2RADF(90.0f); + trace_job->was_ob_created = true; /* Apply image Scale. */ - copy_v3_v3(ob_gpencil->scale, ob_active->scale); + copy_v3_v3(trace_job->ob_gpencil->scale, trace_job->ob_active->scale); + /* The default display size of the image is 5.0 and this is used as scale = 1.0. */ + mul_v3_fl(trace_job->ob_gpencil->scale, trace_job->ob_active->empty_drawsize / 5.0f); } - if ((ob_gpencil == NULL) || (ob_gpencil->type != OB_GPENCIL)) { - BKE_report(op->reports, RPT_ERROR, "Target grease pencil object not valid"); - return OPERATOR_CANCELLED; + /* Create Layer. */ + trace_job->gpd = (bGPdata *)trace_job->ob_gpencil->data; + trace_job->gpl = BKE_gpencil_layer_active_get(trace_job->gpd); + if (trace_job->gpl == NULL) { + trace_job->gpl = BKE_gpencil_layer_addnew(trace_job->gpd, DATA_("Trace"), true); } +} - /* Create Layer. */ - bGPdata *gpd = (bGPdata *)ob_gpencil->data; - bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); - if (gpl == NULL) { - gpl = BKE_gpencil_layer_addnew(gpd, DATA_("Trace"), true); +static void trace_start_job(void *customdata, short *stop, short *do_update, float *progress) +{ + TraceJob *trace_job = customdata; + + trace_job->stop = stop; + trace_job->do_update = do_update; + trace_job->progress = progress; + trace_job->was_canceled = false; + + G.is_break = false; + + /* Single Image. */ + + if ((trace_job->image->source == IMA_SRC_FILE) || + (trace_job->mode == GPENCIL_TRACE_MODE_SINGLE)) { + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, NULL, &lock); + if (ibuf) { + /* Create frame. */ + bGPDframe *gpf = BKE_gpencil_layer_frame_get( + trace_job->gpl, trace_job->frame_target, GP_GETFRAME_ADD_NEW); + gpencil_trace_image(trace_job, ibuf, gpf); + BKE_image_release_ibuf(trace_job->image, ibuf, lock); + *(trace_job->progress) = 1.0f; + } + } + /* Image sequence. */ + else if (trace_job->image->type == IMA_TYPE_IMAGE) { + ImageUser *iuser = trace_job->ob_active->iuser; + for (int i = 0; i < iuser->frames; i++) { + if (G.is_break) { + trace_job->was_canceled = true; + break; + } + + *(trace_job->progress) = (float)i / (float)iuser->frames; + *do_update = true; + + iuser->framenr = i + 1; + + void *lock; + ImBuf *ibuf = BKE_image_acquire_ibuf(trace_job->image, iuser, &lock); + if (ibuf) { + /* Create frame. */ + bGPDframe *gpf = BKE_gpencil_layer_frame_get( + trace_job->gpl, trace_job->frame_target + i, GP_GETFRAME_ADD_NEW); + gpencil_trace_image(trace_job, ibuf, gpf); + + BKE_image_release_ibuf(trace_job->image, ibuf, lock); + } + } } - /* Create frame. */ - bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, frame_target, GP_GETFRAME_ADD_NEW); - gpencil_trace_image(C, op, ob_gpencil, image, gpf); + trace_job->success = !trace_job->was_canceled; + *do_update = true; + *stop = 0; +} - /* Back to active base. */ - ED_object_base_activate(C, base_active); +static void trace_end_job(void *customdata) +{ + TraceJob *trace_job = customdata; + + /* If canceled, delete all previously created object and data-block. */ + if ((trace_job->was_canceled) && (trace_job->was_ob_created) && (trace_job->ob_gpencil)) { + bGPdata *gpd = trace_job->ob_gpencil->data; + BKE_id_delete(trace_job->bmain, &trace_job->ob_gpencil->id); + BKE_id_delete(trace_job->bmain, &gpd->id); + } - /* notifiers */ - if (ob_created) { - DEG_relations_tag_update(bmain); + if (trace_job->success) { + DEG_relations_tag_update(trace_job->bmain); + + DEG_id_tag_update(&trace_job->scene->id, ID_RECALC_SELECT); + DEG_id_tag_update(&trace_job->gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); + + WM_main_add_notifier(NC_OBJECT | NA_ADDED, NULL); + WM_main_add_notifier(NC_SCENE | ND_OB_ACTIVE, trace_job->scene); } +} - DEG_id_tag_update(&scene->id, ID_RECALC_SELECT); - DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); +static void trace_free_job(void *customdata) +{ + TraceJob *tj = customdata; + MEM_freeN(tj); +} - WM_event_add_notifier(C, NC_OBJECT | NA_ADDED, NULL); - WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); +static int gpencil_trace_image_exec(bContext *C, wmOperator *op) +{ + TraceJob *job = MEM_mallocN(sizeof(TraceJob), "TraceJob"); + job->C = C; + job->owner = CTX_data_active_object(C); + job->wm = CTX_wm_manager(C); + job->bmain = CTX_data_main(C); + Scene *scene = CTX_data_scene(C); + job->scene = scene; + job->v3d = CTX_wm_view3d(C); + job->base_active = CTX_data_active_base(C); + job->ob_active = job->base_active->object; + job->image = (Image *)job->ob_active->data; + job->frame_target = CFRA; + + job->ob_gpencil = (Object *)RNA_pointer_get(op->ptr, "target").data; + job->was_ob_created = false; + + job->threshold = RNA_float_get(op->ptr, "threshold"); + job->scale = RNA_float_get(op->ptr, "scale"); + job->sample = RNA_float_get(op->ptr, "sample"); + job->resolution = RNA_int_get(op->ptr, "resolution"); + job->thickness = RNA_int_get(op->ptr, "thickness"); + job->turnpolicy = RNA_enum_get(op->ptr, "turnpolicy"); + job->mode = RNA_enum_get(op->ptr, "mode"); + + trace_initialize_job_data(job); + + /* Back to active base. */ + ED_object_base_activate(job->C, job->base_active); + + if (job->image->source == IMA_SRC_FILE) { + short stop = 0, do_update = true; + float progress; + trace_start_job(job, &stop, &do_update, &progress); + trace_end_job(job); + trace_free_job(job); + } + else { + wmJob *wm_job = WM_jobs_get(job->wm, + CTX_wm_window(C), + job->scene, + "Trace Image", + WM_JOB_PROGRESS, + WM_JOB_TYPE_TRACE_IMAGE); + + WM_jobs_customdata_set(wm_job, job, trace_free_job); + WM_jobs_timer(wm_job, 0.1, NC_GEOM | ND_DATA, NC_GEOM | ND_DATA); + WM_jobs_callbacks(wm_job, trace_start_job, NULL, NULL, trace_end_job); + + WM_jobs_start(CTX_wm_manager(C), wm_job); + } return OPERATOR_FINISHED; } +static int gpencil_trace_image_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + /* Show popup dialog to allow editing. */ + /* FIXME: hard-coded dimensions here are just arbitrary. */ + return WM_operator_props_dialog_popup(C, op, 250); +} + static bool rna_GPencil_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value) { return ((Object *)value.owner_id)->type == OB_GPENCIL; @@ -257,12 +406,19 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem trace_modes[] = { + {GPENCIL_TRACE_MODE_SINGLE, "SINGLE", 0, "Single", "Trace the current frame of the image"}, + {GPENCIL_TRACE_MODE_SEQUENCE, "SEQUENCE", 0, "Sequence", "Trace full sequence"}, + {0, NULL, 0, NULL, NULL}, + }; + /* identifiers */ ot->name = "Trace Image to Grease Pencil"; ot->idname = "GPENCIL_OT_trace_image"; ot->description = "Extract Grease Pencil strokes from image"; /* callbacks */ + ot->invoke = gpencil_trace_image_invoke; ot->exec = gpencil_trace_image_exec; ot->poll = gpencil_trace_image_poll; @@ -270,9 +426,16 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop = RNA_def_pointer_runtime(ot->srna, "target", &RNA_Object, "Target", ""); + prop = RNA_def_pointer_runtime( + ot->srna, + "target", + &RNA_Object, + "Target Object", + "Target grease pencil object name. Leave empty to create a new object"); RNA_def_property_poll_runtime(prop, rna_GPencil_object_poll); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + RNA_def_int(ot->srna, "thickness", 10, 1, 1000, "Thickness", "", 1, 1000); RNA_def_int( ot->srna, "resolution", 5, 1, 20, "Resolution", "Resolution of the generated curves", 1, 20); @@ -301,7 +464,7 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot) 0.0f, 1.0f, "Color Threshold", - "Determine what is considered white and what black", + "Determine the lightness threshold above which strokes are generated", 0.0f, 1.0f); RNA_def_enum(ot->srna, @@ -310,4 +473,10 @@ void GPENCIL_OT_trace_image(wmOperatorType *ot) POTRACE_TURNPOLICY_MINORITY, "Turn Policy", "Determines how to resolve ambiguities during decomposition of bitmaps into paths"); + RNA_def_enum(ot->srna, + "mode", + trace_modes, + GPENCIL_TRACE_MODE_SINGLE, + "Mode", + "Determines if trace simple image or full sequence"); } diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 28a90a26a9d..0fdd70c55bc 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -555,7 +555,7 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *area, const bGPDstroke *gps /* filter stroke types by flags + spacetype */ if (gps->flag & GP_STROKE_3DSPACE) { /* 3D strokes - only in 3D view */ - return ((area->spacetype == SPACE_VIEW3D) || (area->spacetype == SPACE_PROPERTIES)); + return (ELEM(area->spacetype, SPACE_VIEW3D, SPACE_PROPERTIES)); } if (gps->flag & GP_STROKE_2DIMAGE) { /* Special "image" strokes - only in Image Editor */ @@ -1429,7 +1429,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { if (gpl->parent != NULL) { /* calculate new matrix */ - if ((gpl->partype == PAROBJECT) || (gpl->partype == PARSKEL)) { + if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) { invert_m4_m4(cur_mat, gpl->parent->obmat); copy_v3_v3(gpl_loc, obact->obmat[3]); } @@ -2289,7 +2289,7 @@ static void gpencil_insert_point( gpencil_copy_points(gps, pt, pt_final, i, i2); /* create new point duplicating point and copy location */ - if ((i == a_idx) || (i == b_idx)) { + if (ELEM(i, a_idx, b_idx)) { i2++; pt_final = &gps->points[i2]; gpencil_copy_points(gps, pt, pt_final, i, i2); @@ -2982,8 +2982,8 @@ bool ED_gpencil_stroke_check_collision(GP_SpaceConversion *gsc, * * \param gps: Stroke to check. * \param gsc: Space conversion data. - * \param mouse: Mouse position. - * \param diff_mat: View matrix. + * \param mouse: Mouse position. + * \param diff_mat: View matrix. * \return True if the point is inside. */ bool ED_gpencil_stroke_point_is_inside(bGPDstroke *gps, diff --git a/source/blender/editors/gpencil/gpencil_uv.c b/source/blender/editors/gpencil/gpencil_uv.c index 8304641611e..3bd2c3e6be6 100644 --- a/source/blender/editors/gpencil/gpencil_uv.c +++ b/source/blender/editors/gpencil/gpencil_uv.c @@ -502,13 +502,13 @@ static int gpencil_reset_transform_fill_exec(bContext *C, wmOperator *op) /* Loop all selected strokes and reset. */ GP_EDITABLE_STROKES_BEGIN (gpstroke_iter, C, gpl, gps) { if (gps->flag & GP_STROKE_SELECT) { - if ((mode == GP_UV_TRANSLATE) || (mode == GP_UV_ALL)) { + if (ELEM(mode, GP_UV_TRANSLATE, GP_UV_ALL)) { zero_v2(gps->uv_translation); } - if ((mode == GP_UV_ROTATE) || (mode == GP_UV_ALL)) { + if (ELEM(mode, GP_UV_ROTATE, GP_UV_ALL)) { gps->uv_rotation = 0.0f; } - if ((mode == GP_UV_SCALE) || (mode == GP_UV_ALL)) { + if (ELEM(mode, GP_UV_SCALE, GP_UV_ALL)) { gps->uv_scale = 1.0f; } /* Calc geometry data. */ diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 5d153757900..1ff160b2ca8 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -27,6 +27,7 @@ extern "C" { #endif struct SpaceProperties; +struct bContext; int ED_buttons_tabs_list(struct SpaceProperties *sbuts, short *context_tabs_array); bool ED_buttons_tab_has_search_result(struct SpaceProperties *sbuts, const int index); @@ -35,6 +36,8 @@ void ED_buttons_search_string_set(struct SpaceProperties *sbuts, const char *val int ED_buttons_search_string_length(struct SpaceProperties *sbuts); const char *ED_buttons_search_string_get(struct SpaceProperties *sbuts); +void ED_buttons_set_context(const struct bContext *C, PointerRNA *ptr, const int context); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index f9b1d9cdc64..8015a665970 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -84,7 +84,7 @@ void ED_curve_editfont_load(struct Object *obedit); void ED_curve_editfont_make(struct Object *obedit); void ED_curve_editfont_free(struct Object *obedit); -void ED_text_to_object(struct bContext *C, struct Text *text, const bool split_lines); +void ED_text_to_object(struct bContext *C, const struct Text *text, const bool split_lines); void ED_curve_beztcpy(struct EditNurb *editnurb, struct BezTriple *dst, diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 341f97943a5..84808416074 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -35,6 +35,7 @@ struct SpaceFile; struct bContext; struct bScreen; struct uiBlock; +struct wmOperator; struct wmWindow; struct wmWindowManager; @@ -145,6 +146,9 @@ void ED_fileselect_window_params_get(const struct wmWindow *win, int win_size[2], bool *is_maximized); +struct ScrArea *ED_fileselect_handler_area_find(const struct wmWindow *win, + const struct wmOperator *file_operator); + int ED_path_extension_type(const char *path); int ED_file_extension_icon(const char *path); diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 861b563521f..434ab743d18 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -19,7 +19,7 @@ * * \name Generic Gizmos. * - * This is exposes pre-defined gizmos for re-use. + * This is exposes predefined gizmos for re-use. */ #pragma once diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h index 6c5aacafc7a..50f1ce1efe2 100644 --- a/source/blender/editors/include/ED_numinput.h +++ b/source/blender/editors/include/ED_numinput.h @@ -99,6 +99,7 @@ bool hasNumInput(const NumInput *n); bool applyNumInput(NumInput *n, float *vec); bool handleNumInput(struct bContext *C, NumInput *n, const struct wmEvent *event); +/** Share with `TFM_MODAL_CANCEL` in `transform.h`. */ #define NUM_MODAL_INCREMENT_UP 18 #define NUM_MODAL_INCREMENT_DOWN 19 diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 6fdd65fdcc9..2e9b711c99a 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -160,6 +160,7 @@ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; #endif +/* Set the object's parent, return true iff successful. */ bool ED_object_parent_set(struct ReportList *reports, const struct bContext *C, struct Scene *scene, diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index b8500ba0c37..dc1c43c0337 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -199,6 +199,7 @@ int ED_region_global_size_y(void); void ED_area_update_region_sizes(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *area); +bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b); ScrArea *ED_screen_areas_iter_first(const struct wmWindow *win, const bScreen *screen); ScrArea *ED_screen_areas_iter_next(const bScreen *screen, const ScrArea *area); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index d3eb6c00f57..f64c6a42f18 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -693,7 +693,7 @@ void ED_view3d_grid_steps(const struct Scene *scene, float *r_grid_steps); float ED_view3d_grid_view_scale(struct Scene *scene, struct View3D *v3d, - struct RegionView3D *rv3d, + struct ARegion *region, const char **r_grid_unit); void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset); diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index c987a8ac13b..f9dc23502c7 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1682,7 +1682,7 @@ void UI_panels_begin(const struct bContext *C, struct ARegion *region); void UI_panels_end(const struct bContext *C, struct ARegion *region, int *r_x, int *r_y); void UI_panels_draw(const struct bContext *C, struct ARegion *region); -struct Panel *UI_panel_find_by_type(struct ListBase *lb, struct PanelType *pt); +struct Panel *UI_panel_find_by_type(struct ListBase *lb, const struct PanelType *pt); struct Panel *UI_panel_begin(struct ARegion *region, struct ListBase *lb, uiBlock *block, @@ -1695,29 +1695,22 @@ void UI_panel_end(struct Panel *panel, int width, int height); bool UI_panel_is_closed(const struct Panel *panel); bool UI_panel_is_active(const struct Panel *panel); -void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y); +void UI_panel_label_offset(const struct uiBlock *block, int *r_x, int *r_y); int UI_panel_size_y(const struct Panel *panel); bool UI_panel_is_dragging(const struct Panel *panel); bool UI_panel_matches_search_filter(const struct Panel *panel); bool UI_panel_category_is_visible(const struct ARegion *region); void UI_panel_category_add(struct ARegion *region, const char *name); -struct PanelCategoryDyn *UI_panel_category_find(struct ARegion *region, const char *idname); +struct PanelCategoryDyn *UI_panel_category_find(const struct ARegion *region, const char *idname); struct PanelCategoryStack *UI_panel_category_active_find(struct ARegion *region, const char *idname); const char *UI_panel_category_active_get(struct ARegion *region, bool set_fallback); void UI_panel_category_active_set(struct ARegion *region, const char *idname); void UI_panel_category_active_set_default(struct ARegion *region, const char *idname); -struct PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(struct ARegion *region, - const int x, - const int y); -struct PanelCategoryDyn *UI_panel_category_find_mouse_over(struct ARegion *region, - const struct wmEvent *event); void UI_panel_category_clear_all(struct ARegion *region); void UI_panel_category_draw_all(struct ARegion *region, const char *category_id_active); -struct PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname); - /* Panel custom data. */ struct PointerRNA *UI_panel_custom_data_get(const struct Panel *panel); struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContext *C, @@ -1728,7 +1721,7 @@ void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_dat struct Panel *UI_panel_add_instanced(const struct bContext *C, struct ARegion *region, struct ListBase *panels, - char *panel_idname, + const char *panel_idname, struct PointerRNA *custom_data); void UI_panels_free_instanced(const struct bContext *C, struct ARegion *region); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index dc20e6f1813..4c3fd57131c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -463,7 +463,7 @@ void ui_block_bounds_calc(uiBlock *block) /* hardcoded exception... but that one is annoying with larger safety */ uiBut *bt = block->buttons.first; - int xof = (bt && STREQLEN(bt->str, "ERROR", 5)) ? 10 : 40; + int xof = (bt && STRPREFIX(bt->str, "ERROR")) ? 10 : 40; block->safety.xmin = block->rect.xmin - xof; block->safety.ymin = block->rect.ymin - xof; @@ -702,10 +702,10 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut) if (but->funcN != oldbut->funcN) { return false; } - if (oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) { + if (!ELEM(oldbut->func_arg1, oldbut, but->func_arg1)) { return false; } - if (oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) { + if (!ELEM(oldbut->func_arg2, oldbut, but->func_arg2)) { return false; } if (!but->funcN && ((but->poin != oldbut->poin && (uiBut *)oldbut->poin != oldbut) || @@ -772,6 +772,95 @@ static void ui_but_extra_icons_update_from_old_but(const uiBut *new_but, const u } /** + * Update pointers and other information in the old active button based on new information in the + * corresponding new button from the current layout pass. + * + * \param oldbut: The button from the last layout pass that will be moved to the new block. + * \param but: The newly added button with much of the up to date information, to be feed later. + * + * \note #uiBut has ownership of many of its pointers. When the button is freed all these + * pointers are freed as well, so ownership has to be moved out of \a but in order to free it. + */ +static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) +{ + BLI_assert(oldbut->active); + + /* flags from the buttons we want to refresh, may want to add more here... */ + const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON; + const int drawflag_copy = 0; /* None currently. */ + + /* still stuff needs to be copied */ + oldbut->rect = but->rect; + oldbut->context = but->context; /* set by Layout */ + + /* drawing */ + oldbut->icon = but->icon; + oldbut->iconadd = but->iconadd; + oldbut->alignnr = but->alignnr; + + /* typically the same pointers, but not on undo/redo */ + /* XXX some menu buttons store button itself in but->poin. Ugly */ + if (oldbut->poin != (char *)oldbut) { + SWAP(char *, oldbut->poin, but->poin); + SWAP(void *, oldbut->func_argN, but->func_argN); + } + + /* Move tooltip from new to old. */ + SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func); + SWAP(void *, oldbut->tip_argN, but->tip_argN); + + oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); + oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); + + ui_but_extra_icons_update_from_old_but(but, oldbut); + SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons); + + if (oldbut->type == UI_BTYPE_SEARCH_MENU) { + uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; + + SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn); + SWAP(void *, search_oldbut->arg, search_but->arg); + } + + /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position + * when scrolling without moving mouse (see T28432) */ + if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { + oldbut->hardmax = but->hardmax; + } + + if (oldbut->type == UI_BTYPE_PROGRESS_BAR) { + uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut; + uiButProgressbar *progress_but = (uiButProgressbar *)but; + progress_oldbut->progress = progress_but->progress; + } + + /* move/copy string from the new button to the old */ + /* needed for alt+mouse wheel over enums */ + if (but->str != but->strdata) { + if (oldbut->str != oldbut->strdata) { + SWAP(char *, but->str, oldbut->str); + } + else { + oldbut->str = but->str; + but->str = but->strdata; + } + } + else { + if (oldbut->str != oldbut->strdata) { + MEM_freeN(oldbut->str); + oldbut->str = oldbut->strdata; + } + BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); + } + + if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) { + SWAP(void *, but->dragpoin, oldbut->dragpoin); + } + + /* note: if layout hasn't been applied yet, it uses old button pointers... */ +} + +/** * \return true when \a but_p is set (only done for active buttons). */ static bool ui_but_update_from_old_block(const bContext *C, @@ -779,57 +868,36 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBut **but_p, uiBut **but_old_p) { - const int drawflag_copy = 0; /* None currently. */ - uiBlock *oldblock = block->oldblock; - uiBut *oldbut = NULL, *but = *but_p; - bool found_active = false; + uiBut *but = *but_p; #if 0 - /* simple/stupid - search every time */ - oldbut = ui_but_find_old(oldblock, but); - (void)but_old_p; + /* Simple method - search every time. Keep this for easy testing of the "fast path." */ + uiBut *oldbut = ui_but_find_old(oldblock, but); + UNUSED_VARS(but_old_p); #else BLI_assert(*but_old_p == NULL || BLI_findindex(&oldblock->buttons, *but_old_p) != -1); - /* Fast-path - avoid loop-in-loop, calling #ui_but_find_old - * as long as old/new buttons are aligned. */ + /* As long as old and new buttons are aligned, avoid loop-in-loop (calling #ui_but_find_old). */ + uiBut *oldbut; if (LIKELY(*but_old_p && ui_but_equals_old(but, *but_old_p))) { oldbut = *but_old_p; } else { - /* fallback to block search */ + /* Fallback to block search. */ oldbut = ui_but_find_old(oldblock, but); } (*but_old_p) = oldbut ? oldbut->next : NULL; #endif + bool found_active = false; + if (!oldbut) { - return found_active; + return false; } if (oldbut->active) { - /* flags from the buttons we want to refresh, may want to add more here... */ - const int flag_copy = UI_BUT_REDALERT | UI_HAS_ICON; - - found_active = true; - -#if 0 - but->flag = oldbut->flag; - but->active = oldbut->active; - but->pos = oldbut->pos; - but->ofs = oldbut->ofs; - but->editstr = oldbut->editstr; - but->editval = oldbut->editval; - but->editvec = oldbut->editvec; - but->selsta = oldbut->selsta; - but->selend = oldbut->selend; - but->softmin = oldbut->softmin; - but->softmax = oldbut->softmax; - oldbut->active = NULL; -#endif - - /* move button over from oldblock to new block */ + /* Move button over from oldblock to new block. */ BLI_remlink(&oldblock->buttons, oldbut); BLI_insertlinkafter(&block->buttons, but, oldbut); /* Add the old button to the button groups in the new block. */ @@ -837,82 +905,16 @@ static bool ui_but_update_from_old_block(const bContext *C, oldbut->block = block; *but_p = oldbut; - /* still stuff needs to be copied */ - oldbut->rect = but->rect; - oldbut->context = but->context; /* set by Layout */ - - /* drawing */ - oldbut->icon = but->icon; - oldbut->iconadd = but->iconadd; - oldbut->alignnr = but->alignnr; - - /* typically the same pointers, but not on undo/redo */ - /* XXX some menu buttons store button itself in but->poin. Ugly */ - if (oldbut->poin != (char *)oldbut) { - SWAP(char *, oldbut->poin, but->poin); - SWAP(void *, oldbut->func_argN, but->func_argN); - } - - /* Move tooltip from new to old. */ - SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func); - SWAP(void *, oldbut->tip_argN, but->tip_argN); - - oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); - oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); - - ui_but_extra_icons_update_from_old_but(but, oldbut); - SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons); - - if (oldbut->type == UI_BTYPE_SEARCH_MENU) { - uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; - - SWAP(uiButSearchArgFreeFn, search_oldbut->arg_free_fn, search_but->arg_free_fn); - SWAP(void *, search_oldbut->arg, search_but->arg); - } - - /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position - * when scrolling without moving mouse (see T28432) */ - if (ELEM(oldbut->type, UI_BTYPE_ROW, UI_BTYPE_LISTROW)) { - oldbut->hardmax = but->hardmax; - } - - if (oldbut->type == UI_BTYPE_PROGRESS_BAR) { - uiButProgressbar *progress_oldbut = (uiButProgressbar *)oldbut; - uiButProgressbar *progress_but = (uiButProgressbar *)but; - progress_oldbut->progress = progress_but->progress; - } + ui_but_update_old_active_from_new(oldbut, but); if (!BLI_listbase_is_empty(&block->butstore)) { UI_butstore_register_update(block, oldbut, but); } - /* move/copy string from the new button to the old */ - /* needed for alt+mouse wheel over enums */ - if (but->str != but->strdata) { - if (oldbut->str != oldbut->strdata) { - SWAP(char *, but->str, oldbut->str); - } - else { - oldbut->str = but->str; - but->str = but->strdata; - } - } - else { - if (oldbut->str != oldbut->strdata) { - MEM_freeN(oldbut->str); - oldbut->str = oldbut->strdata; - } - BLI_strncpy(oldbut->strdata, but->strdata, sizeof(oldbut->strdata)); - } - - if (but->dragpoin && (but->dragflag & UI_BUT_DRAGPOIN_FREE)) { - SWAP(void *, but->dragpoin, oldbut->dragpoin); - } - BLI_remlink(&block->buttons, but); ui_but_free(C, but); - /* note: if layout hasn't been applied yet, it uses old button pointers... */ + found_active = true; } else { const int flag_copy = UI_BUT_DRAG_MULTI; @@ -928,9 +930,11 @@ static bool ui_but_update_from_old_block(const bContext *C, return found_active; } -/* needed for temporarily rename buttons, such as in outliner or file-select, - * they should keep calling uiDefButs to keep them alive */ -/* returns 0 when button removed */ +/** + * Needed for temporarily rename buttons, such as in outliner or file-select, + * they should keep calling #uiDefBut to keep them alive. + * \return false when button removed. + */ bool UI_but_active_only_ex( const bContext *C, ARegion *region, uiBlock *block, uiBut *but, const bool remove_on_failure) { @@ -1581,6 +1585,7 @@ void ui_but_override_flag(Main *bmain, uiBut *but) } } +/* -------------------------------------------------------------------- */ /** \name Button Extra Operator Icons * * Extra icons are shown on the right hand side of buttons. They can be clicked to invoke custom @@ -4064,6 +4069,11 @@ static uiBut *ui_def_but(uiBlock *block, } #endif + /* Always keep text in radio-buttons (expanded enums) center aligned. */ + if (ELEM(but->type, UI_BTYPE_ROW)) { + but->drawflag &= ~UI_BUT_TEXT_LEFT; + } + but->drawflag |= (block->flag & UI_BUT_ALIGN); if (block->lock == true) { @@ -4251,8 +4261,8 @@ static void ui_def_but_rna__menu(bContext *UNUSED(C), uiLayout *layout, void *bu 0, ""); } - uiItemS(column); } + uiItemS(column); } else { if (item->icon) { diff --git a/source/blender/editors/interface/interface_button_group.c b/source/blender/editors/interface/interface_button_group.c index 2d2da9a4d14..90479eaee94 100644 --- a/source/blender/editors/interface/interface_button_group.c +++ b/source/blender/editors/interface/interface_button_group.c @@ -75,7 +75,6 @@ void ui_block_free_button_groups(uiBlock *block) } } -/* This function should be removed whenever #ui_layout_replace_but_ptr is removed. */ void ui_button_group_replace_but_ptr(uiBlock *block, const void *old_but_ptr, uiBut *new_but) { LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) { diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index dec1710ac69..d9571dc98bd 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -973,15 +973,15 @@ void ui_draw_but_HISTOGRAM(ARegion *UNUSED(region), 1.0, 1.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_a, res, is_line, pos); } else { - if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_R) { + if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_R)) { histogram_draw_one( 1.0, 0.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_r, res, is_line, pos); } - if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_G) { + if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_G)) { histogram_draw_one( 0.0, 1.0, 0.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_g, res, is_line, pos); } - if (hist->mode == HISTO_MODE_RGB || hist->mode == HISTO_MODE_B) { + if (ELEM(hist->mode, HISTO_MODE_RGB, HISTO_MODE_B)) { histogram_draw_one( 0.0, 0.0, 1.0, 0.75, rect.xmin, rect.ymin, w, h, hist->data_b, res, is_line, pos); } diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index a740a152f1c..4d0e1584156 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -78,7 +78,7 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf) { static const EnumPropertyItem modal_items_point[] = { {EYE_MODAL_POINT_CANCEL, "CANCEL", 0, "Cancel", ""}, - {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a point", ""}, + {EYE_MODAL_POINT_SAMPLE, "SAMPLE_SAMPLE", 0, "Sample a Point", ""}, {EYE_MODAL_POINT_CONFIRM, "SAMPLE_CONFIRM", 0, "Confirm Sampling", ""}, {EYE_MODAL_POINT_RESET, "SAMPLE_RESET", 0, "Reset Sampling", ""}, {0, NULL, 0, NULL, NULL}, diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index b77f8bf3b63..fb5844d24f3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1024,7 +1024,7 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) } ui_but_value_set(but, (double)value_toggle); - if (but->type == UI_BTYPE_ICON_TOGGLE || but->type == UI_BTYPE_ICON_TOGGLE_N) { + if (ELEM(but->type, UI_BTYPE_ICON_TOGGLE, UI_BTYPE_ICON_TOGGLE_N)) { ui_but_update_edited(but); } @@ -3564,7 +3564,7 @@ static void ui_do_but_textedit( /* for double click: we do a press again for when you first click on button * (selects all text, no cursor pos) */ - if (event->val == KM_PRESS || event->val == KM_DBL_CLICK) { + if (ELEM(event->val, KM_PRESS, KM_DBL_CLICK)) { float mx = event->x; float my = event->y; ui_window_to_block_fl(data->region, block, &mx, &my); @@ -4550,10 +4550,22 @@ static int ui_do_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data, cons button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } - if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) { - /* Support alt+wheel on expanded enum rows */ + if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) { + /* Support ctrl-wheel to cycle values on expanded enum rows. */ if (but->type == UI_BTYPE_ROW) { - const int direction = (event->type == WHEELDOWNMOUSE) ? -1 : 1; + int type = event->type; + int val = event->val; + + /* Convert pan to scroll-wheel. */ + if (type == MOUSEPAN) { + ui_pan_to_scroll(event, &type, &val); + + if (type == MOUSEPAN) { + return WM_UI_HANDLER_BREAK; + } + } + + const int direction = (type == WHEELDOWNMOUSE) ? -1 : 1; uiBut *but_select = ui_but_find_select_in_enum(but, direction); if (but_select) { uiBut *but_other = (direction == -1) ? but_select->next : but_select->prev; @@ -4728,7 +4740,7 @@ static float ui_numedit_apply_snap(int temp, float softmax, const enum eSnapType snap) { - if (temp == softmin || temp == softmax) { + if (ELEM(temp, softmin, softmax)) { return temp; } @@ -5040,7 +5052,7 @@ static int ui_do_but_NUM( } } else if (data->state == BUTTON_STATE_NUM_EDITING) { - if (event->type == EVT_ESCKEY || event->type == RIGHTMOUSE) { + if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) { if (event->val == KM_PRESS) { data->cancel = true; data->escapecancel = true; @@ -5232,13 +5244,13 @@ static bool ui_numedit_but_SLI(uiBut *but, temp = round_fl_to_int(tempf); if (snap) { - if (tempf == softmin || tempf == softmax) { + if (ELEM(tempf, softmin, softmax)) { /* pass */ } else if (ui_but_is_float(but)) { if (shift) { - if (tempf == softmin || tempf == softmax) { + if (ELEM(tempf, softmin, softmax)) { } else if (softrange < 2.10f) { tempf = roundf(tempf * 100.0f) * 0.01f; @@ -5362,7 +5374,7 @@ static int ui_do_but_SLI( #endif } else if (data->state == BUTTON_STATE_NUM_EDITING) { - if (event->type == EVT_ESCKEY || event->type == RIGHTMOUSE) { + if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) { if (event->val == KM_PRESS) { data->cancel = true; data->escapecancel = true; @@ -5648,8 +5660,20 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_BREAK; } if (ui_but_supports_cycling(but)) { - if (ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) { - const int direction = (event->type == WHEELDOWNMOUSE) ? 1 : -1; + if (ELEM(event->type, MOUSEPAN, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->ctrl) { + int type = event->type; + int val = event->val; + + /* Convert pan to scroll-wheel. */ + if (type == MOUSEPAN) { + ui_pan_to_scroll(event, &type, &val); + + if (type == MOUSEPAN) { + return WM_UI_HANDLER_BREAK; + } + } + + const int direction = (type == WHEELDOWNMOUSE) ? 1 : -1; data->value = ui_but_menu_step(but, direction); @@ -5973,7 +5997,7 @@ static int ui_do_but_UNITVEC( } } } - else if (event->type == EVT_ESCKEY || event->type == RIGHTMOUSE) { + else if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) { if (event->val == KM_PRESS) { data->cancel = true; data->escapecancel = true; @@ -6304,7 +6328,7 @@ static int ui_do_but_HSVCUBE( } } else if (data->state == BUTTON_STATE_NUM_EDITING) { - if (event->type == EVT_ESCKEY || event->type == RIGHTMOUSE) { + if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) { if (event->val == KM_PRESS) { data->cancel = true; data->escapecancel = true; @@ -6372,7 +6396,7 @@ static bool ui_numedit_but_HSVCIRCLE(uiBut *but, * allow choosing a hue for black values, by giving a tiny increment */ if (cpicker->use_color_lock) { if (U.color_picker_type == USER_CP_CIRCLE_HSV) { /* lock */ - if (hsv[2] == 0.f) { + if (hsv[2] == 0.0f) { hsv[2] = 0.0001f; } } @@ -6475,15 +6499,15 @@ static void ui_ndofedit_but_HSVCIRCLE(uiBut *but, * allow choosing a hue for black values, by giving a tiny increment */ if (cpicker->use_color_lock) { if (U.color_picker_type == USER_CP_CIRCLE_HSV) { /* lock */ - if (hsv[2] == 0.f) { + if (hsv[2] == 0.0f) { hsv[2] = 0.0001f; } } else { - if (hsv[2] == 0.f) { + if (hsv[2] == 0.0f) { hsv[2] = 0.0001f; } - if (hsv[2] == 1.f) { + if (hsv[2] == 1.0f) { hsv[2] = 0.9999f; } } @@ -6578,7 +6602,7 @@ static int ui_do_but_HSVCIRCLE( } } else if (data->state == BUTTON_STATE_NUM_EDITING) { - if (event->type == EVT_ESCKEY || event->type == RIGHTMOUSE) { + if (ELEM(event->type, EVT_ESCKEY, RIGHTMOUSE)) { if (event->val == KM_PRESS) { data->cancel = true; data->escapecancel = true; @@ -7291,7 +7315,7 @@ static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int m hist->ymax += (dy * 0.1f) * yfac; /* 0.1 allows us to see HDR colors up to 10 */ - CLAMP(hist->ymax, 0.1f, 100.f); + CLAMP(hist->ymax, 0.1f, 100.0f); data->draglastx = mx; data->draglasty = my; @@ -7324,7 +7348,7 @@ static int ui_do_but_HISTOGRAM( /* XXX hardcoded keymap check.... */ if (event->type == EVT_BACKSPACEKEY && event->val == KM_PRESS) { Histogram *hist = (Histogram *)but->poin; - hist->ymax = 1.f; + hist->ymax = 1.0f; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; @@ -7397,7 +7421,7 @@ static int ui_do_but_WAVEFORM( /* XXX hardcoded keymap check.... */ if (event->type == EVT_BACKSPACEKEY && event->val == KM_PRESS) { Scopes *scopes = (Scopes *)but->poin; - scopes->wavefrm_yfac = 1.f; + scopes->wavefrm_yfac = 1.0f; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; @@ -7693,6 +7717,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * } #ifdef USE_DRAG_MULTINUM + data = but->active; if (data) { if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || /* if we started dragging, progress on any event */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 01eb8f95d18..c4b54af1396 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -943,7 +943,7 @@ typedef struct uiWidgetBaseParameters { /* We pack alpha check and discard factor in alpha_discard. * If the value is negative then we do alpha check. * The absolute value itself is the discard factor. - * Initialize value to 1.0.f if you don't want discard */ + * Initialize value to 1.0f if you don't want discard. */ float alpha_discard; float tria_type; float _pad[3]; @@ -995,8 +995,9 @@ void ui_draw_preview_item( #define UI_TEXT_MARGIN_X 0.4f #define UI_POPUP_MARGIN (UI_DPI_FAC * 12) -/* margin at top of screen for popups */ -#define UI_POPUP_MENU_TOP (int)(8 * UI_DPI_FAC) +/* Margin at top of screen for popups. Note this value must be sufficient + to draw a popover arrow to avoid cropping it. */ +#define UI_POPUP_MENU_TOP (int)(10 * UI_DPI_FAC) #define UI_PIXEL_AA_JITTER 8 extern const float ui_pixel_jitter[UI_PIXEL_AA_JITTER][2]; diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index ad260274e78..df7fd3dee0e 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -964,7 +964,11 @@ static uiBut *ui_item_with_label(uiLayout *layout, UI_block_layout_set_current(block, layout); /* Only add new row if more than 1 item will be added. */ - if (name[0] || use_prop_decorate) { + if (name[0] +#ifdef UI_PROP_DECORATE + || use_prop_decorate +#endif + ) { /* Also avoid setting 'align' if possible. Set the space to zero instead as aligning a large * number of labels can end up aligning thousands of buttons when displaying key-map search (a * heavy operation), see: T78636. */ @@ -972,8 +976,8 @@ static uiBut *ui_item_with_label(uiLayout *layout, sub->space = 0; } -#ifdef UI_PROP_DECORATE if (name[0]) { +#ifdef UI_PROP_DECORATE if (use_prop_sep) { layout_prop_decorate = uiItemL_respect_property_split(layout, name, 0); } @@ -998,7 +1002,7 @@ static uiBut *ui_item_with_label(uiLayout *layout, const PropertySubType subtype = RNA_property_subtype(prop); uiBut *but; - if (subtype == PROP_FILEPATH || subtype == PROP_DIRPATH) { + if (ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH)) { UI_block_layout_set_current(block, uiLayoutRow(sub, true)); but = uiDefAutoButR(block, ptr, prop, index, "", icon, x, y, prop_but_width - UI_UNIT_X, h); @@ -1882,7 +1886,7 @@ static void ui_item_rna_size(uiLayout *layout, else if (type == PROP_ENUM && !icon_only) { w += UI_UNIT_X / 4; } - else if (type == PROP_FLOAT || type == PROP_INT) { + else if (ELEM(type, PROP_FLOAT, PROP_INT)) { w += UI_UNIT_X * 3; } } @@ -2148,7 +2152,6 @@ void uiItemFullR(uiLayout *layout, uiLayout *layout_split = uiLayoutSplit( layout_row ? layout_row : layout, UI_ITEM_PROP_SEP_DIVIDE, true); bool label_added = false; - layout_split->space = 0; uiLayout *layout_sub = uiLayoutColumn(layout_split, true); layout_sub->space = 0; @@ -2292,7 +2295,7 @@ void uiItemFullR(uiLayout *layout, ui_item_enum_expand(layout, block, ptr, prop, name, h, icon_only); } /* property with separate label */ - else if (type == PROP_ENUM || type == PROP_STRING || type == PROP_POINTER) { + else if (ELEM(type, PROP_ENUM, PROP_STRING, PROP_POINTER)) { but = ui_item_with_label(layout, block, name, icon, ptr, prop, index, 0, 0, w, h, flag); but = ui_but_add_search(but, ptr, prop, NULL, NULL); @@ -3186,7 +3189,6 @@ uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout) uiLayout *layout_row = uiLayoutRow(parent_layout, true); uiLayout *layout_split = uiLayoutSplit(layout_row, UI_ITEM_PROP_SEP_DIVIDE, true); - layout_split->space = 0; split_wrapper.label_column = uiLayoutColumn(layout_split, true); split_wrapper.label_column->alignment = UI_LAYOUT_ALIGN_RIGHT; split_wrapper.property_row = ui_item_prop_split_layout_hack(parent_layout, layout_split); @@ -5478,7 +5480,7 @@ uiLayout *UI_block_layout(uiBlock *block, layout->context = NULL; layout->emboss = UI_EMBOSS_UNDEFINED; - if (type == UI_LAYOUT_MENU || type == UI_LAYOUT_PIEMENU) { + if (ELEM(type, UI_LAYOUT_MENU, UI_LAYOUT_PIEMENU)) { layout->space = 0; } diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index bfe5dc223c8..0d81b43146d 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -85,6 +85,11 @@ typedef enum uiPanelRuntimeFlag { PANEL_USE_CLOSED_FROM_SEARCH = (1 << 8), /** The Panel was before the start of the current / latest layout pass. */ PANEL_WAS_CLOSED = (1 << 9), + /** + * Set when the panel is being dragged and while it animates back to its aligned + * position. Unlike #PANEL_STATE_ANIMATION, this is applied to sub-panels as well. + */ + PANEL_IS_DRAG_DROP = (1 << 10), } uiPanelRuntimeFlag; /* The state of the mouse position relative to the panel. */ @@ -96,8 +101,6 @@ typedef enum uiPanelMouseState { typedef enum uiHandlePanelState { PANEL_STATE_DRAG, - PANEL_STATE_DRAG_SCALE, - PANEL_STATE_WAIT_UNTAB, PANEL_STATE_ANIMATION, PANEL_STATE_EXIT, } uiHandlePanelState; @@ -110,10 +113,8 @@ typedef struct uiHandlePanelData { double starttime; /* Dragging. */ - bool is_drag_drop; int startx, starty; int startofsx, startofsy; - int startsizex, startsizey; float start_cur_xmin, start_cur_ymin; } uiHandlePanelData; @@ -209,7 +210,7 @@ static bool panel_active_animation_changed(ListBase *lb, /** * \return True if the properties editor switch tabs since the last layout pass. */ -static bool properties_space_needs_realign(ScrArea *area, ARegion *region) +static bool properties_space_needs_realign(const ScrArea *area, const ARegion *region) { if (area->spacetype == SPACE_PROPERTIES && region->regiontype == RGN_TYPE_WINDOW) { SpaceProperties *sbuts = area->spacedata.first; @@ -222,7 +223,7 @@ static bool properties_space_needs_realign(ScrArea *area, ARegion *region) return false; } -static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_animation) +static bool panels_need_realign(const ScrArea *area, ARegion *region, Panel **r_panel_animation) { *r_panel_animation = NULL; @@ -259,7 +260,7 @@ static Panel *panel_add_instanced(ARegion *region, PanelType *panel_type, PointerRNA *custom_data) { - Panel *panel = MEM_callocN(sizeof(Panel), "instanced panel"); + Panel *panel = MEM_callocN(sizeof(Panel), __func__); panel->type = panel_type; BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname)); @@ -298,7 +299,7 @@ static Panel *panel_add_instanced(ARegion *region, Panel *UI_panel_add_instanced(const bContext *C, ARegion *region, ListBase *panels, - char *panel_idname, + const char *panel_idname, PointerRNA *custom_data) { ARegionType *region_type = region->type; @@ -313,19 +314,19 @@ Panel *UI_panel_add_instanced(const bContext *C, Panel *new_panel = panel_add_instanced(region, panels, panel_type, custom_data); - /* Do this after #panel_add_instatnced so all subpanels are added. */ + /* Do this after #panel_add_instatnced so all sub-panels are added. */ panel_set_expansion_from_list_data(C, new_panel); return new_panel; } /** - * Find a unique key to append to the #PanelTyype.idname for the lookup to the panel's #uiBlock. + * Find a unique key to append to the #PanelType.idname for the lookup to the panel's #uiBlock. * Needed for instanced panels, where there can be multiple with the same type and identifier. */ void UI_list_panel_unique_str(Panel *panel, char *r_name) { - /* The panel sortorder will be unique for a specific panel type because the instanced + /* The panel sort-order will be unique for a specific panel type because the instanced * panel list is regenerated for every change in the data order / length. */ snprintf(r_name, INSTANCED_PANEL_UNIQUE_STR_LEN, "%d", panel->sortorder); } @@ -455,7 +456,7 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr /* Find how many instanced panels with this context string. */ int list_panels_len = 0; - LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { + LISTBASE_FOREACH (const Panel *, panel, ®ion->panels) { if (panel->type) { if (panel->type->flag & PNL_INSTANCED) { if (panel_type_context_poll(region, panel->type, context)) { @@ -466,7 +467,7 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr } /* Sort the matching instanced panels by their display order. */ - PanelSort *panel_sort = MEM_callocN(list_panels_len * sizeof(*panel_sort), "instancedpanelsort"); + PanelSort *panel_sort = MEM_callocN(list_panels_len * sizeof(*panel_sort), __func__); PanelSort *sort_index = panel_sort; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->type) { @@ -556,12 +557,12 @@ static void region_panels_set_expansion_from_list_data(const bContext *C, ARegio /** * Recursive implementation for #set_panels_list_data_expand_flag. */ -static void get_panel_expand_flag(Panel *panel, short *flag, short *flag_index) +static void get_panel_expand_flag(const Panel *panel, short *flag, short *flag_index) { const bool open = !(panel->flag & PNL_CLOSED); SET_FLAG_FROM_TEST(*flag, open, (1 << *flag_index)); - LISTBASE_FOREACH (Panel *, child, &panel->children) { + LISTBASE_FOREACH (const Panel *, child, &panel->children) { *flag_index = *flag_index + 1; get_panel_expand_flag(child, flag, flag_index); } @@ -571,8 +572,8 @@ static void get_panel_expand_flag(Panel *panel, short *flag, short *flag_index) * Call the callback to store the panel and sub-panel expansion settings in the list item that * corresponds to each instanced panel. * - * \note This needs to iterate through all of the regions panels because the panel with changed - * expansion could have been the sub-panel of a instanced panel, meaning it might not know + * \note This needs to iterate through all of the region's panels because the panel with changed + * expansion might have been the sub-panel of an instanced panel, meaning it might not know * which list item it corresponds to. */ static void set_panels_list_data_expand_flag(const bContext *C, const ARegion *region) @@ -621,6 +622,18 @@ static bool panel_set_flag_recursive(Panel *panel, int flag, bool value) return changed; } +/** + * Set runtime flag state for a panel and its sub-panels. + */ +static void panel_set_runtime_flag_recursive(Panel *panel, int flag, bool value) +{ + SET_FLAG_FROM_TEST(panel->runtime_flag, value, flag); + + LISTBASE_FOREACH (Panel *, sub_panel, &panel->children) { + panel_set_runtime_flag_recursive(sub_panel, flag, value); + } +} + static void panels_collapse_all(ARegion *region, const Panel *from_panel) { const bool has_category_tabs = UI_panel_category_is_visible(region); @@ -657,7 +670,7 @@ static bool panel_type_context_poll(ARegion *region, return false; } -Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt) +Panel *UI_panel_find_by_type(ListBase *lb, const PanelType *pt) { const char *idname = pt->idname; @@ -681,7 +694,7 @@ Panel *UI_panel_begin( const bool newpanel = (panel == NULL); if (newpanel) { - panel = MEM_callocN(sizeof(Panel), "new panel"); + panel = MEM_callocN(sizeof(Panel), __func__); panel->type = pt; BLI_strncpy(panel->panelname, idname, sizeof(panel->panelname)); @@ -753,8 +766,8 @@ Panel *UI_panel_begin( /** * Create the panel header button group, used to mark which buttons are part of - * panel headers for later panel search handling. Should be called before adding - * buttons for the panel's header layout. + * panel headers for the panel search process that happens later. This Should be + * called before adding buttons for the panel's header layout. */ void UI_panel_header_buttons_begin(Panel *panel) { @@ -764,20 +777,20 @@ void UI_panel_header_buttons_begin(Panel *panel) } /** - * Allow new button groups to be created after the header group. + * Finish the button group for the panel header to avoid putting panel body buttons in it. */ void UI_panel_header_buttons_end(Panel *panel) { uiBlock *block = panel->runtime.block; - /* There should always be the button group created in #UI_panel_header_buttons_begin. */ + /* A button group should always be created in #UI_panel_header_buttons_begin. */ BLI_assert(!BLI_listbase_is_empty(&block->button_groups)); uiButtonGroup *button_group = block->button_groups.last; button_group->flag &= ~UI_BUTTON_GROUP_LOCK; - /* Repurpose the first "header" button group if it is empty, in case the first button added to + /* Repurpose the first header button group if it is empty, in case the first button added to * the panel doesn't add a new group (if the button is created directly rather than through an * interface layout call). */ if (BLI_listbase_is_single(&block->button_groups) && @@ -785,9 +798,9 @@ void UI_panel_header_buttons_end(Panel *panel) button_group->flag &= ~UI_BUTTON_GROUP_PANEL_HEADER; } else { - /* We should still always add a new button group. Although this results in many empty groups, - * without it, new buttons not protected with a #ui_block_new_button_group call would end up - * in the panel header group. */ + /* Always add a new button group. Although this may result in many empty groups, without it, + * new buttons in the panel body not protected with a #ui_block_new_button_group call would + * end up in the panel header group. */ ui_block_new_button_group(block, 0); } } @@ -805,7 +818,7 @@ static float panel_region_offset_x_get(const ARegion *region) /** * Starting from the "block size" set in #UI_panel_end, calculate the full size - * of the panel including the subpanel headers and buttons. + * of the panel including the sub-panel headers and buttons. */ static void panel_calculate_size_recursive(ARegion *region, Panel *panel) { @@ -854,7 +867,7 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel) void UI_panel_end(Panel *panel, int width, int height) { /* Store the size of the buttons layout in the panel. The actual panel size - * (including subpanels) is calculated in #UI_panels_end. */ + * (including sub-panels) is calculated in #UI_panels_end. */ panel->blocksizex = width; panel->blocksizey = height; } @@ -878,7 +891,7 @@ static void ui_offset_panel_block(uiBlock *block) block->rect.xmin = block->rect.ymin = 0.0; } -void ui_panel_tag_search_filter_match(struct Panel *panel) +void ui_panel_tag_search_filter_match(Panel *panel) { panel->runtime_flag |= PANEL_SEARCH_FILTER_MATCH; } @@ -907,25 +920,22 @@ bool UI_panel_matches_search_filter(const Panel *panel) } /** - * Set the flag telling the panel to use its search result status for - * its expansion. Also activate animation if that changes the expansion. + * Set the flag telling the panel to use its search result status for its expansion. */ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C, Panel *panel, - const bool use_search_closed, - const bool use_animation) + const bool use_search_closed) { /* This has to run on inactive panels that may not have a type, - * but we can prevent running on headerless panels in some cases. */ + * but we can prevent running on header-less panels in some cases. */ if (panel->type == NULL || !(panel->type->flag & PNL_NO_HEADER)) { SET_FLAG_FROM_TEST(panel->runtime_flag, use_search_closed, PANEL_USE_CLOSED_FROM_SEARCH); } LISTBASE_FOREACH (Panel *, child_panel, &panel->children) { - /* Don't check if the subpanel is active, otherwise the + /* Don't check if the sub-panel is active, otherwise the * expansion won't be reset when the parent is closed. */ - panel_set_expansion_from_seach_filter_recursive( - C, child_panel, use_search_closed, use_animation); + panel_set_expansion_from_seach_filter_recursive(C, child_panel, use_search_closed); } } @@ -934,18 +944,19 @@ static void panel_set_expansion_from_seach_filter_recursive(const bContext *C, */ static void region_panels_set_expansion_from_seach_filter(const bContext *C, ARegion *region, - const bool use_search_closed, - const bool use_animation) + const bool use_search_closed) { LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { - panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed, use_animation); + /* Don't check if the panel is active, otherwise the expansion won't + * be correct when switching back to tab after exiting search. */ + panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed); } set_panels_list_data_expand_flag(C, region); } /** - * Hide buttons in invisible layouts, which are created because in order to search, - * buttons must be added for all panels, even panels that will end up closed. + * Hide buttons in invisible layouts, which are created because buttons must be + * added for all panels in order to search, even panels that will end up closed. */ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *parent_panel) { @@ -960,8 +971,8 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel * } } else if (UI_panel_is_closed(panel)) { - /* If subpanels have no search results but the parent panel does, then the parent panel open - * and the subpanels will close. In that case there must be a way to hide the buttons in the + /* If sub-panels have no search results but the parent panel does, then the parent panel open + * and the sub-panels will close. In that case there must be a way to hide the buttons in the * panel but keep the header buttons. */ LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) { if (button_group->flag & UI_BUTTON_GROUP_PANEL_HEADER) { @@ -1029,42 +1040,24 @@ void UI_panels_draw(const bContext *C, ARegion *region) /* Draw in reverse order, because #uiBlocks are added in reverse order * and we need child panels to draw on top. */ LISTBASE_FOREACH_BACKWARD (uiBlock *, block, ®ion->uiblocks) { - if (block->active && block->panel && !(block->panel->flag & PNL_SELECT) && + if (block->active && block->panel && !UI_panel_is_dragging(block->panel) && !UI_block_is_search_only(block)) { UI_block_draw(C, block); } } LISTBASE_FOREACH_BACKWARD (uiBlock *, block, ®ion->uiblocks) { - if (block->active && block->panel && (block->panel->flag & PNL_SELECT) && + if (block->active && block->panel && UI_panel_is_dragging(block->panel) && !UI_block_is_search_only(block)) { UI_block_draw(C, block); } } } -/* Triangle 'icon' for panel header. */ -void UI_draw_icon_tri(float x, float y, char dir, const float color[4]) -{ - const float f3 = 0.05 * U.widget_unit; - const float f5 = 0.15 * U.widget_unit; - const float f7 = 0.25 * U.widget_unit; - - if (dir == 'h') { - UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color); - } - else if (dir == 't') { - UI_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color); - } - else { /* 'v' = vertical, down. */ - UI_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color); - } -} - #define PNL_ICON UI_UNIT_X /* Could be UI_UNIT_Y too. */ /* For button layout next to label. */ -void UI_panel_label_offset(uiBlock *block, int *r_x, int *r_y) +void UI_panel_label_offset(const uiBlock *block, int *r_x, int *r_y) { Panel *panel = block->panel; const bool is_subpanel = (panel->type && panel->type->parent); @@ -1628,14 +1621,9 @@ static int get_panel_real_ofsy(Panel *panel) return panel->ofsy; } -bool UI_panel_is_dragging(const struct Panel *panel) +bool UI_panel_is_dragging(const Panel *panel) { - uiHandlePanelData *data = panel->activedata; - if (!data) { - return false; - } - - return data->is_drag_drop; + return panel->runtime_flag & PANEL_IS_DRAG_DROP; } /** @@ -1857,15 +1845,13 @@ static void ui_do_animate(bContext *C, Panel *panel) } if (fac >= 1.0f) { - /* Store before data is freed. */ - const bool is_drag_drop = data->is_drag_drop; - - panel_activate_state(C, panel, PANEL_STATE_EXIT); - if (is_drag_drop) { - /* Note: doing this in #panel_activate_state would require removing `const` for context in - * many other places. */ + if (UI_panel_is_dragging(panel)) { + /* Note: doing this in #panel_activate_state would require + * removing `const` for context in many other places. */ reorder_instanced_panel_list(C, region, panel); } + + panel_activate_state(C, panel, PANEL_STATE_EXIT); return; } } @@ -1874,7 +1860,7 @@ static void panels_layout_begin_clear_flags(ListBase *lb) { LISTBASE_FOREACH (Panel *, panel, lb) { /* Flags to copy over to the next layout pass. */ - const short flag_copy = PANEL_USE_CLOSED_FROM_SEARCH; + const short flag_copy = PANEL_USE_CLOSED_FROM_SEARCH | PANEL_IS_DRAG_DROP; const bool was_active = panel->runtime_flag & PANEL_ACTIVE; const bool was_closed = UI_panel_is_closed(panel); @@ -1902,10 +1888,10 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) const bool region_search_filter_active = region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE; if (properties_space_needs_realign(area, region)) { - region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active, false); + region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active); } else if (region->flag & RGN_FLAG_SEARCH_FILTER_UPDATE) { - region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active, true); + region_panels_set_expansion_from_seach_filter(C, region, region_search_filter_active); } if (region->flag & RGN_FLAG_SEARCH_FILTER_ACTIVE) { @@ -1965,28 +1951,13 @@ static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel) dx *= BLI_rctf_size_x(®ion->v2d.cur) / (float)BLI_rcti_size_x(®ion->winrct); dy *= BLI_rctf_size_y(®ion->v2d.cur) / (float)BLI_rcti_size_y(®ion->winrct); - if (data->state == PANEL_STATE_DRAG_SCALE) { - panel->sizex = MAX2(data->startsizex + dx, UI_PANEL_MINX); + /* Add the movement of the view due to edge scrolling while dragging. */ + dx += ((float)region->v2d.cur.xmin - data->start_cur_xmin); + dy += ((float)region->v2d.cur.ymin - data->start_cur_ymin); + panel->ofsx = data->startofsx + round_fl_to_int(dx); + panel->ofsy = data->startofsy + round_fl_to_int(dy); - if (data->startsizey - dy < UI_PANEL_MINY) { - dy = -UI_PANEL_MINY + data->startsizey; - } - - panel->sizey = data->startsizey - dy; - panel->ofsy = data->startofsy + dy; - } - else { - /* Reset the panel snapping, to allow dragging away from snapped edges. */ - panel->snap = PNL_SNAP_NONE; - - /* Add the movement of the view due to edge scrolling while dragging. */ - dx += ((float)region->v2d.cur.xmin - data->start_cur_xmin); - dy += ((float)region->v2d.cur.ymin - data->start_cur_ymin); - panel->ofsx = data->startofsx + round_fl_to_int(dx); - panel->ofsy = data->startofsy + round_fl_to_int(dy); - - uiAlignPanelStep(region, 0.2f, true); - } + uiAlignPanelStep(region, 0.2f, true); ED_region_tag_redraw(region); } @@ -2135,9 +2106,9 @@ static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was * \param mx: The mouse x coordinate, in panel space. */ static void ui_handle_panel_header(const bContext *C, - uiBlock *block, + const uiBlock *block, const int mx, - short int event_type, + const int event_type, const short ctrl, const short shift) { @@ -2187,27 +2158,10 @@ static void ui_handle_panel_header(const bContext *C, } } - if (UI_panel_is_closed(panel)) { - panel->flag &= ~PNL_CLOSED; - /* Snap back up so full panel aligns with screen edge. */ - if (panel->snap & PNL_SNAP_BOTTOM) { - panel->ofsy = 0; - } + SET_FLAG_FROM_TEST(panel->flag, !UI_panel_is_closed(panel), PNL_CLOSED); - if (event_type == LEFTMOUSE) { - ui_panel_drag_collapse_handler_add(C, false); - } - } - else { - /* Snap down to bottom screen edge. */ - panel->flag |= PNL_CLOSED; - if (panel->snap & PNL_SNAP_BOTTOM) { - panel->ofsy = -panel->sizey; - } - - if (event_type == LEFTMOUSE) { - ui_panel_drag_collapse_handler_add(C, true); - } + if (event_type == LEFTMOUSE) { + ui_panel_drag_collapse_handler_add(C, UI_panel_is_closed(panel)); } set_panels_list_data_expand_flag(C, region); @@ -2244,7 +2198,7 @@ bool UI_panel_category_is_visible(const ARegion *region) region->panels_category.first != region->panels_category.last; } -PanelCategoryDyn *UI_panel_category_find(ARegion *region, const char *idname) +PanelCategoryDyn *UI_panel_category_find(const ARegion *region, const char *idname) { return BLI_findstring(®ion->panels_category, idname, offsetof(PanelCategoryDyn, idname)); } @@ -2325,10 +2279,10 @@ const char *UI_panel_category_active_get(ARegion *region, bool set_fallback) return NULL; } -PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(ARegion *region, const int x, const int y) +static PanelCategoryDyn *panel_categories_find_mouse_over(ARegion *region, const wmEvent *event) { LISTBASE_FOREACH (PanelCategoryDyn *, ptd, ®ion->panels_category) { - if (BLI_rcti_isect_pt(&ptd->rect, x, y)) { + if (BLI_rcti_isect_pt(&ptd->rect, event->mval[0], event->mval[1])) { return ptd; } } @@ -2336,11 +2290,6 @@ PanelCategoryDyn *UI_panel_category_find_mouse_over_ex(ARegion *region, const in return NULL; } -PanelCategoryDyn *UI_panel_category_find_mouse_over(ARegion *region, const wmEvent *event) -{ - return UI_panel_category_find_mouse_over_ex(region, event->mval[0], event->mval[1]); -} - void UI_panel_category_add(ARegion *region, const char *name) { PanelCategoryDyn *pc_dyn = MEM_callocN(sizeof(*pc_dyn), __func__); @@ -2436,7 +2385,7 @@ int ui_handler_panel_region(bContext *C, /* Handle category tabs. */ if (UI_panel_category_is_visible(region)) { if (event->type == LEFTMOUSE) { - PanelCategoryDyn *pc_dyn = UI_panel_category_find_mouse_over(region, event); + PanelCategoryDyn *pc_dyn = panel_categories_find_mouse_over(region, event); if (pc_dyn) { UI_panel_category_active_set(region, pc_dyn->idname); ED_region_tag_redraw(region); @@ -2617,7 +2566,7 @@ static void ui_handler_remove_panel(bContext *C, void *userdata) panel_activate_state(C, panel, PANEL_STATE_EXIT); } -static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state) +static void panel_activate_state(const bContext *C, Panel *panel, const uiHandlePanelState state) { uiHandlePanelData *data = panel->activedata; wmWindow *win = CTX_wm_window(C); @@ -2627,15 +2576,20 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS return; } - const bool was_drag_drop = (data && data->state == PANEL_STATE_DRAG); - - /* Set selection state for the panel and its sub-panels, which need to know they are selected - * too so they can be drawn above their parent when it's dragged. */ - if (state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) { + /* + * Note on "select" and "drag drop" flags: + * First, the panel is "picked up" and both flags are set. Then when the mouse releases + * and the panel starts animating to its aligned position, PNL_SELECT is unset. When the + * animation finishes, PANEL_IS_DRAG_DROP is cleared. */ + if (state == PANEL_STATE_DRAG) { + panel_set_flag_recursive(panel, PNL_SELECT, true); + panel_set_runtime_flag_recursive(panel, PANEL_IS_DRAG_DROP, true); + } + else if (state == PANEL_STATE_ANIMATION) { panel_set_flag_recursive(panel, PNL_SELECT, false); } - else { - panel_set_flag_recursive(panel, PNL_SELECT, true); + else if (state == PANEL_STATE_EXIT) { + panel_set_runtime_flag_recursive(panel, PANEL_IS_DRAG_DROP, false); } if (data && data->animtimer) { @@ -2674,32 +2628,12 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS data->starty = win->eventstate->y; data->startofsx = panel->ofsx; data->startofsy = panel->ofsy; - data->startsizex = panel->sizex; - data->startsizey = panel->sizey; data->start_cur_xmin = region->v2d.cur.xmin; data->start_cur_ymin = region->v2d.cur.ymin; data->starttime = PIL_check_seconds_timer(); - - /* Remember drag drop state even when animating to the aligned position after dragging. */ - data->is_drag_drop = was_drag_drop; - if (state == PANEL_STATE_DRAG) { - data->is_drag_drop = true; - } } ED_region_tag_redraw(region); } -PanelType *UI_paneltype_find(int space_id, int region_id, const char *idname) -{ - SpaceType *st = BKE_spacetype_from_id(space_id); - if (st) { - ARegionType *art = BKE_regiontype_from_id(st, region_id); - if (art) { - return BLI_findstring(&art->paneltypes, idname, offsetof(PanelType, idname)); - } - } - return NULL; -} - /** \} */ diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c index 14f97cb14a9..5c778043381 100644 --- a/source/blender/editors/interface/interface_template_search_menu.c +++ b/source/blender/editors/interface/interface_template_search_menu.c @@ -429,8 +429,8 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d /** * Create #MenuSearch_Data by inspecting the current context, this uses two methods: * - * - Look-up pre-defined editor-menus. - * - Look-up key-map items which call menus. + * - Look up predefined editor-menus. + * - Look up key-map items which call menus. */ static struct MenuSearch_Data *menu_items_from_ui_create( bContext *C, wmWindow *win, ScrArea *area_init, ARegion *region_init, bool include_all_areas) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index d4d24b3e3c2..83274db9db9 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -3304,7 +3304,6 @@ static void colorband_buttons_layout(uiLayout *layout, row = uiLayoutRow(split, false); uiItemR(row, &ptr, "position", 0, IFACE_("Pos"), ICON_NONE); bt = block->buttons.last; - bt->a1 = 1.0f; /* gives a bit more precision for modifying position */ UI_but_func_set(bt, colorband_update_cb, bt, coba); row = uiLayoutRow(layout, false); @@ -3336,7 +3335,6 @@ static void colorband_buttons_layout(uiLayout *layout, row = uiLayoutRow(subsplit, false); uiItemR(row, &ptr, "position", UI_ITEM_R_SLIDER, IFACE_("Pos"), ICON_NONE); bt = block->buttons.last; - bt->a1 = 1.0f; /* gives a bit more precision for modifying position */ UI_but_func_set(bt, colorband_update_cb, bt, coba); row = uiLayoutRow(split, false); @@ -4971,7 +4969,7 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp selection_y = &point->h2_loc[1]; } } - if (i == 0 || i == profile->path_len - 1) { + if (ELEM(i, 0, profile->path_len - 1)) { point_last_or_first = true; } @@ -5330,7 +5328,7 @@ static void ui_template_palette_menu(bContext *UNUSED(C), uiLayout *layout, void { uiLayout *row; - uiItemL(layout, IFACE_("Sort by:"), ICON_NONE); + uiItemL(layout, IFACE_("Sort By:"), ICON_NONE); row = uiLayoutRow(layout, false); uiItemEnumO_value(row, IFACE_("Hue"), ICON_NONE, "PALETTE_OT_sort", "type", 1); row = uiLayoutRow(layout, false); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index 6bc644ce5b5..958a0bc03cd 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -645,10 +645,10 @@ bool UI_but_online_manual_id_from_active(const struct bContext *C, char *r_str, } /* -------------------------------------------------------------------- */ -/* Modal Button Store API */ - /** \name Button Store * + * Modal Button Store API. + * * Store for modal operators & handlers to register button pointers * which are maintained while drawing or NULL when removed. * @@ -792,7 +792,7 @@ void UI_butstore_update(uiBlock *block) /* warning, loop-in-loop, in practice we only store <10 buttons at a time, * so this isn't going to be a problem, if that changes old-new mapping can be cached first */ LISTBASE_FOREACH (uiButStore *, bs_handle, &block->butstore) { - BLI_assert((bs_handle->block == NULL) || (bs_handle->block == block) || + BLI_assert(ELEM(bs_handle->block, NULL, block) || (block->oldblock && block->oldblock == bs_handle->block)); if (bs_handle->block == block->oldblock) { diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 49760b99d2e..e2c835ac461 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -548,6 +548,24 @@ void UI_draw_anti_tria( GPU_blend(GPU_BLEND_NONE); } +/* Triangle 'icon' for panel header and other cases. */ +void UI_draw_icon_tri(float x, float y, char dir, const float color[4]) +{ + const float f3 = 0.05 * U.widget_unit; + const float f5 = 0.15 * U.widget_unit; + const float f7 = 0.25 * U.widget_unit; + + if (dir == 'h') { + UI_draw_anti_tria(x - f3, y - f5, x - f3, y + f5, x + f7, y, color); + } + else if (dir == 't') { + UI_draw_anti_tria(x - f5, y - f7, x + f5, y - f7, x, y + f3, color); + } + else { /* 'v' = vertical, down. */ + UI_draw_anti_tria(x - f5, y + f3, x + f5, y + f3, x, y - f7, color); + } +} + /* triangle 'icon' inside rect */ void ui_draw_anti_tria_rect(const rctf *rect, char dir, const float color[4]) { @@ -899,7 +917,7 @@ static void shape_preset_init_trias_ex(uiWidgetTrias *tria, float centx, centy, sizex, sizey, minsize; int a, i1 = 0, i2 = 1; - if (where == 'r' || where == 'l') { + if (ELEM(where, 'r', 'l')) { minsize = BLI_rcti_size_y(rect); } else { @@ -2426,19 +2444,23 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle, } } else if (but->drawflag & UI_BUT_TEXT_LEFT) { - - /* Reduce the left padding for labels without an icon. */ - if ((but->type == UI_BTYPE_LABEL) && !(but->flag & UI_HAS_ICON) && - !ui_block_is_menu(but->block)) { - text_padding /= 2; - } - rect->xmin += text_padding; } else if (but->drawflag & UI_BUT_TEXT_RIGHT) { rect->xmax -= text_padding; } } + else { + /* In case a separate text label and some other button are placed under each other, + and the outline of the button does not contrast with the background. + Add an offset (thickness of the outline) so that the text does not stick out visually. */ + if (but->drawflag & UI_BUT_TEXT_LEFT) { + rect->xmin += U.pixelsize; + } + else if (but->drawflag & UI_BUT_TEXT_RIGHT) { + rect->xmax -= U.pixelsize; + } + } /* Menu contains sub-menu items with triangle icon on their right. Shortcut * strings should be drawn with some padding to the right then. */ @@ -4053,7 +4075,7 @@ static void widget_optionbut(uiWidgetColors *wcol, } /* smaller */ - delta = 1 + BLI_rcti_size_y(&recttemp) / 8; + delta = (BLI_rcti_size_y(&recttemp) - 2 * U.pixelsize) / 6; BLI_rcti_resize( &recttemp, BLI_rcti_size_x(&recttemp) - delta * 2, BLI_rcti_size_y(&recttemp) - delta * 2); /* Keep one edge in place. */ @@ -4575,6 +4597,9 @@ void ui_draw_but(const bContext *C, struct ARegion *region, uiStyle *style, uiBu wt->wcol_theme = &tui->wcol_menu_back; wt->state = widget_state; } + if (!(but->flag & UI_HAS_ICON)) { + but->drawflag |= UI_BUT_NO_TEXT_PADDING; + } break; case UI_BTYPE_SEPR: diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index d8ebbbca023..a5999962e09 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -293,7 +293,7 @@ static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event) } #endif default: - if (event->type == vpd->invoke_event || event->type == EVT_ESCKEY) { + if (ELEM(event->type, vpd->invoke_event, EVT_ESCKEY)) { if (event->val == KM_RELEASE) { /* calculate overall delta mouse-movement for redo */ RNA_int_set(op->ptr, "deltax", (vpd->startx - vpd->lastx)); @@ -1122,8 +1122,9 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) dy *= -1; } - /* continuous zoom shouldn't move that fast... */ - if (U.viewzoom == USER_ZOOM_CONT) { /* XXX store this setting as RNA prop? */ + /* Check if the 'timer' is initialized, as zooming with the trackpad + * never uses the "Continuous" zoom method, and the 'timer' is not initialized. */ + if ((U.viewzoom == USER_ZOOM_CONT) && vzd->timer) { /* XXX store this setting as RNA prop? */ const double time = PIL_check_seconds_timer(); const float time_step = (float)(time - vzd->timer_lastdraw); @@ -1232,10 +1233,15 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even v2d = vzd->v2d; if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) { + ARegion *region = CTX_wm_region(C); + + /* Store initial mouse position (in view space). */ + UI_view2d_region_to_view( + ®ion->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d); vzd->zoom_to_mouse_pos = true; } - if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { + if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) { float dx, dy, fac; vzd->lastx = event->prevx; @@ -1278,14 +1284,6 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even /* for modal exit test */ vzd->invoke_event = event->type; - if (U.uiflag & USER_ZOOM_TO_MOUSEPOS) { - ARegion *region = CTX_wm_region(C); - - /* store initial mouse position (in view space) */ - UI_view2d_region_to_view( - ®ion->v2d, event->mval[0], event->mval[1], &vzd->mx_2d, &vzd->my_2d); - } - if (v2d->keepofs & V2D_LOCKOFS_X) { WM_cursor_modal_set(window, WM_CURSOR_NS_SCROLL); } @@ -1415,7 +1413,7 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event /* apply zooming */ view_zoomdrag_apply(C, op); } - else if (event->type == vzd->invoke_event || event->type == EVT_ESCKEY) { + else if (ELEM(event->type, vzd->invoke_event, EVT_ESCKEY)) { if (event->val == KM_RELEASE) { /* for redo, store the overall deltas - need to respect zoom-locks here... */ diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c index 292d8e6066c..70125ff35fc 100644 --- a/source/blender/editors/io/io_alembic.c +++ b/source/blender/editors/io/io_alembic.c @@ -292,7 +292,7 @@ void WM_OT_alembic_export(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_int(ot->srna, "start", @@ -677,7 +677,7 @@ void WM_OT_alembic_import(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_float( ot->srna, diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c index 045a293f71b..b73b8abccfe 100644 --- a/source/blender/editors/io/io_cache.c +++ b/source/blender/editors/io/io_cache.c @@ -134,7 +134,7 @@ void CACHEFILE_OT_open(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /* ***************************** Reload Operator **************************** */ diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 54ef5e6b8c5..af505043e6a 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -507,7 +507,7 @@ void WM_OT_collada_export(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_enum(func, "prop_bc_export_ui_section", @@ -828,7 +828,7 @@ void WM_OT_collada_import(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "import_units", diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 45ea52bdebc..0eadb38abb5 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -185,7 +185,7 @@ void WM_OT_usd_export(struct wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "selected_objects_only", diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index 62f46c93bc7..d7b3d74bc7e 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -202,7 +202,7 @@ static void finSelectedSplinePoint(MaskLayer *mask_layer, MaskSplinePoint *cur_point = &cur_spline->points[i]; if (MASKPOINT_ISSEL_ANY(cur_point)) { - if (*spline != NULL && *spline != cur_spline) { + if (!ELEM(*spline, NULL, cur_spline)) { *spline = NULL; *point = NULL; return; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index 8acbb328ab0..c757b6f0cc3 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -111,7 +111,7 @@ static void draw_single_handle(const MaskLayer *mask_layer, const BezTriple *bezt = &point->bezt; char handle_type; - if (which_handle == MASK_WHICH_HANDLE_STICK || which_handle == MASK_WHICH_HANDLE_LEFT) { + if (ELEM(which_handle, MASK_WHICH_HANDLE_STICK, MASK_WHICH_HANDLE_LEFT)) { handle_type = bezt->h1; } else { diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c index a90d6530453..b8badd207fe 100644 --- a/source/blender/editors/mesh/editmesh_bevel.c +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -127,15 +127,10 @@ enum { static float get_bevel_offset(wmOperator *op) { - float val; - if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) { - val = RNA_float_get(op->ptr, "offset_pct"); - } - else { - val = RNA_float_get(op->ptr, "offset"); + return RNA_float_get(op->ptr, "offset_pct"); } - return val; + return RNA_float_get(op->ptr, "offset"); } static void edbm_bevel_update_status_text(bContext *C, wmOperator *op) @@ -145,14 +140,12 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op) char *p = buf; int available_len = sizeof(buf); Scene *sce = CTX_data_scene(C); - char offset_str[NUM_STR_REP_LEN]; - const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str; - PropertyRNA *prop; #define WM_MODALKEY(_id) \ WM_modalkeymap_operator_items_to_string_buf( \ op->type, (_id), true, UI_MAX_SHORTCUT_STR, &available_len, &p) + char offset_str[NUM_STR_REP_LEN]; if (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT) { BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%.1f%%", RNA_float_get(op->ptr, "offset_pct")); } @@ -167,6 +160,8 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op) true); } + PropertyRNA *prop; + const char *mode_str, *omiter_str, *imiter_str, *vmesh_str, *profile_type_str, *affect_str; prop = RNA_struct_find_property(op->ptr, "offset_type"); RNA_property_enum_name_gettexted( C, op->ptr, prop, RNA_property_enum_get(op->ptr, prop), &mode_str); @@ -240,18 +235,17 @@ static void edbm_bevel_update_status_text(bContext *C, wmOperator *op) static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) { Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); ToolSettings *ts = CTX_data_tool_settings(C); - BevelData *opdata; ViewLayer *view_layer = CTX_data_view_layer(C); - float pixels_per_inch; - int i, otype; if (is_modal) { RNA_float_set(op->ptr, "offset", 0.0f); RNA_float_set(op->ptr, "offset_pct", 0.0f); } - op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); + op->customdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); + BevelData *opdata = op->customdata; uint objects_used_len = 0; opdata->max_obj_scale = FLT_MIN; @@ -261,7 +255,7 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) { uint ob_store_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - view_layer, CTX_wm_view3d(C), &ob_store_len); + view_layer, v3d, &ob_store_len); opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__); for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) { Object *obedit = objects[ob_index]; @@ -278,12 +272,12 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) } opdata->is_modal = is_modal; - otype = RNA_enum_get(op->ptr, "offset_type"); + int otype = RNA_enum_get(op->ptr, "offset_type"); opdata->value_mode = (otype == BEVEL_AMT_PERCENT) ? OFFSET_VALUE_PERCENT : OFFSET_VALUE; opdata->segments = (float)RNA_int_get(op->ptr, "segments"); - pixels_per_inch = U.dpi * U.pixelsize; + float pixels_per_inch = U.dpi * U.pixelsize; - for (i = 0; i < NUM_VALUE_KINDS; i++) { + for (int i = 0; i < NUM_VALUE_KINDS; i++) { opdata->shift_value[i] = -1.0f; opdata->initial_length[i] = -1.0f; /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */ @@ -304,7 +298,6 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) /* avoid the cost of allocating a bm copy */ if (is_modal) { - View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) { @@ -491,23 +484,21 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed) { - BevelData *opdata; - float mlen[2], len, value, sc, st; - int vmode; - - opdata = op->customdata; - mlen[0] = opdata->mcenter[0] - event->mval[0]; - mlen[1] = opdata->mcenter[1] - event->mval[1]; - len = len_v2(mlen); - vmode = opdata->value_mode; + BevelData *opdata = op->customdata; + const float mlen[2] = { + opdata->mcenter[0] - event->mval[0], + opdata->mcenter[1] - event->mval[1], + }; + float len = len_v2(mlen); + int vmode = opdata->value_mode; if (mode_changed || opdata->initial_length[vmode] == -1.0f) { /* If current value is not default start value, adjust len so that * the scaling and offset in edbm_bevel_mouse_set_value will * start at current value */ - value = (vmode == SEGMENTS_VALUE) ? opdata->segments : - RNA_float_get(op->ptr, value_rna_name[vmode]); - sc = opdata->scale[vmode]; - st = value_start[vmode]; + float value = (vmode == SEGMENTS_VALUE) ? opdata->segments : + RNA_float_get(op->ptr, value_rna_name[vmode]); + float sc = opdata->scale[vmode]; + float st = value_start[vmode]; if (value != value_start[vmode]) { len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc; } @@ -518,18 +509,17 @@ static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event) { RegionView3D *rv3d = CTX_wm_region_view3d(C); - BevelData *opdata; - float center_3d[3]; if (!edbm_bevel_init(C, op, true)) { return OPERATOR_CANCELLED; } - opdata = op->customdata; + BevelData *opdata = op->customdata; opdata->launch_event = WM_userdef_event_type_from_keymap_type(event->type); /* initialize mouse values */ + float center_3d[3]; if (!calculateTransformCenter(C, V3D_AROUND_CENTER_MEDIAN, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ @@ -561,13 +551,13 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event) { BevelData *opdata = op->customdata; int vmode = opdata->value_mode; - float mdiff[2]; - float value; - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; + const float mdiff[2] = { + opdata->mcenter[0] - event->mval[0], + opdata->mcenter[1] - event->mval[1], + }; - value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]); + float value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]); /* Scale according to value mode */ value = value_start[vmode] + value * opdata->scale[vmode]; @@ -599,12 +589,10 @@ static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event) static void edbm_bevel_numinput_set_value(wmOperator *op) { BevelData *opdata = op->customdata; - float value; - int vmode; - vmode = opdata->value_mode; - value = (vmode == SEGMENTS_VALUE) ? opdata->segments : - RNA_float_get(op->ptr, value_rna_name[vmode]); + int vmode = opdata->value_mode; + float value = (vmode == SEGMENTS_VALUE) ? opdata->segments : + RNA_float_get(op->ptr, value_rna_name[vmode]); applyNumInput(&opdata->num_input[vmode], &value); CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]); if (vmode == SEGMENTS_VALUE) { @@ -616,82 +604,61 @@ static void edbm_bevel_numinput_set_value(wmOperator *op) } } -/* Hide one of offset or offset_pct, depending on offset_type */ -static bool edbm_bevel_poll_property(const bContext *UNUSED(C), - wmOperator *op, - const PropertyRNA *prop) -{ - const char *prop_id = RNA_property_identifier(prop); - - if (STRPREFIX(prop_id, "offset")) { - int offset_type = RNA_enum_get(op->ptr, "offset_type"); - - if (STREQ(prop_id, "offset") && offset_type == BEVEL_AMT_PERCENT) { - return false; - } - if (STREQ(prop_id, "offset_pct") && offset_type != BEVEL_AMT_PERCENT) { - return false; - } - } - - return true; -} - wmKeyMap *bevel_modal_keymap(wmKeyConfig *keyconf) { static const EnumPropertyItem modal_items[] = { {BEV_MODAL_CANCEL, "CANCEL", 0, "Cancel", "Cancel bevel"}, {BEV_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", "Confirm bevel"}, - {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change offset", "Value changes offset"}, - {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change profile", "Value changes profile"}, - {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change segments", "Value changes segments"}, - {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase segments", "Increase segments"}, - {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease segments", "Decrease segments"}, + {BEV_MODAL_VALUE_OFFSET, "VALUE_OFFSET", 0, "Change Offset", "Value changes offset"}, + {BEV_MODAL_VALUE_PROFILE, "VALUE_PROFILE", 0, "Change Profile", "Value changes profile"}, + {BEV_MODAL_VALUE_SEGMENTS, "VALUE_SEGMENTS", 0, "Change Segments", "Value changes segments"}, + {BEV_MODAL_SEGMENTS_UP, "SEGMENTS_UP", 0, "Increase Segments", "Increase segments"}, + {BEV_MODAL_SEGMENTS_DOWN, "SEGMENTS_DOWN", 0, "Decrease Segments", "Decrease segments"}, {BEV_MODAL_OFFSET_MODE_CHANGE, "OFFSET_MODE_CHANGE", 0, - "Change offset mode", + "Change Offset Mode", "Cycle through offset modes"}, {BEV_MODAL_CLAMP_OVERLAP_TOGGLE, "CLAMP_OVERLAP_TOGGLE", 0, - "Toggle clamp overlap", + "Toggle Clamp Overlap", "Toggle clamp overlap flag"}, {BEV_MODAL_AFFECT_CHANGE, "AFFECT_CHANGE", 0, - "Change affect type", + "Change Affect Type", "Change which geometry type the operation affects, edges or vertices"}, {BEV_MODAL_HARDEN_NORMALS_TOGGLE, "HARDEN_NORMALS_TOGGLE", 0, - "Toggle harden normals", + "Toggle Harden Normals", "Toggle harden normals flag"}, {BEV_MODAL_MARK_SEAM_TOGGLE, "MARK_SEAM_TOGGLE", 0, - "Toggle mark seam", + "Toggle Mark Seam", "Toggle mark seam flag"}, {BEV_MODAL_MARK_SHARP_TOGGLE, "MARK_SHARP_TOGGLE", 0, - "Toggle mark sharp", + "Toggle Mark Sharp", "Toggle mark sharp flag"}, {BEV_MODAL_OUTER_MITER_CHANGE, "OUTER_MITER_CHANGE", 0, - "Change outer miter", + "Change Outer Miter", "Cycle through outer miter kinds"}, {BEV_MODAL_INNER_MITER_CHANGE, "INNER_MITER_CHANGE", 0, - "Change inner miter", + "Change Inner Miter", "Cycle through inner miter kinds"}, {BEV_MODAL_PROFILE_TYPE_CHANGE, "PROFILE_TYPE_CHANGE", 0, "Cycle through profile types", ""}, {BEV_MODAL_VERTEX_MESH_CHANGE, "VERTEX_MESH_CHANGE", 0, - "Change intersection method", + "Change Intersection Method", "Cycle through intersection methods"}, {0, NULL, 0, NULL, NULL}, }; @@ -1109,7 +1076,6 @@ void MESH_OT_bevel(wmOperatorType *ot) ot->modal = edbm_bevel_modal; ot->cancel = edbm_bevel_cancel; ot->poll = ED_operator_editmesh; - ot->poll_property = edbm_bevel_poll_property; ot->ui = edbm_bevel_ui; /* flags */ diff --git a/source/blender/editors/mesh/editmesh_extrude_spin.c b/source/blender/editors/mesh/editmesh_extrude_spin.c index 6dde45a4f5f..7b3fabf07fc 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin.c @@ -24,6 +24,7 @@ #include "DNA_object_types.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BKE_context.h" #include "BKE_editmesh.h" @@ -172,7 +173,7 @@ static bool edbm_spin_poll_property(const bContext *UNUSED(C), const bool dupli = RNA_boolean_get(op->ptr, "dupli"); if (dupli) { - if (STREQ(prop_id, "use_auto_merge") || STREQ(prop_id, "use_normal_flip")) { + if (STR_ELEM(prop_id, "use_auto_merge", "use_normal_flip")) { return false; } } diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c index 528ad57b9bf..e2112f91060 100644 --- a/source/blender/editors/mesh/editmesh_intersect.c +++ b/source/blender/editors/mesh/editmesh_intersect.c @@ -121,11 +121,10 @@ static void edbm_intersect_select(BMEditMesh *em, struct Mesh *me, bool do_selec } /* -------------------------------------------------------------------- */ -/* Cut intersections into geometry */ - /** \name Simple Intersect (self-intersect) - * \{ - */ + * + * Cut intersections into geometry. + * \{ */ enum { ISECT_SEL = 0, @@ -331,15 +330,11 @@ void MESH_OT_intersect(struct wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/* Boolean (a kind of intersect) */ - /** \name Boolean Intersect * * \note internally this is nearly exactly the same as 'MESH_OT_intersect', * however from a user perspective they are quite different, so expose as different tools. - * - * \{ - */ + * \{ */ static int edbm_intersect_boolean_exec(bContext *C, wmOperator *op) { @@ -488,9 +483,7 @@ void MESH_OT_intersect_boolean(struct wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/* Face Split by Edges */ - -/** \name Face/Edge Split +/** \name Face Split by Edges * \{ */ static void bm_face_split_by_edges(BMesh *bm, diff --git a/source/blender/editors/mesh/editmesh_preselect_edgering.c b/source/blender/editors/mesh/editmesh_preselect_edgering.c index aa1df3d76fc..43e36957dc9 100644 --- a/source/blender/editors/mesh/editmesh_preselect_edgering.c +++ b/source/blender/editors/mesh/editmesh_preselect_edgering.c @@ -110,7 +110,7 @@ static void edgering_find_order(BMEdge *eed_last, BMEdge *eed, BMVert *eve_last, BMLoop *l_other = BM_loop_other_edge_loop(l, eed->v1); const bool rev = (l_other == l->prev); - while (l_other->v != eed_last->v1 && l_other->v != eed_last->v2) { + while (!ELEM(l_other->v, eed_last->v1, eed_last->v2)) { l_other = rev ? l_other->prev : l_other->next; } diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index f94d3ba5a70..00349983c57 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -83,7 +83,7 @@ static const EnumPropertyItem prop_similar_types[] = { {SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""}, {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, - {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, + {SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""}, {SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""}, {SIMFACE_FACEMAP, "FACE_MAP", 0, "Face-Map", ""}, #ifdef WITH_FREESTYLE diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 85cc19e7471..c8367c720a7 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -875,7 +875,7 @@ static void edbm_add_edge_face_exec__tricky_finalize_sel(BMesh *bm, BMElem *ele_ } else { BMLoop *l = BM_face_edge_share_loop(f, (BMEdge *)ele_desel); - BLI_assert(f->len == 4 || f->len == 3); + BLI_assert(ELEM(f->len, 4, 3)); BM_edge_select_set(bm, (BMEdge *)ele_desel, false); if (f->len == 4) { @@ -4082,7 +4082,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) isect = bm_edge_seg_isect(sco_a, sco_b, mouse_path, len, mode, &isected); if (isect != 0.0f) { - if (mode != KNIFE_MULTICUT && mode != KNIFE_MIDPOINT) { + if (!ELEM(mode, KNIFE_MULTICUT, KNIFE_MIDPOINT)) { BMO_slot_map_float_insert(&bmop, slot_edge_percents, be, isect); } } diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 41d840c4a2d..43cad2db185 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -118,6 +118,7 @@ typedef struct UndoMesh { #ifdef USE_ARRAY_STORE +/* -------------------------------------------------------------------- */ /** \name Array Store * \{ */ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 62dd4a22654..3b5897de0b0 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -407,7 +407,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) me = (Mesh *)ob->data; key = me->key; - if (totvert == 0 || totvert == me->totvert) { + if (ELEM(totvert, 0, me->totvert)) { BKE_report(op->reports, RPT_WARNING, "No mesh data to join"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 36e780f7472..8973a74cd1d 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -2930,7 +2930,7 @@ static int object_convert_exec(bContext *C, wmOperator *op) /* Remove curves and meshes converted to Grease Pencil object. */ if (gpencilConverted) { FOREACH_SCENE_OBJECT_BEGIN (scene, ob_delete) { - if ((ob_delete->type == OB_CURVE) || (ob_delete->type == OB_MESH)) { + if (ELEM(ob_delete->type, OB_CURVE, OB_MESH)) { if (ob_delete->flag & OB_DONE) { ED_object_base_free_and_unlink(bmain, scene, ob_delete); } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index ae1aae27b7f..bb8597bf02c 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -97,7 +97,6 @@ typedef struct MultiresBakerJobData { int len; } ob_image; DerivedMesh *lores_dm, *hires_dm; - bool simple; int lvl, tot_lvl; ListBase images; } MultiresBakerJobData; @@ -247,7 +246,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l return dm; } -static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple) +static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl) { Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -264,7 +263,6 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH.pmask); *lvl = mmd->totlvl; - *simple = mmd->simple != 0; tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; @@ -386,7 +384,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) bkr.ob_image.array = bake_object_image_get_array(ob); bkr.ob_image.len = ob->totcol; - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); + bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl); bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); RE_multires_bake_images(&bkr); @@ -441,7 +439,7 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data->ob_image.len = ob->totcol; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl); data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); data->lvl = lvl; @@ -491,7 +489,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa bkr.hires_dm = data->hires_dm; bkr.tot_lvl = data->tot_lvl; bkr.lvl = data->lvl; - bkr.simple = data->simple; /* needed for proper progress bar */ bkr.tot_obj = tot_obj; diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 0073aa830de..fa8531dfb48 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -2219,7 +2219,7 @@ static const EnumPropertyItem *object_constraint_add_itemf(bContext *UNUSED(C), int totitem = 0; while (item->identifier) { - if ((item->value != CONSTRAINT_TYPE_KINEMATIC) && (item->value != CONSTRAINT_TYPE_SPLINEIK)) { + if (!ELEM(item->value, CONSTRAINT_TYPE_KINEMATIC, CONSTRAINT_TYPE_SPLINEIK)) { RNA_enum_item_add(&object_constraint_items, &totitem, item); } item++; diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 4884df1edb6..99989f86381 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -28,6 +28,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -562,32 +563,45 @@ static bool data_transfer_poll_property(const bContext *UNUSED(C), return false; } - if (STREQ(prop_id, "use_object_transform") && use_auto_transform) { - return false; + if (STREQ(prop_id, "use_object_transform")) { + if (use_auto_transform) { + return false; + } } - if (STREQ(prop_id, "max_distance") && !use_max_distance) { - return false; + else if (STREQ(prop_id, "max_distance")) { + if (!use_max_distance) { + return false; + } } - if (STREQ(prop_id, "islands_precision") && !DT_DATATYPE_IS_LOOP(data_type)) { - return false; + else if (STREQ(prop_id, "islands_precision")) { + if (!DT_DATATYPE_IS_LOOP(data_type)) { + return false; + } } - - if (STREQ(prop_id, "vert_mapping") && !DT_DATATYPE_IS_VERT(data_type)) { - return false; + else if (STREQ(prop_id, "vert_mapping")) { + if (!DT_DATATYPE_IS_VERT(data_type)) { + return false; + } } - if (STREQ(prop_id, "edge_mapping") && !DT_DATATYPE_IS_EDGE(data_type)) { - return false; + else if (STREQ(prop_id, "edge_mapping")) { + if (!DT_DATATYPE_IS_EDGE(data_type)) { + return false; + } } - if (STREQ(prop_id, "loop_mapping") && !DT_DATATYPE_IS_LOOP(data_type)) { - return false; + else if (STREQ(prop_id, "loop_mapping")) { + if (!DT_DATATYPE_IS_LOOP(data_type)) { + return false; + } } - if (STREQ(prop_id, "poly_mapping") && !DT_DATATYPE_IS_POLY(data_type)) { - return false; + else if (STREQ(prop_id, "poly_mapping")) { + if (!DT_DATATYPE_IS_POLY(data_type)) { + return false; + } } - - if ((STREQ(prop_id, "layers_select_src") || STREQ(prop_id, "layers_select_dst")) && - !DT_DATATYPE_IS_MULTILAYERS(data_type)) { - return false; + else if (STR_ELEM(prop_id, "layers_select_src", "layers_select_dst")) { + if (!DT_DATATYPE_IS_MULTILAYERS(data_type)) { + return false; + } } /* Else, show it! */ diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index df940d3fa25..70c3552e8da 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -761,7 +761,7 @@ bool ED_object_editmode_enter_ex(Main *bmain, Scene *scene, Object *ob, int flag WM_main_add_notifier(NC_SCENE | ND_MODE | NS_EDITMODE_LATTICE, scene); } - else if (ob->type == OB_SURF || ob->type == OB_CURVE) { + else if (ELEM(ob->type, OB_SURF, OB_CURVE)) { ok = 1; ED_curve_editnurb_make(ob); diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index 5cfe02dbc59..91c9916d227 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -238,12 +238,11 @@ static void select_editlattice_hook(Object *obedit, HookModifierData *hmd) static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, float r_cent[3]) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int *index, a, nr, totvert = 0; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -280,7 +279,7 @@ static int return_editcurve_indexar(Object *obedit, int *r_tot, int **r_indexar, nr = 0; zero_v3(r_cent); - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -377,12 +376,11 @@ static bool object_hook_index_array(Main *bmain, static void select_editcurve_hook(Object *obedit, HookModifierData *hmd) { ListBase *editnurb = object_editcurve_get(obedit); - Nurb *nu; BPoint *bp; BezTriple *bezt; int index = 0, a, nr = 0; - for (nu = editnurb->first; nu; nu = nu->next) { + LISTBASE_FOREACH (Nurb *, nu, editnurb) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 4eed9187d66..ce08c5926f2 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -31,6 +31,7 @@ #include "DNA_armature_types.h" #include "DNA_curve_types.h" #include "DNA_key_types.h" +#include "DNA_lattice_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_force_types.h" @@ -679,16 +680,15 @@ static int modifier_apply_shape(Main *bmain, return 0; } - /* - * It should be ridiculously easy to extract the original verts that we want - * and form the shape data. We can probably use the CD KEYINDEX layer (or - * whatever I ended up calling it, too tired to check now), though this would - * by necessity have to make some potentially ugly assumptions about the order - * of the mesh data :-/ you can probably assume in 99% of cases that the first - * element of a given index is the original, and any subsequent duplicates are - * copies/interpolates, but that's an assumption that would need to be tested - * and then predominantly stated in comments in a half dozen headers. - */ + /* We could investigate using the #CD_ORIGINDEX layer + * to support other kinds of modifiers besides deforming modifiers. + * as this is done in many other places, see: #BKE_mesh_foreach_mapped_vert_coords_get. + * + * This isn't high priority in practice since most modifiers users + * want to apply as a shape are deforming modifiers. + * + * If a compelling use-case comes up where we want to support other kinds of modifiers + * we can look into supporting them. */ if (ob->type == OB_MESH) { Mesh *mesh_applied; @@ -721,7 +721,7 @@ static int modifier_apply_shape(Main *bmain, BKE_id_free(NULL, mesh_applied); } else { - /* TODO: implement for hair, pointclouds and volumes. */ + /* TODO: implement for hair, point-clouds and volumes. */ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } @@ -798,8 +798,27 @@ static int modifier_apply_obdata( DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); } + else if (ob->type == OB_LATTICE) { + Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); + Lattice *lattice = ob->data; + ModifierEvalContext mectx = {depsgraph, object_eval, 0}; + + if (ELEM(mti->type, eModifierTypeType_Constructive, eModifierTypeType_Nonconstructive)) { + BKE_report(reports, RPT_ERROR, "Constructive modifiers cannot be applied"); + return 0; + } + + int numVerts; + float(*vertexCos)[3] = BKE_lattice_vert_coords_alloc(lattice, &numVerts); + mti->deformVerts(md_eval, &mectx, NULL, vertexCos, numVerts); + BKE_lattice_vert_coords_apply(lattice, vertexCos); + + MEM_freeN(vertexCos); + + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + } else { - /* TODO: implement for hair, pointclouds and volumes. */ + /* TODO: implement for hair, point-clouds and volumes. */ BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } @@ -1478,8 +1497,8 @@ static char *modifier_apply_as_shapekey_get_description(struct bContext *UNUSED( void OBJECT_OT_modifier_apply_as_shapekey(wmOperatorType *ot) { - ot->name = "Apply Modifier As Shapekey"; - ot->description = "Apply modifier as a new shapekey and remove from the stack"; + ot->name = "Apply Modifier as Shape Key"; + ot->description = "Apply modifier as a new shape key and remove from the stack"; ot->idname = "OBJECT_OT_modifier_apply_as_shapekey"; ot->invoke = modifier_apply_as_shapekey_invoke; @@ -1887,7 +1906,7 @@ void OBJECT_OT_multires_external_save(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); edit_modifier_properties(ot); } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index de3e5f3d5f9..29393e8a8d1 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -696,7 +696,7 @@ bool ED_object_parent_set(ReportList *reports, /* Preconditions. */ if (ob == par) { /* Parenting an object to itself is impossible. */ - return true; + return false; } if (BKE_object_parent_loop_check(par, ob)) { @@ -911,7 +911,7 @@ bool ED_object_parent_set(ReportList *reports, else if (partype == PAR_ARMATURE_NAME) { ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_NAME); } - else if ((partype == PAR_ARMATURE_AUTO) || (partype == PAR_ARMATURE_ENVELOPE)) { + else if (ELEM(partype, PAR_ARMATURE_AUTO, PAR_ARMATURE_ENVELOPE)) { WM_cursor_wait(1); ED_gpencil_add_armature_weights(C, reports, ob, par, GP_PAR_ARMATURE_AUTO); WM_cursor_wait(0); @@ -981,6 +981,12 @@ struct ParentingContext { static bool parent_set_nonvertex_parent(bContext *C, struct ParentingContext *parenting_context) { CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + if (ob == parenting_context->par) { + /* ED_object_parent_set() will fail (and thus return false), but this case shouldn't break + * this loop. It's expected that the active object is also selected. */ + continue; + } + if (!ED_object_parent_set(parenting_context->reports, C, parenting_context->scene, @@ -1005,6 +1011,12 @@ static bool parent_set_vertex_parent_with_kdtree(bContext *C, int vert_par[3] = {0, 0, 0}; CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { + if (ob == parenting_context->par) { + /* ED_object_parent_set() will fail (and thus return false), but this case shouldn't break + * this loop. It's expected that the active object is also selected. */ + continue; + } + parent_set_vert_find(tree, ob, vert_par, parenting_context->is_vertex_tri); if (!ED_object_parent_set(parenting_context->reports, C, @@ -1359,7 +1371,7 @@ enum { static const EnumPropertyItem prop_make_track_types[] = { {CREATE_TRACK_DAMPTRACK, "DAMPTRACK", 0, "Damped Track Constraint", ""}, - {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track To Constraint", ""}, + {CREATE_TRACK_TRACKTO, "TRACKTO", 0, "Track to Constraint", ""}, {CREATE_TRACK_LOCKTRACK, "LOCKTRACK", 0, "Lock Track Constraint", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 7d853745ad6..76d0c162f29 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -565,7 +565,7 @@ static void append_sorted_object_parent_hierarchy(Object *root_object, Object **sorted_objects, int *object_index) { - if (object->parent != NULL && object->parent != root_object) { + if (!ELEM(object->parent, NULL, root_object)) { append_sorted_object_parent_hierarchy( root_object, object->parent, sorted_objects, object_index); } @@ -1374,7 +1374,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) if (centermode == ORIGIN_TO_CURSOR) { copy_v3_v3(gpcenter, cursor); } - if ((centermode == ORIGIN_TO_GEOMETRY) || (centermode == ORIGIN_TO_CURSOR)) { + if (ELEM(centermode, ORIGIN_TO_GEOMETRY, ORIGIN_TO_CURSOR)) { bGPDspoint *pt; float imat[3][3], bmat[3][3]; float offset_global[3]; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index e92b3323441..3d6a6abfe0d 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -2664,12 +2664,23 @@ static void vgroup_assign_verts(Object *ob, const float weight) static bool vertex_group_supported_poll_ex(bContext *C, const Object *ob) { if (!ED_operator_object_active_local_editable_ex(C, ob)) { + CTX_wm_operator_poll_msg_set(C, "No active editable object"); return false; } + + if (!OB_TYPE_SUPPORT_VGROUP(ob->type)) { + CTX_wm_operator_poll_msg_set(C, "Object type does not support vertex groups"); + return false; + } + + /* Data checks. */ const ID *data = ob->data; - return (OB_TYPE_SUPPORT_VGROUP(ob->type) && - /* Data checks. */ - (data != NULL) && !ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data)); + if (data == NULL || ID_IS_LINKED(data) || ID_IS_OVERRIDE_LIBRARY(data)) { + CTX_wm_operator_poll_msg_set(C, "Object type \"%s\" does not have editable data"); + return false; + } + + return true; } static bool vertex_group_supported_poll(bContext *C) @@ -2678,48 +2689,61 @@ static bool vertex_group_supported_poll(bContext *C) return vertex_group_supported_poll_ex(C, ob); } -static bool vertex_group_poll(bContext *C) +static bool vertex_group_poll_ex(bContext *C, Object *ob) { - Object *ob = ED_object_context(C); + if (!vertex_group_supported_poll_ex(C, ob)) { + return false; + } + + if (BLI_listbase_is_empty(&ob->defbase)) { + CTX_wm_operator_poll_msg_set(C, "Object has no vertex groups"); + return false; + } - return (vertex_group_supported_poll(C) && ob->defbase.first); + return true; } -static bool vertex_group_mesh_poll(bContext *C) +static bool vertex_group_poll(bContext *C) { Object *ob = ED_object_context(C); - - return (vertex_group_poll(C) && ob->type == OB_MESH); + return vertex_group_poll_ex(C, ob); } -static bool vertex_group_mesh_with_dvert_poll(bContext *C) +static bool vertex_group_mesh_poll_ex(bContext *C, Object *ob) { - Object *ob = ED_object_context(C); - - if (!vertex_group_mesh_poll(C)) { + if (!vertex_group_poll_ex(C, ob)) { return false; } - Mesh *me = ob->data; - if (me->dvert == NULL) { + if (ob->type != OB_MESH) { + CTX_wm_operator_poll_msg_set(C, "Only mesh objects are supported"); return false; } return true; } -static bool UNUSED_FUNCTION(vertex_group_mesh_supported_poll)(bContext *C) +static bool vertex_group_mesh_with_dvert_poll(bContext *C) { Object *ob = ED_object_context(C); + if (!vertex_group_mesh_poll_ex(C, ob)) { + return false; + } + + Mesh *me = ob->data; + if (me->dvert == NULL) { + CTX_wm_operator_poll_msg_set(C, "The active mesh object has no vertex group data"); + return false; + } - return (vertex_group_supported_poll(C) && ob->type == OB_MESH); + return true; } static bool UNUSED_FUNCTION(vertex_group_poll_edit)(bContext *C) { Object *ob = ED_object_context(C); - if (!vertex_group_supported_poll(C)) { + if (!vertex_group_supported_poll_ex(C, ob)) { return false; } @@ -2733,7 +2757,7 @@ static bool vertex_group_vert_poll_ex(bContext *C, { Object *ob = ED_object_context(C); - if (!vertex_group_supported_poll(C)) { + if (!vertex_group_supported_poll_ex(C, ob)) { return false; } @@ -2786,7 +2810,7 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C) { Object *ob = ED_object_context(C); - if (!vertex_group_supported_poll(C)) { + if (!vertex_group_supported_poll_ex(C, ob)) { return false; } @@ -2807,7 +2831,7 @@ static bool vertex_group_vert_select_mesh_poll(bContext *C) { Object *ob = ED_object_context(C); - if (!vertex_group_supported_poll(C)) { + if (!vertex_group_supported_poll_ex(C, ob)) { return false; } @@ -3181,9 +3205,9 @@ void OBJECT_OT_vertex_group_levels(wmOperatorType *ot) vgroup_operator_subset_select_props(ot, true); RNA_def_float( - ot->srna, "offset", 0.f, -1.0, 1.0, "Offset", "Value to add to weights", -1.0f, 1.f); + ot->srna, "offset", 0.0f, -1.0, 1.0, "Offset", "Value to add to weights", -1.0f, 1.0f); RNA_def_float( - ot->srna, "gain", 1.f, 0.f, FLT_MAX, "Gain", "Value to multiply weights by", 0.0f, 10.f); + ot->srna, "gain", 1.0f, 0.0f, FLT_MAX, "Gain", "Value to multiply weights by", 0.0f, 10.0f); } /** \} */ @@ -3345,7 +3369,7 @@ void OBJECT_OT_vertex_group_fix(wmOperatorType *ot) 10.0f); RNA_def_float(ot->srna, "strength", - 1.f, + 1.0f, -2.0f, FLT_MAX, "Strength", @@ -3361,7 +3385,7 @@ void OBJECT_OT_vertex_group_fix(wmOperatorType *ot) "Change Sensitivity", "Change the amount weights are altered with each iteration: lower values are slower", 0.05f, - 1.f); + 1.0f); } /** \} */ diff --git a/source/blender/editors/object/object_volume.c b/source/blender/editors/object/object_volume.c index c5dc7f9f24d..5aa61139468 100644 --- a/source/blender/editors/object/object_volume.c +++ b/source/blender/editors/object/object_volume.c @@ -184,7 +184,7 @@ void OBJECT_OT_volume_import(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean( ot->srna, diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index e6d11398279..63f12e339b9 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -4438,7 +4438,7 @@ static int brush_add(const bContext *C, PEData *data, short number) for (k = 0, hkey = pa->hair; k < pset->totaddkey; k++, hkey++) { madd_v3_v3v3fl(hkey->co, pa->state.co, pa->state.vel, k * framestep * timestep); hkey->time += k * framestep; - hkey->weight = 1.f - (float)k / (float)(pset->totaddkey - 1); + hkey->weight = 1.0f - (float)k / (float)(pset->totaddkey - 1); } } for (k = 0, hkey = pa->hair; k < pset->totaddkey; k++, hkey++) { diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 56bdc5c21f4..017cd63d9d5 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -691,7 +691,7 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; RNA_def_boolean( - ot->srna, "all", 0, "All hair", "Disconnect all hair systems from the emitter mesh"); + ot->srna, "all", 0, "All Hair", "Disconnect all hair systems from the emitter mesh"); } /* from/to_world_space : whether from/to particles are in world or hair space @@ -981,7 +981,7 @@ void PARTICLE_OT_connect_hair(wmOperatorType *ot) /* No REGISTER, redo does not work due to missing update, see T47750. */ ot->flag = OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "all", 0, "All hair", "Connect all hair systems to the emitter mesh"); + RNA_def_boolean(ot->srna, "all", 0, "All Hair", "Connect all hair systems to the emitter mesh"); } /************************ particle system copy operator *********************/ diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c index 42f270874e3..f2e2d7589df 100644 --- a/source/blender/editors/physics/rigidbody_world.c +++ b/source/blender/editors/physics/rigidbody_world.c @@ -210,5 +210,5 @@ void RIGIDBODY_OT_world_export(wmOperatorType *ot) FILE_SAVE, FILE_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 7ca711cd2b8..3dbf70aa4bc 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -57,7 +57,6 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_undo_system.h" #include "DEG_depsgraph.h" @@ -83,6 +82,8 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "SEQ_sequencer.h" + #include "BLO_undofile.h" #include "render_intern.h" @@ -435,20 +436,6 @@ static void make_renderinfo_string(const RenderStats *rs, } } else { - if (rs->totvert || rs->totface || rs->totlamp) { - spos += sprintf(spos, "| "); - } - - if (rs->totvert) { - spos += sprintf(spos, TIP_("Ve:%d "), rs->totvert); - } - if (rs->totface) { - spos += sprintf(spos, TIP_("Fa:%d "), rs->totface); - } - if (rs->totlamp) { - spos += sprintf(spos, TIP_("Li:%d "), rs->totlamp); - } - if (rs->mem_peak == 0.0f) { spos += sprintf(spos, TIP_("| Mem:%.2fM (Peak %.2fM) "), megs_used_memory, megs_peak_memory); } diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 8d410e36ca6..79eaf007fcb 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -54,7 +54,6 @@ #include "BKE_main.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_writeavi.h" #include "DEG_depsgraph.h" @@ -78,6 +77,8 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "SEQ_sequencer.h" + #include "GPU_framebuffer.h" #include "GPU_matrix.h" @@ -488,19 +489,19 @@ static void screen_opengl_render_apply(const bContext *C, OGLRender *oglrender) SpaceSeq *sseq = oglrender->sseq; int chanshown = sseq ? sseq->chanshown : 0; - BKE_sequencer_new_render_data(oglrender->bmain, - oglrender->depsgraph, - scene, - oglrender->sizex, - oglrender->sizey, - 100, - false, - &context); + SEQ_render_new_render_data(oglrender->bmain, + oglrender->depsgraph, + scene, + oglrender->sizex, + oglrender->sizey, + 100, + false, + &context); for (view_id = 0; view_id < oglrender->views_len; view_id++) { context.view_id = view_id; context.gpu_offscreen = oglrender->ofs; - oglrender->seq_data.ibufs_arr[view_id] = BKE_sequencer_give_ibuf(&context, CFRA, chanshown); + oglrender->seq_data.ibufs_arr[view_id] = SEQ_render_give_ibuf(&context, CFRA, chanshown); } } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index f5962f36412..720d4608125 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1385,7 +1385,7 @@ static void region_rect_recursive( region->winrct = *remainder; BLI_rcti_init(remainder, 0, 0, 0, 0); } - else if (alignment == RGN_ALIGN_TOP || alignment == RGN_ALIGN_BOTTOM) { + else if (ELEM(alignment, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { rcti *winrct = (region->overlap) ? overlap_remainder : remainder; if ((prefsizey == 0) || (rct_fits(winrct, 'v', prefsizey) < 0)) { @@ -1437,7 +1437,7 @@ static void region_rect_recursive( BLI_rcti_sanitize(winrct); } } - else if (alignment == RGN_ALIGN_VSPLIT || alignment == RGN_ALIGN_HSPLIT) { + else if (ELEM(alignment, RGN_ALIGN_VSPLIT, RGN_ALIGN_HSPLIT)) { /* percentage subdiv*/ region->winrct = *remainder; @@ -1871,6 +1871,11 @@ void ED_area_update_region_sizes(wmWindowManager *wm, wmWindow *win, ScrArea *ar area->flag &= ~AREA_FLAG_REGION_SIZE_UPDATE; } +bool ED_area_has_shared_border(struct ScrArea *a, struct ScrArea *b) +{ + return area_getorientation(a, b) != -1; +} + /* called in screen_refresh, or screens_init, also area size changes */ void ED_area_init(wmWindowManager *wm, wmWindow *win, ScrArea *area) { @@ -3577,7 +3582,7 @@ static void metadata_draw_imbuf(ImBuf *ibuf, const rctf *rect, int fontid, const ofs_y += vertical_offset; } } /* Strip */ - else if (i == 1 || i == 2) { + else if (ELEM(i, 1, 2)) { int len = BLI_snprintf_rlen(temp_str, MAX_METADATA_STR, "%s: ", meta_data_list[i + 1]); if (metadata_is_valid(ibuf, temp_str, i + 1, len)) { BLF_position(fontid, xmin, ymax - vertical_offset - ofs_y, 0.0f); diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 3924c334541..af09100b8e6 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -48,7 +48,6 @@ #include "BKE_gpencil.h" #include "BKE_layer.h" #include "BKE_object.h" -#include "BKE_sequencer.h" #include "RNA_access.h" @@ -56,6 +55,8 @@ #include "ED_armature.h" #include "ED_gpencil.h" +#include "SEQ_sequencer.h" + #include "UI_interface.h" #include "WM_api.h" diff --git a/source/blender/editors/screen/screen_draw.c b/source/blender/editors/screen/screen_draw.c index ddb1f5c87ba..6432bdac1b1 100644 --- a/source/blender/editors/screen/screen_draw.c +++ b/source/blender/editors/screen/screen_draw.c @@ -203,7 +203,7 @@ static void draw_vertical_join_shape(ScrArea *area, char dir, uint pos) */ static void draw_join_shape(ScrArea *area, char dir, uint pos) { - if (dir == 'u' || dir == 'd') { + if (ELEM(dir, 'u', 'd')) { draw_vertical_join_shape(area, dir, pos); } else { diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 5f56bbaef9d..5e67d6855c0 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -362,7 +362,7 @@ static void screen_areas_align( { wmWindow *win = CTX_wm_window(C); - if (dir == 0 || dir == 2) { + if (ELEM(dir, 0, 2)) { /* horizontal join, use average for new top and bottom. */ int top = (sa1->v2->vec.y + sa2->v2->vec.y) / 2; int bottom = (sa1->v4->vec.y + sa2->v4->vec.y) / 2; @@ -687,7 +687,7 @@ static void screen_cursor_set(wmWindow *win, const int xy[2]) WM_cursor_set(win, WM_CURSOR_EDIT); } else if (az->type == AZONE_REGION) { - if (az->edge == AE_LEFT_TO_TOPRIGHT || az->edge == AE_RIGHT_TO_TOPLEFT) { + if (ELEM(az->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { WM_cursor_set(win, WM_CURSOR_X_MOVE); } else { @@ -772,7 +772,7 @@ void ED_screen_set_active_region(bContext *C, wmWindow *win, const int xy[2]) } } - if (region == region_prev || region == screen->active_region) { + if (ELEM(region, region_prev, screen->active_region)) { do_draw = true; } } diff --git a/source/blender/editors/screen/screen_geometry.c b/source/blender/editors/screen/screen_geometry.c index 4acf3dd7ba5..ac159f4d633 100644 --- a/source/blender/editors/screen/screen_geometry.c +++ b/source/blender/editors/screen/screen_geometry.c @@ -202,7 +202,7 @@ static bool screen_geom_vertices_scale_pass(const wmWindow *win, /* all selected vertices get the right offset */ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { /* if is a collapsed area */ - if (sv != area->v1 && sv != area->v4) { + if (!ELEM(sv, area->v1, area->v4)) { if (sv->flag) { sv->vec.y = yval; /* Changed size of a area. Run another pass to ensure everything still fits. */ @@ -228,7 +228,7 @@ static bool screen_geom_vertices_scale_pass(const wmWindow *win, /* all selected vertices get the right offset */ LISTBASE_FOREACH (ScrVert *, sv, &screen->vertbase) { /* if is not a collapsed area */ - if (sv != area->v2 && sv != area->v3) { + if (!ELEM(sv, area->v2, area->v3)) { if (sv->flag) { sv->vec.y = yval; /* Changed size of a area. Run another pass to ensure everything still fits. */ diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 27a1d4e4a50..72b3b344813 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1617,7 +1617,7 @@ static int area_snap_calc_location(const bScreen *screen, switch (snap_type) { case SNAP_AREAGRID: m_cursor_final = m_cursor; - if (delta != bigger && delta != -smaller) { + if (!ELEM(delta, bigger, -smaller)) { m_cursor_final -= (m_cursor % AREAGRID); CLAMP(m_cursor_final, origval - smaller, origval + bigger); } @@ -2477,7 +2477,7 @@ static int area_max_regionsize(ScrArea *area, ARegion *scalear, AZEdge edge) } } else { - if (edge == AE_RIGHT_TO_TOPLEFT || edge == AE_LEFT_TO_TOPRIGHT) { + if (ELEM(edge, AE_RIGHT_TO_TOPLEFT, AE_LEFT_TO_TOPRIGHT)) { dist = BLI_rcti_size_x(&area->totrct); } else { /* AE_BOTTOM_TO_TOPLEFT, AE_TOP_TO_BOTTOMRIGHT */ @@ -2574,7 +2574,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event } /* now copy to regionmovedata */ - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { + if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { rmd->origval = rmd->region->sizex; } else { @@ -2598,7 +2598,7 @@ static void region_scale_validate_size(RegionMoveData *rmd) if ((rmd->region->flag & RGN_FLAG_HIDDEN) == 0) { short *size, maxsize = -1; - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { + if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { size = &rmd->region->sizex; } else { @@ -2648,7 +2648,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) const float aspect = BLI_rctf_size_x(&rmd->region->v2d.cur) / (BLI_rcti_size_x(&rmd->region->v2d.mask) + 1); const int snap_size_threshold = (U.widget_unit * 2) / aspect; - if (rmd->edge == AE_LEFT_TO_TOPRIGHT || rmd->edge == AE_RIGHT_TO_TOPLEFT) { + if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { delta = event->x - rmd->origx; if (rmd->edge == AE_LEFT_TO_TOPRIGHT) { delta = -delta; @@ -2827,7 +2827,7 @@ static int frame_offset_exec(bContext *C, wmOperator *op) CFRA += delta; FRAMENUMBER_MIN_CLAMP(CFRA); - SUBFRA = 0.f; + SUBFRA = 0.0f; areas_do_frame_follow(C, false); @@ -5523,8 +5523,8 @@ static void keymap_modal_set(wmKeyConfig *keyconf) static const EnumPropertyItem modal_items[] = { {KM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, {KM_MODAL_APPLY, "APPLY", 0, "Apply", ""}, - {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap on", ""}, - {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap off", ""}, + {KM_MODAL_SNAP_ON, "SNAP", 0, "Snap On", ""}, + {KM_MODAL_SNAP_OFF, "SNAP_OFF", 0, "Snap Off", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c index 5d0ae292ffa..7d7a3340dc3 100644 --- a/source/blender/editors/screen/screendump.c +++ b/source/blender/editors/screen/screendump.c @@ -249,7 +249,7 @@ void SCREEN_OT_screenshot(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "full", 1, diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index cab2d32bdcf..5430137f5ca 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -57,6 +57,7 @@ #include "screen_intern.h" +/* -------------------------------------------------------------------- */ /** \name Workspace API * * \brief API for managing workspaces and their data. @@ -231,6 +232,7 @@ void ED_workspace_scene_data_sync(WorkSpaceInstanceHook *hook, Scene *scene) /** \} Workspace API */ +/* -------------------------------------------------------------------- */ /** \name Workspace Operators * * \{ */ diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index f0285c8faf3..550913fc8af 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1310,6 +1310,11 @@ static bool paint_cursor_context_init(bContext *C, Object *active_object = pcontext->vc.obact; pcontext->ss = active_object ? active_object->sculpt : NULL; + if (pcontext->ss && pcontext->ss->draw_faded_cursor) { + pcontext->outline_alpha = 0.3f; + copy_v3_fl(pcontext->outline_col, 0.8f); + } + pcontext->is_stroke_active = pcontext->ups->stroke_active; return true; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index fe16611a6eb..3a6b91443a0 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -349,8 +349,8 @@ typedef struct PaintOperation { bool paint_use_opacity_masking(Brush *brush) { return ((brush->flag & BRUSH_AIRBRUSH) || (brush->flag & BRUSH_DRAG_DOT) || - (brush->flag & BRUSH_ANCHORED) || (brush->imagepaint_tool == PAINT_TOOL_SMEAR) || - (brush->imagepaint_tool == PAINT_TOOL_SOFTEN) || + (brush->flag & BRUSH_ANCHORED) || + (ELEM(brush->imagepaint_tool, PAINT_TOOL_SMEAR, PAINT_TOOL_SOFTEN)) || (brush->imagepaint_tool == PAINT_TOOL_FILL) || (brush->flag & BRUSH_USE_GRADIENT) || (brush->mtex.tex && !ELEM(brush->mtex.brush_map_mode, diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 37af1fb6cda..8c16300a047 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -1789,7 +1789,7 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, static int project_paint_pixel_sizeof(const short tool) { - if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) { + if (ELEM(tool, PAINT_TOOL_CLONE, PAINT_TOOL_SMEAR)) { return sizeof(ProjPixelClone); } return sizeof(ProjPixel); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index aec58eb8191..5ee38069fd9 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -247,8 +247,16 @@ typedef struct LassoGestureData { } LassoGestureData; typedef struct LineGestureData { + /* Plane aligned to the gesture line. */ float true_plane[4]; float plane[4]; + + /* Planes to limit the action to the length of the gesture segment at both sides of the affected + * area. */ + float side_plane[2][4]; + float true_side_plane[2][4]; + bool use_side_planes; + bool flip; } LineGestureData; @@ -321,6 +329,13 @@ static void sculpt_gesture_operator_properties(wmOperatorType *ot) false, "Front Faces Only", "Affect only faces facing towards the view"); + + RNA_def_boolean(ot->srna, + "use_limit_to_segment", + false, + "Limit to Segment", + "Apply the gesture action only to the area that is contained within the " + "segement without extending its effect to the entire line"); } static void sculpt_gesture_context_init_common(bContext *C, @@ -333,6 +348,7 @@ static void sculpt_gesture_context_init_common(bContext *C, /* Operator properties. */ sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only"); + sgcontext->line.use_side_planes = RNA_boolean_get(op->ptr, "use_limit_to_segment"); /* SculptSession */ sgcontext->ss = ob->sculpt; @@ -449,6 +465,50 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato return sgcontext; } +static void sculpt_gesture_line_plane_from_tri(float *r_plane, + SculptGestureContext *sgcontext, + const bool flip, + const float p1[3], + const float p2[3], + const float p3[3]) +{ + float normal[3]; + normal_tri_v3(normal, p1, p2, p3); + mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal); + if (flip) { + mul_v3_fl(normal, -1.0f); + } + float plane_point_object_space[3]; + mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, p1); + plane_from_point_normal_v3(r_plane, plane_point_object_space, normal); +} + +/* Creates 4 points in the plane defined by the line and 2 extra points with an offset relative to + * this plane. */ +static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgcontext, + float line_points[2][2], + float r_plane_points[4][3], + float r_offset_plane_points[2][3]) +{ + float depth_point[3]; + add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal); + ED_view3d_win_to_3d( + sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[0]); + ED_view3d_win_to_3d( + sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[3]); + + madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f); + ED_view3d_win_to_3d( + sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], r_plane_points[1]); + ED_view3d_win_to_3d( + sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], r_plane_points[2]); + + float normal[3]; + normal_tri_v3(normal, r_plane_points[0], r_plane_points[1], r_plane_points[2]); + add_v3_v3v3(r_offset_plane_points[0], r_plane_points[0], normal); + add_v3_v3v3(r_offset_plane_points[1], r_plane_points[3], normal); +} + static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op) { SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), @@ -465,36 +525,33 @@ static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperat sgcontext->line.flip = RNA_boolean_get(op->ptr, "flip"); - float depth_point[3]; - float plane_points[3][3]; - - /* Calculate a triangle in the line's plane. */ - add_v3_v3v3(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal); - ED_view3d_win_to_3d( - sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[0]); - - madd_v3_v3v3fl(depth_point, sgcontext->true_view_origin, sgcontext->true_view_normal, 10.0f); - ED_view3d_win_to_3d( - sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[0], plane_points[1]); - ED_view3d_win_to_3d( - sgcontext->vc.v3d, sgcontext->vc.region, depth_point, line_points[1], plane_points[2]); - - /* Calculate final line plane and normal using the triangle. */ - float normal[3]; - normal_tri_v3(normal, plane_points[0], plane_points[1], plane_points[2]); - if (!sgcontext->vc.rv3d->is_persp) { - mul_v3_fl(normal, -1.0f); - } - - /* Apply flip. */ - if (sgcontext->line.flip) { - mul_v3_fl(normal, -1.0f); - } - - mul_v3_mat3_m4v3(normal, sgcontext->vc.obact->imat, normal); - float plane_point_object_space[3]; - mul_v3_m4v3(plane_point_object_space, sgcontext->vc.obact->imat, plane_points[0]); - plane_from_point_normal_v3(sgcontext->line.true_plane, plane_point_object_space, normal); + float plane_points[4][3]; + float offset_plane_points[2][3]; + sculpt_gesture_line_calculate_plane_points( + sgcontext, line_points, plane_points, offset_plane_points); + + /* Calculate line plane and normal. */ + const bool flip = sgcontext->line.flip ^ !sgcontext->vc.rv3d->is_persp; + sculpt_gesture_line_plane_from_tri(sgcontext->line.true_plane, + sgcontext, + flip, + plane_points[0], + plane_points[1], + plane_points[2]); + + /* Calculate the side planes. */ + sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[0], + sgcontext, + false, + plane_points[1], + plane_points[0], + offset_plane_points[0]); + sculpt_gesture_line_plane_from_tri(sgcontext->line.true_side_plane[1], + sgcontext, + false, + plane_points[3], + plane_points[2], + offset_plane_points[1]); return sgcontext; } @@ -545,14 +602,20 @@ static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontex flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass); flip_v3_v3(sgcontext->view_origin, sgcontext->true_view_origin, symmpass); flip_plane(sgcontext->line.plane, sgcontext->line.true_plane, symmpass); + flip_plane(sgcontext->line.side_plane[0], sgcontext->line.true_side_plane[0], symmpass); + flip_plane(sgcontext->line.side_plane[1], sgcontext->line.true_side_plane[1], symmpass); } static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureContext *sgcontext) { SculptSession *ss = sgcontext->ss; - float clip_planes[1][4]; + float clip_planes[3][4]; copy_v4_v4(clip_planes[0], sgcontext->line.plane); - PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 1}; + copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]); + copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]); + + const int num_planes = sgcontext->line.use_side_planes ? 3 : 1; + PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes}; BKE_pbvh_search_gather(ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, @@ -631,6 +694,11 @@ static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, P case SCULPT_GESTURE_SHAPE_LASSO: return sculpt_gesture_is_effected_lasso(sgcontext, vd->co); case SCULPT_GESTURE_SHAPE_LINE: + if (sgcontext->line.use_side_planes) { + return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f && + plane_point_side_v3(sgcontext->line.side_plane[0], vd->co) > 0.0f && + plane_point_side_v3(sgcontext->line.side_plane[1], vd->co) > 0.0f; + } return plane_point_side_v3(sgcontext->line.plane, vd->co) > 0.0f; } return false; @@ -863,6 +931,24 @@ static EnumPropertyItem prop_trim_operation_types[] = { {0, NULL, 0, NULL, NULL}, }; +typedef enum eSculptTrimOrientationType { + SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, + SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE, +} eSculptTrimOrientationType; +static EnumPropertyItem prop_trim_orientation_types[] = { + {SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, + "VIEW", + 0, + "View", + "Use the view to orientate the trimming shape"}, + {SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE, + "SURFACE", + 0, + "Surface", + "Use the surface normal to orientate the trimming shape"}, + {0, NULL, 0, NULL, NULL}, +}; + typedef struct SculptGestureTrimOperation { SculptGestureOperation op; @@ -875,6 +961,7 @@ typedef struct SculptGestureTrimOperation { bool use_cursor_depth; eSculptTrimOperationType mode; + eSculptTrimOrientationType orientation; } SculptGestureTrimOperation; static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) @@ -911,6 +998,29 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) trim_operation->mesh = result; } +/* Get the origin and normal that are going to be used for calculating the depth and position the + * trimming geometry. */ +static void sculpt_gesture_trim_shape_origin_normal_get(SculptGestureContext *sgcontext, + float *r_origin, + float *r_normal) +{ + SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; + /* Use the view origin and normal in world space. The trimming mesh coordinates are + * calculated in world space, aligned to the view, and then converted to object space to + * store them in the final trimming mesh which is going to be used in the boolean operation. + */ + switch (trim_operation->orientation) { + case SCULPT_GESTURE_TRIM_ORIENTATION_VIEW: + copy_v3_v3(r_origin, sgcontext->world_space_view_origin); + copy_v3_v3(r_normal, sgcontext->world_space_view_normal); + break; + case SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE: + mul_v3_m4v3(r_origin, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_location); + mul_v3_m4v3(r_normal, sgcontext->vc.obact->obmat, sgcontext->ss->gesture_initial_normal); + break; + } +} + static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContext *sgcontext) { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; @@ -920,11 +1030,11 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex const int totvert = SCULPT_vertex_count_get(ss); - float view_plane[4]; - const float *view_origin = sgcontext->world_space_view_origin; - const float *view_normal = sgcontext->world_space_view_normal; - - plane_from_point_normal_v3(view_plane, view_origin, view_normal); + float shape_plane[4]; + float shape_origin[3]; + float shape_normal[3]; + sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal); + plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal); trim_operation->depth_front = FLT_MAX; trim_operation->depth_back = -FLT_MAX; @@ -936,7 +1046,7 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex * store them. */ float world_space_vco[3]; mul_v3_m4v3(world_space_vco, vc->obact->obmat, vco); - const float dist = dist_signed_to_plane_v3(world_space_vco, view_plane); + const float dist = dist_signed_to_plane_v3(world_space_vco, shape_plane); trim_operation->depth_front = min_ff(dist, trim_operation->depth_front); trim_operation->depth_back = max_ff(dist, trim_operation->depth_back); } @@ -945,11 +1055,22 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex float world_space_gesture_initial_location[3]; mul_v3_m4v3( world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location); - const float mid_point_depth = ss->gesture_initial_hit ? - dist_signed_to_plane_v3(world_space_gesture_initial_location, - view_plane) : - (trim_operation->depth_back + trim_operation->depth_front) * - 0.5f; + + float mid_point_depth; + if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { + mid_point_depth = ss->gesture_initial_hit ? + dist_signed_to_plane_v3(world_space_gesture_initial_location, + shape_plane) : + (trim_operation->depth_back + trim_operation->depth_front) * 0.5f; + } + else { + /* When using normal orientation, if the stroke started over the mesh, position the mid point + * at 0 distance from the shape plane. This positions the trimming shape half inside of the + * surface. */ + mid_point_depth = ss->gesture_initial_hit ? + 0.0f : + (trim_operation->depth_back + trim_operation->depth_front) * 0.5f; + } Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); @@ -987,30 +1108,41 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex depth_back += 0.1f; } - /* Use the view origin and normal in world space. The trimming mesh coordinates are calculated in - * world space, aligned to the view, and then converted to object space to store them in the - * final trimming mesh which is going to be used in the boolean operation. - */ - const float *view_origin = sgcontext->world_space_view_origin; - const float *view_normal = sgcontext->world_space_view_normal; + float shape_origin[3]; + float shape_normal[3]; + float shape_plane[4]; + sculpt_gesture_trim_shape_origin_normal_get(sgcontext, shape_origin, shape_normal); + plane_from_point_normal_v3(shape_plane, shape_origin, shape_normal); const float(*ob_imat)[4] = vc->obact->imat; /* Write vertices coordinates for the front face. */ float depth_point[3]; - madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_front); + madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front); for (int i = 0; i < tot_screen_points; i++) { float new_point[3]; - ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { + ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + } + else { + ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); + madd_v3_v3fl(new_point, shape_normal, depth_front); + } mul_v3_m4v3(trim_operation->mesh->mvert[i].co, ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); } /* Write vertices coordinates for the back face. */ - madd_v3_v3v3fl(depth_point, view_origin, view_normal, depth_back); + madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back); for (int i = 0; i < tot_screen_points; i++) { float new_point[3]; - ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { + ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + } + else { + ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); + madd_v3_v3fl(new_point, shape_normal, depth_back); + } mul_v3_m4v3(trim_operation->mesh->mvert[i + tot_screen_points].co, ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point); } @@ -1229,6 +1361,12 @@ static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode"); trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth"); + trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation"); + + /* If the cursor was not over the mesh, force the orientation to view. */ + if (!sgcontext->ss->gesture_initial_hit) { + trim_operation->orientation = SCULPT_GESTURE_TRIM_ORIENTATION_VIEW; + } } static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) @@ -1245,6 +1383,12 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) false, "Use Cursor for Depth", "Use cursor location and radius for the dimensions and position of the trimming shape"); + RNA_def_enum(ot->srna, + "trim_orientation", + prop_trim_orientation_types, + SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, + "Shape Orientation", + NULL); } /* Project Gesture Operation. */ @@ -1430,6 +1574,7 @@ static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmE ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); if (ss->gesture_initial_hit) { copy_v3_v3(ss->gesture_initial_location, sgi.location); + copy_v3_v3(ss->gesture_initial_normal, sgi.normal); } return WM_gesture_box_invoke(C, op, event); @@ -1465,6 +1610,7 @@ static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const w ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); if (ss->gesture_initial_hit) { copy_v3_v3(ss->gesture_initial_location, sgi.location); + copy_v3_v3(ss->gesture_initial_normal, sgi.normal); } return WM_gesture_lasso_invoke(C, op, event); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 75357214936..57b1102219e 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -717,7 +717,7 @@ static float paint_space_stroke_spacing(bContext *C, spacing *= stroke->zoom_2d; if (paint_stroke_use_scene_spacing(brush, mode)) { - return max_ff(0.001f, size_clamp * spacing / 50.f); + return max_ff(0.001f, size_clamp * spacing / 50.0f); } return max_ff(stroke->zoom_2d, size_clamp * spacing / 50.0f); } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 25b1764e562..9e9e0f441f7 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -372,7 +372,7 @@ static float wpaint_blend(const VPaint *wp, if (do_flip) { switch (blend) { case IMB_BLEND_MIX: - paintval = 1.f - paintval; + paintval = 1.0f - paintval; break; case IMB_BLEND_ADD: blend = IMB_BLEND_SUB; @@ -964,7 +964,7 @@ static void do_weight_paint_vertex_multi( if (me->editflag & ME_EDIT_VERTEX_GROUPS_X_SYMMETRY) { index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology); - if (index_mirr != -1 && index_mirr != index) { + if (!ELEM(index_mirr, -1, index)) { dv_mirr = &me->dvert[index_mirr]; } else { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 875f24837c1..421a3653d8c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -76,6 +76,11 @@ #include "IMB_colormanagement.h" +#include "GPU_immediate.h" +#include "GPU_immediate_util.h" +#include "GPU_matrix.h" +#include "GPU_state.h" + #include "WM_api.h" #include "WM_message.h" #include "WM_toolsystem.h" @@ -84,6 +89,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_space_api.h" #include "ED_view3d.h" #include "paint_intern.h" #include "sculpt_intern.h" @@ -1174,6 +1180,7 @@ void SCULPT_floodfill_free(SculptFloodFill *flood) flood->queue = NULL; } +/* -------------------------------------------------------------------- */ /** \name Tool Capabilities * * Avoid duplicate checks, internal logic only, @@ -1395,6 +1402,7 @@ static void sculpt_project_v3_normal_align(SculptSession *ss, grab_delta, ss->cache->sculpt_normal_symm, (len_signed * normal_weight) * len_view_scale); } +/* -------------------------------------------------------------------- */ /** \name SculptProjectVector * * Fast-path for #project_plane_v3_v3v3 @@ -1902,6 +1910,7 @@ static float calc_symmetry_feather(Sculpt *sd, StrokeCache *cache) return 1.0f; } +/* -------------------------------------------------------------------- */ /** \name Calculate Normal and Center * * Calculate geometry surrounding the brush center. @@ -2353,7 +2362,7 @@ static float brush_strength(const Sculpt *sd, final_pressure = pressure * pressure; return final_pressure * overlap * feather; case SCULPT_TOOL_SMEAR: - return pressure * overlap * feather; + return alpha * pressure * overlap * feather; case SCULPT_TOOL_CLAY_STRIPS: /* Clay Strips needs less strength to compensate the curve. */ final_pressure = powf(pressure, 1.5f); @@ -3022,6 +3031,7 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) } } +/* -------------------------------------------------------------------- */ /** \name Sculpt Multires Displacement Eraser Brush * \{ */ @@ -3244,7 +3254,6 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to } /* -------------------------------------------------------------------- */ - /** \name Sculpt Topology Brush * \{ */ @@ -3820,20 +3829,33 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); + const bool grab_silhouette = brush->flag2 & BRUSH_GRAB_SILHOUETTE; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { SCULPT_orig_vert_data_update(&orig_data, &vd); if (sculpt_brush_test_sq_fn(&test, orig_data.co)) { - const float fade = bstrength * SCULPT_brush_strength_factor(ss, - brush, - orig_data.co, - sqrtf(test.dist), - orig_data.no, - NULL, - vd.mask ? *vd.mask : 0.0f, - vd.index, - thread_id); + float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + orig_data.co, + sqrtf(test.dist), + orig_data.no, + NULL, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + if (grab_silhouette) { + float silhouette_test_dir[3]; + normalize_v3_v3(silhouette_test_dir, grab_delta); + if (dot_v3v3(ss->cache->initial_normal, ss->cache->grab_delta_symmetry) < 0.0f) { + mul_v3_fl(silhouette_test_dir, -1.0f); + } + float vno[3]; + normal_short_to_float_v3(vno, orig_data.no); + fade *= max_ff(dot_v3v3(vno, silhouette_test_dir), 0.0f); + } mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -3900,7 +3922,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, if (brush->elastic_deform_type == BRUSH_ELASTIC_DEFORM_TWIST) { int symm = ss->cache->mirror_symmetry_pass; - if (symm == 1 || symm == 2 || symm == 4 || symm == 7) { + if (ELEM(symm, 1, 2, 4, 7)) { dir = -dir; } } @@ -4767,7 +4789,6 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno } /* -------------------------------------------------------------------- */ - /** \name Sculpt Clay Brush * \{ */ @@ -5292,7 +5313,6 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod } /* -------------------------------------------------------------------- */ - /** \name Sculpt Clay Thumb Brush * \{ */ @@ -5681,15 +5701,11 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe /* Check for unsupported features. */ PBVHType type = BKE_pbvh_type(ss->pbvh); if (brush->sculpt_tool == SCULPT_TOOL_PAINT && type != PBVH_FACES) { - if (!U.experimental.use_sculpt_vertex_colors) { - return; - } + return; } if (brush->sculpt_tool == SCULPT_TOOL_SMEAR && type != PBVH_FACES) { - if (!U.experimental.use_sculpt_vertex_colors) { - return; - } + return; } /* Build a list of all nodes that are potentially within the brush's area of influence */ @@ -8141,6 +8157,7 @@ static void SCULPT_OT_symmetrize(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ +/** \warning Expects a fully evaluated depsgraph. */ static void sculpt_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob) { /* Create persistent sculpt mode data. */ @@ -8205,6 +8222,7 @@ void ED_object_sculptmode_enter_ex(Main *bmain, if (flush_recalc) { DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); } /* Create sculpt mode session data. */ @@ -8212,10 +8230,6 @@ void ED_object_sculptmode_enter_ex(Main *bmain, BKE_sculptsession_free(ob); } - /* Make sure derived final from original object does not reference possibly - * freed memory. */ - BKE_object_free_derived_caches(ob); - /* Copy the current mesh visibility to the Face Sets. */ BKE_sculpt_face_sets_ensure_from_base_mesh_visibility(me); @@ -9246,6 +9260,335 @@ static void SCULPT_OT_mask_by_color(wmOperatorType *ot) 1.0f); } +/* -------------------------------------------------------------------- */ +/** \name Dyntopo Detail Size Edit Operator + * \{ */ + +/* Defines how much the mouse movement will modify the detail size value. */ +#define DETAIL_SIZE_DELTA_SPEED 0.08f +#define DETAIL_SIZE_DELTA_ACCURATE_SPEED 0.004f + +typedef struct DyntopoDetailSizeEditCustomData { + void *draw_handle; + Object *active_object; + + float init_mval[2]; + float accurate_mval[2]; + + float outline_col[4]; + + bool accurate_mode; + bool sample_mode; + + float init_detail_size; + float accurate_detail_size; + float detail_size; + float radius; + + float preview_tri[3][3]; + float gizmo_mat[4][4]; +} DyntopoDetailSizeEditCustomData; + +static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, + DyntopoDetailSizeEditCustomData *cd, + const float start_co[3], + const float end_co[3], + bool flip, + const float angle) +{ + float object_space_constant_detail = 1.0f / + (cd->detail_size * mat4_to_scale(cd->active_object->obmat)); + + /* The constant detail represents the maximum edge length allowed before subdividing it. If the + * triangle grid preview is created with this value it will represent an ideal mesh density where + * all edges have the exact maximum length, which never happens in practice. As the minimum edge + * length for dyntopo is 0.4 * max_edge_length, this adjust the detail size to the average + * between max and min edge length so the preview is more accurate. */ + object_space_constant_detail *= 0.7f; + + const float total_len = len_v3v3(cd->preview_tri[0], cd->preview_tri[1]); + const int tot_lines = (int)(total_len / object_space_constant_detail) + 1; + const float tot_lines_fl = total_len / object_space_constant_detail; + float spacing_disp[3]; + sub_v3_v3v3(spacing_disp, end_co, start_co); + normalize_v3(spacing_disp); + + float line_disp[3]; + rotate_v2_v2fl(line_disp, spacing_disp, DEG2RAD(angle)); + mul_v3_fl(spacing_disp, total_len / tot_lines_fl); + + immBegin(GPU_PRIM_LINES, (uint)tot_lines * 2); + for (int i = 0; i < tot_lines; i++) { + float line_length; + if (flip) { + line_length = total_len * ((float)i / (float)tot_lines_fl); + } + else { + line_length = total_len * (1.0f - ((float)i / (float)tot_lines_fl)); + } + float line_start[3]; + copy_v3_v3(line_start, start_co); + madd_v3_v3v3fl(line_start, line_start, spacing_disp, i); + float line_end[3]; + madd_v3_v3v3fl(line_end, line_start, line_disp, line_length); + immVertex3fv(pos3d, line_start); + immVertex3fv(pos3d, line_end); + } + immEnd(); +} + +static void dyntopo_detail_size_edit_draw(const bContext *UNUSED(C), + ARegion *UNUSED(ar), + void *arg) +{ + DyntopoDetailSizeEditCustomData *cd = arg; + GPU_blend(GPU_BLEND_ALPHA); + GPU_line_smooth(true); + + uint pos3d = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + GPU_matrix_push(); + GPU_matrix_mul(cd->gizmo_mat); + + /* Draw Cursor */ + immUniformColor4fv(cd->outline_col); + GPU_line_width(3.0f); + + imm_draw_circle_wire_3d(pos3d, 0, 0, cd->radius, 80); + + /* Draw Triangle. */ + immUniformColor4f(0.9f, 0.9f, 0.9f, 0.8f); + immBegin(GPU_PRIM_LINES, 6); + immVertex3fv(pos3d, cd->preview_tri[0]); + immVertex3fv(pos3d, cd->preview_tri[1]); + + immVertex3fv(pos3d, cd->preview_tri[1]); + immVertex3fv(pos3d, cd->preview_tri[2]); + + immVertex3fv(pos3d, cd->preview_tri[2]); + immVertex3fv(pos3d, cd->preview_tri[0]); + immEnd(); + + /* Draw Grid */ + GPU_line_width(1.0f); + dyntopo_detail_size_parallel_lines_draw( + pos3d, cd, cd->preview_tri[0], cd->preview_tri[1], false, 60.0f); + dyntopo_detail_size_parallel_lines_draw( + pos3d, cd, cd->preview_tri[0], cd->preview_tri[1], true, 120.0f); + dyntopo_detail_size_parallel_lines_draw( + pos3d, cd, cd->preview_tri[0], cd->preview_tri[2], false, -60.0f); + + immUnbindProgram(); + GPU_matrix_pop(); + GPU_blend(GPU_BLEND_NONE); + GPU_line_smooth(false); +} + +static void dyntopo_detail_size_edit_cancel(bContext *C, wmOperator *op) +{ + Object *active_object = CTX_data_active_object(C); + SculptSession *ss = active_object->sculpt; + ARegion *ar = CTX_wm_region(C); + DyntopoDetailSizeEditCustomData *cd = op->customdata; + ED_region_draw_cb_exit(ar->type, cd->draw_handle); + ss->draw_faded_cursor = false; + MEM_freeN(op->customdata); + ED_workspace_status_text(C, NULL); +} + +static void dyntopo_detail_size_sample_from_surface(Object *ob, + DyntopoDetailSizeEditCustomData *cd) +{ + SculptSession *ss = ob->sculpt; + const int active_vertex = SCULPT_active_vertex_get(ss); + + float len_accum = 0; + int num_neighbors = 0; + SculptVertexNeighborIter ni; + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) { + len_accum += len_v3v3(SCULPT_vertex_co_get(ss, active_vertex), + SCULPT_vertex_co_get(ss, ni.index)); + num_neighbors++; + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + + if (num_neighbors > 0) { + const float avg_edge_len = len_accum / num_neighbors; + /* Use 0.7 as the average of min and max dyntopo edge length. */ + const float detail_size = 0.7f / (avg_edge_len * mat4_to_scale(cd->active_object->obmat)); + cd->detail_size = clamp_f(detail_size, 1.0f, 500.0f); + } +} + +static void dyntopo_detail_size_update_from_mouse_delta(DyntopoDetailSizeEditCustomData *cd, + const wmEvent *event) +{ + const float mval[2] = {event->mval[0], event->mval[1]}; + + float detail_size_delta; + if (cd->accurate_mode) { + detail_size_delta = mval[0] - cd->accurate_mval[0]; + cd->detail_size = cd->accurate_detail_size + + detail_size_delta * DETAIL_SIZE_DELTA_ACCURATE_SPEED; + } + else { + detail_size_delta = mval[0] - cd->init_mval[0]; + cd->detail_size = cd->init_detail_size + detail_size_delta * DETAIL_SIZE_DELTA_SPEED; + } + + if (event->type == EVT_LEFTSHIFTKEY && event->val == KM_PRESS) { + cd->accurate_mode = true; + copy_v2_v2(cd->accurate_mval, mval); + cd->accurate_detail_size = cd->detail_size; + } + if (event->type == EVT_LEFTSHIFTKEY && event->val == KM_RELEASE) { + cd->accurate_mode = false; + cd->accurate_detail_size = 0.0f; + } + + cd->detail_size = clamp_f(cd->detail_size, 1.0f, 500.0f); +} + +static int dyntopo_detail_size_edit_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *active_object = CTX_data_active_object(C); + SculptSession *ss = active_object->sculpt; + ARegion *ar = CTX_wm_region(C); + DyntopoDetailSizeEditCustomData *cd = op->customdata; + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + + /* Cancel modal operator */ + if ((event->type == EVT_ESCKEY && event->val == KM_PRESS) || + (event->type == RIGHTMOUSE && event->val == KM_PRESS)) { + dyntopo_detail_size_edit_cancel(C, op); + ED_region_tag_redraw(ar); + return OPERATOR_FINISHED; + } + + /* Finish modal operator */ + if ((event->type == LEFTMOUSE && event->val == KM_RELEASE) || + (event->type == EVT_RETKEY && event->val == KM_PRESS) || + (event->type == EVT_PADENTER && event->val == KM_PRESS)) { + ED_region_draw_cb_exit(ar->type, cd->draw_handle); + sd->constant_detail = cd->detail_size; + ss->draw_faded_cursor = false; + MEM_freeN(op->customdata); + ED_region_tag_redraw(ar); + ED_workspace_status_text(C, NULL); + return OPERATOR_FINISHED; + } + + ED_region_tag_redraw(ar); + + if (event->type == EVT_LEFTCTRLKEY && event->val == KM_PRESS) { + cd->sample_mode = true; + } + if (event->type == EVT_LEFTCTRLKEY && event->val == KM_RELEASE) { + cd->sample_mode = false; + } + + /* Sample mode sets the detail size sampling the average edge length under the surface. */ + if (cd->sample_mode) { + dyntopo_detail_size_sample_from_surface(active_object, cd); + return OPERATOR_RUNNING_MODAL; + } + /* Regular mode, changes the detail size by moving the cursor. */ + dyntopo_detail_size_update_from_mouse_delta(cd, event); + + return OPERATOR_RUNNING_MODAL; +} + +static int dyntopo_detail_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + Object *active_object = CTX_data_active_object(C); + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + DyntopoDetailSizeEditCustomData *cd = MEM_callocN(sizeof(DyntopoDetailSizeEditCustomData), + "Dyntopo Detail Size Edit OP Custom Data"); + + /* Initial operator Custom Data setup. */ + cd->draw_handle = ED_region_draw_cb_activate( + ar->type, dyntopo_detail_size_edit_draw, cd, REGION_DRAW_POST_VIEW); + cd->active_object = active_object; + cd->init_mval[0] = event->mval[0]; + cd->init_mval[1] = event->mval[1]; + cd->detail_size = sd->constant_detail; + cd->init_detail_size = sd->constant_detail; + copy_v4_v4(cd->outline_col, brush->add_col); + op->customdata = cd; + + SculptSession *ss = active_object->sculpt; + cd->radius = ss->cursor_radius; + + /* Generates the matrix to position the gizmo in the surface of the mesh using the same location + * and orientation as the brush cursor. */ + float cursor_trans[4][4], cursor_rot[4][4]; + const float z_axis[4] = {0.0f, 0.0f, 1.0f, 0.0f}; + float quat[4]; + copy_m4_m4(cursor_trans, active_object->obmat); + translate_m4( + cursor_trans, ss->cursor_location[0], ss->cursor_location[1], ss->cursor_location[2]); + + float cursor_normal[3]; + if (!is_zero_v3(ss->cursor_sampled_normal)) { + copy_v3_v3(cursor_normal, ss->cursor_sampled_normal); + } + else { + copy_v3_v3(cursor_normal, ss->cursor_normal); + } + + rotation_between_vecs_to_quat(quat, z_axis, cursor_normal); + quat_to_mat4(cursor_rot, quat); + copy_m4_m4(cd->gizmo_mat, cursor_trans); + mul_m4_m4_post(cd->gizmo_mat, cursor_rot); + + /* Initize the position of the triangle vertices. */ + const float y_axis[3] = {0.0f, cd->radius, 0.0f}; + for (int i = 0; i < 3; i++) { + zero_v3(cd->preview_tri[i]); + rotate_v2_v2fl(cd->preview_tri[i], y_axis, DEG2RAD(120.0f * i)); + } + + SCULPT_vertex_random_access_ensure(ss); + + WM_event_add_modal_handler(C, op); + ED_region_tag_redraw(ar); + + ss->draw_faded_cursor = true; + + const char *status_str = TIP_( + "Move the mouse to change the dyntopo detail size. LMB: confirm size, ESC/RMB: cancel"); + ED_workspace_status_text(C, status_str); + + return OPERATOR_RUNNING_MODAL; +} + +static bool dyntopo_detail_size_edit_poll(bContext *C) +{ + Object *ob = CTX_data_active_object(C); + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + + return SCULPT_mode_poll(C) && ob->sculpt->bm && (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT); +} + +static void SCULPT_OT_dyntopo_detail_size_edit(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Edit Dyntopo Detail Size"; + ot->description = "Modify the constant detail size of dyntopo interactively"; + ot->idname = "SCULPT_OT_dyntopo_detail_size_edit"; + + /* api callbacks */ + ot->poll = dyntopo_detail_size_edit_poll; + ot->invoke = dyntopo_detail_size_edit_invoke; + ot->modal = dyntopo_detail_size_edit_modal; + ot->cancel = dyntopo_detail_size_edit_cancel; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + void ED_operatortypes_sculpt(void) { WM_operatortype_append(SCULPT_OT_brush_stroke); @@ -9279,4 +9622,5 @@ void ED_operatortypes_sculpt(void) WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors); WM_operatortype_append(SCULPT_OT_color_filter); WM_operatortype_append(SCULPT_OT_mask_by_color); + WM_operatortype_append(SCULPT_OT_dyntopo_detail_size_edit); } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 67129d5da50..20b164fa80c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -139,14 +139,14 @@ static float cloth_brush_simulation_falloff_get(const Brush *brush, const float falloff = radius + (radius * brush->cloth_sim_limit * brush->cloth_sim_falloff); if (distance > limit) { - /* Outiside the limits. */ + /* Outside the limits. */ return 0.0f; } if (distance < falloff) { /* Before the falloff area. */ return 1.0f; } - /* Do a smoothstep transition inside the falloff area. */ + /* Do a smooth-step transition inside the falloff area. */ float p = 1.0f - ((distance - falloff) / (limit - falloff)); return 3.0f * p * p - 2.0f * p * p * p; } @@ -214,7 +214,7 @@ static void cloth_brush_add_length_constraint(SculptSession *ss, /* Reallocation if the array capacity is exceeded. */ cloth_brush_reallocate_constraints(cloth_sim); - /* Add the constraint to the GSet to avoid creating it again. */ + /* Add the constraint to the #GSet to avoid creating it again. */ BLI_edgeset_add(cloth_sim->created_length_constraints, v1, v2); } @@ -326,12 +326,15 @@ static void do_cloth_brush_build_constraints_task_cb_ex( * positions. */ const bool cloth_is_deform_brush = ss->cache != NULL && brush != NULL && SCULPT_is_cloth_deform_brush(brush); + + const bool use_falloff_plane = brush->cloth_force_falloff_type == + BRUSH_CLOTH_FORCE_FALLOFF_PLANE; float radius_squared = 0.0f; if (cloth_is_deform_brush) { radius_squared = ss->cache->initial_radius * ss->cache->initial_radius; } - /* Only limit the contraint creation to a radius when the simulation is local. */ + /* Only limit the constraint creation to a radius when the simulation is local. */ const float cloth_sim_radius_squared = brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL ? data->cloth_sim_radius * data->cloth_sim_radius : @@ -380,12 +383,21 @@ static void do_cloth_brush_build_constraints_task_cb_ex( if (brush && brush->sculpt_tool == SCULPT_TOOL_CLOTH) { /* The cloth brush works by applying forces in most of its modes, but some of them require * deformation coordinates to make the simulation stable. */ - if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB && len_squared < radius_squared) { - /* When the grab brush brush is used as part of the cloth brush, deformation constraints - * are created with different strengths and only inside the radius of the brush. */ - const float fade = BKE_brush_curve_strength(brush, sqrtf(len_squared), ss->cache->radius); - cloth_brush_add_deformation_constraint( - data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH); + if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { + if (use_falloff_plane) { + /* With plane falloff the strength of the constraints is set when applying the + * deformation forces. */ + cloth_brush_add_deformation_constraint( + data->cloth_sim, node_index, vd.index, CLOTH_DEFORMATION_GRAB_STRENGTH); + } + else if (len_squared < radius_squared) { + /* With radial falloff deformation constraints are created with different strengths and + * only inside the radius of the brush. */ + const float fade = BKE_brush_curve_strength( + brush, sqrtf(len_squared), ss->cache->radius); + cloth_brush_add_deformation_constraint( + data->cloth_sim, node_index, vd.index, fade * CLOTH_DEFORMATION_GRAB_STRENGTH); + } } else if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) { /* Cloth Snake Hook creates deformation constraint with fixed strength because the strength @@ -436,9 +448,8 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, const float *grab_delta = data->grab_delta; float(*imat)[4] = data->mat; - const bool use_falloff_plane = !SCULPT_is_cloth_deform_brush(brush) && - brush->cloth_force_falloff_type == - BRUSH_CLOTH_FORCE_FALLOFF_PLANE; + const bool use_falloff_plane = brush->cloth_force_falloff_type == + BRUSH_CLOTH_FORCE_FALLOFF_PLANE; PBVHVertexIter vd; const float bstrength = ss->cache->bstrength; @@ -448,7 +459,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - /* For Pich Perpendicular Deform Type. */ + /* For Pinch Perpendicular Deform Type. */ float x_object_space[3]; float z_object_space[3]; if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PINCH_PERPENDICULAR) { @@ -470,12 +481,6 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, madd_v3_v3fl(gravity, ss->cache->gravity_direction, -data->sd->gravity_factor); } - /* Original data for deform brushes. */ - SculptOrigVertData orig_data; - if (SCULPT_is_cloth_deform_brush(brush)) { - SCULPT_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); - } - BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float force[3]; @@ -486,8 +491,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, float current_vertex_location[3]; if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { - SCULPT_orig_vert_data_update(&orig_data, &vd); - copy_v3_v3(current_vertex_location, orig_data.co); + copy_v3_v3(current_vertex_location, ss->cache->cloth_sim->init_pos[vd.index]); } else { copy_v3_v3(current_vertex_location, vd.co); @@ -504,7 +508,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, float dist = sqrtf(test.dist); if (use_falloff_plane) { - dist = dist_to_plane_v3(vd.co, deform_plane); + dist = dist_to_plane_v3(current_vertex_location, deform_plane); } const float fade = sim_factor * bstrength * @@ -539,9 +543,15 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, break; case BRUSH_CLOTH_DEFORM_GRAB: madd_v3_v3v3fl(cloth_sim->deformation_pos[vd.index], - orig_data.co, + cloth_sim->init_pos[vd.index], ss->cache->grab_delta_symmetry, fade); + if (use_falloff_plane) { + cloth_sim->deformation_strength[vd.index] = clamp_f(fade, 0.0f, 1.0f); + } + else { + cloth_sim->deformation_strength[vd.index] = 1.0f; + } zero_v3(force); break; case BRUSH_CLOTH_DEFORM_SNAKE_HOOK: @@ -920,7 +930,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod BKE_curvemapping_init(brush->curve); - /* Init the grab delta. */ + /* Initialize the grab delta. */ copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); normalize_v3(grab_delta); @@ -930,7 +940,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod return; } - /* Calcuate push offset. */ + /* Calculate push offset. */ if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_PUSH) { mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius); @@ -944,7 +954,7 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod brush->cloth_force_falloff_type == BRUSH_CLOTH_FORCE_FALLOFF_PLANE) { SCULPT_calc_brush_plane(sd, ob, nodes, totnode, area_no, area_co); - /* Init stroke local space matrix. */ + /* Initialize stroke local space matrix. */ cross_v3_v3v3(mat[0], area_no, ss->cache->grab_delta_symmetry); mat[0][3] = 0.0f; cross_v3_v3v3(mat[1], area_no, mat[0]); @@ -965,8 +975,8 @@ static void cloth_brush_apply_brush_foces(Sculpt *sd, Object *ob, PBVHNode **nod } } - if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_SNAKE_HOOK) { - /* Set the deformation strength to 0. Snake hook will initialize the strength in the required + if (ELEM(brush->cloth_deform_type, BRUSH_CLOTH_DEFORM_SNAKE_HOOK, BRUSH_CLOTH_DEFORM_GRAB)) { + /* Set the deformation strength to 0. Brushes will initialize the strength in the required * area. */ const int totverts = SCULPT_vertex_count_get(ss); for (int i = 0; i < totverts; i++) { @@ -1058,7 +1068,7 @@ void SCULPT_cloth_brush_ensure_nodes_constraints( PBVHNode **nodes, int totnode, SculptClothSimulation *cloth_sim, - /* Cannot be const, because it is assigned to a non-const variable. + /* Cannot be `const`, because it is assigned to a `non-const` variable. * NOLINTNEXTLINE: readability-non-const-parameter. */ float initial_location[3], const float radius) @@ -1178,7 +1188,7 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode sculpt_cloth_ensure_constraints_in_simulation_area(sd, ob, nodes, totnode); } /* The first step of a symmetry pass is never simulated as deformation modes need valid delta - * for brush tip alignement. */ + * for brush tip alignment. */ return; } @@ -1253,9 +1263,14 @@ void SCULPT_cloth_plane_falloff_preview_draw(const uint gpuattr, const float outline_col[3], float outline_alpha) { - float local_mat_inv[4][4]; - invert_m4_m4(local_mat_inv, ss->cache->stroke_local_mat); - GPU_matrix_mul(ss->cache->stroke_local_mat); + float local_mat[4][4]; + copy_m4_m4(local_mat, ss->cache->stroke_local_mat); + + if (ss->cache->brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { + add_v3_v3v3(local_mat[3], ss->cache->true_location, ss->cache->grab_delta); + } + + GPU_matrix_mul(local_mat); const float dist = ss->cache->radius; const float arrow_x = ss->cache->radius * 0.2f; @@ -1299,7 +1314,7 @@ static EnumPropertyItem prop_cloth_filter_type[] = { "SCALE", 0, "Scale", - "Scales the mesh as a softbody using the origin of the object as scale"}, + "Scales the mesh as a soft-body using the origin of the object as scale"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index bfe741d2625..6eb51c77aef 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -1020,6 +1020,7 @@ void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot) typedef enum eSculptFaceSetEditMode { SCULPT_FACE_SET_EDIT_GROW = 0, SCULPT_FACE_SET_EDIT_SHRINK = 1, + SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY = 2, } eSculptFaceSetEditMode; static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = { @@ -1037,6 +1038,13 @@ static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = { "Shrink Face Set", "Shrinks the Face Sets boundary by one face based on mesh topology", }, + { + SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY, + "DELETE_GEOMETRY", + 0, + "Delete Geometry", + "Deletes the faces that are assigned to the Face Set", + }, {0, NULL, 0, NULL, NULL}, }; @@ -1098,6 +1106,78 @@ static void sculpt_face_set_shrink(Object *ob, } } +static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool check_visible_only) +{ + + int first_face_set = SCULPT_FACE_SET_NONE; + if (check_visible_only) { + for (int f = 0; f < ss->totfaces; f++) { + if (face_sets[f] > 0) { + first_face_set = face_sets[f]; + break; + } + } + } + else { + first_face_set = abs(face_sets[0]); + } + + if (first_face_set == SCULPT_FACE_SET_NONE) { + return true; + } + + for (int f = 0; f < ss->totfaces; f++) { + const int face_set_id = check_visible_only ? face_sets[f] : abs(face_sets[f]); + if (face_set_id != first_face_set) { + return false; + } + } + return true; +} + +static void sculpt_face_set_delete_geometry(Object *ob, + SculptSession *ss, + const int active_face_set_id, + const bool modify_hidden) +{ + + Mesh *mesh = ob->data; + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh); + BMesh *bm = BM_mesh_create(&allocsize, + &((struct BMeshCreateParams){ + .use_toolflags = true, + })); + + BM_mesh_bm_from_me(bm, + mesh, + (&(struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + + BM_mesh_elem_table_init(bm, BM_FACE); + BM_mesh_elem_table_ensure(bm, BM_FACE); + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); + BMIter iter; + BMFace *f; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + const int face_index = BM_elem_index_get(f); + const int face_set_id = modify_hidden ? abs(ss->face_sets[face_index]) : + ss->face_sets[face_index]; + BM_elem_flag_set(f, BM_ELEM_TAG, face_set_id == active_face_set_id); + } + BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES); + BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); + + BM_mesh_bm_to_me(NULL, + bm, + ob->data, + (&(struct BMeshToMeshParams){ + .calc_object_remap = false, + })); + + BM_mesh_free(bm); +} + static void sculpt_face_set_apply_edit(Object *ob, const int active_face_set_id, const int mode, @@ -1105,80 +1185,135 @@ static void sculpt_face_set_apply_edit(Object *ob, { SculptSession *ss = ob->sculpt; - int *prev_face_sets = MEM_dupallocN(ss->face_sets); - switch (mode) { - case SCULPT_FACE_SET_EDIT_GROW: + case SCULPT_FACE_SET_EDIT_GROW: { + int *prev_face_sets = MEM_dupallocN(ss->face_sets); sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id, modify_hidden); + MEM_SAFE_FREE(prev_face_sets); break; - case SCULPT_FACE_SET_EDIT_SHRINK: + } + case SCULPT_FACE_SET_EDIT_SHRINK: { + int *prev_face_sets = MEM_dupallocN(ss->face_sets); sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id, modify_hidden); + MEM_SAFE_FREE(prev_face_sets); + break; + } + case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY: + sculpt_face_set_delete_geometry(ob, ss, active_face_set_id, modify_hidden); break; } - - MEM_SAFE_FREE(prev_face_sets); } -static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss, + const eSculptFaceSetEditMode mode, + const bool modify_hidden) { - Object *ob = CTX_data_active_object(C); - SculptSession *ss = ob->sculpt; - Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - - const int mode = RNA_enum_get(op->ptr, "mode"); - - /* Dyntopo not supported. */ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { + /* Dyntopo is not supported. */ return OPERATOR_CANCELLED; } - /* Ignore other events to avoid repeated operations. */ - if (event->val != KM_PRESS) { - return OPERATOR_CANCELLED; + if (mode == SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY) { + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + /* Modification of base mesh geometry requires special remapping of multires displacement, + * which does not happen here. + * Disable delete operation. It can be supported in the future by doing similar displacement + * data remapping as what happens in the mesh edit mode. */ + return false; + } + if (check_single_face_set(ss, ss->face_sets, !modify_hidden)) { + /* Cancel the operator if the mesh only contains one Face Set to avoid deleting the + * entire object. */ + return false; + } } + return true; +} - BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); +static void sculpt_face_set_edit_modify_geometry(bContext *C, + Object *ob, + const int active_face_set, + const eSculptFaceSetEditMode mode, + const bool modify_hidden) +{ + ED_sculpt_undo_geometry_begin(ob, "edit face set delete geometry"); + sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden); + ED_sculpt_undo_geometry_end(ob); + BKE_mesh_batch_cache_dirty_tag(ob->data, BKE_MESH_BATCH_DIRTY_ALL); + DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); +} - /* Update the current active Face Set and Vertex as the operator can be used directly from the - * tool without brush cursor. */ - SculptCursorGeometryInfo sgi; - float mouse[2]; - mouse[0] = event->mval[0]; - mouse[1] = event->mval[1]; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); +static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode) +{ + SculptSession *ss = ob->sculpt; + PBVH *pbvh = ss->pbvh; + + /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ + SCULPT_visibility_sync_all_face_sets_to_vertices(ob); + + for (int i = 0; i < totnode; i++) { + BKE_pbvh_node_mark_update_visibility(nodes[i]); + } + + BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); + + if (BKE_pbvh_type(pbvh) == PBVH_FACES) { + BKE_mesh_flush_hidden_from_verts(ob->data); + } +} +static void sculpt_face_set_edit_modify_face_sets(Object *ob, + const int active_face_set, + const eSculptFaceSetEditMode mode, + const bool modify_hidden) +{ PBVH *pbvh = ob->sculpt->pbvh; PBVHNode **nodes; int totnode; BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); if (!nodes) { - return OPERATOR_CANCELLED; + return; } - SCULPT_undo_push_begin("face set edit"); SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS); - - const int active_face_set = SCULPT_active_face_set_get(ss); - const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden"); - sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden); - SCULPT_undo_push_end(); + face_set_edit_do_post_visibility_updates(ob, nodes, totnode); + MEM_freeN(nodes); +} - /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ - SCULPT_visibility_sync_all_face_sets_to_vertices(ob); +static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Object *ob = CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); - for (int i = 0; i < totnode; i++) { - BKE_pbvh_node_mark_update_visibility(nodes[i]); + const int mode = RNA_enum_get(op->ptr, "mode"); + const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden"); + + if (!sculpt_face_set_edit_is_operation_valid(ss, mode, modify_hidden)) { + return OPERATOR_CANCELLED; } - BKE_pbvh_update_vertex_data(ss->pbvh, PBVH_UpdateVisibility); + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); - MEM_SAFE_FREE(nodes); + /* Update the current active Face Set and Vertex as the operator can be used directly from the + * tool without brush cursor. */ + SculptCursorGeometryInfo sgi; + const float mouse[2] = {event->mval[0], event->mval[1]}; + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + const int active_face_set = SCULPT_active_face_set_get(ss); - if (BKE_pbvh_type(pbvh) == PBVH_FACES) { - BKE_mesh_flush_hidden_from_verts(ob->data); + switch (mode) { + case SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY: + sculpt_face_set_edit_modify_geometry(C, ob, active_face_set, mode, modify_hidden); + break; + case SCULPT_FACE_SET_EDIT_GROW: + case SCULPT_FACE_SET_EDIT_SHRINK: + sculpt_face_set_edit_modify_face_sets(ob, active_face_set, mode, modify_hidden); + break; } SCULPT_tag_update_overlays(C); diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index f1410ffad1b..f4f30c903aa 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -1477,8 +1477,6 @@ static void sculpt_undosys_step_decode( { Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - /* Sculpt needs evaluated state. */ - BKE_scene_view_layer_graph_evaluated_ensure(bmain, scene, view_layer); Object *ob = OBACT(view_layer); if (ob && (ob->type == OB_MESH)) { if (ob->mode & OB_MODE_SCULPT) { @@ -1486,6 +1484,12 @@ static void sculpt_undosys_step_decode( } else { ED_object_mode_generic_exit(bmain, depsgraph, scene, ob); + + /* Sculpt needs evaluated state. + * Note: needs to be done here, as #ED_object_mode_generic_exit will usually invalidate + * (some) evaluated data. */ + BKE_scene_graph_evaluated_ensure(depsgraph, bmain); + Mesh *me = ob->data; /* Don't add sculpt topology undo steps when reading back undo state. * The undo steps must enter/exit for us. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 5be72ec87e7..f77d473ae57 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -172,7 +172,7 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em, for (i = 0; i < sculptdata->totalUniqueUvs; i++) { copy_v2_v2(diff, tmp_uvdata[i].sum_co); - mul_v2_fl(diff, 1.f / tmp_uvdata[i].ncounter); + mul_v2_fl(diff, 1.0f / tmp_uvdata[i].ncounter); copy_v2_v2(tmp_uvdata[i].p, diff); tmp_uvdata[i].b[0] = diff[0] - sculptdata->uv[i].uv[0]; @@ -260,7 +260,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, * here it is not needed since we translate along the UV plane always. */ for (i = 0; i < sculptdata->totalUniqueUvs; i++) { copy_v2_v2(tmp_uvdata[i].p, tmp_uvdata[i].sum_co); - mul_v2_fl(tmp_uvdata[i].p, 1.f / tmp_uvdata[i].ncounter); + mul_v2_fl(tmp_uvdata[i].p, 1.0f / tmp_uvdata[i].ncounter); } for (i = 0; i < sculptdata->totalUniqueUvs; i++) { diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index e5f6b61a2ae..c6961cc9d4b 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -46,13 +46,14 @@ #include "BKE_packedFile.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "RNA_access.h" #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_sequencer.h" + #include "UI_interface.h" #include "WM_api.h" @@ -170,7 +171,7 @@ static void SOUND_OT_open(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one"); } @@ -197,7 +198,7 @@ static void SOUND_OT_open_mono(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", true, "Mono", "Mixdown the sound to mono"); } @@ -511,8 +512,7 @@ static bool sound_mixdown_draw_check_prop(PointerRNA *UNUSED(ptr), void *UNUSED(user_data)) { const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath") || STREQ(prop_id, "directory") || - STREQ(prop_id, "filename")); + return !(STR_ELEM(prop_id, "filepath", "directory", "filename")); } static void sound_mixdown_draw(bContext *C, wmOperator *op) @@ -721,7 +721,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); #ifdef WITH_AUDASPACE RNA_def_int( ot->srna, diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index f058ec5546a..167215b3813 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1665,7 +1665,7 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) if (ked.i1) { Scene *scene = ac.scene; CFRA = round_fl_to_int(ked.f1 / ked.i1); - SUBFRA = 0.f; + SUBFRA = 0.0f; } /* set notifier that things have changed */ diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index b89c8cb2193..10ce7b81954 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -271,18 +271,15 @@ void ED_region_draw_cb_exit(ARegionType *art, void *handle) void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type) { RegionDrawCB *rdc; - bool has_drawn_something = false; for (rdc = region->type->drawcalls.first; rdc; rdc = rdc->next) { if (rdc->type == type) { rdc->draw(C, region, rdc->customdata); - has_drawn_something = true; + + /* This is needed until we get rid of BGL which can change the states we are tracking. */ + GPU_bgl_end(); } } - if (has_drawn_something) { - /* This is needed until we get rid of BGL which can change the states we are tracking. */ - GPU_bgl_end(); - } } /* ********************* space template *********************** */ diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 60ce86740cd..8fc16e66466 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -56,6 +56,7 @@ #include "RNA_access.h" +#include "ED_buttons.h" #include "ED_physics.h" #include "ED_screen.h" @@ -512,11 +513,11 @@ static bool buttons_context_linestyle_pinnable(const bContext *C, ViewLayer *vie } #endif -static bool buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag) +static bool buttons_context_path( + const bContext *C, SpaceProperties *sbuts, ButsContextPath *path, int mainb, int flag) { /* Note we don't use CTX_data here, instead we get it from the window. * Otherwise there is a loop reading the context that we are setting. */ - SpaceProperties *sbuts = CTX_wm_space_properties(C); wmWindow *window = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(window); ViewLayer *view_layer = WM_window_get_active_view_layer(window); @@ -660,14 +661,14 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts) int flag = 0; /* Set scene path. */ - buttons_context_path(C, path, BCONTEXT_SCENE, pflag); + buttons_context_path(C, sbuts, path, BCONTEXT_SCENE, pflag); buttons_texture_context_compute(C, sbuts); /* for each context, see if we can compute a valid path to it, if * this is the case, we know we have to display the button */ for (int i = 0; i < BCONTEXT_TOT; i++) { - if (buttons_context_path(C, path, i, pflag)) { + if (buttons_context_path(C, sbuts, path, i, pflag)) { flag |= (1 << i); /* setting icon for data context */ @@ -713,7 +714,7 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts) } } - buttons_context_path(C, path, sbuts->mainb, pflag); + buttons_context_path(C, sbuts, path, sbuts->mainb, pflag); if (!(flag & (1 << sbuts->mainb))) { if (flag & (1 << BCONTEXT_OBJECT)) { @@ -734,6 +735,39 @@ void buttons_context_compute(const bContext *C, SpaceProperties *sbuts) sbuts->pathflag = flag; } +static bool is_pointer_in_path(ButsContextPath *path, PointerRNA *ptr) +{ + for (int i = 0; i < path->len; ++i) { + if (ptr->owner_id == path->ptr[i].owner_id) { + return true; + } + } + return false; +} + +void ED_buttons_set_context(const bContext *C, PointerRNA *ptr, const int context) +{ + ScrArea *active_area = CTX_wm_area(C); + bScreen *screen = CTX_wm_screen(C); + + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + /* Only update for properties editors that are visible and share a border. */ + if (area->spacetype != SPACE_PROPERTIES) { + continue; + } + if (!ED_area_has_shared_border(active_area, area)) { + continue; + } + + SpaceProperties *sbuts = (SpaceProperties *)area->spacedata.first; + ButsContextPath path; + if (buttons_context_path(C, sbuts, &path, context, 0) && is_pointer_in_path(&path, ptr)) { + sbuts->mainbuser = context; + sbuts->mainb = sbuts->mainbuser; + } + } +} + /************************* Context Callback ************************/ const char *buttons_context_dir[] = { diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 87cf8507dd4..8bdc2ed993f 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -378,7 +378,7 @@ void BUTTONS_OT_file_browse(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /* Second operator, only difference from BUTTONS_OT_file_browse is WM_FILESEL_DIRECTORY. */ @@ -405,7 +405,7 @@ void BUTTONS_OT_directory_browse(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index ee9cc0e31df..bd11a746e11 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -675,7 +675,7 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl } } else { - if (cur_sc->clip == old_clip || cur_sc->clip == NULL) { + if (ELEM(cur_sc->clip, old_clip, NULL)) { cur_sc->clip = clip; } } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 26fa5b8a06c..3f00e3114a5 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -329,7 +329,7 @@ void CLIP_OT_open(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ @@ -616,7 +616,7 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { + if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) { float delta, factor; delta = event->prevx - event->x + event->prevy - event->y; diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 0631b6ea8a0..4d3e6cf4d6a 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -1043,13 +1043,13 @@ static int clear_track_path_exec(bContext *C, wmOperator *op) void CLIP_OT_clear_track_path(wmOperatorType *ot) { static const EnumPropertyItem clear_path_actions[] = { - {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear up-to", "Clear path up to current frame"}, + {TRACK_CLEAR_UPTO, "UPTO", 0, "Clear Up To", "Clear path up to current frame"}, {TRACK_CLEAR_REMAINED, "REMAINED", 0, - "Clear remained", + "Clear Remained", "Clear path at remaining frames (after current)"}, - {TRACK_CLEAR_ALL, "ALL", 0, "Clear all", "Clear the whole path"}, + {TRACK_CLEAR_ALL, "ALL", 0, "Clear All", "Clear the whole path"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 478d22c7582..063ea9592aa 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -975,15 +975,15 @@ static int select_grouped_exec(bContext *C, wmOperator *op) void CLIP_OT_select_grouped(wmOperatorType *ot) { static const EnumPropertyItem select_group_items[] = { - {0, "KEYFRAMED", 0, "Keyframed tracks", "Select all keyframed tracks"}, - {1, "ESTIMATED", 0, "Estimated tracks", "Select all estimated tracks"}, - {2, "TRACKED", 0, "Tracked tracks", "Select all tracked tracks"}, - {3, "LOCKED", 0, "Locked tracks", "Select all locked tracks"}, - {4, "DISABLED", 0, "Disabled tracks", "Select all disabled tracks"}, + {0, "KEYFRAMED", 0, "Keyframed Tracks", "Select all keyframed tracks"}, + {1, "ESTIMATED", 0, "Estimated Tracks", "Select all estimated tracks"}, + {2, "TRACKED", 0, "Tracked Tracks", "Select all tracked tracks"}, + {3, "LOCKED", 0, "Locked Tracks", "Select all locked tracks"}, + {4, "DISABLED", 0, "Disabled Tracks", "Select all disabled tracks"}, {5, "COLOR", 0, - "Tracks with same color", + "Tracks with Same Color", "Select all tracks with same color as active track"}, {6, "FAILED", 0, "Failed Tracks", "Select all tracks which failed to be reconstructed"}, {0, NULL, 0, NULL, NULL}, diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 91653fb7785..93367ad3d3c 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1351,18 +1351,17 @@ static int file_column_sort_ui_context_invoke(bContext *C, if (column_type != COLUMN_NONE) { const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type]; - if (column->sort_type != FILE_SORT_NONE) { - if (sfile->params->sort == column->sort_type) { - /* Already sorting by selected column -> toggle sort invert (three state logic). */ - sfile->params->flag ^= FILE_SORT_INVERT; - } - else { - sfile->params->sort = column->sort_type; - sfile->params->flag &= ~FILE_SORT_INVERT; - } - - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + BLI_assert(column->sort_type != FILE_SORT_DEFAULT); + if (sfile->params->sort == column->sort_type) { + /* Already sorting by selected column -> toggle sort invert (three state logic). */ + sfile->params->flag ^= FILE_SORT_INVERT; } + else { + sfile->params->sort = column->sort_type; + sfile->params->flag &= ~FILE_SORT_INVERT; + } + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } } @@ -2415,7 +2414,8 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, "directory", sfile->params->dir); RNA_boolean_set(&ptr, "open", true); - /* Enable confirmation prompt, else it's too easy to accidentally create new directories. */ + /* Enable confirmation prompt, else it's too easy + * to accidentally create new directories. */ RNA_boolean_set(&ptr, "confirm", true); if (lastdir) { diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 3004aadb5dd..9e51b6ca4ba 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -294,9 +294,6 @@ enum { typedef struct FileList { FileDirEntryArr filelist; - short prv_w; - short prv_h; - short flags; short sort; @@ -586,7 +583,7 @@ static int compare_extension(void *user_data, const void *a1, const void *a2) void filelist_sort(struct FileList *filelist) { - if ((filelist->flags & FL_NEED_SORTING) && (filelist->sort != FILE_SORT_NONE)) { + if (filelist->flags & FL_NEED_SORTING) { void *sort_cb = NULL; switch (filelist->sort) { @@ -602,7 +599,7 @@ void filelist_sort(struct FileList *filelist) case FILE_SORT_EXTENSION: sort_cb = compare_extension; break; - case FILE_SORT_NONE: /* Should never reach this point! */ + case FILE_SORT_DEFAULT: default: BLI_assert(0); break; @@ -951,12 +948,6 @@ void filelist_free_icons(void) } } -void filelist_imgsize(struct FileList *filelist, short w, short h) -{ - filelist->prv_w = w; - filelist->prv_h = h; -} - static FileDirEntry *filelist_geticon_get_file(struct FileList *filelist, const int index) { BLI_assert(G.background == false); @@ -1303,6 +1294,8 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat } IMB_thumb_path_lock(preview->path); + /* Always generate biggest preview size for now, it's simpler and avoids having to re-generate in + * case user switch to a bigger preview size. */ preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source); IMB_thumb_path_unlock(preview->path); @@ -1569,7 +1562,6 @@ void filelist_free(struct FileList *filelist) memset(&filelist->filter_data, 0, sizeof(filelist->filter_data)); filelist->flags &= ~(FL_NEED_SORTING | FL_NEED_FILTERING); - filelist->sort = FILE_SORT_NONE; } void filelist_freelib(struct FileList *filelist) diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 051b811b001..4b8cc052382 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -69,7 +69,6 @@ void filelist_filter(struct FileList *filelist); void filelist_init_icons(void); void filelist_free_icons(void); -void filelist_imgsize(struct FileList *filelist, short w, short h); struct ImBuf *filelist_getimage(struct FileList *filelist, const int index); struct ImBuf *filelist_geticon_image(struct FileList *filelist, const int index); int filelist_geticon(struct FileList *filelist, const int index, const bool is_main); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 42b2806814b..15c6972c5f5 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -61,6 +61,7 @@ #include "BLF_api.h" #include "ED_fileselect.h" +#include "ED_screen.h" #include "WM_api.h" #include "WM_types.h" @@ -266,15 +267,16 @@ short ED_fileselect_set_params(SpaceFile *sfile) params->display = RNA_property_enum_get(op->ptr, prop); } + if (params->display == FILE_DEFAULTDISPLAY) { + params->display = U_default.file_space_data.display_type; + } + if ((prop = RNA_struct_find_property(op->ptr, "sort_method"))) { params->sort = RNA_property_enum_get(op->ptr, prop); } - else { - params->sort = U_default.file_space_data.sort_type; - } - if (params->display == FILE_DEFAULTDISPLAY) { - params->display = U_default.file_space_data.display_type; + if (params->sort == FILE_SORT_DEFAULT) { + params->sort = U_default.file_space_data.sort_type; } if (is_relative_path) { @@ -326,8 +328,9 @@ short ED_fileselect_set_params(SpaceFile *sfile) return 1; } -/* The subset of FileSelectParams.flag items we store into preferences. */ -#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT | FILE_SORT_INVERT) +/* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA + * may also be remembered, but only conditionally. */ +#define PARAMS_FLAGS_REMEMBERED (FILE_HIDE_DOT) void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized) { @@ -340,6 +343,22 @@ void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool *is_maximized = WM_window_is_maximized(win); } +static bool file_select_use_default_display_type(const SpaceFile *sfile) +{ + PropertyRNA *prop; + return (sfile->op == NULL) || + !(prop = RNA_struct_find_property(sfile->op->ptr, "display_type")) || + (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_DEFAULTDISPLAY); +} + +static bool file_select_use_default_sort_type(const SpaceFile *sfile) +{ + PropertyRNA *prop; + return (sfile->op == NULL) || + !(prop = RNA_struct_find_property(sfile->op->ptr, "sort_method")) || + (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_SORT_DEFAULT); +} + void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) { wmOperator *op = sfile->op; @@ -351,12 +370,6 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) return; } - if (!RNA_struct_property_is_set(op->ptr, "display_type")) { - sfile->params->display = sfile_udata->display_type; - } - if (!RNA_struct_property_is_set(op->ptr, "sort_method")) { - sfile->params->sort = sfile_udata->sort_type; - } sfile->params->thumbnail_size = sfile_udata->thumbnail_size; sfile->params->details_flags = sfile_udata->details_flags; sfile->params->filter_id = sfile_udata->filter_id; @@ -364,6 +377,16 @@ void ED_fileselect_set_params_from_userdef(SpaceFile *sfile) /* Combine flags we take from params with the flags we take from userdef. */ sfile->params->flag = (sfile->params->flag & ~PARAMS_FLAGS_REMEMBERED) | (sfile_udata->flag & PARAMS_FLAGS_REMEMBERED); + + if (file_select_use_default_display_type(sfile)) { + sfile->params->display = sfile_udata->display_type; + } + if (file_select_use_default_sort_type(sfile)) { + sfile->params->sort = sfile_udata->sort_type; + /* For the default sorting, also take invert flag from userdef. */ + sfile->params->flag = (sfile->params->flag & ~FILE_SORT_INVERT) | + (sfile_udata->flag & FILE_SORT_INVERT); + } } /** @@ -380,13 +403,24 @@ void ED_fileselect_params_to_userdef(SpaceFile *sfile, UserDef_FileSpaceData *sfile_udata_new = &U.file_space_data; UserDef_FileSpaceData sfile_udata_old = U.file_space_data; - sfile_udata_new->display_type = sfile->params->display; sfile_udata_new->thumbnail_size = sfile->params->thumbnail_size; - sfile_udata_new->sort_type = sfile->params->sort; sfile_udata_new->details_flags = sfile->params->details_flags; sfile_udata_new->flag = sfile->params->flag & PARAMS_FLAGS_REMEMBERED; sfile_udata_new->filter_id = sfile->params->filter_id; + /* In some rare cases, operators ask for a specific display or sort type (e.g. chronological + * sorting for "Recover Auto Save"). So the settings are optimized for a specific operation. + * Don't let that change the userdef memory for more general cases. */ + if (file_select_use_default_display_type(sfile)) { + sfile_udata_new->display_type = sfile->params->display; + } + if (file_select_use_default_sort_type(sfile)) { + sfile_udata_new->sort_type = sfile->params->sort; + /* In this case also remember the invert flag. */ + sfile_udata_new->flag = (sfile_udata_new->flag & ~FILE_SORT_INVERT) | + (sfile->params->flag & FILE_SORT_INVERT); + } + if (temp_win_size && !is_maximized) { sfile_udata_new->temp_win_sizex = temp_win_size[0]; sfile_udata_new->temp_win_sizey = temp_win_size[1]; @@ -1050,3 +1084,20 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) params->rename_flag = 0; } } + +ScrArea *ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator *file_operator) +{ + bScreen *screen = WM_window_get_active_screen(win); + + ED_screen_areas_iter (win, screen, area) { + if (area->spacetype == SPACE_FILE) { + SpaceFile *sfile = area->spacedata.first; + + if (sfile->op == file_operator) { + return area; + } + } + } + + return NULL; +} diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 329b5fe67fd..d8556711c55 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -203,7 +203,7 @@ static void fsmenu_xdg_insert_entry(GHash *xdg_map, xdg_path = xdg_path_buf; } fsmenu_insert_entry( - fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, xdg_path, IFACE_(default_path), icon, FS_INSERT_LAST); + fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, xdg_path, N_(default_path), icon, FS_INSERT_LAST); } /** \} */ @@ -579,10 +579,10 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) name[0] = '\0'; while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */ - if (STREQLEN(line, "[Bookmarks]", 11)) { + if (STRPREFIX(line, "[Bookmarks]")) { category = FS_CATEGORY_BOOKMARKS; } - else if (STREQLEN(line, "[Recent]", 8)) { + else if (STRPREFIX(line, "[Recent]")) { category = FS_CATEGORY_RECENT; } else if (line[0] == '!') { @@ -698,49 +698,49 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Profile, - IFACE_("Home"), + N_("Home"), ICON_HOME, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Desktop, - IFACE_("Desktop"), + N_("Desktop"), ICON_DESKTOP, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Documents, - IFACE_("Documents"), + N_("Documents"), ICON_DOCUMENTS, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Downloads, - IFACE_("Downloads"), + N_("Downloads"), ICON_IMPORT, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Music, - IFACE_("Music"), + N_("Music"), ICON_FILE_SOUND, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Pictures, - IFACE_("Pictures"), + N_("Pictures"), ICON_FILE_IMAGE, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Videos, - IFACE_("Videos"), + N_("Videos"), ICON_FILE_MOVIE, FS_INSERT_LAST); fsmenu_add_windows_folder(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, &FOLDERID_Fonts, - IFACE_("Fonts"), + N_("Fonts"), ICON_FILE_FONT, FS_INSERT_LAST); @@ -757,16 +757,12 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) { /* We store some known macOS system paths and corresponding icons * and names in the FS_CATEGORY_OTHER (not displayed directly) category. */ - fsmenu_insert_entry(fsmenu, - FS_CATEGORY_OTHER, - "/Library/Fonts/", - IFACE_("Fonts"), - ICON_FILE_FONT, - FS_INSERT_LAST); + fsmenu_insert_entry( + fsmenu, FS_CATEGORY_OTHER, "/Library/Fonts/", N_("Fonts"), ICON_FILE_FONT, FS_INSERT_LAST); fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, "/Applications/", - IFACE_("Applications"), + N_("Applications"), ICON_FILE_FOLDER, FS_INSERT_LAST); @@ -777,13 +773,13 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) fsmenu_insert_entry(fsmenu, FS_CATEGORY_OTHER, line, name, icon, FS_INSERT_LAST); FS_MACOS_PATH("%s/", NULL, ICON_HOME) - FS_MACOS_PATH("%s/Desktop/", IFACE_("Desktop"), ICON_DESKTOP) - FS_MACOS_PATH("%s/Documents/", IFACE_("Documents"), ICON_DOCUMENTS) - FS_MACOS_PATH("%s/Downloads/", IFACE_("Downloads"), ICON_IMPORT) - FS_MACOS_PATH("%s/Movies/", IFACE_("Movies"), ICON_FILE_MOVIE) - FS_MACOS_PATH("%s/Music/", IFACE_("Music"), ICON_FILE_SOUND) - FS_MACOS_PATH("%s/Pictures/", IFACE_("Pictures"), ICON_FILE_IMAGE) - FS_MACOS_PATH("%s/Library/Fonts/", IFACE_("Fonts"), ICON_FILE_FONT) + FS_MACOS_PATH("%s/Desktop/", N_("Desktop"), ICON_DESKTOP) + FS_MACOS_PATH("%s/Documents/", N_("Documents"), ICON_DOCUMENTS) + FS_MACOS_PATH("%s/Downloads/", N_("Downloads"), ICON_IMPORT) + FS_MACOS_PATH("%s/Movies/", N_("Movies"), ICON_FILE_MOVIE) + FS_MACOS_PATH("%s/Music/", N_("Music"), ICON_FILE_SOUND) + FS_MACOS_PATH("%s/Pictures/", N_("Pictures"), ICON_FILE_IMAGE) + FS_MACOS_PATH("%s/Library/Fonts/", N_("Fonts"), ICON_FILE_FONT) # undef FS_MACOS_PATH @@ -902,7 +898,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) if (read_bookmarks && home) { fsmenu_insert_entry( - fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, home, IFACE_("Home"), ICON_HOME, FS_INSERT_LAST); + fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, home, N_("Home"), ICON_HOME, FS_INSERT_LAST); /* Follow the XDG spec, check if these are available. */ GHash *xdg_map = fsmenu_xdg_user_dirs_parse(home); diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index a491ce29bd4..9c7c859a05d 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -309,7 +309,7 @@ static void graphedit_activekey_left_handle_coord_cb(bContext *C, void *fcu_ptr, /* perform normal updates NOW */ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr); - /* restore selection state so that no-one notices this hack */ + /* restore selection state so that no one notices this hack */ bezt->f1 = f1; bezt->f3 = f3; } @@ -331,7 +331,7 @@ static void graphedit_activekey_right_handle_coord_cb(bContext *C, void *fcu_ptr /* perform normal updates NOW */ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr); - /* restore selection state so that no-one notices this hack */ + /* restore selection state so that no one notices this hack */ bezt->f1 = f1; bezt->f3 = f3; } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 7fc1329df64..ae15b651059 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1863,6 +1863,75 @@ void GRAPH_OT_bake(wmOperatorType *ot) /* TODO: add props for start/end frames (Joshua Leung 2009) */ } +/* ******************** Un-Bake F-Curve Operator *********************** */ +/* This operator unbakes the data of the selected F-Points to F-Curves. */ + +/* Un-Bake F-Points into F-Curves. */ +static void unbake_graph_curves(bAnimContext *ac, int start, int end) +{ + ListBase anim_data = {NULL, NULL}; + bAnimListElem *ale; + + /* Filter data. */ + const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_SEL | + ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); + + /* Loop through filtered data and add keys between selected keyframes on every frame. */ + for (ale = anim_data.first; ale; ale = ale->next) { + FCurve *fcu = (FCurve *)ale->key_data; + + fcurve_samples_to_keyframes(fcu, start, end); + + ale->update |= ANIM_UPDATE_DEPS; + } + + ANIM_animdata_update(ac, &anim_data); + ANIM_animdata_freelist(&anim_data); +} + +/* ------------------- */ + +static int graphkeys_unbake_exec(bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + Scene *scene = NULL; + int start, end; + + /* Get editor data. */ + if (ANIM_animdata_get_context(C, &ac) == 0) { + return OPERATOR_CANCELLED; + } + + scene = ac.scene; + start = PSFRA; + end = PEFRA; + + /* Unbake keyframes. */ + unbake_graph_curves(&ac, start, end); + + /* Set notifier that keyframes have changed. */ + /* NOTE: some distinction between order/number of keyframes and type should be made? */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_unbake(wmOperatorType *ot) +{ + /* Identifiers */ + ot->name = "Un-Bake Curve"; + ot->idname = "GRAPH_OT_unbake"; + ot->description = "Un-Bake selected F-Points to F-Curves"; + + /* API callbacks */ + ot->exec = graphkeys_unbake_exec; + ot->poll = graphop_selected_fcurve_poll; + + /* Flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + #ifdef WITH_AUDASPACE /* ******************** Sound Bake F-Curve Operator *********************** */ @@ -2021,7 +2090,7 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_float(ot->srna, "low", 0.0f, @@ -2815,7 +2884,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) else { /* Animation Mode - Affects current frame (int) */ CFRA = round_fl_to_int(sum_time / num_keyframes); - SUBFRA = 0.f; + SUBFRA = 0.0f; } sipo->cursorVal = sum_value / (float)num_keyframes; @@ -3507,7 +3576,7 @@ void GRAPH_OT_fmodifier_paste(wmOperatorType *ot) /* Properties */ RNA_def_boolean( - ot->srna, "only_active", true, "Only Active", "Only paste F-Modifiers on active F-Curve"); + ot->srna, "only_active", false, "Only Active", "Only paste F-Modifiers on active F-Curve"); RNA_def_boolean( ot->srna, "replace", diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index eaa14fedb93..7add2f7cbb8 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -103,6 +103,7 @@ void GRAPH_OT_clean(struct wmOperatorType *ot); void GRAPH_OT_decimate(struct wmOperatorType *ot); void GRAPH_OT_sample(struct wmOperatorType *ot); void GRAPH_OT_bake(struct wmOperatorType *ot); +void GRAPH_OT_unbake(struct wmOperatorType *ot); void GRAPH_OT_sound_bake(struct wmOperatorType *ot); void GRAPH_OT_smooth(struct wmOperatorType *ot); void GRAPH_OT_euler_filter(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index fd68303e759..63acc2a1774 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -459,6 +459,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_easing_type); WM_operatortype_append(GRAPH_OT_sample); WM_operatortype_append(GRAPH_OT_bake); + WM_operatortype_append(GRAPH_OT_unbake); WM_operatortype_append(GRAPH_OT_sound_bake); WM_operatortype_append(GRAPH_OT_smooth); WM_operatortype_append(GRAPH_OT_clean); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index e36c7d6b6e7..69e9c975bd1 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -519,7 +519,7 @@ enum { static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) { - if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { + if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) { SpaceImage *sima = CTX_wm_space_image(C); ARegion *region = CTX_wm_region(C); float delta, factor, location[2]; @@ -1436,8 +1436,7 @@ static bool image_open_draw_check_prop(PointerRNA *UNUSED(ptr), { const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath") || STREQ(prop_id, "directory") || - STREQ(prop_id, "filename")); + return !(STR_ELEM(prop_id, "filepath", "directory", "filename")); } static void image_open_draw(bContext *UNUSED(C), wmOperator *op) @@ -1486,7 +1485,7 @@ void IMAGE_OT_open(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean( ot->srna, @@ -1638,7 +1637,7 @@ void IMAGE_OT_replace(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ @@ -2038,7 +2037,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ @@ -2047,36 +2046,17 @@ void IMAGE_OT_save_as(wmOperatorType *ot) /** \name Save Image Operator * \{ */ -static bool image_file_path_saveable(bContext *C, Image *ima, ImageUser *iuser) +/** + * \param iuser: Image user or NULL when called outside the image space. + */ +static bool image_file_format_writable(Image *ima, ImageUser *iuser) { - /* Can always repack images. */ - if (BKE_image_has_packedfile(ima)) { - return true; - } - - /* Test for valid filepath. */ void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock); bool ret = false; - if (ibuf) { - Main *bmain = CTX_data_main(C); - char name[FILE_MAX]; - BLI_strncpy(name, ibuf->name, FILE_MAX); - BLI_path_abs(name, BKE_main_blendfile_path(bmain)); - - if (BLI_exists(name) == false) { - CTX_wm_operator_poll_msg_set(C, "image file not found"); - } - else if (!BLI_file_is_writable(name)) { - CTX_wm_operator_poll_msg_set(C, "image path can't be written to"); - } - else if (!BKE_image_buffer_format_writable(ibuf)) { - CTX_wm_operator_poll_msg_set(C, "image format is read-only"); - } - else { - ret = true; - } + if (ibuf && BKE_image_buffer_format_writable(ibuf)) { + ret = true; } BKE_image_release_ibuf(ima, ibuf, lock); @@ -2090,16 +2070,12 @@ static bool image_save_poll(bContext *C) return false; } - Image *ima = image_from_context(C); - ImageUser *iuser = image_user_from_context(C); - - /* Images without a filepath will go to save as. */ - if (!BKE_image_has_filepath(ima)) { - return true; - } + /* Check if there is a valid file path and image format we can write + * outside of the 'poll' so we can show a report with a pop-up. */ - /* Check if there is a valid file path and image format we can write. */ - return image_file_path_saveable(C, ima, iuser); + /* Can always repack images. + * Images without a filepath will go to "Save As". */ + return true; } static int image_save_exec(bContext *C, wmOperator *op) @@ -2114,6 +2090,8 @@ static int image_save_exec(bContext *C, wmOperator *op) if (BKE_image_has_packedfile(image)) { /* Save packed files to memory. */ BKE_image_memorypack(image); + /* Report since this can be called from key shortcuts. */ + BKE_reportf(op->reports, RPT_INFO, "Packed to memory image \"%s\"", image->filepath); return OPERATOR_FINISHED; } @@ -2123,16 +2101,15 @@ static int image_save_exec(bContext *C, wmOperator *op) } image_save_options_from_op(bmain, &opts, op, NULL); - if (BLI_exists(opts.filepath) && BLI_file_is_writable(opts.filepath)) { - if (save_image_op(bmain, image, iuser, op, &opts)) { - /* report since this can be called from key-shortcuts */ - BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", opts.filepath); - ok = true; - } - } - else { + /* Check if file write permission is ok. */ + if (BLI_exists(opts.filepath) && !BLI_file_is_writable(opts.filepath)) { BKE_reportf( - op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", opts.filepath); + op->reports, RPT_ERROR, "Cannot save image, path \"%s\" is not writable", opts.filepath); + } + else if (save_image_op(bmain, image, iuser, op, &opts)) { + /* Report since this can be called from key shortcuts. */ + BKE_reportf(op->reports, RPT_INFO, "Saved image \"%s\"", opts.filepath); + ok = true; } BKE_color_managed_view_settings_free(&opts.im_format.view_settings); @@ -2147,8 +2124,11 @@ static int image_save_exec(bContext *C, wmOperator *op) static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { Image *ima = image_from_context(C); + ImageUser *iuser = image_user_from_context(C); - if (!BKE_image_has_packedfile(ima) && !BKE_image_has_filepath(ima)) { + /* Not writable formats or images without a file-path will go to "Save As". */ + if (!BKE_image_has_packedfile(ima) && + (!BKE_image_has_filepath(ima) || !image_file_format_writable(ima, iuser))) { WM_operator_name_call(C, "IMAGE_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 0544a2cbefa..1435b95c9bf 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -516,7 +516,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /********************* report box operator *********************/ diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c index db8b6240558..bf21b383ba6 100644 --- a/source/blender/editors/space_info/info_stats.c +++ b/source/blender/editors/space_info/info_stats.c @@ -503,7 +503,7 @@ static void get_stats_string( else if (obedit->type == OB_ARMATURE) { *ofs += BLI_snprintf(info + *ofs, len - *ofs, - TIP_("Verts:%s/%s | Bones:%s/%s"), + TIP_("Joints:%s/%s | Bones:%s/%s"), stats_fmt->totvertsel, stats_fmt->totvert, stats_fmt->totbonesel, @@ -664,6 +664,7 @@ void ED_info_draw_stats( EDGES, FACES, TRIS, + JOINTS, BONES, LAYERS, FRAMES, @@ -678,6 +679,7 @@ void ED_info_draw_stats( STRNCPY(labels[EDGES], IFACE_("Edges")); STRNCPY(labels[FACES], IFACE_("Faces")); STRNCPY(labels[TRIS], IFACE_("Triangles")); + STRNCPY(labels[JOINTS], IFACE_("Joints")); STRNCPY(labels[BONES], IFACE_("Bones")); STRNCPY(labels[LAYERS], IFACE_("Layers")); STRNCPY(labels[FRAMES], IFACE_("Frames")); @@ -709,7 +711,7 @@ void ED_info_draw_stats( stats_row(col1, labels[TRIS], col2, stats_fmt.tottri, NULL, y, height); } else if (obedit->type == OB_ARMATURE) { - stats_row(col1, labels[VERTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height); + stats_row(col1, labels[JOINTS], col2, stats_fmt.totvertsel, stats_fmt.totvert, y, height); stats_row(col1, labels[BONES], col2, stats_fmt.totbonesel, stats_fmt.totbone, y, height); } else { diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 66da2887427..16bbca2a0c3 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -748,6 +748,7 @@ static void node_shader_buts_vect_transform(uiLayout *layout, bContext *UNUSED(C static void node_shader_buts_attribute(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { + uiItemR(layout, ptr, "attribute_type", DEFAULT_FLAGS, IFACE_("Type"), ICON_NONE); uiItemR(layout, ptr, "attribute_name", DEFAULT_FLAGS, IFACE_("Name"), ICON_NONE); } diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c index f8382a17c59..508c0a47e21 100644 --- a/source/blender/editors/space_node/node_add.c +++ b/source/blender/editors/space_node/node_add.c @@ -404,7 +404,7 @@ void NODE_OT_add_file(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_string(ot->srna, "name", "Image", MAX_ID_NAME - 2, "Name", "Data-block name to assign"); } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index b1659bcd023..a39e84419d0 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -108,7 +108,7 @@ static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags) node->flag |= NODE_DO_OUTPUT_RECALC; } } - else if (node->type == CMP_NODE_VIEWER || node->type == CMP_NODE_SPLITVIEWER) { + else if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { if (recalc_flags & COM_RECALC_VIEWER) { node->flag |= NODE_DO_OUTPUT_RECALC; } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index c6c14a9886e..654b95858bb 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -31,6 +31,7 @@ #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLT_translation.h" @@ -59,7 +60,11 @@ #include "NOD_socket.h" #include "node_intern.h" /* own include */ -static bool node_group_operator_active(bContext *C) +/* -------------------------------------------------------------------- */ +/** \name Local Utilities + * \{ */ + +static bool node_group_operator_active_poll(bContext *C) { if (ED_operator_node_active(C)) { SpaceNode *snode = CTX_wm_space_node(C); @@ -68,10 +73,11 @@ static bool node_group_operator_active(bContext *C) * Disabled otherwise to allow pynodes define their own operators * with same keymap. */ - if (STREQ(snode->tree_idname, "ShaderNodeTree") || - STREQ(snode->tree_idname, "CompositorNodeTree") || - STREQ(snode->tree_idname, "TextureNodeTree") || - STREQ(snode->tree_idname, "SimulationNodeTree")) { + if (STR_ELEM(snode->tree_idname, + "ShaderNodeTree", + "CompositorNodeTree", + "TextureNodeTree", + "SimulationNodeTree")) { return true; } } @@ -132,7 +138,11 @@ static bNode *node_group_get_active(bContext *C, const char *node_idname) return NULL; } -/* ***************** Edit Group operator ************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Edit Group Operator + * \{ */ static int node_group_edit_exec(bContext *C, wmOperator *op) { @@ -169,7 +179,7 @@ void NODE_OT_group_edit(wmOperatorType *ot) /* api callbacks */ ot->exec = node_group_edit_exec; - ot->poll = node_group_operator_active; + ot->poll = node_group_operator_active_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -177,10 +187,16 @@ void NODE_OT_group_edit(wmOperatorType *ot) RNA_def_boolean(ot->srna, "exit", false, "Exit", ""); } -/* ******************** Ungroup operator ********************** */ +/** \} */ -/* The given paths will be owned by the returned instance. Both pointers are allowed to point to - * the same string. */ +/* -------------------------------------------------------------------- */ +/** \name Ungroup Operator + * \{ */ + +/** + * The given paths will be owned by the returned instance. + * Both pointers are allowed to point to the same string. + */ static AnimationBasePathChange *animation_basepath_change_new(const char *src_basepath, const char *dst_basepath) { @@ -422,7 +438,11 @@ void NODE_OT_group_ungroup(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ******************** Separate operator ********************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Separate Operator + * \{ */ /* returns 1 if its OK */ static int node_group_separate_selected( @@ -634,7 +654,11 @@ void NODE_OT_group_separate(wmOperatorType *ot) RNA_def_enum(ot->srna, "type", node_group_separate_types, NODE_GS_COPY, "Type", ""); } -/* ****************** Make Group operator ******************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Make Group Operator + * \{ */ static bool node_group_make_use_node(bNode *node, bNode *gnode) { @@ -1036,7 +1060,11 @@ void NODE_OT_group_make(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/* ****************** Group Insert operator ******************* */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Group Insert Operator + * \{ */ static int node_group_insert_exec(bContext *C, wmOperator *op) { @@ -1086,3 +1114,5 @@ void NODE_OT_group_insert(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } + +/** \} */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 04e452d5270..aa59b7293a3 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -266,7 +266,7 @@ extern const char *node_context_dir[]; #define NODE_SOCKDY (0.08f * U.widget_unit) #define NODE_WIDTH(node) (node->width * UI_DPI_FAC) #define NODE_HEIGHT(node) (node->height * UI_DPI_FAC) -#define NODE_MARGIN_X (0.95f * U.widget_unit) +#define NODE_MARGIN_X (1.10f * U.widget_unit) #define NODE_SOCKSIZE (0.25f * U.widget_unit) #define NODE_RESIZE_MARGIN (0.20f * U.widget_unit) #define NODE_LINK_RESOL 12 diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c index ef7e7874c63..3c861896d37 100644 --- a/source/blender/editors/space_node/node_view.c +++ b/source/blender/editors/space_node/node_view.c @@ -55,7 +55,9 @@ #include "NOD_composite.h" #include "node_intern.h" /* own include */ -/* **************** View All Operator ************** */ +/* -------------------------------------------------------------------- */ +/** \name View All Operator + * \{ */ int space_node_view_flag( bContext *C, SpaceNode *snode, ARegion *region, const int node_flag, const int smooth_viewtx) @@ -151,6 +153,12 @@ void NODE_OT_view_all(wmOperatorType *ot) ot->flag = 0; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name View Selected Operator + * \{ */ + static int node_view_selected_exec(bContext *C, wmOperator *op) { ARegion *region = CTX_wm_region(C); @@ -178,7 +186,11 @@ void NODE_OT_view_selected(wmOperatorType *ot) ot->flag = 0; } -/* **************** Background Image Operators ************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Background Image Operators + * \{ */ typedef struct NodeViewMove { int mvalo[2]; @@ -284,6 +296,12 @@ void NODE_OT_backimage_move(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR_XY; } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Background Image Zoom + * \{ */ + static int backimage_zoom_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); @@ -316,6 +334,12 @@ void NODE_OT_backimage_zoom(wmOperatorType *ot) RNA_def_float(ot->srna, "factor", 1.2f, 0.0f, 10.0f, "Factor", "", 0.0f, 10.0f); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Background Image Fit + * \{ */ + static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); @@ -372,7 +396,11 @@ void NODE_OT_backimage_fit(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING; } -/******************** sample backdrop operator ********************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sample Backdrop Operator + * \{ */ typedef struct ImageSampleInfo { ARegionType *art; @@ -642,3 +670,5 @@ void NODE_OT_backimage_sample(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_BLOCKING; } + +/** \} */ diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 779efc3cacb..0d7255b5558 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -440,7 +440,7 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto ID *id = tselem->id; BLI_assert(id != NULL); - BLI_assert((tselem->type == 0 && te->idcode != 0) || tselem->type == TSE_LAYER_COLLECTION); + BLI_assert(ELEM(tselem->type, 0 && te->idcode != 0, TSE_LAYER_COLLECTION)); UNUSED_VARS_NDEBUG(te); if (te->idcode == ID_LI && ((Library *)id)->parent != NULL) { diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c index 688f6d646ff..703624f5735 100644 --- a/source/blender/editors/space_outliner/outliner_select.c +++ b/source/blender/editors/space_outliner/outliner_select.c @@ -27,12 +27,16 @@ #include "DNA_armature_types.h" #include "DNA_collection_types.h" +#include "DNA_constraint_types.h" +#include "DNA_gpencil_modifier_types.h" #include "DNA_gpencil_types.h" #include "DNA_light_types.h" #include "DNA_material_types.h" +#include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_sequence_types.h" +#include "DNA_shader_fx_types.h" #include "DNA_world_types.h" #include "BLI_listbase.h" @@ -40,21 +44,26 @@ #include "BKE_armature.h" #include "BKE_collection.h" +#include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" #include "BKE_layer.h" #include "BKE_main.h" +#include "BKE_modifier.h" #include "BKE_object.h" #include "BKE_paint.h" +#include "BKE_particle.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" +#include "BKE_shader_fx.h" #include "BKE_workspace.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "ED_armature.h" +#include "ED_buttons.h" #include "ED_gpencil.h" #include "ED_object.h" #include "ED_outliner.h" @@ -63,6 +72,8 @@ #include "ED_sequencer.h" #include "ED_undo.h" +#include "SEQ_sequencer.h" + #include "WM_api.h" #include "WM_toolsystem.h" #include "WM_types.h" @@ -801,15 +812,26 @@ static eOLDrawState tree_element_active_psys(bContext *C, } static int tree_element_active_constraint(bContext *C, - Scene *UNUSED(scene), - ViewLayer *UNUSED(sl), - TreeElement *UNUSED(te), + Scene *scene, + ViewLayer *view_layer, + TreeElement *te, TreeStoreElem *tselem, const eOLSetState set) { if (set != OL_SETSEL_NONE) { Object *ob = (Object *)tselem->id; + /* Activate the parent bone if this is a bone constraint. */ + te = te->parent; + while (te) { + tselem = TREESTORE(te); + if (tselem->type == TSE_POSE_CHANNEL) { + tree_element_active_posechannel(C, scene, view_layer, ob, te, tselem, set, false); + return OL_DRAWSEL_NONE; + } + te = te->parent; + } + WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob); } @@ -1041,6 +1063,7 @@ eOLDrawState tree_element_type_active(bContext *C, case TSE_POSE_CHANNEL: return tree_element_active_posechannel( C, tvc->scene, tvc->view_layer, tvc->ob_pose, te, tselem, set, recursive); + case TSE_CONSTRAINT_BASE: case TSE_CONSTRAINT: return tree_element_active_constraint(C, tvc->scene, tvc->view_layer, te, tselem, set); case TSE_R_LAYER: @@ -1081,6 +1104,169 @@ bPoseChannel *outliner_find_parent_bone(TreeElement *te, TreeElement **r_bone_te return NULL; } +static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreElem *tselem) +{ + PointerRNA ptr = {0}; + int context = 0; + + /* ID Types */ + if (tselem->type == 0) { + RNA_id_pointer_create(tselem->id, &ptr); + + switch (te->idcode) { + case ID_SCE: + context = BCONTEXT_SCENE; + break; + case ID_OB: + context = BCONTEXT_OBJECT; + break; + case ID_ME: + case ID_CU: + case ID_MB: + case ID_IM: + case ID_LT: + case ID_LA: + case ID_CA: + case ID_KE: + case ID_SPK: + case ID_AR: + case ID_GD: + case ID_LP: + case ID_HA: + case ID_PT: + case ID_VO: + context = BCONTEXT_DATA; + break; + case ID_MA: + context = BCONTEXT_MATERIAL; + break; + case ID_WO: + context = BCONTEXT_WORLD; + break; + } + } + else { + switch (tselem->type) { + case TSE_DEFGROUP_BASE: + case TSE_DEFGROUP: + RNA_id_pointer_create(tselem->id, &ptr); + context = BCONTEXT_DATA; + break; + case TSE_CONSTRAINT_BASE: + case TSE_CONSTRAINT: { + TreeElement *bone_te = NULL; + bPoseChannel *pchan = outliner_find_parent_bone(te, &bone_te); + + if (pchan) { + RNA_pointer_create(TREESTORE(bone_te)->id, &RNA_PoseBone, pchan, &ptr); + context = BCONTEXT_BONE_CONSTRAINT; + } + else { + RNA_id_pointer_create(tselem->id, &ptr); + context = BCONTEXT_CONSTRAINT; + } + + /* Expand the selected constraint in the properties editor. */ + if (tselem->type != TSE_CONSTRAINT_BASE) { + BKE_constraint_panel_expand(te->directdata); + } + break; + } + case TSE_MODIFIER_BASE: + case TSE_MODIFIER: + RNA_id_pointer_create(tselem->id, &ptr); + context = BCONTEXT_MODIFIER; + + if (tselem->type != TSE_MODIFIER_BASE) { + Object *ob = (Object *)tselem->id; + + if (ob->type == OB_GPENCIL) { + BKE_gpencil_modifier_panel_expand(te->directdata); + } + else { + BKE_modifier_panel_expand(te->directdata); + } + } + break; + case TSE_GPENCIL_EFFECT_BASE: + case TSE_GPENCIL_EFFECT: + RNA_id_pointer_create(tselem->id, &ptr); + context = BCONTEXT_SHADERFX; + + if (tselem->type != TSE_GPENCIL_EFFECT_BASE) { + BKE_shaderfx_panel_expand(te->directdata); + } + break; + case TSE_BONE: { + bArmature *arm = (bArmature *)tselem->id; + Bone *bone = te->directdata; + + RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr); + context = BCONTEXT_BONE; + break; + } + case TSE_EBONE: { + bArmature *arm = (bArmature *)tselem->id; + EditBone *ebone = te->directdata; + + RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &ptr); + context = BCONTEXT_BONE; + break; + } + case TSE_POSE_CHANNEL: { + Object *ob = (Object *)tselem->id; + bArmature *arm = ob->data; + bPoseChannel *pchan = te->directdata; + + RNA_pointer_create(&arm->id, &RNA_PoseBone, pchan, &ptr); + context = BCONTEXT_BONE; + break; + } + case TSE_POSE_BASE: { + Object *ob = (Object *)tselem->id; + bArmature *arm = ob->data; + + RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr); + context = BCONTEXT_DATA; + break; + } + case TSE_R_LAYER_BASE: + case TSE_R_LAYER: { + ViewLayer *view_layer = te->directdata; + + RNA_pointer_create(tselem->id, &RNA_ViewLayer, view_layer, &ptr); + context = BCONTEXT_VIEW_LAYER; + break; + } + case TSE_POSEGRP_BASE: + case TSE_POSEGRP: { + Object *ob = (Object *)tselem->id; + bArmature *arm = ob->data; + + RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr); + context = BCONTEXT_DATA; + break; + } + case TSE_LINKED_PSYS: { + Object *ob = (Object *)tselem->id; + ParticleSystem *psys = psys_get_current(ob); + + RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &ptr); + context = BCONTEXT_PARTICLE; + break; + } + case TSE_GP_LAYER: + RNA_id_pointer_create(tselem->id, &ptr); + context = BCONTEXT_DATA; + break; + } + } + + if (ptr.data) { + ED_buttons_set_context(C, &ptr, context); + } +} + /* ================================================ */ /** @@ -1105,14 +1291,8 @@ static void do_outliner_item_activate_tree_element(bContext *C, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) { - /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, - * we do not want to switch out of edit mode (see T48328 for details). */ - } - else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) { - /* Support edit-mode toggle, keeping the active object as is. */ - } - else if (tselem->type == TSE_POSE_BASE) { - /* Support pose mode toggle, keeping the active object as is. */ + /* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several + * objects, we do not want to switch out of edit mode (see T48328 for details). */ } else if (do_activate_data) { tree_element_set_active_object(C, @@ -1187,6 +1367,8 @@ static void do_outliner_item_activate_tree_element(bContext *C, extend ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL, recursive); } + + outliner_set_properties_tab(C, te, tselem); } /* Select the item using the set flags */ @@ -1242,7 +1424,7 @@ static bool do_outliner_range_select_recursive(ListBase *lb, } /* Set state for selection */ - if (te == active || te == cursor) { + if (ELEM(te, active, cursor)) { selecting = !selecting; } diff --git a/source/blender/editors/space_outliner/outliner_sync.c b/source/blender/editors/space_outliner/outliner_sync.c index 24fa72fdabf..4591a545783 100644 --- a/source/blender/editors/space_outliner/outliner_sync.c +++ b/source/blender/editors/space_outliner/outliner_sync.c @@ -39,7 +39,6 @@ #include "BKE_layer.h" #include "BKE_main.h" #include "BKE_object.h" -#include "BKE_sequencer.h" #include "DEG_depsgraph.h" @@ -47,6 +46,8 @@ #include "ED_object.h" #include "ED_outliner.h" +#include "SEQ_sequencer.h" + #include "WM_api.h" #include "WM_types.h" diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index cbdeb350ba4..159a4616ba7 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -65,7 +65,6 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -89,6 +88,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_sequencer.h" + #include "outliner_intern.h" /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 4fbb394c38f..9cd38ac07f5 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -69,7 +69,6 @@ #include "BKE_main.h" #include "BKE_modifier.h" #include "BKE_outliner_treehash.h" -#include "BKE_sequencer.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" @@ -81,6 +80,8 @@ #include "RNA_access.h" +#include "SEQ_sequencer.h" + #include "UI_interface.h" #include "outliner_intern.h" @@ -2206,6 +2207,9 @@ static int outliner_exclude_filter_get(const SpaceOutliner *space_outliner) case SO_FILTER_OB_ACTIVE: exclude_filter |= SO_FILTER_OB_STATE_ACTIVE; break; + case SO_FILTER_OB_SELECTABLE: + exclude_filter |= SO_FILTER_OB_STATE_SELECTABLE; + break; } return exclude_filter; @@ -2288,6 +2292,11 @@ static bool outliner_element_visible_get(ViewLayer *view_layer, return false; } } + else if (exclude_filter & SO_FILTER_OB_STATE_SELECTABLE) { + if ((base->flag & BASE_SELECTABLE) == 0) { + return false; + } + } else { BLI_assert(exclude_filter & SO_FILTER_OB_STATE_ACTIVE); if (base != BASACT(view_layer)) { diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 0725109944a..7335882e947 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -43,7 +43,6 @@ #include "BKE_mask.h" #include "BKE_movieclip.h" #include "BKE_report.h" -#include "BKE_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -51,6 +50,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_sequencer.h" + /* For menu, popup, icons, etc. */ #include "ED_screen.h" #include "ED_sequencer.h" @@ -314,7 +315,7 @@ static bool seq_effect_add_properties_poll(const bContext *UNUSED(C), /* Hide start/end frames for effect strips that are locked to their parents' location. */ if (BKE_sequence_effect_get_num_inputs(type) != 0) { - if ((STREQ(prop_id, "frame_start")) || (STREQ(prop_id, "frame_end"))) { + if (STR_ELEM(prop_id, "frame_start", "frame_end")) { return false; } } @@ -638,8 +639,7 @@ static bool sequencer_add_draw_check_fn(PointerRNA *UNUSED(ptr), { const char *prop_id = RNA_property_identifier(prop); - return !(STREQ(prop_id, "filepath") || STREQ(prop_id, "directory") || - STREQ(prop_id, "filename")); + return !(STR_ELEM(prop_id, "filepath", "directory", "filename")); } static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op) @@ -724,7 +724,7 @@ void SEQUENCER_OT_movie_strip_add(struct wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "sound", true, "Sound", "Load sound with the movie"); RNA_def_boolean(ot->srna, @@ -779,7 +779,7 @@ void SEQUENCER_OT_sound_strip_add(struct wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME); RNA_def_boolean(ot->srna, "cache", false, "Cache", "Cache the sound in memory"); RNA_def_boolean(ot->srna, "mono", false, "Mono", "Merge all the sound's channels into one"); @@ -902,7 +902,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op) } } - BKE_sequence_init_colorspace(seq); + SEQ_render_init_colorspace(seq); BKE_sequence_calc_disp(scene, seq); BKE_sequencer_sort(scene); @@ -971,7 +971,7 @@ void SEQUENCER_OT_image_strip_add(struct wmOperatorType *ot) WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_SHOW_PROPS | WM_FILESEL_DIRECTORY, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); sequencer_generic_props__internal(ot, SEQPROP_STARTFRAME | SEQPROP_ENDFRAME); RNA_def_boolean(ot->srna, diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index e9c5b003420..7e23f4ed281 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -44,7 +44,6 @@ #include "BKE_fcurve.h" #include "BKE_global.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "IMB_colormanagement.h" @@ -69,6 +68,8 @@ #include "BIF_glutil.h" +#include "SEQ_sequencer.h" + #include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -625,7 +626,7 @@ static void draw_seq_text(View2D *v2d, name = BKE_sequence_give_name(seq); } - if (seq->type == SEQ_TYPE_META || seq->type == SEQ_TYPE_ADJUSTMENT) { + if (ELEM(seq->type, SEQ_TYPE_META, SEQ_TYPE_ADJUSTMENT)) { str_len = BLI_snprintf(str, sizeof(str), "%s | %d", name, seq->len); } else if (seq->type == SEQ_TYPE_SCENE) { @@ -1258,13 +1259,13 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, render_size = scene->r.size / 100.0; } else { - render_size = BKE_sequencer_rendersize_to_scale_factor(sseq->render_size); + render_size = SEQ_rendersize_to_scale_factor(sseq->render_size); } rectx = roundf(render_size * scene->r.xsch); recty = roundf(render_size * scene->r.ysch); - BKE_sequencer_new_render_data( + SEQ_render_new_render_data( bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context); context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname); @@ -1284,10 +1285,10 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, } if (special_seq_update) { - ibuf = BKE_sequencer_give_ibuf_direct(&context, cfra + frame_ofs, special_seq_update); + ibuf = SEQ_render_give_ibuf_direct(&context, cfra + frame_ofs, special_seq_update); } else { - ibuf = BKE_sequencer_give_ibuf(&context, cfra + frame_ofs, sseq->chanshown); + ibuf = SEQ_render_give_ibuf(&context, cfra + frame_ofs, sseq->chanshown); } if (viewport) { @@ -2085,7 +2086,7 @@ static bool draw_cache_view_init_fn(void *userdata, size_t item_count) /* Called as a callback */ static bool draw_cache_view_iter_fn( - void *userdata, struct Sequence *seq, int nfra, int cache_type, float UNUSED(cost)) + void *userdata, struct Sequence *seq, int timeline_frame, int cache_type, float UNUSED(cost)) { CacheDrawData *drawdata = userdata; struct View2D *v2d = drawdata->v2d; @@ -2131,14 +2132,13 @@ static bool draw_cache_view_iter_fn( return false; } - int cfra = seq->start + nfra; float vert_pos[6][2]; - copy_v2_fl2(vert_pos[0], cfra, stripe_bot); - copy_v2_fl2(vert_pos[1], cfra, stripe_top); - copy_v2_fl2(vert_pos[2], cfra + 1, stripe_top); + copy_v2_fl2(vert_pos[0], timeline_frame, stripe_bot); + copy_v2_fl2(vert_pos[1], timeline_frame, stripe_top); + copy_v2_fl2(vert_pos[2], timeline_frame + 1, stripe_top); copy_v2_v2(vert_pos[3], vert_pos[2]); copy_v2_v2(vert_pos[4], vert_pos[0]); - copy_v2_fl2(vert_pos[5], cfra + 1, stripe_bot); + copy_v2_fl2(vert_pos[5], timeline_frame + 1, stripe_bot); for (int i = 0; i < 6; i++) { GPU_vertbuf_vert_set(vbo, *vert_count + i, vert_pos[i]); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 8a705ef49dd..8f3a3ba50a0 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -43,9 +43,10 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_report.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" +#include "SEQ_sequencer.h" + #include "WM_api.h" #include "WM_types.h" @@ -97,11 +98,11 @@ EnumPropertyItem sequencer_prop_effect_types[] = { #define SEQ_SIDE_MOUSE -1 EnumPropertyItem prop_side_types[] = { - {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse position", ""}, + {SEQ_SIDE_MOUSE, "MOUSE", 0, "Mouse Position", ""}, {SEQ_SIDE_LEFT, "LEFT", 0, "Left", ""}, {SEQ_SIDE_RIGHT, "RIGHT", 0, "Right", ""}, {SEQ_SIDE_BOTH, "BOTH", 0, "Both", ""}, - {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No change", ""}, + {SEQ_SIDE_NO_CHANGE, "NO_CHANGE", 0, "No Change", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -153,7 +154,7 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog for (link = pj->queue.first; link; link = link->next) { struct SeqIndexBuildContext *context = link->data; - BKE_sequencer_proxy_rebuild(context, stop, do_update, progress); + SEQ_proxy_rebuild(context, stop, do_update, progress); if (*stop) { pj->stop = 1; @@ -170,7 +171,7 @@ static void proxy_endjob(void *pjv) LinkData *link; for (link = pj->queue.first; link; link = link->next) { - BKE_sequencer_proxy_rebuild_finish(link->data, pj->stop); + SEQ_proxy_rebuild_finish(link->data, pj->stop); } BKE_sequencer_free_imbuf(pj->scene, &ed->seqbase, false); @@ -233,7 +234,7 @@ static void seq_proxy_build_job(const bContext *C, ReportList *reports) continue; } - bool success = BKE_sequencer_proxy_rebuild_context( + bool success = SEQ_proxy_rebuild_context( pj->main, pj->depsgraph, pj->scene, seq, file_list, &pj->queue); if (!success && (seq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) != 0) { @@ -588,7 +589,7 @@ int seq_effect_find_selected(Scene *scene, *r_error_str = N_("Cannot apply effects to audio sequence strips"); return 0; } - if ((seq != activeseq) && (seq != seq2)) { + if (!ELEM(seq, activeseq, seq2)) { if (seq2 == NULL) { seq2 = seq; } @@ -1105,7 +1106,7 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) /* Check if the current frame has a gap already. */ for (cfra = CFRA; cfra >= sfra; cfra--) { - if (BKE_sequencer_evaluate_frame(scene, cfra)) { + if (SEQ_render_evaluate_frame(scene, cfra)) { first = true; break; } @@ -1114,13 +1115,13 @@ static int sequencer_gap_remove_exec(bContext *C, wmOperator *op) for (; cfra < efra; cfra++) { /* There's still no strip to remove a gap for. */ if (first == false) { - if (BKE_sequencer_evaluate_frame(scene, cfra)) { + if (SEQ_render_evaluate_frame(scene, cfra)) { first = true; } } - else if (BKE_sequencer_evaluate_frame(scene, cfra) == 0) { + else if (SEQ_render_evaluate_frame(scene, cfra) == 0) { done = true; - while (BKE_sequencer_evaluate_frame(scene, cfra) == 0) { + while (SEQ_render_evaluate_frame(scene, cfra) == 0) { done = sequence_offset_after_frame(scene, -1, cfra); if (done == false) { break; @@ -2680,7 +2681,7 @@ static int sequencer_separate_images_exec(bContext *C, wmOperator *op) while (cfra < frame_end) { /* New seq. */ - se = BKE_sequencer_give_stripelem(seq, cfra); + se = SEQ_render_give_stripelem(seq, cfra); seq_new = BKE_sequence_dupli_recursive( scene, scene, ed->seqbasep, seq, SEQ_DUPE_UNIQUE_NAME); @@ -3220,7 +3221,7 @@ static int sequencer_rendersize_exec(bContext *C, wmOperator *UNUSED(op)) if (active_seq->strip) { switch (active_seq->type) { case SEQ_TYPE_IMAGE: - se = BKE_sequencer_give_stripelem(active_seq, scene->r.cfra); + se = SEQ_render_give_stripelem(active_seq, scene->r.cfra); break; case SEQ_TYPE_MOVIE: se = active_seq->strip->stripdata; @@ -3504,12 +3505,12 @@ static int sequencer_rebuild_proxy_exec(bContext *C, wmOperator *UNUSED(op)) short stop = 0, do_update; float progress; - BKE_sequencer_proxy_rebuild_context(bmain, depsgraph, scene, seq, file_list, &queue); + SEQ_proxy_rebuild_context(bmain, depsgraph, scene, seq, file_list, &queue); for (link = queue.first; link; link = link->next) { struct SeqIndexBuildContext *context = link->data; - BKE_sequencer_proxy_rebuild(context, &stop, &do_update, &progress); - BKE_sequencer_proxy_rebuild_finish(context, 0); + SEQ_proxy_rebuild(context, &stop, &do_update, &progress); + SEQ_proxy_rebuild_finish(context, 0); } BKE_sequencer_free_imbuf(scene, &ed->seqbase, false); } @@ -3568,7 +3569,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op) SEQ_CURRENT_BEGIN (ed, seq) { if ((seq->flag & SELECT)) { if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE, SEQ_TYPE_META)) { - BKE_sequencer_proxy_set(seq, turnon); + SEQ_proxy_set(seq, turnon); if (seq->strip->proxy == NULL) { continue; } @@ -3918,7 +3919,7 @@ void SEQUENCER_OT_change_path(struct wmOperatorType *ot) WM_FILESEL_DIRECTORY | WM_FILESEL_RELPATH | WM_FILESEL_FILEPATH | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "use_placeholders", false, @@ -4063,7 +4064,7 @@ void SEQUENCER_OT_export_subtitles(struct wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ diff --git a/source/blender/editors/space_sequencer/sequencer_modifier.c b/source/blender/editors/space_sequencer/sequencer_modifier.c index 50f2a5084ef..fb09afc6ca5 100644 --- a/source/blender/editors/space_sequencer/sequencer_modifier.c +++ b/source/blender/editors/space_sequencer/sequencer_modifier.c @@ -27,7 +27,6 @@ #include "DNA_scene_types.h" #include "BKE_context.h" -#include "BKE_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -35,6 +34,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "SEQ_sequencer.h" + /* Own include. */ #include "sequencer_intern.h" diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index 0a7aa1a6072..bdf6e4ece7f 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -34,7 +34,7 @@ #include "ED_sequencer.h" #include "ED_transform.h" /* Transform keymap. */ -#include "BKE_sequencer.h" +#include "SEQ_sequencer.h" #include "sequencer_intern.h" diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 0a4a1ae92d9..f7c8c35d563 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -33,13 +33,14 @@ #include "BKE_context.h" #include "BKE_report.h" -#include "BKE_sequencer.h" #include "WM_api.h" #include "WM_types.h" #include "RNA_define.h" +#include "SEQ_sequencer.h" + /* For menu, popup, icons, etc. */ #include "ED_outliner.h" @@ -205,7 +206,7 @@ void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool desel BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { if (seq->strip) { BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } @@ -465,7 +466,7 @@ static int sequencer_select_exec(bContext *C, wmOperator *op) BKE_sequencer_active_set(scene, seq); - if ((seq->type == SEQ_TYPE_IMAGE) || (seq->type == SEQ_TYPE_MOVIE)) { + if (ELEM(seq->type, SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE)) { if (seq->strip) { BLI_strncpy(ed->act_imagedir, seq->strip->dir, FILE_MAXDIR); } diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c index 491c475b596..75d92d5f00d 100644 --- a/source/blender/editors/space_sequencer/sequencer_view.c +++ b/source/blender/editors/space_sequencer/sequencer_view.c @@ -28,7 +28,6 @@ #include "DNA_scene_types.h" #include "BKE_context.h" -#include "BKE_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -39,6 +38,8 @@ #include "RNA_define.h" +#include "SEQ_sequencer.h" + /* For menu, popup, icons, etc. */ #include "ED_anim_api.h" #include "ED_screen.h" diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c index 289477c8353..45c7bac54f8 100644 --- a/source/blender/editors/space_sequencer/space_sequencer.c +++ b/source/blender/editors/space_sequencer/space_sequencer.c @@ -38,7 +38,6 @@ #include "BKE_global.h" #include "BKE_lib_id.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "BKE_sequencer_offscreen.h" #include "ED_screen.h" @@ -52,6 +51,8 @@ #include "RNA_access.h" +#include "SEQ_sequencer.h" + #include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index d3e6fd8f79c..2c9ea1d6afa 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -285,7 +285,7 @@ void wrap_offset( end += max; chop = 1; } - else if (ch == ' ' || ch == '-') { + else if (ELEM(ch, ' ', '-')) { end = i + 1; chop = 0; if (linep == linein && i >= cursin) { @@ -362,7 +362,7 @@ void wrap_offset_in_line( end += max; chop = 1; } - else if (ch == ' ' || ch == '-') { + else if (ELEM(ch, ' ', '-')) { end = i + 1; chop = 0; if (i >= cursin) { @@ -483,7 +483,7 @@ static int text_draw_wrapped(const SpaceText *st, break; } } - else if (str[mi] == ' ' || str[mi] == '-') { + else if (ELEM(str[mi], ' ', '-')) { wrap = i + 1; mend = mi + 1; } @@ -820,7 +820,7 @@ int text_get_visible_lines(const SpaceText *st, ARegion *region, const char *str start = MIN2(end, i); end += max; } - else if (ch == ' ' || ch == '-') { + else if (ELEM(ch, ' ', '-')) { end = i + 1; } diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c index 4f6d91451e0..16eb66624ce 100644 --- a/source/blender/editors/space_text/text_format_lua.c +++ b/source/blender/editors/space_text/text_format_lua.c @@ -271,7 +271,7 @@ static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const bool do_ else if (*str == '-' && *(str + 1) == '-') { text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format)); } - else if (*str == '"' || *str == '\'') { + else if (ELEM(*str, '"', '\'')) { /* Strings */ find = *str; cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE; diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c index b205996d1d2..1a024779a83 100644 --- a/source/blender/editors/space_text/text_format_osl.c +++ b/source/blender/editors/space_text/text_format_osl.c @@ -292,7 +292,7 @@ static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const bool do_ str++; *fmt = FMT_TYPE_COMMENT; } - else if (*str == '"' || *str == '\'') { + else if (ELEM(*str, '"', '\'')) { /* Strings */ find = *str; cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE; diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c index 96d9c234a40..a68632c0d56 100644 --- a/source/blender/editors/space_text/text_format_pov.c +++ b/source/blender/editors/space_text/text_format_pov.c @@ -864,7 +864,7 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_ else if (*str == '/' && *(str + 1) == '/') { text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format)); } - else if (*str == '"' || *str == '\'') { + else if (ELEM(*str, '"', '\'')) { /* Strings */ find = *str; cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE; diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c index 8d6b877d3f7..1c6a93d2d7a 100644 --- a/source/blender/editors/space_text/text_format_pov_ini.c +++ b/source/blender/editors/space_text/text_format_pov_ini.c @@ -442,7 +442,7 @@ static void txtfmt_pov_ini_format_line(SpaceText *st, TextLine *line, const bool if (*str == ';') { text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format)); } - else if (*str == '"' || *str == '\'') { + else if (ELEM(*str, '"', '\'')) { /* Strings */ find = *str; cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE; diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c index 39985438462..31177c53d6a 100644 --- a/source/blender/editors/space_text/text_format_py.c +++ b/source/blender/editors/space_text/text_format_py.c @@ -224,7 +224,7 @@ static uint txtfmt_py_numeral_string_count_hexadecimal(const char *string) /* Zeros. */ static bool txtfmt_py_numeral_char_is_zero(const char c) { - return (c == '0') || (c == '_'); + return (ELEM(c, '0', '_')); } static uint txtfmt_py_numeral_string_count_zeros(const char *string) { @@ -408,7 +408,7 @@ static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const bool do_n /* fill the remaining line */ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format)); } - else if (*str == '"' || *str == '\'') { + else if (ELEM(*str, '"', '\'')) { /* Strings */ find = *str; cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE; diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 5c7f84ea386..52a5ff609d8 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -159,6 +159,15 @@ static bool text_new_poll(bContext *UNUSED(C)) return 1; } +static bool text_data_poll(bContext *C) +{ + Text *text = CTX_data_edit_text(C); + if (!text) { + return false; + } + return true; +} + static bool text_edit_poll(bContext *C) { Text *text = CTX_data_edit_text(C); @@ -407,9 +416,9 @@ void TEXT_OT_open(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); /* TODO: relative_path. */ + FILE_SORT_DEFAULT); /* TODO: relative_path. */ RNA_def_boolean( - ot->srna, "internal", 0, "Make internal", "Make text file internal after loading"); + ot->srna, "internal", 0, "Make Internal", "Make text file internal after loading"); } /** \} */ @@ -573,17 +582,6 @@ void TEXT_OT_make_internal(wmOperatorType *ot) /** \name Save Operator * \{ */ -static bool text_save_poll(bContext *C) -{ - Text *text = CTX_data_edit_text(C); - - if (!text_edit_poll(C)) { - return 0; - } - - return (text->filepath != NULL && !(text->flags & TXT_ISMEM)); -} - static void txt_write_file(Main *bmain, Text *text, ReportList *reports) { FILE *fp; @@ -594,6 +592,13 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports) BLI_strncpy(filepath, text->filepath, FILE_MAX); BLI_path_abs(filepath, BKE_main_blendfile_path(bmain)); + /* Check if file write permission is ok. */ + if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) { + BKE_reportf( + reports, RPT_ERROR, "Cannot save text file, path \"%s\" is not writable", filepath); + return; + } + fp = BLI_fopen(filepath, "w"); if (fp == NULL) { BKE_reportf(reports, @@ -616,8 +621,8 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports) if (BLI_stat(filepath, &st) == 0) { text->mtime = st.st_mtime; - /* report since this can be called from key-shortcuts */ - BKE_reportf(reports, RPT_INFO, "Saved Text '%s'", filepath); + /* Report since this can be called from key shortcuts. */ + BKE_reportf(reports, RPT_INFO, "Saved text \"%s\"", filepath); } else { text->mtime = 0; @@ -644,6 +649,18 @@ static int text_save_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int text_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Text *text = CTX_data_edit_text(C); + + /* Internal and texts without a filepath will go to "Save As". */ + if (text->filepath == NULL || (text->flags & TXT_ISMEM)) { + WM_operator_name_call(C, "TEXT_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL); + return OPERATOR_CANCELLED; + } + return text_save_exec(C, op); +} + void TEXT_OT_save(wmOperatorType *ot) { /* identifiers */ @@ -653,7 +670,8 @@ void TEXT_OT_save(wmOperatorType *ot) /* api callbacks */ ot->exec = text_save_exec; - ot->poll = text_save_poll; + ot->invoke = text_save_invoke; + ot->poll = text_edit_poll; } /** \} */ @@ -733,7 +751,7 @@ void TEXT_OT_save_as(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); /* XXX TODO, relative_path. */ + FILE_SORT_DEFAULT); /* XXX TODO, relative_path. */ } /** \} */ @@ -742,11 +760,6 @@ void TEXT_OT_save_as(wmOperatorType *ot) /** \name Run Script Operator * \{ */ -static bool text_run_script_poll(bContext *C) -{ - return (CTX_data_edit_text(C) != NULL); -} - static int text_run_script(bContext *C, ReportList *reports) { #ifdef WITH_PYTHON @@ -808,7 +821,7 @@ void TEXT_OT_run_script(wmOperatorType *ot) ot->description = "Run active script"; /* api callbacks */ - ot->poll = text_run_script_poll; + ot->poll = text_data_poll; ot->exec = text_run_script_exec; /* flags */ @@ -1709,7 +1722,7 @@ static int text_get_cursor_rel( loop = 0; break; } - else if (ch == ' ' || ch == '-') { + else if (ELEM(ch, ' ', '-')) { if (found) { loop = 0; break; @@ -1884,7 +1897,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *region, const bool sel) end += max; chop = 1; } - else if (ch == ' ' || ch == '-' || ch == '\0') { + else if (ELEM(ch, ' ', '-', '\0')) { if (j >= oldc) { *charp = BLI_str_utf8_offset_from_column((*linep)->line, start); loop = 0; @@ -1974,7 +1987,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *region, const bool sel) loop = 0; break; } - else if (ch == ' ' || ch == '-') { + else if (ELEM(ch, ' ', '-')) { end = i + 1; endj = j; chop = 0; @@ -3052,7 +3065,7 @@ static void text_cursor_set_to_pos_wrapped( break; } } - else if (ch == ' ' || ch == '-' || ch == '\0') { + else if (ELEM(ch, ' ', '-', '\0')) { if (found) { break; } @@ -3693,7 +3706,7 @@ void TEXT_OT_replace(wmOperatorType *ot) /* properties */ PropertyRNA *prop; - prop = RNA_def_boolean(ot->srna, "all", false, "Replace all", "Replace all occurrences"); + prop = RNA_def_boolean(ot->srna, "all", false, "Replace All", "Replace all occurrences"); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } @@ -3781,6 +3794,17 @@ static const EnumPropertyItem resolution_items[] = { {0, NULL, 0, NULL, NULL}, }; +static bool text_resolve_conflict_poll(bContext *C) +{ + Text *text = CTX_data_edit_text(C); + + if (!text_edit_poll(C)) { + return false; + } + + return ((text->filepath != NULL) && !(text->flags & TXT_ISMEM)); +} + static int text_resolve_conflict_exec(bContext *C, wmOperator *op) { Text *text = CTX_data_edit_text(C); @@ -3872,7 +3896,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot) /* api callbacks */ ot->exec = text_resolve_conflict_exec; ot->invoke = text_resolve_conflict_invoke; - ot->poll = text_save_poll; + ot->poll = text_resolve_conflict_poll; /* properties */ RNA_def_enum(ot->srna, @@ -3891,7 +3915,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot) static int text_to_3d_object_exec(bContext *C, wmOperator *op) { - Text *text = CTX_data_edit_text(C); + const Text *text = CTX_data_edit_text(C); const bool split_lines = RNA_boolean_get(op->ptr, "split_lines"); ED_text_to_object(C, text, split_lines); @@ -3908,7 +3932,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot) /* api callbacks */ ot->exec = text_to_3d_object_exec; - ot->poll = text_edit_poll; + ot->poll = text_data_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index d7ef03453f3..5ae012ce5dd 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -153,7 +153,7 @@ bool ED_view3d_area_user_region(const ScrArea *area, const View3D *v3d, ARegion rv3d = region->regiondata; if ((rv3d->viewlock & RV3D_LOCK_ROTATION) == 0) { region_unlock = region; - if (rv3d->persp == RV3D_PERSP || rv3d->persp == RV3D_CAMOB) { + if (ELEM(rv3d->persp, RV3D_PERSP, RV3D_CAMOB)) { region_unlock_user = region; break; } diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 8e03ed6e11d..36da0791c4f 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -280,10 +280,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float has_meshdata = (tot || totedgedata); } - else if (ob->type == OB_CURVE || ob->type == OB_SURF) { + else if (ELEM(ob->type, OB_CURVE, OB_SURF)) { TransformMedian_Curve *median = &median_basis.curve; Curve *cu = ob->data; - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; @@ -291,8 +290,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float StructRNA *seltype = NULL; void *selp = NULL; - nu = nurbs->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { if (nu->type == CU_BEZIER) { bezt = nu->bezt; a = nu->pntsu; @@ -343,7 +341,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float bp++; } } - nu = nu->next; } if (totcurvedata == 1) { @@ -973,15 +970,13 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float const TransformMedian_Curve *median = &median_basis.curve, *ve_median = &ve_median_basis.curve; Curve *cu = ob->data; - Nurb *nu; BPoint *bp; BezTriple *bezt; int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); const float scale_w = compute_scale_factor(ve_median->weight, median->weight); - nu = nurbs->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { if (nu->type == CU_BEZIER) { for (a = nu->pntsu, bezt = nu->bezt; a--; bezt++) { if (bezt->f2 & SELECT) { @@ -1038,8 +1033,6 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } BKE_nurb_test_2d(nu); BKE_nurb_handles_test(nu, true, false); /* test for bezier too */ - - nu = nu->next; } } else if ((ob->type == OB_LATTICE) && (apply_vcos || median_basis.lattice.weight)) { diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c index 1d5b33e7b90..bce0e49d60a 100644 --- a/source/blender/editors/space_view3d/view3d_camera_control.c +++ b/source/blender/editors/space_view3d/view3d_camera_control.c @@ -127,8 +127,7 @@ Object *ED_view3d_cameracontrol_object_get(View3DCameraControl *vctrl) struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph, Scene *scene, View3D *v3d, - RegionView3D *rv3d, - const bool use_parent_root) + RegionView3D *rv3d) { View3DCameraControl *vctrl; @@ -139,7 +138,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph vctrl->ctx_v3d = v3d; vctrl->ctx_rv3d = rv3d; - vctrl->use_parent_root = use_parent_root; + vctrl->use_parent_root = v3d->camera->transflag & OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK; vctrl->persp_backup = rv3d->persp; vctrl->dist_backup = rv3d->dist; @@ -153,7 +152,7 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph if (rv3d->persp == RV3D_CAMOB) { Object *ob_back; - if (use_parent_root && (vctrl->root_parent = v3d->camera->parent)) { + if (vctrl->use_parent_root && (vctrl->root_parent = v3d->camera->parent)) { while (vctrl->root_parent->parent) { vctrl->root_parent = vctrl->root_parent->parent; } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 633344837a1..d4c85eeb3d2 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -949,15 +949,16 @@ void ED_view3d_grid_steps(const Scene *scene, * Currently the simulation is only done when RV3D_VIEW_IS_AXIS. */ float ED_view3d_grid_view_scale(Scene *scene, View3D *v3d, - RegionView3D *rv3d, + ARegion *region, const char **r_grid_unit) { float grid_scale; + RegionView3D *rv3d = region->regiondata; if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) { /* Decrease the distance between grid snap points depending on zoom. */ /* `0.38` was a value visually obtained in order to get a snap distance * that matches previous versions Blender.*/ - float min_dist = 0.38f * (rv3d->dist / v3d->lens); + float min_dist = 16.0f / (region->sizex * rv3d->winmat[0][0]); float grid_steps[STEPS_LEN]; ED_view3d_grid_steps(scene, v3d, rv3d, grid_steps); /* Skip last item, in case the 'mid_dist' is greater than the largest unit. */ @@ -1468,12 +1469,13 @@ static void draw_selected_name( } static void draw_grid_unit_name( - Scene *scene, RegionView3D *rv3d, View3D *v3d, int xoffset, int *yoffset) + Scene *scene, ARegion *region, View3D *v3d, int xoffset, int *yoffset) { + RegionView3D *rv3d = region->regiondata; if (!rv3d->is_persp && RV3D_VIEW_IS_AXIS(rv3d->view)) { const char *grid_unit = NULL; int font_id = BLF_default(); - ED_view3d_grid_view_scale(scene, v3d, rv3d, &grid_unit); + ED_view3d_grid_view_scale(scene, v3d, region, &grid_unit); if (grid_unit) { char numstr[32] = ""; @@ -1558,7 +1560,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *region) if (v3d->gridflag & (V3D_SHOW_FLOOR | V3D_SHOW_X | V3D_SHOW_Y | V3D_SHOW_Z)) { /* draw below the viewport name */ - draw_grid_unit_name(scene, rv3d, v3d, xoffset, &yoffset); + draw_grid_unit_name(scene, region, v3d, xoffset, &yoffset); } DRW_draw_region_engine_info(xoffset, &yoffset, VIEW3D_OVERLAY_LINEHEIGHT); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 7ec6bddd6a3..897777c9159 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2138,7 +2138,7 @@ static void viewzoom_apply_camera(ViewOpsData *vod, zoomfac_prev, &vod->prev.time); - if (zfac != 1.0f && zfac != 0.0f) { + if (!ELEM(zfac, 1.0f, 0.0f)) { /* calculate inverted, then invert again (needed because of camera zoom scaling) */ zfac = 1.0f / zfac; view_zoom_to_window_xy_camera(vod->scene, @@ -2382,7 +2382,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event) viewzoom_exec(C, op); } else { - if (event->type == MOUSEZOOM || event->type == MOUSEPAN) { + if (ELEM(event->type, MOUSEZOOM, MOUSEPAN)) { if (U.uiflag & USER_ZOOM_HORIZ) { vod->init.event_xy[0] = vod->prev.event_xy[0] = event->x; @@ -4828,7 +4828,7 @@ void VIEW3D_OT_background_image_add(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index 6ce76c478df..6824c526888 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -392,7 +392,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent } fly->v3d_camera_control = ED_view3d_cameracontrol_acquire( - fly->depsgraph, fly->scene, fly->v3d, fly->rv3d, (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); + fly->depsgraph, fly->scene, fly->v3d, fly->rv3d); /* calculate center */ if (ED_view3d_cameracontrol_object_get(fly->v3d_camera_control)) { diff --git a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c index aa8905721b4..9f35abf7fef 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_preselect_type.c @@ -453,7 +453,7 @@ void ED_gizmotypes_preselect_3d(void) /* -------------------------------------------------------------------- */ /** \name Gizmo Accessors * - * This avoids each user of the gizmo needing to write their own look-ups to access + * This avoids each user of the gizmo needing to write their own lookups to access * the information from this gizmo. * \{ */ diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index b23b9db3211..0815850d694 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -228,8 +228,7 @@ void view3d_buttons_register(struct ARegionType *art); struct View3DCameraControl *ED_view3d_cameracontrol_acquire(struct Depsgraph *depsgraph, Scene *scene, View3D *v3d, - RegionView3D *rv3d, - const bool use_parent_root); + RegionView3D *rv3d); void ED_view3d_cameracontrol_update(struct View3DCameraControl *vctrl, const bool use_autokey, struct bContext *C, diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 265cb04c7b2..148a0986c5c 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -73,14 +73,14 @@ static int snap_sel_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph); Object *obact = CTX_data_active_object(C); Scene *scene = CTX_data_scene(C); - RegionView3D *rv3d = CTX_wm_region_data(C); + ARegion *region = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); TransVertStore tvs = {NULL}; TransVert *tv; float gridf, imat[3][3], bmat[3][3], vec[3]; int a; - gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL); + gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL); if (OBEDIT_FROM_OBACT(obact)) { ViewLayer *view_layer = CTX_data_view_layer(C); @@ -657,11 +657,11 @@ void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot) static int snap_curs_to_grid_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); - RegionView3D *rv3d = CTX_wm_region_data(C); + ARegion *region = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); float gridf, *curs; - gridf = ED_view3d_grid_view_scale(scene, v3d, rv3d, NULL); + gridf = ED_view3d_grid_view_scale(scene, v3d, region, NULL); curs = scene->cursor.location; curs[0] = gridf * floorf(0.5f + curs[0] / gridf); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 631994c9b85..22cdbb090a5 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -303,8 +303,8 @@ void ED_view3d_clipping_calc( /* four clipping planes and bounding volume */ /* first do the bounding volume */ for (int val = 0; val < 4; val++) { - float xs = (val == 0 || val == 3) ? rect->xmin : rect->xmax; - float ys = (val == 0 || val == 1) ? rect->ymin : rect->ymax; + float xs = (ELEM(val, 0, 3)) ? rect->xmin : rect->xmax; + float ys = (ELEM(val, 0, 1)) ? rect->ymin : rect->ymax; ED_view3d_unproject(region, xs, ys, 0.0, bb->vec[val]); ED_view3d_unproject(region, xs, ys, 1.0, bb->vec[4 + val]); @@ -552,7 +552,8 @@ bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionV ObjectTfmProtectedChannels obtfm; Object *root_parent; - if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) { + if (v3d->camera->transflag & OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK && + (root_parent = v3d->camera->parent)) { Object *ob_update; float tmat[4][4]; float imat[4][4]; @@ -655,7 +656,8 @@ bool ED_view3d_camera_lock_autokey(View3D *v3d, Scene *scene = CTX_data_scene(C); ID *id_key; Object *root_parent; - if ((U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0 && (root_parent = v3d->camera->parent)) { + if (v3d->camera->transflag & OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK && + (root_parent = v3d->camera->parent)) { while (root_parent->parent) { root_parent = root_parent->parent; } diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c index 3c9e4fa49b9..665d704e6b2 100644 --- a/source/blender/editors/space_view3d/view3d_walk.c +++ b/source/blender/editors/space_view3d/view3d_walk.c @@ -473,8 +473,8 @@ enum { }; /* keep the previous speed until user changes userpreferences */ -static float base_speed = -1.f; -static float userdef_speed = -1.f; +static float base_speed = -1.0f; +static float userdef_speed = -1.0f; static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) { @@ -521,8 +521,9 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->speed = 0.0f; walk->is_fast = false; walk->is_slow = false; - walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? 1.f : - 1.f / walk->scene->unit.scale_length; + walk->grid = (walk->scene->unit.system == USER_UNIT_NONE) ? + 1.0f : + 1.0f / walk->scene->unit.scale_length; /* user preference settings */ walk->teleport.duration = U.walk_navigation.teleport_time; @@ -585,11 +586,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) walk->scene, 0, walk->region, walk->v3d); walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( - walk->depsgraph, - walk->scene, - walk->v3d, - walk->rv3d, - (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); + walk->depsgraph, walk->scene, walk->v3d, walk->rv3d); /* center the mouse */ walk->center_mval[0] = walk->region->winx * 0.5f; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5aed4b9c6ef..77ce9c10c77 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -646,12 +646,12 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) static const EnumPropertyItem modal_items[] = { {TFM_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, {TFM_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, - {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X axis", ""}, - {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y axis", ""}, - {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z axis", ""}, - {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X plane", ""}, - {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y plane", ""}, - {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z plane", ""}, + {TFM_MODAL_AXIS_X, "AXIS_X", 0, "X Axis", ""}, + {TFM_MODAL_AXIS_Y, "AXIS_Y", 0, "Y Axis", ""}, + {TFM_MODAL_AXIS_Z, "AXIS_Z", 0, "Z Axis", ""}, + {TFM_MODAL_PLANE_X, "PLANE_X", 0, "X Plane", ""}, + {TFM_MODAL_PLANE_Y, "PLANE_Y", 0, "Y Plane", ""}, + {TFM_MODAL_PLANE_Z, "PLANE_Z", 0, "Z Plane", ""}, {TFM_MODAL_CONS_OFF, "CONS_OFF", 0, "Clear Constraints", ""}, {TFM_MODAL_SNAP_INV_ON, "SNAP_INV_ON", 0, "Snap Invert", ""}, {TFM_MODAL_SNAP_INV_OFF, "SNAP_INV_OFF", 0, "Snap Invert (Off)", ""}, @@ -672,13 +672,13 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) 0, "Decrease Max AutoIK Chain Length", ""}, - {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select next Edge Slide Edge", ""}, - {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select previous Edge Slide Edge", ""}, + {TFM_MODAL_EDGESLIDE_UP, "EDGESLIDE_EDGE_NEXT", 0, "Select Next Edge Slide Edge", ""}, + {TFM_MODAL_EDGESLIDE_DOWN, "EDGESLIDE_PREV_NEXT", 0, "Select Previous Edge Slide Edge", ""}, {TFM_MODAL_PROPSIZE, "PROPORTIONAL_SIZE", 0, "Adjust Proportional Influence", ""}, {TFM_MODAL_INSERTOFS_TOGGLE_DIR, "INSERTOFS_TOGGLE_DIR", 0, - "Toggle Direction for Node Auto-offset", + "Toggle Direction for Node Auto-Offset", ""}, {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""}, {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, @@ -1626,11 +1626,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) static void initSnapSpatial(TransInfo *t, float r_snap[2]) { if (t->spacetype == SPACE_VIEW3D) { - RegionView3D *rv3d = t->region->regiondata; - - if (rv3d) { + if (t->region->regiondata) { View3D *v3d = t->area->spacedata.first; - r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, rv3d, NULL) * 1.0f; + r_snap[0] = ED_view3d_grid_view_scale(t->scene, v3d, t->region, NULL) * 1.0f; r_snap[1] = r_snap[0] * 0.1f; } } @@ -1949,7 +1947,7 @@ int transformEnd(bContext *C, TransInfo *t) t->context = C; - if (t->state != TRANS_STARTING && t->state != TRANS_RUNNING) { + if (!ELEM(t->state, TRANS_STARTING, TRANS_RUNNING)) { /* handle restoring objects */ if (t->state == TRANS_CANCEL) { exit_code = OPERATOR_CANCELLED; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 275ddb993b2..227330e8524 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -36,7 +36,9 @@ #include "transform_data.h" -/* ************************** Types ***************************** */ +/* -------------------------------------------------------------------- */ +/** \name Types/ + * \{ */ struct ARegion; struct Depsgraph; @@ -58,7 +60,7 @@ struct wmKeyConfig; struct wmKeyMap; struct wmTimer; -/* transinfo->redraw */ +/** #TransInfo.redraw */ typedef enum { TREDRAW_NOTHING = 0, TREDRAW_HARD = 1, @@ -264,8 +266,8 @@ typedef struct TransInfo { TransDataContainer *data_container; int data_container_len; - /** eTransConvertType - * TODO: It should be a member of TransDataContainer. */ + /** #eTransConvertType + * TODO: It should be a member of #TransDataContainer. */ int data_type; /** Combine length of all #TransDataContainer.data_len @@ -329,16 +331,16 @@ typedef struct TransInfo { float persinv[4][4]; short persp; short around; - /** spacetype where transforming is. */ + /** space-type where transforming is. */ char spacetype; /** Choice of custom cursor with or without a help line from the gizmo to the mouse position. */ char helpline; - /** Avoid looking inside TransDataContainer obedit. */ + /** Avoid looking inside #TransDataContainer.obedit. */ short obedit_type; /** translation, to show for widget. */ float vec[3]; - /** rot/rescale, to show for widget. */ + /** Rotate/re-scale, to show for widget. */ float mat[3][3]; /** orientation matrix of the current space. */ @@ -368,7 +370,7 @@ typedef struct TransInfo { /** Value taken as input, either through mouse coordinates or entered as a parameter. */ float values[4]; - /** Offset applied ontop of modal input. */ + /** Offset applied on top of modal input. */ float values_modal_offset[4]; /** Final value of the transformation (displayed in the redo panel). @@ -397,7 +399,7 @@ typedef struct TransInfo { struct ViewLayer *view_layer; struct ToolSettings *settings; struct wmTimer *animtimer; - /** so we can do lookups for header text. */ + /** Needed so we can perform a look up for header text. */ struct wmKeyMap *keymap; /** assign from the operator, or can be NULL. */ struct ReportList *reports; @@ -417,9 +419,13 @@ typedef struct TransInfo { TransCustomDataContainer custom; } TransInfo; -/* ******************** Macros & Prototypes *********************** */ +/** \} */ -/* transinfo->state */ +/* -------------------------------------------------------------------- */ +/** \name Flags + * \{ */ + +/** #TransInfo.state */ enum { TRANS_STARTING = 0, TRANS_RUNNING = 1, @@ -427,7 +433,7 @@ enum { TRANS_CANCEL = 3, }; -/* transinfo->flag */ +/** #TransInfo.flag */ enum { T_OBJECT = 1 << 0, /** \note We could remove 'T_EDIT' and use 'obedit_type', for now ensure they're in sync. */ @@ -452,11 +458,11 @@ enum { T_PROP_EDIT_ALL = T_PROP_EDIT | T_PROP_CONNECTED | T_PROP_PROJECTED, T_V3D_ALIGN = 1 << 13, - /** For 2d views like uv or fcurve. */ + /** For 2D views such as UV or f-curve. */ T_2D_EDIT = 1 << 14, T_CLIP_UV = 1 << 15, - /** Auto-ik is on. */ + /** Auto-IK is on. */ T_AUTOIK = 1 << 16, /** Don't use mirror even if the data-block option is set. */ @@ -469,7 +475,7 @@ enum { /** To specify if we save back settings at the end. */ T_MODAL = 1 << 19, - /** No retopo. */ + /** No re-topology (projection). */ T_NO_PROJECT = 1 << 20, T_RELEASE_CONFIRM = 1 << 21, @@ -484,8 +490,9 @@ enum { T_CLNOR_REBUILD = 1 << 25, - /* Special Aftertrans. */ + /** Merges unselected into selected after transforming (runs after transforming). */ T_AUTOMERGE = 1 << 26, + /** Runs auto-merge & splits. */ T_AUTOSPLIT = 1 << 27, }; @@ -503,8 +510,6 @@ enum { */ // #define USE_NODE_CENTER -/* ******************************************************************************** */ - /** #TransInfo.helpline */ enum { HLP_NONE = 0, @@ -538,8 +543,14 @@ enum { MULTI_POINTS = 1 << 3, }; -/** keymap modal items */ -/* NOTE: these values are saved in keymap files, do not change then but just add new ones. */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Keymap Modal Items + * + * \note these values are saved in key-map files, do not change then but just add new ones. + * \{ */ + enum { TFM_MODAL_CANCEL = 1, TFM_MODAL_CONFIRM = 2, @@ -559,7 +570,9 @@ enum { TFM_MODAL_ADD_SNAP = 16, TFM_MODAL_REMOVE_SNAP = 17, - /* 18 and 19 used by numinput, defined in transform.h */ + /* 18 and 19 used by number-input, defined in `ED_numinput.h`. */ + // NUM_MODAL_INCREMENT_UP = 18, + // NUM_MODAL_INCREMENT_DOWN = 19, TFM_MODAL_PROPSIZE_UP = 20, TFM_MODAL_PROPSIZE_DOWN = 21, @@ -569,15 +582,21 @@ enum { TFM_MODAL_EDGESLIDE_UP = 24, TFM_MODAL_EDGESLIDE_DOWN = 25, - /* for analog input, like trackpad */ + /** For analog input, like track-pad. */ TFM_MODAL_PROPSIZE = 26, - /* node editor insert offset (aka auto-offset) direction toggle */ + /** Node editor insert offset (also called auto-offset) direction toggle. */ TFM_MODAL_INSERTOFS_TOGGLE_DIR = 27, TFM_MODAL_AUTOCONSTRAINT = 28, TFM_MODAL_AUTOCONSTRAINTPLANE = 29, }; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Public Transform API + * \{ */ + bool initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, @@ -601,18 +620,31 @@ void removeAspectRatio(TransInfo *t, float vec[2]); struct wmKeyMap *transform_modal_keymap(struct wmKeyConfig *keyconf); -/*********************** transform_gizmo.c ********** */ +/** \} */ +/* -------------------------------------------------------------------- */ +/** \name Gizmo + * \{ */ + +/* transform_gizmo.c */ #define GIZMO_AXIS_LINE_WIDTH 2.0f -/* return 0 when no gimbal for selection */ bool gimbal_axis(struct Object *ob, float gmat[3][3]); void drawDial3d(const TransInfo *t); -/*********************** TransData Creation and General Handling *********** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name TransData Creation and General Handling + * \{ */ + bool transdata_check_local_islands(TransInfo *t, short around); -/********************** Mouse Input ******************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mouse Input + * \{ */ typedef enum { INPUT_NONE, @@ -646,7 +678,11 @@ void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int void setCustomPointsFromDirection(TransInfo *t, MouseInput *mi, const float dir[2]); void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float values[3])); -/*********************** Generics ********************************/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Generics + * \{ */ void initTransDataContainers_FromObjectData(TransInfo *t, struct Object *obact, @@ -716,3 +752,5 @@ bool checkUseAxisMatrix(TransInfo *t); *tc_end = (t)->data_container + (t)->data_container_len; \ th != tc_end; \ th++, i++) + +/** \} */ diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index de1c875a7b0..5e2a8be8db0 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -284,7 +284,9 @@ static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[ * Snap to the nearest point between the snap point and the line that * intersects the face plane with the constraint plane. */ -static void constraint_snap_plane_to_face(const TransInfo *t, const float plane[4], float r_out[3]) +static void UNUSED_FUNCTION(constraint_snap_plane_to_face(const TransInfo *t, + const float plane[4], + float r_out[3])) { float face_plane[4], isect_orig[3], isect_dir[3]; const float *face_snap_point = t->tsnap.snapPoint; @@ -406,7 +408,8 @@ static void applyAxisConstraintVec( constraint_snap_plane_to_edge(t, plane, out); } else if (is_snap_to_face) { - constraint_snap_plane_to_face(t, plane, out); + /* Disabled, as it has not proven to be really useful. (See T82386). */ + // constraint_snap_plane_to_face(t, plane, out); } else { /* View alignment correction. */ diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index a14ff6c500d..a7301161570 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -1504,7 +1504,7 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb) if ((bone->flag & BONE_HINGE) && (bone->flag & BONE_CONNECTED)) { bone->flag |= BONE_HINGE_CHILD_TRANSFORM; } - else if ((bone->flag & BONE_TRANSFORM) && (mode == TFM_ROTATION || mode == TFM_TRACKBALL) && + else if ((bone->flag & BONE_TRANSFORM) && (ELEM(mode, TFM_ROTATION, TFM_TRACKBALL)) && (around == V3D_AROUND_LOCAL_ORIGINS)) { bone->flag |= BONE_TRANSFORM_CHILD; } diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 90257b28f55..d2feb966657 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -406,7 +406,7 @@ void createTransCurveVerts(TransInfo *t) } td->ext = NULL; - if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) { + if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_RESIZE)) { td->val = &(bp->radius); td->ival = bp->radius; } diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 307fbbdf80b..3f86ef3e81b 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -29,10 +29,11 @@ #include "BKE_context.h" #include "BKE_report.h" -#include "BKE_sequencer.h" #include "ED_markers.h" +#include "SEQ_sequencer.h" + #include "UI_view2d.h" #include "transform.h" diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index c40f3d3f140..09100bb50cc 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -53,7 +53,7 @@ /* -------------------------------------------------------------------- */ /** \name Shared Callback's - */ + * \{ */ static bool gizmo2d_generic_poll(const bContext *C, wmGizmoGroupType *gzgt) { diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index a22f6c35139..a71915d8122 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -565,6 +565,9 @@ static bool test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } +/** + * Return false when no gimbal for selection. + */ bool gimbal_axis(Object *ob, float gmat[3][3]) { if (ob->mode & OB_MODE_POSE) { diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index c525bc0e6ea..af0a8e5e505 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -520,9 +520,7 @@ static void constraintSizeLim(TransInfo *t, TransData *td) } /* -------------------------------------------------------------------- */ -/* Transform (Rotation Utils) */ - -/** \name Transform Rotation Utils +/** \name Transform (Rotation Utils) * \{ */ /* Used by Transform Rotation and Transform Normal Rotation */ void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final) @@ -534,13 +532,17 @@ void headerRotation(TransInfo *t, char str[UI_MAX_DRAW_STR], float final) outputNumInput(&(t->num), c, &t->scene->unit); - ofs += BLI_snprintf( - str + ofs, UI_MAX_DRAW_STR - ofs, TIP_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext); + ofs += BLI_snprintf(str + ofs, + UI_MAX_DRAW_STR - ofs, + TIP_("Rotation: %s %s %s"), + &c[0], + t->con.text, + t->proptext); } else { ofs += BLI_snprintf(str + ofs, UI_MAX_DRAW_STR - ofs, - TIP_("Rot: %.2f%s %s"), + TIP_("Rotation: %.2f%s %s"), RAD2DEGF(final), t->con.text, t->proptext); @@ -815,9 +817,7 @@ void ElementRotation( /** \} */ /* -------------------------------------------------------------------- */ -/* Transform (Resize Utils) */ - -/** \name Transform Resize Utils +/** \name Transform (Resize Utils) * \{ */ void headerResize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR]) { @@ -1040,9 +1040,7 @@ void ElementResize(TransInfo *t, TransDataContainer *tc, TransData *td, float ma /** \} */ /* -------------------------------------------------------------------- */ -/* Transform (Frame Utils) */ - -/** \name Transform Frame Utils +/** \name Transform (Frame Utils) * \{ */ /** diff --git a/source/blender/editors/transform/transform_mode_align.c b/source/blender/editors/transform/transform_mode_align.c index 4fd4599b940..f16021914f1 100644 --- a/source/blender/editors/transform/transform_mode_align.c +++ b/source/blender/editors/transform/transform_mode_align.c @@ -35,9 +35,7 @@ #include "transform_mode.h" /* -------------------------------------------------------------------- */ -/* Transform (Align) */ - -/** \name Transform Align +/** \name Transform (Align) * \{ */ static void applyAlign(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_baketime.c b/source/blender/editors/transform/transform_mode_baketime.c index 6470776e1a2..5efed6920dc 100644 --- a/source/blender/editors/transform/transform_mode_baketime.c +++ b/source/blender/editors/transform/transform_mode_baketime.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Bake-Time) */ - -/** \name Transform Bake-Time +/** \name Transform (Bake-Time) * \{ */ static void applyBakeTime(TransInfo *t, const int mval[2]) diff --git a/source/blender/editors/transform/transform_mode_bbone_resize.c b/source/blender/editors/transform/transform_mode_bbone_resize.c index 57e809a566a..e827e604327 100644 --- a/source/blender/editors/transform/transform_mode_bbone_resize.c +++ b/source/blender/editors/transform/transform_mode_bbone_resize.c @@ -41,9 +41,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (EditBone (B-bone) width scaling) */ - -/** \name Transform B-bone width scaling +/** \name Transform (EditBone B-Bone width scaling) * \{ */ static void headerBoneSize(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c index 2f83755b1fe..adf3a0346a0 100644 --- a/source/blender/editors/transform/transform_mode_bend.c +++ b/source/blender/editors/transform/transform_mode_bend.c @@ -47,9 +47,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Bend) */ - -/** \name Transform Bend +/** \name Transform (Bend) * \{ */ struct BendCustomData { diff --git a/source/blender/editors/transform/transform_mode_boneenvelope.c b/source/blender/editors/transform/transform_mode_boneenvelope.c index 1a25ee50543..ced159a76c9 100644 --- a/source/blender/editors/transform/transform_mode_boneenvelope.c +++ b/source/blender/editors/transform/transform_mode_boneenvelope.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Bone Envelope) */ - -/** \name Transform Bone Envelope +/** \name Transform (Bone Envelope) * \{ */ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_boneroll.c b/source/blender/editors/transform/transform_mode_boneroll.c index cd277517d6b..da6c0b44c3a 100644 --- a/source/blender/editors/transform/transform_mode_boneroll.c +++ b/source/blender/editors/transform/transform_mode_boneroll.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (EditBone Roll) */ - -/** \name Transform EditBone Roll +/** \name Transform (EditBone Roll) * \{ */ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c index 1935264d6d0..ee63bf4be6f 100644 --- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Curve Shrink/Fatten) */ - -/** \name Transform Curve Shrink/Fatten +/** \name Transform (Curve Shrink/Fatten) * \{ */ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c index 2f7707cdee4..3ce52ed3296 100644 --- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c +++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Bevel Weight) */ - -/** \name Transform Bevel Weight +/** \name Transform (Bevel Weight) * \{ */ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c index e2e0afc0a8f..23fa20b68ff 100644 --- a/source/blender/editors/transform/transform_mode_edge_crease.c +++ b/source/blender/editors/transform/transform_mode_edge_crease.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Crease) */ - -/** \name Transform Crease +/** \name Transform (Crease) * \{ */ static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c index 4b083a0529f..32f0d4bd365 100644 --- a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c +++ b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c @@ -39,9 +39,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Normal Rotation) */ - -/** \name Transform Normal Rotation +/** \name Transform (Normal Rotation) * \{ */ static void storeCustomLNorValue(TransDataContainer *tc, BMesh *bm) diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index 5222d4d4e5a..dfa5c164acf 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -42,9 +42,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Sequencer Slide) */ - -/** \name Transform Sequencer Slide +/** \name Transform (Sequencer Slide) * \{ */ static void headerSeqSlide(TransInfo *t, const float val[2], char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index c887b69c792..dae3fe6f7b4 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -56,9 +56,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Edge Slide) */ - -/** \name Transform Edge Slide +/** \name Transform (Edge Slide) * \{ */ typedef struct TransDataEdgeSlideVert { diff --git a/source/blender/editors/transform/transform_mode_gpopacity.c b/source/blender/editors/transform/transform_mode_gpopacity.c index 5eb390d7cbd..103eb17c273 100644 --- a/source/blender/editors/transform/transform_mode_gpopacity.c +++ b/source/blender/editors/transform/transform_mode_gpopacity.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (GPencil Opacity) */ - -/** \name Transform GPencil Strokes Opacity +/** \name Transform (GPencil Strokes Opacity) * \{ */ static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c index 2d886b55a04..14e7c1df4f4 100644 --- a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (GPencil Shrink/Fatten) */ - -/** \name Transform GPencil Strokes Shrink/Fatten +/** \name Transform (GPencil Strokes Shrink/Fatten) * \{ */ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c index 1c5b5000f5c..3019984d70b 100644 --- a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Mask Shrink/Fatten) */ - -/** \name Transform Mask Shrink/Fatten +/** \name Transform (Mask Shrink/Fatten) * \{ */ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_mirror.c b/source/blender/editors/transform/transform_mode_mirror.c index 8d953610eb8..1440553de51 100644 --- a/source/blender/editors/transform/transform_mode_mirror.c +++ b/source/blender/editors/transform/transform_mode_mirror.c @@ -38,9 +38,7 @@ #include "transform_mode.h" /* -------------------------------------------------------------------- */ -/* Transform (Mirror) */ - -/** \name Transform Mirror +/** \name Transform (Mirror) * \{ */ static void applyMirror(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_push_pull.c b/source/blender/editors/transform/transform_mode_push_pull.c index 860dd51da94..8a92978f33f 100644 --- a/source/blender/editors/transform/transform_mode_push_pull.c +++ b/source/blender/editors/transform/transform_mode_push_pull.c @@ -41,9 +41,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Push/Pull) */ - -/** \name Transform Push/Pull +/** \name Transform (Push/Pull) * \{ */ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 33303b82567..62a4fbd6f04 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -39,9 +39,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Resize) */ - -/** \name Transform Resize +/** \name Transform (Resize) * \{ */ static float ResizeBetween(TransInfo *t, const float p1[3], const float p2[3]) diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index d8857dbc31e..856e71a0df6 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -37,9 +37,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Rotation) */ - -/** \name Transform Rotation +/** \name Transform (Rotation) * \{ */ static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]) diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c index dfc6f69b341..a41c49710b9 100644 --- a/source/blender/editors/transform/transform_mode_shear.c +++ b/source/blender/editors/transform/transform_mode_shear.c @@ -44,9 +44,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Shear) */ - -/** \name Transform Shear +/** \name Transform (Shear) * \{ */ static void initShear_mouseInputMode(TransInfo *t) diff --git a/source/blender/editors/transform/transform_mode_shrink_fatten.c b/source/blender/editors/transform/transform_mode_shrink_fatten.c index af33c2bb090..cdea388529f 100644 --- a/source/blender/editors/transform/transform_mode_shrink_fatten.c +++ b/source/blender/editors/transform/transform_mode_shrink_fatten.c @@ -42,9 +42,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Shrink-Fatten) */ - -/** \name Transform Shrink-Fatten +/** \name Transform (Shrink-Fatten) * \{ */ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c index a1a6f0ce8f8..b4c919cbb86 100644 --- a/source/blender/editors/transform/transform_mode_skin_resize.c +++ b/source/blender/editors/transform/transform_mode_skin_resize.c @@ -38,9 +38,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Skin) */ - -/** \name Transform Skin +/** \name Transform (Skin) * \{ */ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_tilt.c b/source/blender/editors/transform/transform_mode_tilt.c index 07e0e156803..d3b72fdf503 100644 --- a/source/blender/editors/transform/transform_mode_tilt.c +++ b/source/blender/editors/transform/transform_mode_tilt.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Tilt) */ - -/** \name Transform Tilt +/** \name Transform (Tilt) * \{ */ static void applyTilt(TransInfo *t, const int UNUSED(mval[2])) diff --git a/source/blender/editors/transform/transform_mode_timescale.c b/source/blender/editors/transform/transform_mode_timescale.c index dbe06a6f1f6..7ae97c66660 100644 --- a/source/blender/editors/transform/transform_mode_timescale.c +++ b/source/blender/editors/transform/transform_mode_timescale.c @@ -42,9 +42,7 @@ #include "transform_mode.h" /* -------------------------------------------------------------------- */ -/* Transform (Animation Time Scale) */ - -/** \name Transform Animation Time Scale +/** \name Transform (Animation Time Scale) * \{ */ static void headerTimeScale(TransInfo *t, char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_timeslide.c b/source/blender/editors/transform/transform_mode_timeslide.c index 9636b4f6e42..34d3251f9cf 100644 --- a/source/blender/editors/transform/transform_mode_timeslide.c +++ b/source/blender/editors/transform/transform_mode_timeslide.c @@ -45,9 +45,7 @@ #include "transform_mode.h" /* -------------------------------------------------------------------- */ -/* Transform (Animation Time Slide) */ - -/** \name Transform Animation Time Slide +/** \name Transform (Animation Time Slide) * \{ */ static void headerTimeSlide(TransInfo *t, const float sval, char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_timetranslate.c b/source/blender/editors/transform/transform_mode_timetranslate.c index 226e8a377ea..adebc19c2b9 100644 --- a/source/blender/editors/transform/transform_mode_timetranslate.c +++ b/source/blender/editors/transform/transform_mode_timetranslate.c @@ -43,9 +43,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Animation Translation) */ - -/** \name Transform Animation Translation +/** \name Transform (Animation Translation) * \{ */ static void headerTimeTranslate(TransInfo *t, char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_trackball.c b/source/blender/editors/transform/transform_mode_trackball.c index 32019e151a1..5a57a69f986 100644 --- a/source/blender/editors/transform/transform_mode_trackball.c +++ b/source/blender/editors/transform/transform_mode_trackball.c @@ -40,9 +40,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Rotation - Trackball) */ - -/** \name Transform Rotation - Trackball +/** \name Transform (Rotation - Trackball) * \{ */ static void applyTrackballValue(TransInfo *t, diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index d4748e7933b..183fc8f5dc3 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -49,9 +49,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Translation) */ - -/** \name Transform Translation +/** \name Transform (Translation) * \{ */ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_DRAW_STR]) diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 289ed76c731..1e5d027e253 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -53,9 +53,7 @@ #include "transform_snap.h" /* -------------------------------------------------------------------- */ -/* Transform (Vert Slide) */ - -/** \name Transform Vert Slide +/** \name Transform (Vert Slide) * \{ */ typedef struct TransDataVertSlideVert { diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index b164d0d443f..c455dd55b8a 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -541,7 +541,7 @@ static bool transform_poll_property(const bContext *UNUSED(C), { /* Hide orientation axis if no constraints are set, since it wont be used. */ PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "orient_type"); - if (prop_con != NULL && (prop_con != prop)) { + if (!ELEM(prop_con, NULL, prop)) { if (STRPREFIX(prop_id, "constraint")) { /* Special case: show constraint axis if we don't have values, @@ -825,6 +825,17 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER); } +/* Similar to #transform_shear_poll. */ +static bool transform_rotate_poll(bContext *C) +{ + if (!ED_operator_screenactive(C)) { + return false; + } + + ScrArea *area = CTX_wm_area(C); + return area && !ELEM(area->spacetype, SPACE_ACTION); +} + static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) { /* identifiers */ @@ -838,7 +849,7 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->exec = transform_exec; ot->modal = transform_modal; ot->cancel = transform_cancel; - ot->poll = ED_operator_screenactive; + ot->poll = transform_rotate_poll; ot->poll_property = transform_poll_property; RNA_def_float_rotation( @@ -902,6 +913,7 @@ static void TRANSFORM_OT_bend(struct wmOperatorType *ot) Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER); } +/* Similar to #transform_rotate_poll. */ static bool transform_shear_poll(bContext *C) { if (!ED_operator_screenactive(C)) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index e461bcb88e9..f1c4c243780 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -38,10 +38,11 @@ #include "BKE_layer.h" #include "BKE_object.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "RNA_access.h" +#include "SEQ_sequencer.h" + #include "WM_types.h" #include "ED_gizmo_library.h" diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index 9a2b346132e..b832d9a1d86 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -30,7 +30,6 @@ #include "BKE_image.h" #include "BKE_main.h" #include "BKE_screen.h" -#include "BKE_sequencer.h" #include "ED_image.h" #include "ED_screen.h" @@ -43,6 +42,8 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "SEQ_sequencer.h" + #include "UI_view2d.h" #include "WM_api.h" @@ -369,7 +370,7 @@ static void sequencer_sample_apply(bContext *C, wmOperator *op, const wmEvent *e /* sequencer's image buffers are in non-linear space, need to make them linear */ copy_v4_v4(info->linearcol, info->colf); - BKE_sequencer_pixel_from_sequencer_space_v4(scene, info->linearcol); + SEQ_render_pixel_from_sequencer_space_v4(scene, info->linearcol); info->color_manage = true; } diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c index 0ae167c117e..cc6eb49f984 100644 --- a/source/blender/editors/uvedit/uvedit_parametrizer.c +++ b/source/blender/editors/uvedit/uvedit_parametrizer.c @@ -4407,8 +4407,7 @@ void param_delete(ParamHandle *handle) PHandle *phandle = (PHandle *)handle; int i; - param_assert((phandle->state == PHANDLE_STATE_ALLOCATED) || - (phandle->state == PHANDLE_STATE_CONSTRUCTED)); + param_assert(ELEM(phandle->state, PHANDLE_STATE_ALLOCATED, PHANDLE_STATE_CONSTRUCTED)); for (i = 0; i < phandle->ncharts; i++) { p_chart_delete(phandle->charts[i]); @@ -4507,7 +4506,7 @@ void param_face_add(ParamHandle *handle, param_assert(phash_lookup(phandle->hash_faces, key) == NULL); param_assert(phandle->state == PHANDLE_STATE_ALLOCATED); - param_assert((nverts == 3) || (nverts == 4)); + param_assert(ELEM(nverts, 3, 4)); if (nverts > 4) { /* ngon */ diff --git a/source/blender/freestyle/intern/application/AppCanvas.cpp b/source/blender/freestyle/intern/application/AppCanvas.cpp index d34be79cd66..66e41222ee6 100644 --- a/source/blender/freestyle/intern/application/AppCanvas.cpp +++ b/source/blender/freestyle/intern/application/AppCanvas.cpp @@ -31,13 +31,13 @@ #include "../system/StringUtils.h" namespace Freestyle { -AppCanvas::AppCanvas() : Canvas() +AppCanvas::AppCanvas() { _pViewer = 0; _MapsPath = Config::Path::getInstance()->getMapsDir().c_str(); } -AppCanvas::AppCanvas(AppView *iViewer) : Canvas() +AppCanvas::AppCanvas(AppView *iViewer) { _pViewer = iViewer; } diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp index 4628c76ca7f..0467e057642 100644 --- a/source/blender/freestyle/intern/application/Controller.cpp +++ b/source/blender/freestyle/intern/application/Controller.cpp @@ -927,12 +927,7 @@ Render *Controller::RenderStrokes(Render *re, bool render) float megs_used_memory = (mem_in_use) / (1024.0 * 1024.0); float megs_peak_memory = (peak_memory) / (1024.0 * 1024.0); - printf("%d objs, %d verts, %d faces, mem %.2fM (peak %.2fM)\n", - totmesh, - freestyle_render->i.totvert, - freestyle_render->i.totface, - megs_used_memory, - megs_peak_memory); + printf("%d objs, mem %.2fM (peak %.2fM)\n", totmesh, megs_used_memory, megs_peak_memory); } delete blenderRenderer; diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index ee584f8953c..291a38d23df 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -61,7 +61,7 @@ NodeGroup *BlenderFileLoader::Load() _viewplane_bottom = _re->viewplane.ymin; _viewplane_top = _re->viewplane.ymax; - if (_re->clip_start < 0.f) { + if (_re->clip_start < 0.0f) { // Adjust clipping start/end and set up a Z offset when the viewport preview // is used with the orthographic view. In this case, _re->clip_start is negative, // while Freestyle assumes that imported mesh data are in the camera coordinate @@ -73,7 +73,7 @@ NodeGroup *BlenderFileLoader::Load() else { _z_near = -_re->clip_start; _z_far = -_re->clip_end; - _z_offset = 0.f; + _z_offset = 0.0f; } #if 0 @@ -169,7 +169,7 @@ int BlenderFileLoader::countClippedFaces(float v1[3], float v2[3], float v3[3], } break; case 3: - if (sum == 3 || sum == -3) { + if (ELEM(sum, 3, -3)) { numTris = 0; } else { @@ -577,7 +577,7 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) tmpMat.setLine(mat->line_col[0], mat->line_col[1], mat->line_col[2], mat->line_col[3]); tmpMat.setDiffuse(mat->r, mat->g, mat->b, 1.0f); tmpMat.setSpecular(mat->specr, mat->specg, mat->specb, 1.0f); - tmpMat.setShininess(128.f); + tmpMat.setShininess(128.0f); tmpMat.setPriority(mat->line_priority); } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index f31d7c95997..2f465a973fc 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -70,7 +70,7 @@ namespace Freestyle { const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_tips"}; -BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) : StrokeRenderer() +BlenderStrokeRenderer::BlenderStrokeRenderer(Render *re, int render_count) { freestyle_bmain = BKE_main_new(); diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index 2446bfc13dc..9680e7d25a3 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -150,10 +150,10 @@ static void init_view(Render *re) float thickness = 1.0f; switch (re->r.line_thickness_mode) { case R_LINE_THICKNESS_ABSOLUTE: - thickness = re->r.unit_line_thickness * (re->r.size / 100.f); + thickness = re->r.unit_line_thickness * (re->r.size / 100.0f); break; case R_LINE_THICKNESS_RELATIVE: - thickness = height / 480.f; + thickness = height / 480.0f; break; } diff --git a/source/blender/freestyle/intern/geometry/matrix_util.cpp b/source/blender/freestyle/intern/geometry/matrix_util.cpp index 9d25a240a63..637c2d05574 100644 --- a/source/blender/freestyle/intern/geometry/matrix_util.cpp +++ b/source/blender/freestyle/intern/geometry/matrix_util.cpp @@ -149,7 +149,7 @@ void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec, imv = n * (m - 1); for (i = 1; i <= n; i++) { - if ((i != l) && (i != m)) { + if (!ELEM(i, l, m)) { iq = (i * i - i) / 2; if (i < m) { diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h index 996ebc928a1..8a20cb31300 100644 --- a/source/blender/freestyle/intern/geometry/matrix_util.h +++ b/source/blender/freestyle/intern/geometry/matrix_util.h @@ -42,16 +42,18 @@ namespace MatrixUtil { /** * computes the eigen values and eigen vectors of a semi definite symmetric matrix * - * \param mat: The matrix stored in column symmetric storage, i.e. - * matrix = { m11, m12, m22, m13, m23, m33, m14, m24, m34, m44 ... } - * size = n(n+1)/2 + * \param mat: The matrix stored in column symmetric storage, i.e. + * <pre> + * matrix = { m11, m12, m22, m13, m23, m33, m14, m24, m34, m44 ... } + * size = n(n+1)/2 + * </pre> * * \param eigen_vec: (return) = { v1, v2, v3, ..., vn } - * where vk = vk0, vk1, ..., vkn - * size = n^2, must be allocated by caller + * where `vk = vk0, vk1, ..., vkn` + * `size = n^2`, must be allocated by caller. * * \param eigen_val: (return) are in decreasing order - * size = n, must be allocated by caller + * `size = n`, must be allocated by caller. */ void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec, double *eigen_val); diff --git a/source/blender/freestyle/intern/image/ImagePyramid.cpp b/source/blender/freestyle/intern/image/ImagePyramid.cpp index 2f12081eb76..b6779669a15 100644 --- a/source/blender/freestyle/intern/image/ImagePyramid.cpp +++ b/source/blender/freestyle/intern/image/ImagePyramid.cpp @@ -124,14 +124,12 @@ int ImagePyramid::height(int level) } GaussianPyramid::GaussianPyramid(const GrayImage &level0, unsigned nbLevels, float iSigma) - : ImagePyramid() { _sigma = iSigma; BuildPyramid(level0, nbLevels); } GaussianPyramid::GaussianPyramid(GrayImage *level0, unsigned nbLevels, float iSigma) - : ImagePyramid() { _sigma = iSigma; BuildPyramid(level0, nbLevels); diff --git a/source/blender/freestyle/intern/image/ImagePyramid.h b/source/blender/freestyle/intern/image/ImagePyramid.h index ee8bf69aa10..3b4e5eda52a 100644 --- a/source/blender/freestyle/intern/image/ImagePyramid.h +++ b/source/blender/freestyle/intern/image/ImagePyramid.h @@ -87,7 +87,7 @@ class GaussianPyramid : public ImagePyramid { float _sigma; public: - GaussianPyramid(float iSigma = 1.f) : ImagePyramid() + GaussianPyramid(float iSigma = 1.0f) : ImagePyramid() { _sigma = iSigma; } diff --git a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp index e04a89bad3b..d337bf7f90e 100644 --- a/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp +++ b/source/blender/freestyle/intern/python/Interface1D/BPy_FEdge.cpp @@ -106,7 +106,7 @@ static PyObject *FEdge_sq_item(BPy_FEdge *self, int keynum) if (keynum < 0) { keynum += FEdge_sq_length(self); } - if (keynum == 0 || keynum == 1) { + if (ELEM(keynum, 0, 1)) { SVertex *v = self->fe->operator[](keynum); if (v) { return BPy_SVertex_from_SVertex(*v); diff --git a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp index fe0fc715e34..89c4bedd676 100644 --- a/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp +++ b/source/blender/freestyle/intern/scene_graph/IndexedFaceSet.cpp @@ -23,7 +23,7 @@ namespace Freestyle { -IndexedFaceSet::IndexedFaceSet() : Rep() +IndexedFaceSet::IndexedFaceSet() { _Vertices = NULL; _Normals = NULL; @@ -68,7 +68,6 @@ IndexedFaceSet::IndexedFaceSet(float *iVertices, unsigned *iTIndices, unsigned iTISize, unsigned iCopy) - : Rep() { if (1 == iCopy) { _VSize = iVSize; diff --git a/source/blender/freestyle/intern/scene_graph/NodeLight.cpp b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp index f6585d9f932..7200ae5e83c 100644 --- a/source/blender/freestyle/intern/scene_graph/NodeLight.cpp +++ b/source/blender/freestyle/intern/scene_graph/NodeLight.cpp @@ -25,7 +25,7 @@ namespace Freestyle { int NodeLight::numberOfLights = 0; -NodeLight::NodeLight() : Node() +NodeLight::NodeLight() { if (numberOfLights > 7) { _number = 7; diff --git a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp index abe3871c395..7e2dcb8f99f 100644 --- a/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/AdvancedStrokeShaders.cpp @@ -37,7 +37,6 @@ CalligraphicShader::CalligraphicShader(real iMinThickness, real iMaxThickness, const Vec2f &iOrientation, bool clamp) - : StrokeShader() { _minThickness = iMinThickness; _maxThickness = iMaxThickness; @@ -90,7 +89,6 @@ static const unsigned NB_VALUE_NOISE = 512; SpatialNoiseShader::SpatialNoiseShader( float iAmount, float ixScale, int nbOctave, bool smooth, bool pureRandom) - : StrokeShader() { _amount = iAmount; if (ixScale == 0) { @@ -169,7 +167,6 @@ SmoothingShader::SmoothingShader(int iNbIteration, real iAnisoNormal, real iAnisoCurvature, real iCarricatureFactor) - : StrokeShader() { _nbIterations = iNbIteration; _factorCurvature = ifactorCurvature; diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp index 36234ad619c..0d4f21d9b11 100644 --- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp @@ -170,13 +170,13 @@ int LengthDependingThicknessShader::shade(Stroke &stroke) const static const unsigned NB_VALUE_NOISE = 512; -ThicknessNoiseShader::ThicknessNoiseShader() : StrokeShader() +ThicknessNoiseShader::ThicknessNoiseShader() { _amplitude = 1.0f; _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE; } -ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod) : StrokeShader() +ThicknessNoiseShader::ThicknessNoiseShader(float iAmplitude, float iPeriod) { _amplitude = iAmplitude; _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE; @@ -256,13 +256,13 @@ int MaterialColorShader::shade(Stroke &stroke) const return 0; } -ColorNoiseShader::ColorNoiseShader() : StrokeShader() +ColorNoiseShader::ColorNoiseShader() { _amplitude = 1.0f; _scale = 1.0f / 2.0f / (float)NB_VALUE_NOISE; } -ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod) : StrokeShader() +ColorNoiseShader::ColorNoiseShader(float iAmplitude, float iPeriod) { _amplitude = iAmplitude; _scale = 1.0f / iPeriod / (float)NB_VALUE_NOISE; @@ -646,7 +646,7 @@ int GuidingLinesShader::shade(Stroke &stroke) const // ///////////////////////////////////////// -TipRemoverShader::TipRemoverShader(real tipLength) : StrokeShader() +TipRemoverShader::TipRemoverShader(real tipLength) { _tipLength = tipLength; } diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h index 8663cfd42bf..0ac0aa09cf9 100644 --- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h +++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.h @@ -56,7 +56,7 @@ class ConstantThicknessShader : public StrokeShader { * \param thickness: * The thickness that must be assigned to the stroke. */ - ConstantThicknessShader(float thickness) : StrokeShader() + ConstantThicknessShader(float thickness) { _thickness = thickness; } @@ -86,7 +86,7 @@ class ConstantThicknessShader : public StrokeShader { */ class ConstantExternThicknessShader : public StrokeShader { public: - ConstantExternThicknessShader(float thickness) : StrokeShader() + ConstantExternThicknessShader(float thickness) { _thickness = thickness; } @@ -120,7 +120,7 @@ class IncreasingThicknessShader : public StrokeShader { * \param iThicknessMax: * The second thickness value. */ - IncreasingThicknessShader(float iThicknessMin, float iThicknessMax) : StrokeShader() + IncreasingThicknessShader(float iThicknessMin, float iThicknessMax) { _ThicknessMin = iThicknessMin; _ThicknessMax = iThicknessMax; @@ -164,7 +164,7 @@ class ConstrainedIncreasingThicknessShader : public StrokeShader { * The ration thickness/length we don't want to exceed. */ ConstrainedIncreasingThicknessShader(float iThicknessMin, float iThicknessMax, float iRatio) - : StrokeShader() + { _ThicknessMin = iThicknessMin; _ThicknessMax = iThicknessMax; @@ -199,7 +199,7 @@ class LengthDependingThicknessShader : public StrokeShader { // l < 50 public: - LengthDependingThicknessShader(float iMinThickness, float iMaxThickness) : StrokeShader() + LengthDependingThicknessShader(float iMinThickness, float iMaxThickness) { _minThickness = iMinThickness; _maxThickness = iMaxThickness; @@ -265,7 +265,7 @@ class ConstantColorShader : public StrokeShader { * \param iAlpha: * The alpha value */ - ConstantColorShader(float iR, float iG, float iB, float iAlpha = 1.0f) : StrokeShader() + ConstantColorShader(float iR, float iG, float iB, float iAlpha = 1.0f) { _color[0] = iR; _color[1] = iG; @@ -322,7 +322,7 @@ class IncreasingColorShader : public StrokeShader { float iGM, float iBM, float iAlphaM) - : StrokeShader() + { _colorMin[0] = iRm; _colorMin[1] = iGm; @@ -353,7 +353,7 @@ class MaterialColorShader : public StrokeShader { float _coefficient; public: - MaterialColorShader(float coeff = 1.0f) : StrokeShader() + MaterialColorShader(float coeff = 1.0f) { _coefficient = coeff; } @@ -411,7 +411,7 @@ class BackboneStretcherShader : public StrokeShader { * \param iAmount: * The stretching amount value. */ - BackboneStretcherShader(float iAmount = 2.0f) : StrokeShader() + BackboneStretcherShader(float iAmount = 2.0f) { _amount = iAmount; } @@ -438,7 +438,7 @@ class SamplingShader : public StrokeShader { * \param sampling: * The sampling to use for the stroke resampling */ - SamplingShader(float sampling) : StrokeShader() + SamplingShader(float sampling) { _sampling = sampling; } @@ -457,7 +457,7 @@ class ExternalContourStretcherShader : public StrokeShader { float _amount; public: - ExternalContourStretcherShader(float iAmount = 2.0f) : StrokeShader() + ExternalContourStretcherShader(float iAmount = 2.0f) { _amount = iAmount; } @@ -486,7 +486,7 @@ class BezierCurveShader : public StrokeShader { * The error we're allowing for the approximation. * This error is the max distance allowed between the new curve and the original geometry. */ - BezierCurveShader(float error = 4.0) : StrokeShader() + BezierCurveShader(float error = 4.0) { _error = error; } @@ -517,7 +517,7 @@ class PolygonalizationShader : public StrokeShader { * geometry. The smaller, the closer the new stroke to the original one. * This error corresponds * to the maximum distance between the new stroke and the old one. */ - PolygonalizationShader(float iError) : StrokeShader() + PolygonalizationShader(float iError) { _error = iError; } @@ -548,7 +548,7 @@ class GuidingLinesShader : public StrokeShader { * "bbox". iOffset is the value of the displacement which is applied to this line along its * normal. */ - GuidingLinesShader(float iOffset) : StrokeShader() + GuidingLinesShader(float iOffset) { _offset = iOffset; } @@ -604,7 +604,7 @@ class BlenderTextureShader : public StrokeShader { * \param mtex: * The blender texture to use. */ - BlenderTextureShader(MTex *mtex) : StrokeShader() + BlenderTextureShader(MTex *mtex) { _mtex = mtex; _nodeTree = NULL; @@ -614,7 +614,7 @@ class BlenderTextureShader : public StrokeShader { * \param nodetree: * A node tree (of new shading nodes) to define textures. */ - BlenderTextureShader(bNodeTree *nodetree) : StrokeShader() + BlenderTextureShader(bNodeTree *nodetree) { _nodeTree = nodetree; _mtex = NULL; @@ -642,7 +642,7 @@ class StrokeTextureStepShader : public StrokeShader { * \param id: * The number of the preset to use. */ - StrokeTextureStepShader(float step) : StrokeShader() + StrokeTextureStepShader(float step) { _step = step; } diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp index 562ca32be78..4a0f31bc910 100644 --- a/source/blender/freestyle/intern/stroke/Chain.cpp +++ b/source/blender/freestyle/intern/stroke/Chain.cpp @@ -53,7 +53,7 @@ void Chain::push_viewedge_back(ViewEdge *iViewEdge, bool orientation) } // Ensure the continuity of underlying FEdges CurvePoint *cp = - _Vertices.back(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); + _Vertices.back(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.0f); SVertex *sv_first = (*vfirst); FEdge *fe = _fedgeB->duplicate(); fe->setTemporary(true); @@ -117,7 +117,7 @@ void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation) } // Ensure the continuity of underlying FEdges CurvePoint *cp = - _Vertices.front(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f); + _Vertices.front(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.0f); SVertex *sv_last = cp->A(); SVertex *sv_curr = (*v); FEdge *fe = (orientation) ? iViewEdge->fedgeA() : iViewEdge->fedgeB(); diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index 25954c7ecbf..307122833e4 100644 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -656,7 +656,7 @@ int Operators::sequentialSplit(UnaryPredicate0D &startingPred, goto error; } } while (!startingPred.result); - } while ((itStart != end) && (itStart != last)); + } while (!ELEM(itStart, end, last)); } // Update the current set of chains: @@ -885,7 +885,7 @@ static int __recursiveSplit(Chain *_curve, #endif real _min = FLT_MAX; ++it; - real mean = 0.f; + real mean = 0.0f; // soc unused - real variance = 0.0f; unsigned count = 0; CurveInternal::CurvePointIterator next = it; @@ -1122,7 +1122,7 @@ static Stroke *createStroke(Interface1D &inter) stroke->push_back(stroke_vertex); previous = current; ++it; - } while ((it != itend) && (it != itfirst)); + } while (!ELEM(it, itend, itfirst)); if (it == itfirst) { // Add last vertex: diff --git a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp index c2c263696bc..0e3fea3ddf8 100644 --- a/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/stroke/PSStrokeRenderer.cpp @@ -24,7 +24,7 @@ namespace Freestyle { -PSStrokeRenderer::PSStrokeRenderer(const char *iFileName) : StrokeRenderer() +PSStrokeRenderer::PSStrokeRenderer(const char *iFileName) { if (!iFileName) { iFileName = "freestyle.ps"; diff --git a/source/blender/freestyle/intern/stroke/Stroke.cpp b/source/blender/freestyle/intern/stroke/Stroke.cpp index aa87dc473e2..3e1463e8631 100644 --- a/source/blender/freestyle/intern/stroke/Stroke.cpp +++ b/source/blender/freestyle/intern/stroke/Stroke.cpp @@ -342,7 +342,7 @@ void StrokeAttribute::setAttributeVec3f(const char *iName, const Vec3f &att) /* */ /**********************************/ -StrokeVertex::StrokeVertex() : CurvePoint() +StrokeVertex::StrokeVertex() { _CurvilignAbscissa = 0.0f; _StrokeLength = 0.0f; @@ -691,7 +691,7 @@ int Stroke::Resample(float iSampling) ++next; } // add last: - if ((it != itend) && (next == itend) /* && (t == 0.f)*/) { + if ((it != itend) && (next == itend) /* && (t == 0.0f)*/) { newVertices.push_back(&(*it)); } diff --git a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp index f579bd72038..fa131743afc 100644 --- a/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/stroke/TextStrokeRenderer.cpp @@ -20,7 +20,7 @@ namespace Freestyle { -TextStrokeRenderer::TextStrokeRenderer(const char *iFileName) : StrokeRenderer() +TextStrokeRenderer::TextStrokeRenderer(const char *iFileName) { if (!iFileName) { iFileName = "freestyle.txt"; diff --git a/source/blender/freestyle/intern/view_map/BoxGrid.cpp b/source/blender/freestyle/intern/view_map/BoxGrid.cpp index 5a490e3c7cc..aea54afc0f5 100644 --- a/source/blender/freestyle/intern/view_map/BoxGrid.cpp +++ b/source/blender/freestyle/intern/view_map/BoxGrid.cpp @@ -242,7 +242,7 @@ bool BoxGrid::enableQI() const return _enableQI; } -BoxGrid::Transform::Transform() : GridHelpers::Transform() +BoxGrid::Transform::Transform() { } diff --git a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp index cb3a297076a..b53771ad2c2 100644 --- a/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp +++ b/source/blender/freestyle/intern/view_map/CulledOccluderSource.cpp @@ -191,7 +191,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSe // Either we have run out of FEdges, or we already have the one edge we need to determine // visibility Cull all remaining edges. - while (fe != NULL && fe != festart) { + while (!ELEM(fe, NULL, festart)) { fe->setIsInImage(false); fe = fe->nextEdge(); } @@ -253,7 +253,7 @@ void CulledOccluderSource::cullViewEdges(ViewMap &viewMap, bool extensiveFEdgeSe expandGridSpaceOccluderProscenium(fe); } fe = fe->nextEdge(); - } while (fe != NULL && fe != festart); + } while (!ELEM(fe, NULL, festart)); } } diff --git a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp index 0c6e9741fbd..1399ac396b0 100644 --- a/source/blender/freestyle/intern/view_map/SphericalGrid.cpp +++ b/source/blender/freestyle/intern/view_map/SphericalGrid.cpp @@ -238,7 +238,7 @@ bool SphericalGrid::enableQI() const return _enableQI; } -SphericalGrid::Transform::Transform() : GridHelpers::Transform() +SphericalGrid::Transform::Transform() { } diff --git a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp index aecd37fa0de..8866ec2e267 100644 --- a/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewEdgeXBuilder.cpp @@ -315,7 +315,7 @@ OWXFaceLayer ViewEdgeXBuilder::FindNextFaceLayer(const OWXFaceLayer &iFaceLayer) tend = iFaceLayer.fl->getSmoothEdge()->ta(); } // special case of EDGE_VERTEX config: - if ((tend == 0.0) || (tend == 1.0)) { + if (ELEM(tend, 0.0, 1.0)) { WVertex *nextVertex; if (tend == 0.0) { nextVertex = woeend->GetaVertex(); @@ -397,7 +397,7 @@ OWXFaceLayer ViewEdgeXBuilder::FindPreviousFaceLayer(const OWXFaceLayer &iFaceLa } // special case of EDGE_VERTEX config: - if ((tend == 0.0) || (tend == 1.0)) { + if (ELEM(tend, 0.0, 1.0)) { WVertex *previousVertex; if (tend == 0.0) { previousVertex = woebegin->GetaVertex(); diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp index fa2f95dac72..b4faee7946b 100644 --- a/source/blender/freestyle/intern/view_map/ViewMap.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp @@ -836,7 +836,7 @@ void ViewEdge::UpdateFEdges() do { currentEdge->setViewEdge(this); currentEdge = currentEdge->nextEdge(); - } while ((currentEdge != NULL) && (currentEdge != _FEdgeB)); + } while (!ELEM(currentEdge, NULL, _FEdgeB)); // last one _FEdgeB->setViewEdge(this); } diff --git a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp index a0989c52e4e..2ef01ce0874 100644 --- a/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp +++ b/source/blender/freestyle/intern/view_map/ViewMapBuilder.cpp @@ -2322,7 +2322,7 @@ struct less_Intersection { }; struct silhouette_binary_rule : public binary_rule<segment, segment> { - silhouette_binary_rule() : binary_rule<segment, segment>() + silhouette_binary_rule() { } diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp index f11f30130c8..57eca876913 100644 --- a/source/blender/freestyle/intern/winged_edge/WXEdge.cpp +++ b/source/blender/freestyle/intern/winged_edge/WXEdge.cpp @@ -119,7 +119,7 @@ WXSmoothEdge *WXFaceLayer::BuildSmoothEdge() else if (_nNullDotP == 1) { // that means that we have exactly one of the 2 extremities of our silhouette edge is a vertex // of the mesh - if ((_nPosDotP == 2) || (_nPosDotP == 0)) { + if (ELEM(_nPosDotP, 2, 0)) { _pSmoothEdge = NULL; return _pSmoothEdge; } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index aee345757c6..c67d622ffec 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -215,7 +215,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropDecorate(sub, false); uiItemR(sub, ptr, "invert_vertex_group", 0, "", ICON_ARROW_LEFTRIGHT); - col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to")); + col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To")); uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE); uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c index dec6ef63ffb..628c5bc0476 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c @@ -86,7 +86,7 @@ static void initData(GpencilModifierData *md) MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(ArrayGpencilModifierData), modifier); /* Open the first subpanel too, because it's activated by default. */ - md->ui_expand_flag = (1 << 0) | (1 << 1); + md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c index 6eb12974408..8f17be97710 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -101,6 +101,11 @@ static void deformStroke(GpencilModifierData *md, } BKE_gpencil_stroke_subdivide(gps, mmd->level, mmd->type); + + /* If the stroke is cyclic, must generate the closing geometry. */ + if (gps->flag & GP_STROKE_CYCLIC) { + BKE_gpencil_stroke_close(gps); + } } static void bakeModifier(struct Main *UNUSED(bmain), diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c index d29351646b9..6a630cbf978 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c @@ -97,7 +97,7 @@ static void deformStroke(GpencilModifierData *md, mmd->flag & GP_TEX_INVERT_MATERIAL)) { return; } - if ((mmd->mode == FILL) || (mmd->mode == STROKE_AND_FILL)) { + if (ELEM(mmd->mode, FILL, STROKE_AND_FILL)) { gps->uv_rotation += mmd->fill_rotation; gps->uv_translation[0] += mmd->fill_offset[0]; gps->uv_translation[1] += mmd->fill_offset[1]; @@ -105,7 +105,7 @@ static void deformStroke(GpencilModifierData *md, BKE_gpencil_stroke_geometry_update(gps); } - if ((mmd->mode == STROKE) || (mmd->mode == STROKE_AND_FILL)) { + if (ELEM(mmd->mode, STROKE, STROKE_AND_FILL)) { float totlen = 1.0f; if (mmd->fit_method == GP_TEX_FIT_STROKE) { totlen = 0.0f; @@ -127,6 +127,7 @@ static void deformStroke(GpencilModifierData *md, pt->uv_fac /= totlen; pt->uv_fac *= mmd->uv_scale; pt->uv_fac += mmd->uv_offset; + pt->uv_rot += mmd->alignment_rotation; } } } @@ -171,6 +172,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "fit_method", 0, IFACE_("Stroke Fit Method"), ICON_NONE); uiItemR(col, ptr, "uv_offset", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "alignment_rotation", 0, NULL, ICON_NONE); uiItemR(col, ptr, "uv_scale", 0, IFACE_("Scale"), ICON_NONE); } diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 2f12625acac..67cd1a61aed 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -34,6 +34,7 @@ extern "C" { #endif +struct GHash; struct GPUMaterial; struct GPUNode; struct GPUNodeLink; @@ -143,6 +144,7 @@ typedef void (*GPUMaterialEvalCallbackFn)(GPUMaterial *mat, GPUNodeLink *GPU_constant(const float *num); GPUNodeLink *GPU_uniform(const float *num); GPUNodeLink *GPU_attribute(GPUMaterial *mat, CustomDataType type, const char *name); +GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli); GPUNodeLink *GPU_image(GPUMaterial *mat, struct Image *ima, struct ImageUser *iuser, @@ -259,6 +261,31 @@ ListBase GPU_material_attributes(GPUMaterial *material); ListBase GPU_material_textures(GPUMaterial *material); ListBase GPU_material_volume_grids(GPUMaterial *material); +typedef struct GPUUniformAttr { + struct GPUUniformAttr *next, *prev; + + /* Meaningful part of the attribute set key. */ + char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + bool use_dupli; + + /* Helper fields used by code generation. */ + short id; + int users; +} GPUUniformAttr; + +typedef struct GPUUniformAttrList { + ListBase list; /* GPUUniformAttr */ + + /* List length and hash code precomputed for fast lookup and comparison. */ + unsigned int count, hash_code; +} GPUUniformAttrList; + +GPUUniformAttrList *GPU_material_uniform_attributes(GPUMaterial *material); + +struct GHash *GPU_uniform_attr_list_hash_new(const char *info); +void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src); +void GPU_uniform_attr_list_free(GPUUniformAttrList *set); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 9aaa5d4cae8..27a7ea1e6a5 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -413,6 +413,9 @@ void GPU_shader_free_builtin_shaders(void); * This makes sure the GPUVertexFormat name buffer does not overflow. */ #define GPU_MAX_ATTR 15 +/* Determined by the maximum uniform buffer size divided by chunk size. */ +#define GPU_MAX_UNIFORM_ATTR 8 + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/GPU_uniform_buffer.h b/source/blender/gpu/GPU_uniform_buffer.h index ebcaa80e6f6..4efac0a8c00 100644 --- a/source/blender/gpu/GPU_uniform_buffer.h +++ b/source/blender/gpu/GPU_uniform_buffer.h @@ -53,6 +53,7 @@ void GPU_uniformbuf_unbind(GPUUniformBuf *ubo); void GPU_uniformbuf_unbind_all(void); #define GPU_UBO_BLOCK_NAME "nodeTree" +#define GPU_ATTRIBUTE_UBO_BLOCK_NAME "uniformAttrs" #ifdef __cplusplus } diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index 7b0d8c274d3..d8e4c5377b0 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -38,6 +38,7 @@ extern "C" { #define GPU_INFO_SIZE 512 /* IMA_MAX_RENDER_TEXT */ #define GLA_PIXEL_OFS 0.375f +typedef struct GHash GHash; typedef struct GPUViewport GPUViewport; struct GPUFrameBuffer; @@ -57,6 +58,7 @@ typedef struct ViewportMemoryPool { struct BLI_memblock *images; struct GPUUniformBuf **matrices_ubo; struct GPUUniformBuf **obinfos_ubo; + struct GHash *obattrs_ubo_pool; uint ubo_len; } ViewportMemoryPool; diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 2d76e793fc0..3ebe2edc89e 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -377,6 +377,19 @@ static int codegen_process_uniforms_functions(GPUMaterial *material, BLI_freelistN(&ubo_inputs); } + /* Generate the uniform attribute UBO if necessary. */ + if (!BLI_listbase_is_empty(&graph->uniform_attrs.list)) { + BLI_dynstr_append(ds, "\nstruct UniformAttributes {\n"); + LISTBASE_FOREACH (GPUUniformAttr *, attr, &graph->uniform_attrs.list) { + BLI_dynstr_appendf(ds, " vec4 attr%d;\n", attr->id); + } + BLI_dynstr_append(ds, "};\n"); + BLI_dynstr_appendf(ds, "layout (std140) uniform %s {\n", GPU_ATTRIBUTE_UBO_BLOCK_NAME); + BLI_dynstr_append(ds, " UniformAttributes uniform_attrs[DRW_RESOURCE_CHUNK_LEN];\n"); + BLI_dynstr_append(ds, "};\n"); + BLI_dynstr_append(ds, "#define GET_UNIFORM_ATTR(name) (uniform_attrs[resource_id].name)\n"); + } + BLI_dynstr_append(ds, "\n"); return builtins; @@ -478,7 +491,10 @@ static void codegen_call_functions(DynStr *ds, GPUNodeGraph *graph, GPUOutput *f BLI_dynstr_appendf(ds, "cons%d", input->id); } else if (input->source == GPU_SOURCE_ATTR) { - BLI_dynstr_appendf(ds, "var%d", input->attr->id); + codegen_convert_datatype(ds, input->attr->gputype, input->type, "var", input->attr->id); + } + else if (input->source == GPU_SOURCE_UNIFORM_ATTR) { + BLI_dynstr_appendf(ds, "GET_UNIFORM_ATTR(attr%d)", input->uniform_attr->id); } BLI_dynstr_append(ds, ", "); @@ -799,6 +815,7 @@ GPUPass *GPU_generate_pass(GPUMaterial *material, /* Prune the unused nodes and extract attributes before compiling so the * generated VBOs are ready to accept the future shader. */ gpu_node_graph_prune_unused(graph); + gpu_node_graph_finalize_uniform_attrs(graph); int builtins = 0; LISTBASE_FOREACH (GPUNode *, node, &graph->nodes) { @@ -914,7 +931,7 @@ static int count_active_texture_sampler(GPUShader *shader, char *source) /* Move past "uniform". */ code += 7; /* Skip sampler type suffix. */ - while (*code != ' ' && *code != '\0') { + while (!ELEM(*code, ' ', '\0')) { code++; } /* Skip following spaces. */ diff --git a/source/blender/gpu/intern/gpu_immediate_util.c b/source/blender/gpu/intern/gpu_immediate_util.c index b8cd9fe356d..d18dc862ce7 100644 --- a/source/blender/gpu/intern/gpu_immediate_util.c +++ b/source/blender/gpu/intern/gpu_immediate_util.c @@ -455,8 +455,8 @@ void imm_draw_cylinder_fill_normal_3d( for (int j = 0; j < stacks; j++) { float fac1 = (float)j / (float)stacks; float fac2 = (float)(j + 1) / (float)stacks; - float r1 = base * (1.f - fac1) + top * fac1; - float r2 = base * (1.f - fac2) + top * fac2; + float r1 = base * (1.0f - fac1) + top * fac1; + float r2 = base * (1.0f - fac2) + top * fac2; float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); @@ -511,8 +511,8 @@ void imm_draw_cylinder_wire_3d( for (int j = 0; j < stacks; j++) { float fac1 = (float)j / (float)stacks; float fac2 = (float)(j + 1) / (float)stacks; - float r1 = base * (1.f - fac1) + top * fac1; - float r2 = base * (1.f - fac2) + top * fac2; + float r1 = base * (1.0f - fac1) + top * fac1; + float r2 = base * (1.0f - fac2) + top * fac2; float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); @@ -549,8 +549,8 @@ void imm_draw_cylinder_fill_3d( for (int j = 0; j < stacks; j++) { float fac1 = (float)j / (float)stacks; float fac2 = (float)(j + 1) / (float)stacks; - float r1 = base * (1.f - fac1) + top * fac1; - float r2 = base * (1.f - fac2) + top * fac2; + float r1 = base * (1.0f - fac1) + top * fac1; + float r2 = base * (1.0f - fac2) + top * fac2; float h1 = height * ((float)j / (float)stacks); float h2 = height * ((float)(j + 1) / (float)stacks); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 011d14673b4..a0fe77598f2 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -313,7 +313,7 @@ static float eval_profile(float r, short falloff_type, float sharpness, float pa { r = fabsf(r); - if (falloff_type == SHD_SUBSURFACE_BURLEY || falloff_type == SHD_SUBSURFACE_RANDOM_WALK) { + if (ELEM(falloff_type, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) { return burley_profile(r, param) / BURLEY_TRUNCATE_CDF; } if (falloff_type == SHD_SUBSURFACE_CUBIC) { @@ -353,7 +353,7 @@ static void compute_sss_kernel( /* Christensen-Burley fitting */ float l[3], d[3]; - if (falloff_type == SHD_SUBSURFACE_BURLEY || falloff_type == SHD_SUBSURFACE_RANDOM_WALK) { + if (ELEM(falloff_type, SHD_SUBSURFACE_BURLEY, SHD_SUBSURFACE_RANDOM_WALK)) { mul_v3_v3fl(l, rad, 0.25f * M_1_PI); const float A = 1.0f; const float s = 1.9f - A + 3.5f * (A - 0.8f) * (A - 0.8f); @@ -584,6 +584,12 @@ ListBase GPU_material_volume_grids(GPUMaterial *material) return material->graph.volume_grids; } +GPUUniformAttrList *GPU_material_uniform_attributes(GPUMaterial *material) +{ + GPUUniformAttrList *attrs = &material->graph.uniform_attrs; + return attrs->count > 0 ? attrs : NULL; +} + void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link) { if (!material->graph.outlink) { diff --git a/source/blender/gpu/intern/gpu_node_graph.c b/source/blender/gpu/intern/gpu_node_graph.c index c890d56994f..2a2a51e32b3 100644 --- a/source/blender/gpu/intern/gpu_node_graph.c +++ b/source/blender/gpu/intern/gpu_node_graph.c @@ -132,7 +132,14 @@ static void gpu_node_input_link(GPUNode *node, GPUNodeLink *link, const eGPUType case GPU_NODE_LINK_ATTR: input->source = GPU_SOURCE_ATTR; input->attr = link->attr; - input->attr->gputype = type; + /* Failsafe handling if the same attribute is used with different datatypes for + * some reason (only really makes sense with float/vec2/vec3/vec4 though). This + * can happen if mixing the generic Attribute node with specialized ones. */ + CLAMP_MIN(input->attr->gputype, type); + break; + case GPU_NODE_LINK_UNIFORM_ATTR: + input->source = GPU_SOURCE_UNIFORM_ATTR; + input->uniform_attr = link->uniform_attr; break; case GPU_NODE_LINK_CONSTANT: input->source = (type == GPU_CLOSURE) ? GPU_SOURCE_STRUCT : GPU_SOURCE_CONSTANT; @@ -259,8 +266,90 @@ static void gpu_node_output(GPUNode *node, const eGPUType type, GPUNodeLink **li BLI_addtail(&node->outputs, output); } +/* Uniform Attribute Functions */ + +static int uniform_attr_sort_cmp(const void *a, const void *b) +{ + const GPUUniformAttr *attr_a = a, *attr_b = b; + + int cmps = strcmp(attr_a->name, attr_b->name); + if (cmps != 0) { + return cmps > 0 ? 1 : 0; + } + + return (attr_a->use_dupli && !attr_b->use_dupli); +} + +static unsigned int uniform_attr_list_hash(const void *key) +{ + const GPUUniformAttrList *attrs = key; + return attrs->hash_code; +} + +static bool uniform_attr_list_cmp(const void *a, const void *b) +{ + const GPUUniformAttrList *set_a = a, *set_b = b; + + if (set_a->hash_code != set_b->hash_code || set_a->count != set_b->count) { + return true; + } + + GPUUniformAttr *attr_a = set_a->list.first, *attr_b = set_b->list.first; + + for (; attr_a && attr_b; attr_a = attr_a->next, attr_b = attr_b->next) { + if (!STREQ(attr_a->name, attr_b->name) || attr_a->use_dupli != attr_b->use_dupli) { + return true; + } + } + + return attr_a || attr_b; +} + +struct GHash *GPU_uniform_attr_list_hash_new(const char *info) +{ + return BLI_ghash_new(uniform_attr_list_hash, uniform_attr_list_cmp, info); +} + +void GPU_uniform_attr_list_copy(GPUUniformAttrList *dest, GPUUniformAttrList *src) +{ + dest->count = src->count; + dest->hash_code = src->hash_code; + BLI_duplicatelist(&dest->list, &src->list); +} + +void GPU_uniform_attr_list_free(GPUUniformAttrList *set) +{ + set->count = 0; + set->hash_code = 0; + BLI_freelistN(&set->list); +} + +void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph) +{ + GPUUniformAttrList *attrs = &graph->uniform_attrs; + BLI_assert(attrs->count == BLI_listbase_count(&attrs->list)); + + /* Sort the attributes by name to ensure a stable order. */ + BLI_listbase_sort(&attrs->list, uniform_attr_sort_cmp); + + /* Compute the indices and the hash code. */ + int next_id = 0; + attrs->hash_code = 0; + + LISTBASE_FOREACH (GPUUniformAttr *, attr, &attrs->list) { + attr->id = next_id++; + + attrs->hash_code ^= BLI_ghashutil_strhash_p(attr->name); + + if (attr->use_dupli) { + attrs->hash_code ^= BLI_ghashutil_uinthash(attr->id); + } + } +} + /* Attributes and Textures */ +/** Add a new varying attribute of given type and name. Returns NULL if out of slots. */ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, CustomDataType type, const char *name) @@ -296,6 +385,38 @@ static GPUMaterialAttribute *gpu_node_graph_add_attribute(GPUNodeGraph *graph, return attr; } +/** Add a new uniform attribute of given type and name. Returns NULL if out of slots. */ +static GPUUniformAttr *gpu_node_graph_add_uniform_attribute(GPUNodeGraph *graph, + const char *name, + bool use_dupli) +{ + /* Find existing attribute. */ + GPUUniformAttrList *attrs = &graph->uniform_attrs; + GPUUniformAttr *attr = attrs->list.first; + + for (; attr; attr = attr->next) { + if (STREQ(attr->name, name) && attr->use_dupli == use_dupli) { + break; + } + } + + /* Add new requested attribute if it's within GPU limits. */ + if (attr == NULL && attrs->count < GPU_MAX_UNIFORM_ATTR) { + attr = MEM_callocN(sizeof(*attr), __func__); + STRNCPY(attr->name, name); + attr->use_dupli = use_dupli; + attr->id = -1; + BLI_addtail(&attrs->list, attr); + attrs->count++; + } + + if (attr != NULL) { + attr->users++; + } + + return attr; +} + static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph, Image *ima, ImageUser *iuser, @@ -369,6 +490,7 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const ch GPUNodeGraph *graph = gpu_material_node_graph(mat); GPUMaterialAttribute *attr = gpu_node_graph_add_attribute(graph, type, name); + /* Dummy fallback if out of slots. */ if (attr == NULL) { static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f}; return GPU_constant(zero_data); @@ -380,6 +502,23 @@ GPUNodeLink *GPU_attribute(GPUMaterial *mat, const CustomDataType type, const ch return link; } +GPUNodeLink *GPU_uniform_attribute(GPUMaterial *mat, const char *name, bool use_dupli) +{ + GPUNodeGraph *graph = gpu_material_node_graph(mat); + GPUUniformAttr *attr = gpu_node_graph_add_uniform_attribute(graph, name, use_dupli); + + /* Dummy fallback if out of slots. */ + if (attr == NULL) { + static const float zero_data[GPU_MAX_CONSTANT_DATA] = {0.0f}; + return GPU_constant(zero_data); + } + + GPUNodeLink *link = gpu_node_link_create(); + link->link_type = GPU_NODE_LINK_UNIFORM_ATTR; + link->uniform_attr = attr; + return link; +} + GPUNodeLink *GPU_constant(const float *num) { GPUNodeLink *link = gpu_node_link_create(); @@ -616,6 +755,9 @@ static void gpu_inputs_free(ListBase *inputs) if (input->source == GPU_SOURCE_ATTR) { input->attr->users--; } + else if (input->source == GPU_SOURCE_UNIFORM_ATTR) { + input->uniform_attr->users--; + } else if (ELEM(input->source, GPU_SOURCE_TEX, GPU_SOURCE_TEX_TILED_MAPPING)) { input->texture->users--; } @@ -671,6 +813,7 @@ void gpu_node_graph_free(GPUNodeGraph *graph) BLI_freelistN(&graph->volume_grids); BLI_freelistN(&graph->textures); BLI_freelistN(&graph->attributes); + GPU_uniform_attr_list_free(&graph->uniform_attrs); } /* Prune Unused Nodes */ @@ -735,4 +878,13 @@ void gpu_node_graph_prune_unused(GPUNodeGraph *graph) BLI_freelinkN(&graph->volume_grids, grid); } } + + GPUUniformAttrList *uattrs = &graph->uniform_attrs; + + LISTBASE_FOREACH_MUTABLE (GPUUniformAttr *, attr, &uattrs->list) { + if (attr->users == 0) { + BLI_freelinkN(&uattrs->list, attr); + uattrs->count--; + } + } } diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index 7265abf4d65..a0e6298cd92 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -42,6 +42,7 @@ typedef enum eGPUDataSource { GPU_SOURCE_CONSTANT, GPU_SOURCE_UNIFORM, GPU_SOURCE_ATTR, + GPU_SOURCE_UNIFORM_ATTR, GPU_SOURCE_BUILTIN, GPU_SOURCE_STRUCT, GPU_SOURCE_TEX, @@ -53,6 +54,7 @@ typedef enum eGPUDataSource { typedef enum { GPU_NODE_LINK_NONE = 0, GPU_NODE_LINK_ATTR, + GPU_NODE_LINK_UNIFORM_ATTR, GPU_NODE_LINK_BUILTIN, GPU_NODE_LINK_COLORBAND, GPU_NODE_LINK_CONSTANT, @@ -96,6 +98,8 @@ struct GPUNodeLink { struct GPUOutput *output; /* GPU_NODE_LINK_ATTR */ struct GPUMaterialAttribute *attr; + /* GPU_NODE_LINK_UNIFORM_ATTR */ + struct GPUUniformAttr *uniform_attr; /* GPU_NODE_LINK_IMAGE_BLENDER */ struct GPUMaterialTexture *texture; }; @@ -130,6 +134,8 @@ typedef struct GPUInput { struct GPUMaterialTexture *texture; /* GPU_SOURCE_ATTR */ struct GPUMaterialAttribute *attr; + /* GPU_SOURCE_UNIFORM_ATTR */ + struct GPUUniformAttr *uniform_attr; /* GPU_SOURCE_VOLUME_GRID | GPU_SOURCE_VOLUME_GRID_TRANSFORM */ struct GPUMaterialVolumeGrid *volume_grid; }; @@ -146,11 +152,15 @@ typedef struct GPUNodeGraph { ListBase attributes; ListBase textures; ListBase volume_grids; + + /* The list of uniform attributes. */ + GPUUniformAttrList uniform_attrs; } GPUNodeGraph; /* Node Graph */ void gpu_node_graph_prune_unused(GPUNodeGraph *graph); +void gpu_node_graph_finalize_uniform_attrs(GPUNodeGraph *graph); void gpu_node_graph_free_nodes(GPUNodeGraph *graph); void gpu_node_graph_free(GPUNodeGraph *graph); diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 9063c8bdbce..188c8786665 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -1023,6 +1023,9 @@ void GPU_viewport_free(GPUViewport *viewport) } BLI_memblock_destroy(viewport->vmempool.images, NULL); } + if (viewport->vmempool.obattrs_ubo_pool != NULL) { + DRW_uniform_attrs_pool_free(viewport->vmempool.obattrs_ubo_pool); + } for (int i = 0; i < viewport->vmempool.ubo_len; i++) { GPU_uniformbuf_free(viewport->vmempool.matrices_ubo[i]); diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh index cf159a60b01..1de366fc844 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.hh +++ b/source/blender/gpu/opengl/gl_framebuffer.hh @@ -67,11 +67,11 @@ class GLFrameBuffer : public FrameBuffer { /** * Special frame-buffer encapsulating internal window frame-buffer. * (i.e.: #GL_FRONT_LEFT, #GL_BACK_RIGHT, ...) - * \param ctx: context the handle is from. - * \param target: the internal GL name (i.e: #GL_BACK_LEFT). - * \param fbo: the (optional) already created object for some implementation. Default is 0. - * \param w: buffer width. - * \param h: buffer height. + * \param ctx: Context the handle is from. + * \param target: The internal GL name (i.e: #GL_BACK_LEFT). + * \param fbo: The (optional) already created object for some implementation. Default is 0. + * \param w: Buffer width. + * \param h: Buffer height. **/ GLFrameBuffer(const char *name, GLContext *ctx, GLenum target, GLuint fbo, int w, int h); diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index 5483f889a8a..8f2e0e2a72d 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -42,7 +42,7 @@ namespace blender::gpu { /** \name GLStateManager * \{ */ -GLStateManager::GLStateManager(void) : StateManager() +GLStateManager::GLStateManager(void) { /* Set other states that never change. */ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); diff --git a/source/blender/gpu/opengl/gl_vertex_array.cc b/source/blender/gpu/opengl/gl_vertex_array.cc index ed6699e51f3..7585a327b3b 100644 --- a/source/blender/gpu/opengl/gl_vertex_array.cc +++ b/source/blender/gpu/opengl/gl_vertex_array.cc @@ -76,7 +76,7 @@ static uint16_t vbo_bind(const ShaderInterface *interface, enabled_attrib |= (1 << input->location); - if (a->comp_len == 16 || a->comp_len == 12 || a->comp_len == 8) { + if (ELEM(a->comp_len, 16, 12, 8)) { BLI_assert(a->fetch_mode == GPU_FETCH_FLOAT); BLI_assert(a->comp_type == GPU_COMP_F32); for (int i = 0; i < a->comp_len / 4; i++) { diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl index 10e1b4563bc..faf37db3ea6 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_attribute.glsl @@ -1,6 +1,8 @@ -void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf) +void node_attribute( + vec4 attr, out vec4 outcol, out vec3 outvec, out float outf, out float outalpha) { - outcol = vec4(attr, 1.0); - outvec = attr; - outf = avg(attr); + outcol = vec4(attr.xyz, 1.0); + outvec = attr.xyz; + outf = avg(attr.xyz); + outalpha = attr.w; } diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp index e127e377858..3efb78fe1ca 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.cpp +++ b/source/blender/ikplugin/intern/itasc_plugin.cpp @@ -965,18 +965,18 @@ static int convert_channels(struct Depsgraph *depsgraph, /* set DoF flag */ flag = 0; if (!(pchan->ikflag & BONE_IK_NO_XDOF) && !(pchan->ikflag & BONE_IK_NO_XDOF_TEMP) && - (!(pchan->ikflag & BONE_IK_XLIMIT) || pchan->limitmin[0] < 0.f || - pchan->limitmax[0] > 0.f)) { + (!(pchan->ikflag & BONE_IK_XLIMIT) || pchan->limitmin[0] < 0.0f || + pchan->limitmax[0] > 0.0f)) { flag |= IK_XDOF; } if (!(pchan->ikflag & BONE_IK_NO_YDOF) && !(pchan->ikflag & BONE_IK_NO_YDOF_TEMP) && - (!(pchan->ikflag & BONE_IK_YLIMIT) || pchan->limitmin[1] < 0.f || - pchan->limitmax[1] > 0.f)) { + (!(pchan->ikflag & BONE_IK_YLIMIT) || pchan->limitmin[1] < 0.0f || + pchan->limitmax[1] > 0.0f)) { flag |= IK_YDOF; } if (!(pchan->ikflag & BONE_IK_NO_ZDOF) && !(pchan->ikflag & BONE_IK_NO_ZDOF_TEMP) && - (!(pchan->ikflag & BONE_IK_ZLIMIT) || pchan->limitmin[2] < 0.f || - pchan->limitmax[2] > 0.f)) { + (!(pchan->ikflag & BONE_IK_ZLIMIT) || pchan->limitmin[2] < 0.0f || + pchan->limitmax[2] > 0.0f)) { flag |= IK_ZDOF; } @@ -1535,7 +1535,7 @@ static IK_Scene *convert_tree( /* add the end effector * estimate the average bone length, used to clamp feedback error */ - for (bonecnt = 0, bonelen = 0.f, a = iktarget->channel; a >= 0; + for (bonecnt = 0, bonelen = 0.0f, a = iktarget->channel; a >= 0; a = tree->parent[a], bonecnt++) { bonelen += ikscene->blScale * tree->pchan[a]->bone->length; } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 839b0b12b83..2f848b5be08 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -684,6 +684,8 @@ void IMB_rectfill_area(struct ImBuf *ibuf, int x2, int y2, struct ColorManagedDisplay *display); +void IMB_rectfill_area_replace( + const struct ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2); void IMB_rectfill_alpha(struct ImBuf *ibuf, const float value); /* This should not be here, really, diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c index ab818d451d6..f897b1c6df3 100644 --- a/source/blender/imbuf/intern/bmp.c +++ b/source/blender/imbuf/intern/bmp.c @@ -301,7 +301,7 @@ int imb_savebmp(ImBuf *ibuf, const char *filepath, int UNUSED(flags)) BMPINFOHEADER infoheader; const size_t bytes_per_pixel = (ibuf->planes + 7) >> 3; - BLI_assert(bytes_per_pixel == 1 || bytes_per_pixel == 3); + BLI_assert(ELEM(bytes_per_pixel, 1, 3)); const size_t pad_bytes_per_scanline = (4 - ibuf->x * bytes_per_pixel % 4) % 4; const size_t bytesize = (ibuf->x * bytes_per_pixel + pad_bytes_per_scanline) * ibuf->y; diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index 73003265d8d..b7a15812547 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -277,9 +277,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf } dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample; - if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 && - dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 && - dpx->element[i].bitsPerSample != 16) { + if (!ELEM(dpx->element[i].bitsPerSample, 1, 8, 10, 12, 16)) { if (verbose) { printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, @@ -348,8 +346,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf if (dpx->element[i].refHighQuantity == DPX_UNDEFINED_R32 || isnan(dpx->element[i].refHighQuantity)) { - if (dpx->element[i].transfer == transfer_PrintingDensity || - dpx->element[i].transfer == transfer_Logarithmic) { + if (ELEM(dpx->element[i].transfer, transfer_PrintingDensity, transfer_Logarithmic)) { dpx->element[i].refHighQuantity = 2.048f; } else { diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index 446f360a3e7..d5f5691c5f0 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -215,7 +215,7 @@ size_t getRowLength(size_t width, LogImageElement logElement) if (logElement.packing == 0) { return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4; } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return ((width * logElement.depth - 1) / 3 + 1) * 4; } break; @@ -223,7 +223,7 @@ size_t getRowLength(size_t width, LogImageElement logElement) if (logElement.packing == 0) { return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4; } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return width * logElement.depth * 2; } break; @@ -442,8 +442,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB for (i = 0; i < logImage->numElements; i++) { /* descriptor_Depth and descriptor_Composite are not supported */ - if (logImage->element[i].descriptor != descriptor_Depth && - logImage->element[i].descriptor != descriptor_Composite) { + if (!ELEM(logImage->element[i].descriptor, descriptor_Depth, descriptor_Composite)) { /* Allocate memory */ elementData[i] = imb_alloc_pixels( logImage->width, logImage->height, logImage->element[i].depth, sizeof(float), __func__); @@ -680,7 +679,7 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle if (logElement.packing == 0) { return logImageElementGetData10Packed(logImage, logElement, data); } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return logImageElementGetData10(logImage, logElement, data); } break; @@ -689,7 +688,7 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle if (logElement.packing == 0) { return logImageElementGetData12Packed(logImage, logElement, data); } - else if (logElement.packing == 1 || logElement.packing == 2) { + else if (ELEM(logElement.packing, 1, 2)) { return logImageElementGetData12(logImage, logElement, data); } break; diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 8005049eab2..c169633fa3c 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -54,10 +54,11 @@ #include "BKE_context.h" #include "BKE_image.h" #include "BKE_main.h" -#include "BKE_sequencer.h" #include "RNA_define.h" +#include "SEQ_sequencer.h" + #include <ocio_capi.h> /* -------------------------------------------------------------------- */ diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c index 12c4c63849c..214cdf1b63b 100644 --- a/source/blender/imbuf/intern/iris.c +++ b/source/blender/imbuf/intern/iris.c @@ -286,7 +286,7 @@ struct ImBuf *imb_loadiris(const uchar *mem, size_t size, int flags, char colors rle = ISRLE(image.type); bpp = BPP(image.type); - if (bpp != 1 && bpp != 2) { + if (!ELEM(bpp, 1, 2)) { fprintf(stderr, "longimagedata: image must have 1 or 2 byte per pix chan\n"); return NULL; } diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c index c7e4fe45a26..97af0eb8feb 100644 --- a/source/blender/imbuf/intern/jp2.c +++ b/source/blender/imbuf/intern/jp2.c @@ -126,6 +126,7 @@ static void info_callback(const char *msg, void *client_data) } \ (void)0 +/* -------------------------------------------------------------------- */ /** \name Buffer Stream * \{ */ @@ -217,6 +218,7 @@ static opj_stream_t *opj_stream_create_from_buffer(struct BufInfo *p_file, /** \} */ +/* -------------------------------------------------------------------- */ /** \name File Stream * \{ */ diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c index 525284bd867..38f8806d910 100644 --- a/source/blender/imbuf/intern/jpeg.c +++ b/source/blender/imbuf/intern/jpeg.c @@ -246,7 +246,7 @@ static boolean handle_app1(j_decompress_ptr cinfo) INPUT_BYTE(cinfo, neogeo[i], return false); } length = 0; - if (STREQLEN(neogeo, "NeoGeo", 6)) { + if (STRPREFIX(neogeo, "NeoGeo")) { struct NeoGeo_Word *neogeo_word = (struct NeoGeo_Word *)(neogeo + 6); ibuf_quality = neogeo_word->quality; } @@ -362,7 +362,7 @@ static ImBuf *ibJpegImageFromCinfo(struct jpeg_decompress_struct *cinfo, int fla * That is why we need split it to the * common key/value here. */ - if (!STREQLEN(str, "Blender", 7)) { + if (!STRPREFIX(str, "Blender")) { /* * Maybe the file have text that * we don't know "what it's", in that diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp index ca70ec633c1..08577f767e7 100644 --- a/source/blender/imbuf/intern/openexr/openexr_api.cpp +++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp @@ -1210,7 +1210,7 @@ void IMB_exr_read_channels(void *handle) "BlenderMultiChannel"); /* 'previous multilayer attribute, flipped. */ - short flip = (ta && STREQLEN(ta->value().c_str(), "Blender V2.43", 13)); + short flip = (ta && STRPREFIX(ta->value().c_str(), "Blender V2.43")); exr_printf( "\nIMB_exr_read_channels\n%s %-6s %-22s " @@ -1610,7 +1610,7 @@ static ExrHandle *imb_exr_begin_read_mem(IStream &file_stream, memset(lookup, 0, sizeof(lookup)); /* we can have RGB(A), XYZ(W), UVA */ - if (pass->totchan == 3 || pass->totchan == 4) { + if (ELEM(pass->totchan, 3, 4)) { if (pass->chan[0]->chan_id == 'B' || pass->chan[1]->chan_id == 'B' || pass->chan[2]->chan_id == 'B') { lookup[(unsigned int)'R'] = 0; diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index dbae641f707..c4fbd3f7563 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -521,7 +521,7 @@ static void imb_png_warning(png_structp UNUSED(png_ptr), png_const_charp message * and with new libpng it became too much picky, giving a warning on * the splash screen even. */ - if ((G.debug & G_DEBUG) == 0 && STREQLEN(message, "iCCP", 4)) { + if ((G.debug & G_DEBUG) == 0 && STRPREFIX(message, "iCCP")) { return; } fprintf(stderr, "libpng warning: %s\n", message); diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c index 3dd26e1f7a2..4cd44a25cb8 100644 --- a/source/blender/imbuf/intern/radiance_hdr.c +++ b/source/blender/imbuf/intern/radiance_hdr.c @@ -329,9 +329,9 @@ static int fwritecolrs( fcol[BLU] = (channels >= 3) ? fpscan[j + 2] : fpscan[j]; } else { - fcol[RED] = (float)ibufscan[j] / 255.f; - fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.f; - fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.f; + fcol[RED] = (float)ibufscan[j] / 255.0f; + fcol[GRN] = (float)((channels >= 2) ? ibufscan[j + 1] : ibufscan[j]) / 255.0f; + fcol[BLU] = (float)((channels >= 3) ? ibufscan[j + 2] : ibufscan[j]) / 255.0f; } FLOAT2RGBE(fcol, rgbe); COPY_RGBE(rgbe, rgbe_scan[i]); diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 8b4f33bb306..cdc8cd1068c 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -1069,8 +1069,11 @@ void IMB_rectblend_threaded(ImBuf *dbuf, } } -/* fill */ - +/** + * Replace pixels of entire image with solid color. + * \param ibuf: An image to be filled with color. It must be 4 channel image. + * \param col: RGBA color, which is assigned directly to both byte (via scaling) and float buffers. + */ void IMB_rectfill(ImBuf *drect, const float col[4]) { int num; @@ -1103,6 +1106,61 @@ void IMB_rectfill(ImBuf *drect, const float col[4]) } } +/** + * Replace pixels of image area with solid color. + * \param ibuf: an image to be filled with color. It must be 4 channel image. + * \param col: RGBA color, which is assigned directly to both byte (via scaling) and float buffers. + * \param x1, y1, x2, y2: (x1, y1) defines starting point of the rectangular area to be filled, + * (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that + * x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the + * order the area between x1 and x2, and y1 and y2 is filled. + */ +void IMB_rectfill_area_replace( + const ImBuf *ibuf, const float col[4], int x1, int y1, int x2, int y2) +{ + /* Sanity checks. */ + BLI_assert(ibuf->channels == 4); + + if (ibuf->channels != 4) { + return; + } + + int width = ibuf->x; + int height = ibuf->y; + CLAMP(x1, 0, width); + CLAMP(x2, 0, width); + CLAMP(y1, 0, height); + CLAMP(y2, 0, height); + + if (x1 > x2) { + SWAP(int, x1, x2); + } + if (y1 > y2) { + SWAP(int, y1, y2); + } + if (x1 == x2 || y1 == y2) { + return; + } + + unsigned char col_char[4] = {col[0] * 255, col[1] * 255, col[2] * 255, col[3] * 255}; + + for (int y = y1; y < y2; y++) { + for (int x = x1; x < x2; x++) { + size_t offset = ((size_t)ibuf->x) * y * 4 + 4 * x; + + if (ibuf->rect) { + unsigned char *rrect = (unsigned char *)ibuf->rect + offset; + memcpy(rrect, &col_char, sizeof(unsigned char) * 4); + } + + if (ibuf->rect_float) { + float *rrectf = ibuf->rect_float + offset; + memcpy(rrectf, &col, sizeof(float) * 4); + } + } + } +} + void buf_rectfill_area(unsigned char *rect, float *rectf, int width, @@ -1214,6 +1272,21 @@ void buf_rectfill_area(unsigned char *rect, } } +/** + * Blend pixels of image area with solid color. + * + * For images with `uchar` buffer use color matching image colorspace. + * For images with float buffer use color display colorspace. + * If display colorspace can not be referenced, use color in SRGB colorspace. + * + * \param ibuf: an image to be filled with color. It must be 4 channel image. + * \param col: RGBA color. + * \param x1, y1, x2, y2: (x1, y1) defines starting point of the rectangular area to be filled, + * (x2, y2) is the end point. Note that values are allowed to be loosely ordered, which means that + * x2 is allowed to be lower than x1, as well as y2 is allowed to be lower than y1. No matter the + * order the area between x1 and x2, and y1 and y2 is filled. + * \param display: colorspace reference for display space. + */ void IMB_rectfill_area(ImBuf *ibuf, const float col[4], int x1, diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c index 5f373e4bd3a..5a3cbd375b6 100644 --- a/source/blender/imbuf/intern/targa.c +++ b/source/blender/imbuf/intern/targa.c @@ -703,7 +703,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, return ibuf; } - if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */ + if (!ELEM(tga.imgtyp, 1, 9)) { /* happens sometimes (beuh) */ if (cmap) { MEM_freeN(cmap); cmap = NULL; @@ -777,7 +777,7 @@ ImBuf *imb_loadtarga(const unsigned char *mem, ibuf->planes = 24; } - if (tga.imgtyp == 3 || tga.imgtyp == 11) { + if (ELEM(tga.imgtyp, 3, 11)) { uchar *crect; unsigned int *lrect, col; diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index cd0b012d809..bc69a14fa47 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -888,7 +888,7 @@ int imb_savetiff(ImBuf *ibuf, const char *filepath, int flags) /* convert from float source */ float rgb[4]; - if (channels_in_float == 3 || channels_in_float == 4) { + if (ELEM(channels_in_float, 3, 4)) { if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) { /* Float buffer was managed already, no need in color * space conversion. diff --git a/source/blender/io/alembic/exporter/abc_export_capi.cc b/source/blender/io/alembic/exporter/abc_export_capi.cc index 892109dc578..7663d1790b6 100644 --- a/source/blender/io/alembic/exporter/abc_export_capi.cc +++ b/source/blender/io/alembic/exporter/abc_export_capi.cc @@ -236,7 +236,7 @@ bool ABC_export(Scene *scene, else { /* Fake a job context, so that we don't need NULL pointer checks while exporting. */ short stop = 0, do_update = 0; - float progress = 0.f; + float progress = 0.0f; blender::io::alembic::export_startjob(job, &stop, &do_update, &progress); blender::io::alembic::export_endjob(job); diff --git a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc index 255803a6bfb..334a26df784 100644 --- a/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc +++ b/source/blender/io/alembic/exporter/abc_subdiv_disabler.cc @@ -92,7 +92,7 @@ ModifierData *SubdivModifierDisabler::get_subdiv_modifier(Scene *scene, Object * } /* mesh is not a subsurf. break */ - if ((md->type != eModifierType_Displace) && (md->type != eModifierType_ParticleSystem)) { + if (!ELEM(md->type, eModifierType_Displace, eModifierType_ParticleSystem)) { return nullptr; } } diff --git a/source/blender/io/alembic/intern/alembic_capi.cc b/source/blender/io/alembic/intern/alembic_capi.cc index eba7f64db02..026a11ca25e 100644 --- a/source/blender/io/alembic/intern/alembic_capi.cc +++ b/source/blender/io/alembic/intern/alembic_capi.cc @@ -709,7 +709,7 @@ bool ABC_import(bContext *C, else { /* Fake a job context, so that we don't need NULL pointer checks while importing. */ short stop = 0, do_update = 0; - float progress = 0.f; + float progress = 0.0f; import_startjob(job, &stop, &do_update, &progress); import_endjob(job); diff --git a/source/blender/io/alembic/tests/abc_matrix_test.cc b/source/blender/io/alembic/tests/abc_matrix_test.cc index fc5b645987e..c6d7245a52c 100644 --- a/source/blender/io/alembic/tests/abc_matrix_test.cc +++ b/source/blender/io/alembic/tests/abc_matrix_test.cc @@ -14,7 +14,7 @@ TEST(abc_matrix, CreateRotationMatrixY_YfromZ) float rot_x_mat[3][3]; float rot_y_mat[3][3]; float rot_z_mat[3][3]; - float euler[3] = {0.f, M_PI_4, 0.f}; + float euler[3] = {0.0f, M_PI_4, 0.0f}; /* Construct expected matrices */ float unit[3][3]; @@ -41,7 +41,7 @@ TEST(abc_matrix, CreateRotationMatrixZ_YfromZ) float rot_x_mat[3][3]; float rot_y_mat[3][3]; float rot_z_mat[3][3]; - float euler[3] = {0.f, 0.f, M_PI_4}; + float euler[3] = {0.0f, 0.0f, M_PI_4}; /* Construct expected matrices */ float unit[3][3]; @@ -150,25 +150,25 @@ TEST(abc_matrix, CopyM44AxisSwap_YfromZ) * above. This matrix was created by rotating a cube in Blender over * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */ float input[4][4] = { - {0.81379765272f, 0.4698463380336f, -0.342020124197f, 0.f}, - {-0.44096961617f, 0.8825641274452f, 0.163175910711f, 0.f}, - {0.37852230668f, 0.0180283170193f, 0.925416588783f, 0.f}, - {1.f, 2.f, 3.f, 1.f}, + {0.81379765272f, 0.4698463380336f, -0.342020124197f, 0.0f}, + {-0.44096961617f, 0.8825641274452f, 0.163175910711f, 0.0f}, + {0.37852230668f, 0.0180283170193f, 0.925416588783f, 0.0f}, + {1.0f, 2.0f, 3.0f, 1.0f}, }; copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP); /* Check the resulting rotation & translation. */ - float trans[4] = {1.f, 3.f, -2.f, 1.f}; + float trans[4] = {1.0f, 3.0f, -2.0f, 1.0f}; EXPECT_V4_NEAR(trans, result[3], 1e-5f); /* This matrix was created by rotating a cube in Blender over * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */ float expect[4][4] = { - {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f}, - {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.f}, - {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.f}, - {1.f, 3.f, -2.f, 1.f}, + {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.0f}, + {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.0f}, + {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.0f}, + {1.0f, 3.0f, -2.0f, 1.0f}, }; EXPECT_M4_NEAR(expect, result, 1e-5f); } @@ -182,10 +182,10 @@ TEST(abc_matrix, CopyM44AxisSwapWithScale_YfromZ) * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3), * and scaling by (4, 5, 6). */ float input[4][4] = { - {3.25519061088f, 1.8793853521347f, -1.368080496788f, 0.f}, - {-2.20484805107f, 4.4128208160400f, 0.815879583358f, 0.f}, - {2.27113389968f, 0.1081698983907f, 5.552499771118f, 0.f}, - {1.f, 2.f, 3.f, 1.f}, + {3.25519061088f, 1.8793853521347f, -1.368080496788f, 0.0f}, + {-2.20484805107f, 4.4128208160400f, 0.815879583358f, 0.0f}, + {2.27113389968f, 0.1081698983907f, 5.552499771118f, 0.0f}, + {1.0f, 2.0f, 3.0f, 1.0f}, }; copy_m44_axis_swap(result, input, ABC_YUP_FROM_ZUP); @@ -194,10 +194,10 @@ TEST(abc_matrix, CopyM44AxisSwapWithScale_YfromZ) * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2) * and scaling over (4, 6, 5). */ float expect[4][4] = { - {3.255190610885f, -1.368080496788f, -1.879385352134f, 0.f}, - {2.271133899688f, 5.552499771118f, -0.108169898390f, 0.f}, - {2.204848051071f, -0.815879583358f, 4.412820816040f, 0.f}, - {1.f, 3.f, -2.f, 1.f}, + {3.255190610885f, -1.368080496788f, -1.879385352134f, 0.0f}, + {2.271133899688f, 5.552499771118f, -0.108169898390f, 0.0f}, + {2.204848051071f, -0.815879583358f, 4.412820816040f, 0.0f}, + {1.0f, 3.0f, -2.0f, 1.0f}, }; EXPECT_M4_NEAR(expect, result, 1e-5f); } @@ -209,10 +209,10 @@ TEST(abc_matrix, CopyM44AxisSwap_ZfromY) /* This matrix was created by rotating a cube in Blender over * (X=10, Y=30, Z=-20 degrees in XZY order) and translating over (1, 3, -2) */ float input[4][4] = { - {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.f}, - {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.f}, - {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.f}, - {1.f, 3.f, -2.f, 1.f}, + {0.813797652721f, -0.342020124197f, -0.469846338033f, 0.0f}, + {0.378522306680f, 0.925416588783f, -0.018028317019f, 0.0f}, + {0.440969616174f, -0.163175910711f, 0.882564127445f, 0.0f}, + {1.0f, 3.0f, -2.0f, 1.0f}, }; copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP); @@ -220,10 +220,10 @@ TEST(abc_matrix, CopyM44AxisSwap_ZfromY) /* This matrix was created by rotating a cube in Blender over * (X=10, Y=20, Z=30 degrees in XYZ order) and translating over (1, 2, 3) */ float expect[4][4] = { - {0.813797652721f, 0.469846338033f, -0.342020124197f, 0.f}, - {-0.44096961617f, 0.882564127445f, 0.163175910711f, 0.f}, - {0.378522306680f, 0.018028317019f, 0.925416588783f, 0.f}, - {1.f, 2.f, 3.f, 1.f}, + {0.813797652721f, 0.469846338033f, -0.342020124197f, 0.0f}, + {-0.44096961617f, 0.882564127445f, 0.163175910711f, 0.0f}, + {0.378522306680f, 0.018028317019f, 0.925416588783f, 0.0f}, + {1.0f, 2.0f, 3.0f, 1.0f}, }; EXPECT_M4_NEAR(expect, result, 1e-5f); @@ -237,10 +237,10 @@ TEST(abc_matrix, CopyM44AxisSwapWithScale_ZfromY) * (X=10, Y=30, Z=-20 degrees in XZY order), translating over (1, 3, -2) * and scaling over (4, 6, 5). */ float input[4][4] = { - {3.2551906108f, -1.36808049678f, -1.879385352134f, 0.f}, - {2.2711338996f, 5.55249977111f, -0.108169898390f, 0.f}, - {2.2048480510f, -0.81587958335f, 4.412820816040f, 0.f}, - {1.f, 3.f, -2.f, 1.f}, + {3.2551906108f, -1.36808049678f, -1.879385352134f, 0.0f}, + {2.2711338996f, 5.55249977111f, -0.108169898390f, 0.0f}, + {2.2048480510f, -0.81587958335f, 4.412820816040f, 0.0f}, + {1.0f, 3.0f, -2.0f, 1.0f}, }; copy_m44_axis_swap(result, input, ABC_ZUP_FROM_YUP); @@ -249,10 +249,10 @@ TEST(abc_matrix, CopyM44AxisSwapWithScale_ZfromY) * (X=10, Y=20, Z=30 degrees in XYZ order), translating over (1, 2, 3), * and scaling by (4, 5, 6). */ float expect[4][4] = { - {3.25519061088f, 1.879385352134f, -1.36808049678f, 0.f}, - {-2.2048480510f, 4.412820816040f, 0.81587958335f, 0.f}, - {2.27113389968f, 0.108169898390f, 5.55249977111f, 0.f}, - {1.f, 2.f, 3.f, 1.f}, + {3.25519061088f, 1.879385352134f, -1.36808049678f, 0.0f}, + {-2.2048480510f, 4.412820816040f, 0.81587958335f, 0.0f}, + {2.27113389968f, 0.108169898390f, 5.55249977111f, 0.0f}, + {1.0f, 2.0f, 3.0f, 1.0f}, }; EXPECT_M4_NEAR(expect, result, 1e-5f); diff --git a/source/blender/io/avi/intern/avi.c b/source/blender/io/avi/intern/avi.c index 0ab51b7a084..88f2e1a259f 100644 --- a/source/blender/io/avi/intern/avi.c +++ b/source/blender/io/avi/intern/avi.c @@ -148,7 +148,7 @@ static bool fcc_is_data(int fcc) if (!isdigit(fccs[0]) || !isdigit(fccs[1]) || (fccs[2] != 'd' && fccs[2] != 'w')) { return 0; } - if (fccs[3] != 'b' && fccs[3] != 'c') { + if (!ELEM(fccs[3], 'b', 'c')) { return 0; } diff --git a/source/blender/io/collada/CMakeLists.txt b/source/blender/io/collada/CMakeLists.txt index 8ffce9e3e7e..e1645083116 100644 --- a/source/blender/io/collada/CMakeLists.txt +++ b/source/blender/io/collada/CMakeLists.txt @@ -141,7 +141,7 @@ endif() if(CMAKE_COMPILER_IS_GNUCXX) # COLLADAFWArray.h gives error with gcc 4.5 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") + string(APPEND CMAKE_CXX_FLAGS " -fpermissive") endif() blender_add_lib(bf_collada "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/io/collada/collada_internal.cpp b/source/blender/io/collada/collada_internal.cpp index 091bd2cd7c2..096f6a678ac 100644 --- a/source/blender/io/collada/collada_internal.cpp +++ b/source/blender/io/collada/collada_internal.cpp @@ -26,7 +26,7 @@ #include "BKE_armature.h" -UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) +UnitConverter::UnitConverter() : up_axis(COLLADAFW::FileInfo::Z_UP) { axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI); axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI); diff --git a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc index 6077fc89b91..fc47b024be1 100644 --- a/source/blender/io/common/intern/abstract_hierarchy_iterator.cc +++ b/source/blender/io/common/intern/abstract_hierarchy_iterator.cc @@ -182,7 +182,7 @@ bool AbstractHierarchyWriter::check_has_deforming_physics(const HierarchyContext } AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph) - : depsgraph_(depsgraph), writers_(), export_subset_({true, true}) + : depsgraph_(depsgraph), export_subset_({true, true}) { } diff --git a/source/blender/io/usd/intern/usd_capi.cc b/source/blender/io/usd/intern/usd_capi.cc index 7b375689543..12fc04e2142 100644 --- a/source/blender/io/usd/intern/usd_capi.cc +++ b/source/blender/io/usd/intern/usd_capi.cc @@ -225,7 +225,7 @@ bool USD_export(bContext *C, else { /* Fake a job context, so that we don't need NULL pointer checks while exporting. */ short stop = 0, do_update = 0; - float progress = 0.f; + float progress = 0.0f; blender::io::usd::export_startjob(job, &stop, &do_update, &progress); blender::io::usd::export_endjob(job); diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 17d51c9b7cc..694fc76a446 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -37,10 +37,7 @@ static const pxr::TfToken surface("surface", pxr::TfToken::Immortal); namespace blender::io::usd { USDAbstractWriter::USDAbstractWriter(const USDExporterContext &usd_export_context) - : usd_export_context_(usd_export_context), - usd_value_writer_(), - frame_has_been_written_(false), - is_animated_(false) + : usd_export_context_(usd_export_context), frame_has_been_written_(false), is_animated_(false) { } diff --git a/source/blender/io/usd/intern/usd_writer_light.cc b/source/blender/io/usd/intern/usd_writer_light.cc index b6a81c973d2..f77c51c22ec 100644 --- a/source/blender/io/usd/intern/usd_writer_light.cc +++ b/source/blender/io/usd/intern/usd_writer_light.cc @@ -99,7 +99,7 @@ void USDLightWriter::do_write(HierarchyContext &context) usd_intensity = light->energy; } else { - usd_intensity = light->energy / 100.f; + usd_intensity = light->energy / 100.0f; } usd_light.CreateIntensityAttr().Set(usd_intensity, timecode); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 6aec3c39b29..f2d860a2851 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -305,6 +305,7 @@ typedef struct ID { /** * Only set for data-blocks which are coming from copy-on-write, points to * the original version of it. + * Also used temporarily during memfile undo to keep a reference to old ID when found. */ struct ID *orig_id; diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 37b7947dbea..866c1c44e3f 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -183,7 +183,7 @@ typedef enum eGPBrush_Presets { GP_BRUSH_PRESET_DRAW_WEIGHT = 300, } eGPBrush_Presets; -/* BrushGpencilSettings->gp_flag */ +/* BrushGpencilSettings->flag */ typedef enum eGPDbrush_Flag { /* brush use pressure */ GP_BRUSH_USE_PRESSURE = (1 << 0), @@ -775,6 +775,7 @@ typedef enum eBrushFlags2 { BRUSH_POSE_USE_LOCK_ROTATION = (1 << 5), BRUSH_CLOTH_USE_COLLISION = (1 << 6), BRUSH_AREA_RADIUS_PRESSURE = (1 << 7), + BRUSH_GRAB_SILHOUETTE = (1 << 8), } eBrushFlags2; typedef enum { diff --git a/source/blender/makesdna/DNA_camera_defaults.h b/source/blender/makesdna/DNA_camera_defaults.h index 55fbb59a161..b0237caa544 100644 --- a/source/blender/makesdna/DNA_camera_defaults.h +++ b/source/blender/makesdna/DNA_camera_defaults.h @@ -37,7 +37,7 @@ #define _DNA_DEFAULT_CameraStereoSettings \ { \ .interocular_distance = 0.065f, \ - .convergence_distance = 30.f * 0.065f, \ + .convergence_distance = 30.0f * 0.065f, \ .pole_merge_angle_from = DEG2RADF(60.0f), \ .pole_merge_angle_to = DEG2RADF(75.0f), \ } diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index 92ee3f062a6..93a67602047 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -60,7 +60,7 @@ typedef struct bConstraint { /** Constraint name, MAX_NAME. */ char name[64]; - /* Flag for panel and subpanel closed / open state in the UI. */ + /* An "expand" bit for each of the constraint's (sub)panels (uiPanelDataExpansion). */ short ui_expand_flag; /** Amount of influence exherted by constraint (0.0-1.0). */ @@ -690,8 +690,10 @@ typedef enum eBConstraint_Types { /* flag 0x20 (1 << 5) was used to indicate that a constraint was evaluated * using a 'local' hack for posebones only. */ typedef enum eBConstraint_Flags { +#ifdef DNA_DEPRECATED_ALLOW /* Expansion for old box constraint layouts. Just for versioning. */ CONSTRAINT_EXPAND_DEPRECATED = (1 << 0), +#endif /* pre-check for illegal object name or bone name */ CONSTRAINT_DISABLE = (1 << 2), /* to indicate which Ipo should be shown, maybe for 3d access later too */ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 7e2ec8b6c65..7107e131eda 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -57,7 +57,9 @@ typedef enum GpencilModifierMode { eGpencilModifierMode_Realtime = (1 << 0), eGpencilModifierMode_Render = (1 << 1), eGpencilModifierMode_Editmode = (1 << 2), +#ifdef DNA_DEPRECATED_ALLOW eGpencilModifierMode_Expanded_DEPRECATED = (1 << 3), +#endif eGpencilModifierMode_Virtual = (1 << 4), } GpencilModifierMode; @@ -72,6 +74,7 @@ typedef struct GpencilModifierData { int type, mode; char _pad0[4]; short flag; + /* An "expand" bit for each of the modifier's (sub)panels (uiPanelDataExpansion). */ short ui_expand_flag; /** MAX_NAME. */ char name[64]; @@ -778,6 +781,9 @@ typedef struct TextureGpencilModifierData { /** Texture fit options. */ short fit_method; short mode; + /** Dot texture rotation */ + float alignment_rotation; + char _pad[4]; } TextureGpencilModifierData; typedef enum eTextureGpencil_Flag { diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 355d3d6439b..1d31b876068 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -99,7 +99,8 @@ typedef struct MaterialGPencilStyle { float mix_stroke_factor; /** Mode used to align Dots and Boxes with stroke drawing path and object rotation */ int alignment_mode; - char _pad[4]; + /** Rotation for texture for Dots and Squares. */ + float alignment_rotation; } MaterialGPencilStyle; /* MaterialGPencilStyle->flag */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index e2837ba85f8..a822a6723fa 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -48,7 +48,6 @@ struct MPropCol; struct MVert; struct Material; struct Mesh; -struct Multires; struct SubdivCCG; # @@ -230,9 +229,6 @@ typedef struct Mesh { * default and Face Sets can be used without affecting the color of the mesh. */ int face_sets_color_default; - /** Deprecated multiresolution modeling data, only keep for loading old files. */ - struct Multires *mr DNA_DEPRECATED; - Mesh_Runtime runtime; } Mesh; diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 45bf6e8c282..7cc94a2ad0b 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -518,54 +518,4 @@ typedef struct MRecast { int i; } MRecast; -/** Multires structs kept for compatibility with old files. */ -typedef struct MultiresCol { - float a, r, g, b; -} MultiresCol; - -typedef struct MultiresColFace { - /* vertex colors */ - MultiresCol col[4]; -} MultiresColFace; - -typedef struct MultiresFace { - unsigned int v[4]; - unsigned int mid; - char flag, mat_nr, _pad[2]; -} MultiresFace; - -typedef struct MultiresEdge { - unsigned int v[2]; - unsigned int mid; -} MultiresEdge; - -typedef struct MultiresLevel { - struct MultiresLevel *next, *prev; - - MultiresFace *faces; - MultiresColFace *colfaces; - MultiresEdge *edges; - - unsigned int totvert, totface, totedge; - char _pad[4]; - - /* Kept for compatibility with even older files */ - MVert *verts; -} MultiresLevel; - -typedef struct Multires { - ListBase levels; - MVert *verts; - - unsigned char level_count, current, newlvl, edgelvl, pinlvl, renderlvl; - unsigned char use_col, flag; - - /* Special level 1 data that cannot be modified from other levels */ - CustomData vdata; - CustomData fdata; - short *edge_flags; - char *edge_creases; -} Multires; -/* End multi-res structs. */ - /** \} */ diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index 34a951ca988..b5bcfa4d157 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -438,7 +438,6 @@ .sculptlvl = 0, \ .renderlvl = 0, \ .totlvl = 0, \ - .simple = 0, \ .flags = eMultiresModifierFlag_UseCrease | eMultiresModifierFlag_ControlEdges, \ .uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS, \ .quality = 4, \ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 29bcc5fe903..232fca062fa 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -106,8 +106,10 @@ typedef enum ModifierMode { eModifierMode_Render = (1 << 1), eModifierMode_Editmode = (1 << 2), eModifierMode_OnCage = (1 << 3), - /* Old modifier box expansion, just for versioning. */ +#ifdef DNA_DEPRECATED_ALLOW + /** Old modifier box expansion, just for versioning. */ eModifierMode_Expanded_DEPRECATED = (1 << 4), +#endif eModifierMode_Virtual = (1 << 5), eModifierMode_ApplyOnSpline = (1 << 6), eModifierMode_DisableTemporary = (1u << 31), @@ -119,7 +121,7 @@ typedef struct ModifierData { int type, mode; char _pad0[4]; short flag; - /* An "expand" bit for each of the modifier's (sub)panels. */ + /* An "expand" bit for each of the modifier's (sub)panels (uiPanelDataExpansion). */ short ui_expand_flag; /** MAX_NAME. */ char name[64]; @@ -1047,7 +1049,8 @@ typedef struct MultiresModifierData { ModifierData modifier; char lvl, sculptlvl, renderlvl, totlvl; - char simple, flags, _pad[2]; + char simple DNA_DEPRECATED; + char flags, _pad[2]; short quality; short uv_smooth; short boundary_smooth; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index cba93bbadfc..6f6c9029d07 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -923,6 +923,8 @@ typedef struct NodeTexMagic { typedef struct NodeShaderAttribute { char name[64]; + int type; + char _pad[4]; } NodeShaderAttribute; typedef struct NodeShaderVectTransform { @@ -1092,6 +1094,13 @@ typedef struct NodeDenoise { #define SHD_VECT_TRANSFORM_SPACE_OBJECT 1 #define SHD_VECT_TRANSFORM_SPACE_CAMERA 2 +/* attribute */ +enum { + SHD_ATTRIBUTE_GEOMETRY = 0, + SHD_ATTRIBUTE_OBJECT = 1, + SHD_ATTRIBUTE_INSTANCER = 2, +}; + /* toon modes */ #define SHD_TOON_DIFFUSE 0 #define SHD_TOON_GLOSSY 1 diff --git a/source/blender/makesdna/DNA_object_force_types.h b/source/blender/makesdna/DNA_object_force_types.h index 3b0640544ae..3bd11d02b7a 100644 --- a/source/blender/makesdna/DNA_object_force_types.h +++ b/source/blender/makesdna/DNA_object_force_types.h @@ -54,7 +54,7 @@ typedef enum ePFieldType { PFIELD_LENNARDJ = 9, /** Defines predator / goal for boids. */ PFIELD_BOID = 10, - /** Force defined by BLI_gTurbulence. */ + /** Force defined by BLI_noise_generic_turbulence. */ PFIELD_TURBULENCE = 11, /** Linear & quadratic drag. */ PFIELD_DRAG = 12, diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 112c8210460..345d1287ab1 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -508,7 +508,7 @@ enum { /* (short) transflag */ enum { - OB_TRANSFLAG_UNUSED_0 = 1 << 0, /* cleared */ + OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK = 1 << 0, OB_TRANSFLAG_UNUSED_1 = 1 << 1, /* cleared */ OB_NEG_SCALE = 1 << 2, OB_TRANSFLAG_UNUSED_3 = 1 << 3, /* cleared */ diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index f0ff02d3668..7101dacc803 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -37,8 +37,8 @@ struct PointerRNA; struct Scene; struct SpaceLink; struct SpaceType; -struct uiLayout; struct uiBlock; +struct uiLayout; struct wmDrawBuffer; struct wmTimer; struct wmTooltipState; @@ -170,9 +170,8 @@ typedef struct Panel { /** Panel size excluding children. */ int blocksizex, blocksizey; short labelofs; - char _pad[4]; short flag, runtime_flag; - short snap; + char _pad[6]; /** Panels are aligned according to increasing sort-order. */ int sortorder; /** Runtime for panel manipulation. */ @@ -184,6 +183,34 @@ typedef struct Panel { } Panel; /** + * Used for passing expansion between instanced panel data and the panels themselves. + * There are 16 defines because the expansion data is typically stored in a short. + * + * \note Expansion for instanced panels is stored in depth first order. For example, the value of + * UI_SUBPANEL_DATA_EXPAND_2 correspond to mean the expansion of the second subpanel or the first + * subpanel's first subpanel. + */ +typedef enum uiPanelDataExpansion { + UI_PANEL_DATA_EXPAND_ROOT = (1 << 0), + UI_SUBPANEL_DATA_EXPAND_1 = (1 << 1), + UI_SUBPANEL_DATA_EXPAND_2 = (1 << 2), + UI_SUBPANEL_DATA_EXPAND_3 = (1 << 3), + UI_SUBPANEL_DATA_EXPAND_4 = (1 << 4), + UI_SUBPANEL_DATA_EXPAND_5 = (1 << 5), + UI_SUBPANEL_DATA_EXPAND_6 = (1 << 6), + UI_SUBPANEL_DATA_EXPAND_7 = (1 << 7), + UI_SUBPANEL_DATA_EXPAND_8 = (1 << 8), + UI_SUBPANEL_DATA_EXPAND_9 = (1 << 9), + UI_SUBPANEL_DATA_EXPAND_10 = (1 << 10), + UI_SUBPANEL_DATA_EXPAND_11 = (1 << 11), + UI_SUBPANEL_DATA_EXPAND_12 = (1 << 12), + UI_SUBPANEL_DATA_EXPAND_13 = (1 << 13), + UI_SUBPANEL_DATA_EXPAND_14 = (1 << 14), + UI_SUBPANEL_DATA_EXPAND_15 = (1 << 15), + UI_SUBPANEL_DATA_EXPAND_16 = (1 << 16), +} uiPanelDataExpansion; + +/** * Notes on Panel Categories: * * - #ARegion.panels_category (#PanelCategoryDyn) @@ -294,10 +321,6 @@ typedef struct uiPreview { char _pad1[6]; } uiPreview; -/* These two lines with # tell makesdna this struct can be excluded. - * Should be: #ifndef WITH_GLOBAL_AREA_WRITING */ -# -# typedef struct ScrGlobalAreaData { /* Global areas have a non-dynamic size. That means, changing the window * size doesn't affect their size at all. However, they can still be @@ -548,15 +571,6 @@ enum { PNL_INSTANCED_LIST_ORDER_CHANGED = (1 << 7), }; -/** #Panel.snap - for snapping to screen edges */ -#define PNL_SNAP_NONE 0 -/* #define PNL_SNAP_TOP 1 */ -/* #define PNL_SNAP_RIGHT 2 */ -#define PNL_SNAP_BOTTOM 4 -/* #define PNL_SNAP_LEFT 8 */ - -/* #define PNL_SNAP_DIST 9.0 */ - /* paneltype flag */ enum { PNL_DEFAULT_CLOSED = (1 << 0), diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 1d89657faf6..1847fbfa986 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -68,6 +68,9 @@ typedef struct StripCrop { typedef struct StripTransform { int xofs; int yofs; + float scale_x; + float scale_y; + float rotation; } StripTransform; typedef struct StripColorBalance { @@ -494,8 +497,8 @@ enum { SEQ_MAKE_FLOAT = (1 << 13), SEQ_LOCK = (1 << 14), SEQ_USE_PROXY = (1 << 15), - SEQ_USE_TRANSFORM = (1 << 16), - SEQ_USE_CROP = (1 << 17), + SEQ_FLAG_UNUSED_23 = (1 << 16), /* cleared */ + SEQ_FLAG_UNUSED_22 = (1 << 17), /* cleared */ SEQ_FLAG_UNUSED_18 = (1 << 18), /* cleared */ SEQ_FLAG_UNUSED_19 = (1 << 19), /* cleared */ SEQ_FLAG_UNUSED_21 = (1 << 21), /* cleared */ diff --git a/source/blender/makesdna/DNA_shader_fx_types.h b/source/blender/makesdna/DNA_shader_fx_types.h index 5bb78edb280..07ccac5ba29 100644 --- a/source/blender/makesdna/DNA_shader_fx_types.h +++ b/source/blender/makesdna/DNA_shader_fx_types.h @@ -49,7 +49,9 @@ typedef enum ShaderFxMode { eShaderFxMode_Realtime = (1 << 0), eShaderFxMode_Render = (1 << 1), eShaderFxMode_Editmode = (1 << 2), +#ifdef DNA_DEPRECATED_ALLOW eShaderFxMode_Expanded_DEPRECATED = (1 << 3), +#endif } ShaderFxMode; typedef enum { @@ -63,7 +65,7 @@ typedef struct ShaderFxData { int type, mode; char _pad0[4]; short flag; - /* Expansion for shader effect panels and sub-panels. */ + /* An "expand" bit for each of the constraint's (sub)panels (uiPanelDataExpansion). */ short ui_expand_flag; /** MAX_NAME. */ char name[64]; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 7785c700e1c..1b7ec3889bc 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -59,10 +59,6 @@ struct wmTimer; /* Defined in `buttons_intern.h`. */ typedef struct SpaceProperties_Runtime SpaceProperties_Runtime; -/* TODO 2.8: We don't write the global areas to files currently. Uncomment - * define to enable writing (should become the default in a bit). */ -//#define WITH_GLOBAL_AREA_WRITING - /* -------------------------------------------------------------------- */ /** \name SpaceLink (Base) * \{ */ @@ -309,11 +305,11 @@ typedef enum eSpaceOutliner_Filter { SO_FILTER_NO_OB_CAMERA = (1 << 10), SO_FILTER_NO_OB_OTHERS = (1 << 11), - SO_FILTER_UNUSED_12 = (1 << 12), /* cleared */ - SO_FILTER_OB_STATE_VISIBLE = (1 << 13), /* Not set via DNA. */ - SO_FILTER_OB_STATE_HIDDEN = (1 << 14), /* Not set via DNA. */ - SO_FILTER_OB_STATE_SELECTED = (1 << 15), /* Not set via DNA. */ - SO_FILTER_OB_STATE_ACTIVE = (1 << 16), /* Not set via DNA. */ + SO_FILTER_OB_STATE_SELECTABLE = (1 << 12), /* Not set via DNA. */ + SO_FILTER_OB_STATE_VISIBLE = (1 << 13), /* Not set via DNA. */ + SO_FILTER_OB_STATE_HIDDEN = (1 << 14), /* Not set via DNA. */ + SO_FILTER_OB_STATE_SELECTED = (1 << 15), /* Not set via DNA. */ + SO_FILTER_OB_STATE_ACTIVE = (1 << 16), /* Not set via DNA. */ SO_FILTER_NO_COLLECTION = (1 << 17), SO_FILTER_ID_TYPE = (1 << 18), @@ -325,7 +321,7 @@ typedef enum eSpaceOutliner_Filter { #define SO_FILTER_OB_STATE \ (SO_FILTER_OB_STATE_VISIBLE | SO_FILTER_OB_STATE_HIDDEN | SO_FILTER_OB_STATE_SELECTED | \ - SO_FILTER_OB_STATE_ACTIVE) + SO_FILTER_OB_STATE_ACTIVE | SO_FILTER_OB_STATE_SELECTABLE) #define SO_FILTER_ANY \ (SO_FILTER_NO_OB_CONTENT | SO_FILTER_NO_CHILDREN | SO_FILTER_OB_TYPE | SO_FILTER_OB_STATE | \ @@ -338,6 +334,7 @@ typedef enum eSpaceOutliner_StateFilter { SO_FILTER_OB_HIDDEN = 2, SO_FILTER_OB_SELECTED = 3, SO_FILTER_OB_ACTIVE = 4, + SO_FILTER_OB_SELECTABLE = 5, } eSpaceOutliner_StateFilter; /* SpaceOutliner.show_restrict_flags */ @@ -764,7 +761,13 @@ typedef struct SpaceFile { /* FileSelectParams.display */ enum eFileDisplayType { + /** Internal (not exposed to users): Keep whatever display type was used during the last File + * Browser use, or the default if no such record is found. Use this unless there's a good reason + * to set a specific display type. */ FILE_DEFAULTDISPLAY = 0, + + /* User selectable choices. */ + FILE_VERTICALDISPLAY = 1, FILE_HORIZONTALDISPLAY = 2, FILE_IMGDISPLAY = 3, @@ -772,7 +775,13 @@ enum eFileDisplayType { /* FileSelectParams.sort */ enum eFileSortType { - FILE_SORT_NONE = 0, + /** Internal (not exposed to users): Sort by whatever was sorted by during the last File Browser + * use, or the default if no such record is found. Use this unless there's a good reason to set a + * specific sort order. */ + FILE_SORT_DEFAULT = 0, + + /* User selectable choices. */ + FILE_SORT_ALPHA = 1, FILE_SORT_EXTENSION = 2, FILE_SORT_TIME = 3, @@ -1672,10 +1681,6 @@ typedef enum eSpaceClip_GPencil_Source { /** \name Top Bar * \{ */ -/* These two lines with # tell makesdna this struct can be excluded. - * Should be: #ifndef WITH_GLOBAL_AREA_WRITING */ -# -# typedef struct SpaceTopBar { SpaceLink *next, *prev; /** Storage of regions for inactive spaces. */ @@ -1692,10 +1697,6 @@ typedef struct SpaceTopBar { /** \name Status Bar * \{ */ -/* These two lines with # tell makesdna this struct can be excluded. - * Should be: #ifndef WITH_GLOBAL_AREA_WRITING */ -# -# typedef struct SpaceStatusBar { SpaceLink *next, *prev; /** Storage of regions for inactive spaces. */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index d0105cda1ea..0bbeabf130f 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -288,8 +288,7 @@ typedef struct MovieTrackingSettings { int reconstruction_flag; /* which camera intrinsics to refine. uses on the REFINE_* flags */ - short refine_camera_intrinsics; - char _pad2[2]; + int refine_camera_intrinsics; /* ** tool settings ** */ @@ -551,10 +550,12 @@ enum { /* MovieTrackingSettings->refine_camera_intrinsics */ enum { + REFINE_NO_INTRINSICS = (0), + REFINE_FOCAL_LENGTH = (1 << 0), REFINE_PRINCIPAL_POINT = (1 << 1), - REFINE_RADIAL_DISTORTION_K1 = (1 << 2), - REFINE_RADIAL_DISTORTION_K2 = (1 << 4), + REFINE_RADIAL_DISTORTION = (1 << 2), + REFINE_TANGENTIAL_DISTORTION = (1 << 3), }; /* MovieTrackingStrabilization->flag */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4a02ac8f429..ed232d4ad89 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -589,6 +589,7 @@ typedef struct WalkNavigation { } WalkNavigation; typedef struct UserDef_Runtime { + /** Mark as changed so the preferences are saved on exit. */ char is_dirty; char _pad0[7]; } UserDef_Runtime; @@ -1045,7 +1046,7 @@ typedef enum eUserpref_UI_Flag { USER_HIDE_DOT = (1 << 16), USER_SHOW_GIZMO_NAVIGATE = (1 << 17), USER_SHOW_VIEWPORTNAME = (1 << 18), - USER_CAM_LOCK_NO_PARENT = (1 << 19), + USER_UIFLAG_UNUSED_3 = (1 << 19), /* Cleared. */ USER_ZOOM_TO_MOUSEPOS = (1 << 20), USER_SHOW_FPS = (1 << 21), USER_UIFLAG_UNUSED_22 = (1 << 22), /* cleared */ diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c index df1626157b0..3690a1126d4 100644 --- a/source/blender/makesdna/intern/dna_genfile.c +++ b/source/blender/makesdna/intern/dna_genfile.c @@ -1699,7 +1699,7 @@ bool DNA_sdna_patch_struct(SDNA *sdna, const char *struct_name_old, const char * return false; } -/* Make public if called often with same struct (avoid duplicate look-ups). */ +/* Make public if called often with same struct (avoid duplicate lookups). */ static bool DNA_sdna_patch_struct_member_nr(SDNA *sdna, const int struct_name_nr, const char *elem_old, diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 7067caa60d9..2a4160bdfb1 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -126,3 +126,6 @@ DNA_STRUCT_RENAME_ELEM(bTheme, ttopbar, space_topbar) DNA_STRUCT_RENAME_ELEM(bTheme, tuserpref, space_preferences) DNA_STRUCT_RENAME_ELEM(bTheme, tv3d, space_view3d) DNA_STRUCT_RENAME_ELEM(RigidBodyWorld, steps_per_second, substeps_per_frame) +/* Write with a different name, old Blender versions crash loading files with non-NULL + * global_areas. See D9442. */ +DNA_STRUCT_RENAME_ELEM(wmWindow, global_area_map, global_areas) diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 44b6e4dd3a1..81a7da7b4d8 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -742,7 +742,7 @@ static int convert_include(const char *filename) break; } - if (*md1 == ',' || *md1 == ' ') { + if (ELEM(*md1, ',', ' ')) { *md1 = 0; } md1++; @@ -1439,7 +1439,7 @@ int main(int argc, char **argv) { int return_status = 0; - if (argc != 4 && argc != 5) { + if (!ELEM(argc, 4, 5)) { printf("Usage: %s dna.c dna_struct_offsets.h [base directory]\n", argv[0]); return_status = 1; } diff --git a/source/blender/makesrna/RNA_enum_types.h b/source/blender/makesrna/RNA_enum_types.h index 831e8dc424d..a94466e30c2 100644 --- a/source/blender/makesrna/RNA_enum_types.h +++ b/source/blender/makesrna/RNA_enum_types.h @@ -61,6 +61,7 @@ extern const EnumPropertyItem rna_enum_space_type_items[]; extern const EnumPropertyItem rna_enum_space_image_mode_items[]; extern const EnumPropertyItem rna_enum_space_image_mode_all_items[]; extern const EnumPropertyItem rna_enum_space_action_mode_items[]; +extern const EnumPropertyItem rna_enum_fileselect_params_sort_items[]; extern const EnumPropertyItem rna_enum_region_type_items[]; extern const EnumPropertyItem rna_enum_object_modifier_type_items[]; extern const EnumPropertyItem rna_enum_constraint_type_items[]; @@ -190,8 +191,6 @@ extern const EnumPropertyItem rna_enum_shading_type_items[]; extern const EnumPropertyItem rna_enum_navigation_mode_items[]; -extern const EnumPropertyItem rna_enum_file_sort_items[]; - extern const EnumPropertyItem rna_enum_node_socket_in_out_items[]; extern const EnumPropertyItem rna_enum_node_math_items[]; diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index d8029ff16a0..bd015f3e477 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -20,7 +20,7 @@ if(CMAKE_COMPILER_IS_GNUCC) # add here so we fail early. - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration") + string(APPEND CMAKE_C_FLAGS " -Werror=implicit-function-declaration") endif() # files rna_access.c rna_define.c makesrna.c intentionally excluded. @@ -151,7 +151,7 @@ if(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_C_COMPILER_ID MATCHES "Clang")) set(GENSRC_CFLAGS "-Wno-missing-prototypes") endif() if(CMAKE_C_COMPILER_ID MATCHES "Clang") - set(GENSRC_CFLAGS "${GENSRC_CFLAGS} -Wno-missing-variable-declarations") + string(APPEND GENSRC_CFLAGS " -Wno-missing-variable-declarations") endif() if(GENSRC_CFLAGS) diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index e193aa78353..5aa684539af 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -29,6 +29,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_string.h" #include "BLI_system.h" /* for 'BLI_system_backtrace' stub. */ #include "BLI_utildefines.h" @@ -577,8 +578,7 @@ static int rna_enum_bitmask(PropertyRNA *prop) static int rna_color_quantize(PropertyRNA *prop, PropertyDefRNA *dp) { - return ((prop->type == PROP_FLOAT) && - (prop->subtype == PROP_COLOR || prop->subtype == PROP_COLOR_GAMMA) && + return ((prop->type == PROP_FLOAT) && (ELEM(prop->subtype, PROP_COLOR, PROP_COLOR_GAMMA)) && (IS_DNATYPE_FLOAT_COMPAT(dp->dnatype) == 0)); } @@ -671,7 +671,7 @@ static char *rna_def_property_get_func( return NULL; } } - else if (prop->type == PROP_INT || prop->type == PROP_ENUM) { + else if (ELEM(prop->type, PROP_INT, PROP_ENUM)) { if (IS_DNATYPE_INT_COMPAT(dp->dnatype) == 0) { CLOG_ERROR(&LOG, "%s.%s is a '%s' but wrapped as type '%s'.", @@ -761,9 +761,10 @@ static char *rna_def_property_get_func( fprintf(f, "static PointerRNA %s(CollectionPropertyIterator *iter)\n", func); fprintf(f, "{\n"); if (manualfunc) { - if (STREQ(manualfunc, "rna_iterator_listbase_get") || - STREQ(manualfunc, "rna_iterator_array_get") || - STREQ(manualfunc, "rna_iterator_array_dereference_get")) { + if (STR_ELEM(manualfunc, + "rna_iterator_listbase_get", + "rna_iterator_array_get", + "rna_iterator_array_dereference_get")) { fprintf(f, " return rna_pointer_inherit_refine(&iter->parent, &RNA_%s, %s(iter));\n", (cprop->item_type) ? (const char *)cprop->item_type : "UnknownType", diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index a6084ae6a43..0fd35a25b41 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -1310,7 +1310,7 @@ static void rna_def_ID_override_library_property_operation(BlenderRNA *brna) "MANDATORY", 0, "Mandatory", - "For templates, prevents the user from removing pre-defined operation (NOT USED)"}, + "For templates, prevents the user from removing predefined operation (NOT USED)"}, {IDOVERRIDE_LIBRARY_FLAG_LOCKED, "LOCKED", 0, diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 562738efdaa..d367bc663f1 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -26,6 +26,7 @@ #include "DNA_constraint_types.h" #include "DNA_key_types.h" #include "DNA_modifier_types.h" +#include "DNA_object_types.h" #include "BLI_listbase.h" #include "BLI_string.h" @@ -37,6 +38,7 @@ # include "PIL_time_utildefines.h" #endif +#include "BKE_armature.h" #include "BKE_idprop.h" #include "BKE_lib_override.h" #include "BKE_main.h" @@ -593,6 +595,27 @@ bool RNA_struct_override_matches(Main *bmain, } #endif + if (ptr_local->owner_id == ptr_local->data && GS(ptr_local->owner_id->name) == ID_OB) { + /* Our beloved pose's bone cross-data pointers. Usually, depsgraph evaluation would + * ensure this is valid, but in some situations (like hidden collections etc.) this won't + * be the case, so we need to take care of this ourselves. + * + * Note: Typically callers of this function (from BKE_lib_override area) will already have + * ensured this. However, studio is still reporting sporadic, unreproducible crashes due to + * invalid pose data, so think there are still some cases where some armatures are somehow + * missing updates (possibly due to dependencies?). Since calling this function on same ID + * several time is almost free, and safe even in a threaded context as long as it has been done + * at least once first outside of threaded processing, we do it another time here. */ + Object *ob_local = (Object *)ptr_local->owner_id; + if (ob_local->type == OB_ARMATURE) { + Object *ob_reference = (Object *)ptr_local->owner_id->override_library->reference; + BLI_assert(ob_local->data != NULL); + BLI_assert(ob_reference->data != NULL); + BKE_pose_ensure(bmain, ob_local, ob_local->data, true); + BKE_pose_ensure(bmain, ob_reference, ob_reference->data, true); + } + } + iterprop = RNA_struct_iterator_property(ptr_local->type); for (RNA_property_collection_begin(ptr_local, iterprop, &iter); iter.valid; diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 89687c1234c..576431b7fd1 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -450,7 +450,7 @@ static void rna_def_dopesheet(BlenderRNA *brna) prop = RNA_def_property(srna, "show_shapekeys", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "filterflag", ADS_FILTER_NOSHAPEKEYS); RNA_def_property_ui_text( - prop, "Display Shapekeys", "Include visualization of shape key related animation data"); + prop, "Display Shape Keys", "Include visualization of shape key related animation data"); RNA_def_property_ui_icon(prop, ICON_SHAPEKEY_DATA, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index cc0c11fb089..d586f222203 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -1336,7 +1336,7 @@ static void rna_def_edit_bone(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Editbone Matrix", - "Matrix combining loc/rot of the bone (head position, direction and roll), " + "Matrix combining location and rotation of the bone (head position, direction and roll), " "in armature space (does not include/support bone's length/size)"); RNA_def_property_float_funcs(prop, "rna_EditBone_matrix_get", "rna_EditBone_matrix_set", NULL); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index d119be66916..736edc61d74 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -79,6 +79,27 @@ static const EnumPropertyItem sculpt_stroke_method_items[] = { {0, NULL, 0, NULL, NULL}, }; +static const EnumPropertyItem rna_enum_brush_texture_slot_map_all_mode_items[] = { + {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""}, + {MTEX_MAP_MODE_AREA, "AREA_PLANE", 0, "Area Plane", ""}, + {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, + {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, + {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, + {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, + {0, NULL, 0, NULL, NULL}, +}; + +#ifdef RNA_RUNTIME +static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items[] = { + {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""}, + {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, + {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, + {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, + {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, + {0, NULL, 0, NULL, NULL}, +}; +#endif + /* clang-format off */ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = { {SCULPT_TOOL_DRAW, "DRAW", ICON_BRUSH_SCULPT_DRAW, "Draw", ""}, @@ -1015,6 +1036,28 @@ static void rna_GPencilBrush_pin_mode_update(bContext *C, PointerRNA *ptr) } } +static const EnumPropertyItem *rna_BrushTextureSlot_map_mode_itemf(bContext *C, + PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), + bool *UNUSED(r_free)) +{ + + if (C == NULL) { + return rna_enum_brush_texture_slot_map_all_mode_items; + } + +# define rna_enum_brush_texture_slot_map_sculpt_mode_items \ + rna_enum_brush_texture_slot_map_all_mode_items; + + const ePaintMode mode = BKE_paintmode_get_active_from_context(C); + if (mode == PAINT_MODE_SCULPT) { + return rna_enum_brush_texture_slot_map_sculpt_mode_items; + } + return rna_enum_brush_texture_slot_map_texture_mode_items; + +# undef rna_enum_brush_texture_slot_map_sculpt_mode_items +} + #else static void rna_def_brush_texture_slot(BlenderRNA *brna) @@ -1022,25 +1065,6 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static const EnumPropertyItem prop_map_mode_items[] = { - {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""}, - {MTEX_MAP_MODE_AREA, "AREA_PLANE", 0, "Area Plane", ""}, - {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, - {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, - {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, - {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, - {0, NULL, 0, NULL, NULL}, - }; - - static const EnumPropertyItem prop_tex_paint_map_mode_items[] = { - {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""}, - {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, - {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, - {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, - {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, - {0, NULL, 0, NULL, NULL}, - }; - static const EnumPropertyItem prop_mask_paint_map_mode_items[] = { {MTEX_MAP_MODE_VIEW, "VIEW_PLANE", 0, "View Plane", ""}, {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, @@ -1069,14 +1093,8 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna) prop = RNA_def_property(srna, "map_mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode"); - RNA_def_property_enum_items(prop, prop_map_mode_items); - RNA_def_property_ui_text(prop, "Mode", ""); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); - - prop = RNA_def_property(srna, "tex_paint_map_mode", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode"); - RNA_def_property_enum_items(prop, prop_tex_paint_map_mode_items); + RNA_def_property_enum_items(prop, rna_enum_brush_texture_slot_map_all_mode_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_BrushTextureSlot_map_mode_itemf"); RNA_def_property_ui_text(prop, "Mode", ""); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, 0, "rna_TextureSlot_update"); @@ -2968,6 +2986,12 @@ static void rna_def_brush(BlenderRNA *brna) "Apply the maximum grab strength to the active vertex instead of the cursor location"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_grab_silhouette", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", BRUSH_GRAB_SILHOUETTE); + RNA_def_property_ui_text( + prop, "Grab Silhouette", "Grabs trying to automask the silhouette of the object"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "use_paint_antialiasing", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "sampling_flag", BRUSH_PAINT_ANTIALIASING); RNA_def_property_ui_text(prop, "Anti-Aliasing", "Smooths the edges of the strokes"); diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c index 31a71a80bbc..1810cee5cee 100644 --- a/source/blender/makesrna/intern/rna_camera.c +++ b/source/blender/makesrna/intern/rna_camera.c @@ -36,11 +36,12 @@ # include "BKE_camera.h" # include "BKE_object.h" -# include "BKE_sequencer.h" # include "DEG_depsgraph.h" # include "DEG_depsgraph_build.h" +# include "SEQ_sequencer.h" + static float rna_Camera_angle_get(PointerRNA *ptr) { Camera *cam = (Camera *)ptr->owner_id; @@ -383,7 +384,7 @@ static void rna_def_camera_stereo_data(BlenderRNA *brna) prop = RNA_def_property(srna, "convergence_distance", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_range(prop, 0.00001f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.00001f, 15.f, 1, 3); + RNA_def_property_ui_range(prop, 0.00001f, 15.0f, 1, 3); RNA_def_property_ui_text(prop, "Convergence Plane Distance", "The converge point for the stereo cameras " @@ -583,7 +584,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_DISTANCE_CAMERA); RNA_def_property_float_sdna(prop, NULL, "sensor_x"); RNA_def_property_range(prop, 1.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 1.0f, 100.f, 100, 4); + RNA_def_property_ui_range(prop, 1.0f, 100.0f, 100, 4); RNA_def_property_ui_text( prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); @@ -591,7 +592,7 @@ void RNA_def_camera(BlenderRNA *brna) prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_DISTANCE_CAMERA); RNA_def_property_float_sdna(prop, NULL, "sensor_y"); RNA_def_property_range(prop, 1.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 1.0f, 100.f, 100, 4); + RNA_def_property_ui_range(prop, 1.0f, 100.0f, 100, 4); RNA_def_property_ui_text( prop, "Sensor Height", "Vertical size of the image sensor area in millimeters"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update"); diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c index df1d7abd6b1..90414613fdd 100644 --- a/source/blender/makesrna/intern/rna_collection.c +++ b/source/blender/makesrna/intern/rna_collection.c @@ -275,7 +275,7 @@ static bool rna_Collection_children_override_apply(Main *bmain, Collection *coll_dst = (Collection *)ptr_dst->owner_id; if (ptr_item_dst->type == NULL || ptr_item_src->type == NULL) { - BLI_assert(0 && "invalid source or destination sub-collection."); + /* This can happen when reference and overrides differ, just ignore then. */ return false; } diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index b4f053a0d2b..ac47f434c3b 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -52,7 +52,6 @@ # include "BKE_linestyle.h" # include "BKE_movieclip.h" # include "BKE_node.h" -# include "BKE_sequencer.h" # include "DEG_depsgraph.h" @@ -61,6 +60,8 @@ # include "IMB_colormanagement.h" # include "IMB_imbuf.h" +# include "SEQ_sequencer.h" + static int rna_CurveMapping_curves_length(PointerRNA *ptr) { CurveMapping *cumap = (CurveMapping *)ptr->data; @@ -796,7 +797,7 @@ static void rna_def_curvemapping(BlenderRNA *brna) static const EnumPropertyItem tone_items[] = { {CURVE_TONE_STANDARD, "STANDARD", 0, "Standard", ""}, - {CURVE_TONE_FILMLIKE, "FILMLIKE", 0, "Film like", ""}, + {CURVE_TONE_FILMLIKE, "FILMLIKE", 0, "Filmlike", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 76b419926a1..774187d18b7 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -673,8 +673,8 @@ static void rna_ActionConstraint_minmax_range( *max = 180.0f; } else { - *min = -1000.f; - *max = 1000.f; + *min = -1000.0f; + *max = 1000.0f; } } @@ -1183,13 +1183,13 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01, 1.f); + RNA_def_property_range(prop, 0.01, 1.0f); RNA_def_property_ui_text( prop, "Weight", "For Tree-IK: Weight of position control for this target"); prop = RNA_def_property(srna, "orient_weight", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "orientweight"); - RNA_def_property_range(prop, 0.01, 1.f); + RNA_def_property_range(prop, 0.01, 1.0f); RNA_def_property_ui_text( prop, "Orientation Weight", "For Tree-IK: Weight of orientation control for this target"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -1274,7 +1274,7 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna) prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "dist"); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 0.0, 100.0f); RNA_def_property_ui_text(prop, "Distance", "Radius of limiting sphere"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -1790,21 +1790,21 @@ static void rna_def_constraint_action(BlenderRNA *brna) prop = RNA_def_property(srna, "max", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "max"); - RNA_def_property_range(prop, -1000.f, 1000.f); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Maximum", "Maximum value for target channel range"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range"); prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "min"); - RNA_def_property_range(prop, -1000.f, 1000.f); + RNA_def_property_range(prop, -1000.0f, 1000.0f); RNA_def_property_ui_text(prop, "Minimum", "Minimum value for target channel range"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_ActionConstraint_minmax_range"); prop = RNA_def_property(srna, "eval_time", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "eval_time"); - RNA_def_property_range(prop, 0.f, 1.f); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text( prop, "Evaluation Time", "Interpolates between Action Start and End frames"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -2003,7 +2003,7 @@ static void rna_def_constraint_stretch_to(BlenderRNA *brna) RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 0.0, 100.0f); RNA_def_property_ui_text( prop, "Volume Variation", "Factor between volume variation and stretching"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -2546,37 +2546,37 @@ static void rna_def_constraint_rotation_limit(BlenderRNA *brna) prop = RNA_def_property(srna, "min_x", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "xmin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum X", "Lowest X value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "min_y", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "ymin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum Y", "Lowest Y value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "min_z", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "zmin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum Z", "Lowest Z value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_x", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "xmax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum X", "Highest X value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_y", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "ymax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum Y", "Highest Y value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_z", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "zmax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum Z", "Highest Z value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -2634,37 +2634,37 @@ static void rna_def_constraint_size_limit(BlenderRNA *brna) prop = RNA_def_property(srna, "min_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xmin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum X", "Lowest X value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "min_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ymin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum Y", "Lowest Y value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "min_z", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zmin"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Minimum Z", "Lowest Z value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_x", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "xmax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum X", "Highest X value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_y", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "ymax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum Y", "Highest Y value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); prop = RNA_def_property(srna, "max_z", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "zmax"); - RNA_def_property_range(prop, -1000.0, 1000.f); + RNA_def_property_range(prop, -1000.0, 1000.0f); RNA_def_property_ui_text(prop, "Maximum Z", "Highest Z value to allow"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -3017,7 +3017,7 @@ static void rna_def_constraint_spline_ik(BlenderRNA *brna) /* volume presevation for "volumetric" scale mode */ prop = RNA_def_property(srna, "bulge", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.0, 100.f); + RNA_def_property_range(prop, 0.0, 100.0f); RNA_def_property_ui_text( prop, "Volume Variation", "Factor between volume variation and stretching"); RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update"); @@ -3453,7 +3453,7 @@ void RNA_def_constraint(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( prop, - "Rot error", + "Rotation error", "Amount of residual error in radians for constraints that work on orientation"); RNA_define_lib_overridable(false); diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 2d6bf2897e0..2e73fabe103 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -543,11 +543,9 @@ static void rna_Curve_resolution_u_update_data(Main *bmain, Scene *scene, Pointe { Curve *cu = (Curve *)ptr->owner_id; ListBase *nurbs = BKE_curve_nurbs_get(cu); - Nurb *nu = nurbs->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { nu->resolu = cu->resolu; - nu = nu->next; } rna_Curve_update_data(bmain, scene, ptr); @@ -557,11 +555,9 @@ static void rna_Curve_resolution_v_update_data(Main *bmain, Scene *scene, Pointe { Curve *cu = (Curve *)ptr->owner_id; ListBase *nurbs = BKE_curve_nurbs_get(cu); - Nurb *nu = nurbs->first; - while (nu) { + LISTBASE_FOREACH (Nurb *, nu, nurbs) { nu->resolv = cu->resolv; - nu = nu->next; } rna_Curve_update_data(bmain, scene, ptr); diff --git a/source/blender/makesrna/intern/rna_curveprofile.c b/source/blender/makesrna/intern/rna_curveprofile.c index ee1c659fcd5..25f0c5fb9b4 100644 --- a/source/blender/makesrna/intern/rna_curveprofile.c +++ b/source/blender/makesrna/intern/rna_curveprofile.c @@ -53,7 +53,6 @@ # include "BKE_linestyle.h" # include "BKE_movieclip.h" # include "BKE_node.h" -# include "BKE_sequencer.h" # include "DEG_depsgraph.h" @@ -62,6 +61,8 @@ # include "IMB_colormanagement.h" # include "IMB_imbuf.h" +# include "SEQ_sequencer.h" + /** * Set both handle types for all selected points in the profile-- faster than changing types * for many points individually. Also set both handles for the points. diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 8eb964b8c17..b298d49fad5 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -1407,7 +1407,7 @@ PropertyRNA *RNA_def_property(StructOrFunctionRNA *cont_, /* a priori not raw editable */ prop->rawtype = -1; - if (type != PROP_COLLECTION && type != PROP_POINTER) { + if (!ELEM(type, PROP_COLLECTION, PROP_POINTER)) { prop->flag = PROP_EDITABLE; if (type != PROP_STRING) { @@ -1843,6 +1843,10 @@ void RNA_def_property_struct_runtime(PropertyRNA *prop, StructRNA *type) DefRNA.error = true; break; } + + if ((type->flag & STRUCT_ID) != 0) { + prop->flag |= PROP_PTR_NO_OWNERSHIP; + } } void RNA_def_property_enum_native_type(PropertyRNA *prop, const char *native_enum_type) diff --git a/source/blender/makesrna/intern/rna_fcurve_api.c b/source/blender/makesrna/intern/rna_fcurve_api.c index f7be65b4e75..5a720b91f87 100644 --- a/source/blender/makesrna/intern/rna_fcurve_api.c +++ b/source/blender/makesrna/intern/rna_fcurve_api.c @@ -76,52 +76,7 @@ static void rna_FCurve_convert_to_keyframes(FCurve *fcu, ReportList *reports, in BKE_report(reports, RPT_WARNING, "FCurve has no sample points"); } else { - BezTriple *bezt; - FPoint *fpt = fcu->fpt; - int tot_kf = end - start; - int tot_sp = fcu->totvert; - - bezt = fcu->bezt = MEM_callocN(sizeof(*fcu->bezt) * (size_t)tot_kf, __func__); - fcu->totvert = tot_kf; - - /* Get first sample point to 'copy' as keyframe. */ - for (; tot_sp && (fpt->vec[0] < (float)start); fpt++, tot_sp--) { - /* pass */ - } - - /* Add heading dummy flat points if needed. */ - for (; tot_kf && (fpt->vec[0] > (float)start); start++, bezt++, tot_kf--) { - /* Linear interpolation, of course. */ - bezt->f1 = bezt->f2 = bezt->f3 = SELECT; - bezt->ipo = BEZT_IPO_LIN; - bezt->h1 = bezt->h2 = HD_AUTO_ANIM; - bezt->vec[1][0] = (float)start; - bezt->vec[1][1] = fpt->vec[1]; - } - - /* Copy actual sample points. */ - for (; tot_kf && tot_sp; start++, bezt++, tot_kf--, fpt++, tot_sp--) { - /* Linear interpolation, of course. */ - bezt->f1 = bezt->f2 = bezt->f3 = SELECT; - bezt->ipo = BEZT_IPO_LIN; - bezt->h1 = bezt->h2 = HD_AUTO_ANIM; - copy_v2_v2(bezt->vec[1], fpt->vec); - } - - /* Add leading dummy flat points if needed. */ - for (fpt--; tot_kf; start++, bezt++, tot_kf--) { - /* Linear interpolation, of course. */ - bezt->f1 = bezt->f2 = bezt->f3 = SELECT; - bezt->ipo = BEZT_IPO_LIN; - bezt->h1 = bezt->h2 = HD_AUTO_ANIM; - bezt->vec[1][0] = (float)start; - bezt->vec[1][1] = fpt->vec[1]; - } - - MEM_SAFE_FREE(fcu->fpt); - - /* Not strictly needed since we use linear interpolation, but better be consistent here. */ - calchandles_fcurve(fcu); + fcurve_samples_to_keyframes(fcu, start, end); WM_main_add_notifier(NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); } } diff --git a/source/blender/makesrna/intern/rna_fluid.c b/source/blender/makesrna/intern/rna_fluid.c index 60eed60ace1..02ae71e3b3d 100644 --- a/source/blender/makesrna/intern/rna_fluid.c +++ b/source/blender/makesrna/intern/rna_fluid.c @@ -1456,8 +1456,16 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem simulation_methods[] = { - {FLUID_DOMAIN_METHOD_FLIP, "FLIP", 0, "FLIP", "Use FLIP as the simulation method"}, - /*{FLUID_DOMAIN_METHOD_APIC, "APIC", 0, "APIC", "Use APIC as the simulation method"},*/ + {FLUID_DOMAIN_METHOD_FLIP, + "FLIP", + 0, + "FLIP", + "Use FLIP as the simulation method (more splashy behavior)"}, + {FLUID_DOMAIN_METHOD_APIC, + "APIC", + 0, + "APIC", + "Use APIC as the simulation method (more energetic and stable behavior)"}, {0, NULL, 0, NULL, NULL}, }; @@ -1820,6 +1828,7 @@ static void rna_def_fluid_domain_settings(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "simulation_method"); RNA_def_property_enum_items(prop, simulation_methods); RNA_def_property_ui_text(prop, "Simulation Method", "Change the underlying simulation method"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Fluid_domain_data_reset"); prop = RNA_def_property(srna, "flip_ratio", PROP_FLOAT, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 5592474a348..abbb55734e5 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -2263,6 +2263,16 @@ static void rna_def_modifier_gpenciltexture(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Scale", "Factor to scale the UVs"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + /* Rotation of Dot Texture. */ + prop = RNA_def_property(srna, "alignment_rotation", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "alignment_rotation"); + RNA_def_property_float_default(prop, 0.0f); + RNA_def_property_range(prop, -DEG2RADF(90.0f), DEG2RADF(90.0f)); + RNA_def_property_ui_range(prop, -DEG2RADF(90.0f), DEG2RADF(90.0f), 10, 3); + RNA_def_property_ui_text( + prop, "Rotation", "Additional rotation applied to dots and square strokes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "fill_rotation", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "fill_rotation"); RNA_def_property_ui_text(prop, "Fill Rotation", "Additional rotation of the fill UV"); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 1c43815d3a2..ea36289d361 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -1034,7 +1034,7 @@ static void rna_def_image(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "aspx"); RNA_def_property_array(prop, 2); RNA_def_property_range(prop, 0.1f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.1f, 5000.f, 1, 2); + RNA_def_property_ui_range(prop, 0.1f, 5000.0f, 1, 2); RNA_def_property_ui_text( prop, "Display Aspect", "Display Aspect for this image, does not affect rendering"); RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, NULL); diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c index 64c50b82d1f..03442748854 100644 --- a/source/blender/makesrna/intern/rna_linestyle.c +++ b/source/blender/makesrna/intern/rna_linestyle.c @@ -1573,7 +1573,7 @@ static void rna_def_linestyle_modifiers(BlenderRNA *brna) prop = RNA_def_property(srna, "pivot_u", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "pivot_u"); - RNA_def_property_range(prop, 0.f, 1.f); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Stroke Point Parameter", "Pivot in terms of the stroke point parameter u (0 <= u <= 1)"); @@ -1920,7 +1920,7 @@ static void rna_def_linestyle(BlenderRNA *brna) prop = RNA_def_property(srna, "thickness_ratio", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "thickness_ratio"); - RNA_def_property_range(prop, 0.f, 1.f); + RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text( prop, "Thickness Ratio", diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 5e16f1187fb..086a182e085 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -24,6 +24,8 @@ #include "DNA_material_types.h" #include "DNA_texture_types.h" +#include "BLI_math.h" + #include "RNA_define.h" #include "RNA_enum_types.h" @@ -594,6 +596,16 @@ static void rna_def_material_greasepencil(BlenderRNA *brna) prop, "Alignment", "Defines how align Dots and Boxes with drawing path and object rotation"); RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + /* Rotation of texture for Dots or Strokes. */ + prop = RNA_def_property(srna, "alignment_rotation", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "alignment_rotation"); + RNA_def_property_float_default(prop, 0.0f); + RNA_def_property_range(prop, -DEG2RADF(90.0f), DEG2RADF(90.0f)); + RNA_def_property_ui_range(prop, -DEG2RADF(90.0f), DEG2RADF(90.0f), 10, 3); + RNA_def_property_ui_text( + prop, "Rotation", "Additional rotation applied to dots and square strokes"); + RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); + /* pass index for future compositing and editing tools */ prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "index"); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 7885e182787..e2b09b1c055 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -969,15 +969,6 @@ static void rna_fluid_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) rna_Modifier_dependency_update(bmain, scene, ptr); } -static void rna_MultiresModifier_type_set(PointerRNA *ptr, int value) -{ - Object *ob = (Object *)ptr->owner_id; - MultiresModifierData *mmd = (MultiresModifierData *)ptr->data; - - multires_force_sculpt_rebuild(ob); - mmd->simple = value; -} - static void rna_MultiresModifier_level_range( PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax)) { @@ -1538,12 +1529,7 @@ static void rna_ParticleInstanceModifier_particle_system_set(PointerRNA *ptr, static void rna_Modifier_show_expanded_set(PointerRNA *ptr, bool value) { ModifierData *md = ptr->data; - if (value) { - md->ui_expand_flag |= (1 << 0); - } - else { - md->ui_expand_flag &= ~(1 << 0); - } + SET_FLAG_FROM_TEST(md->ui_expand_flag, value, UI_PANEL_DATA_EXPAND_ROOT); } /** @@ -1554,7 +1540,7 @@ static void rna_Modifier_show_expanded_set(PointerRNA *ptr, bool value) static bool rna_Modifier_show_expanded_get(PointerRNA *ptr) { ModifierData *md = ptr->data; - return md->ui_expand_flag & (1 << 0); + return md->ui_expand_flag & UI_PANEL_DATA_EXPAND_ROOT; } static int rna_MeshSequenceCacheModifier_has_velocity_get(PointerRNA *ptr) @@ -1604,15 +1590,8 @@ static int rna_MeshSequenceCacheModifier_read_velocity_get(PointerRNA *ptr) #else -/* NOTE: *MUST* return subdivision_type property. */ -static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const char type[]) +static void rna_def_property_subdivision_common(StructRNA *srna) { - static const EnumPropertyItem prop_subdivision_type_items[] = { - {SUBSURF_TYPE_CATMULL_CLARK, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, - {SUBSURF_TYPE_SIMPLE, "SIMPLE", 0, "Simple", ""}, - {0, NULL, 0, NULL, NULL}, - }; - static const EnumPropertyItem prop_uv_smooth_items[] = { {SUBSURF_UV_SMOOTH_NONE, "NONE", 0, "None", "UVs are not smoothed, boundaries are kept sharp"}, {SUBSURF_UV_SMOOTH_PRESERVE_CORNERS, @@ -1677,19 +1656,17 @@ static PropertyRNA *rna_def_property_subdivision_common(StructRNA *srna, const c RNA_def_property_ui_text(prop, "Boundary Smooth", "Controls how open boundaries are smoothed"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); - prop = RNA_def_property(srna, "subdivision_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, type); - RNA_def_property_enum_items(prop, prop_subdivision_type_items); - RNA_def_property_ui_text(prop, "Subdivision Type", "Select type of subdivision algorithm"); - RNA_def_property_update(prop, 0, "rna_Modifier_update"); - RNA_define_lib_overridable(false); - - return prop; } static void rna_def_modifier_subsurf(BlenderRNA *brna) { + static const EnumPropertyItem prop_subdivision_type_items[] = { + {SUBSURF_TYPE_CATMULL_CLARK, "CATMULL_CLARK", 0, "Catmull-Clark", ""}, + {SUBSURF_TYPE_SIMPLE, "SIMPLE", 0, "Simple", ""}, + {0, NULL, 0, NULL, NULL}, + }; + StructRNA *srna; PropertyRNA *prop; @@ -1698,10 +1675,16 @@ static void rna_def_modifier_subsurf(BlenderRNA *brna) RNA_def_struct_sdna(srna, "SubsurfModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_SUBSURF); - rna_def_property_subdivision_common(srna, "subdivType"); + rna_def_property_subdivision_common(srna); RNA_define_lib_overridable(true); + prop = RNA_def_property(srna, "subdivision_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "subdivType"); + RNA_def_property_enum_items(prop, prop_subdivision_type_items); + RNA_def_property_ui_text(prop, "Subdivision Type", "Select type of subdivision algorithm"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + /* see CCGSUBSURF_LEVEL_MAX for max limit */ prop = RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "levels"); @@ -1893,8 +1876,7 @@ static void rna_def_modifier_multires(BlenderRNA *brna) RNA_define_lib_overridable(true); - prop = rna_def_property_subdivision_common(srna, "simple"); - RNA_def_property_enum_funcs(prop, NULL, "rna_MultiresModifier_type_set", NULL); + rna_def_property_subdivision_common(srna); prop = RNA_def_property(srna, "levels", PROP_INT, PROP_UNSIGNED); RNA_def_property_int_sdna(prop, NULL, "lvl"); diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c index ff5445f1d71..d07a4b4fac7 100644 --- a/source/blender/makesrna/intern/rna_movieclip.c +++ b/source/blender/makesrna/intern/rna_movieclip.c @@ -46,11 +46,11 @@ # include "ED_clip.h" -# include "BKE_sequencer.h" - # include "DNA_screen_types.h" # include "DNA_space_types.h" +# include "SEQ_sequencer.h" + static void rna_MovieClip_reload_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { MovieClip *clip = (MovieClip *)ptr->owner_id; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 0dea0e47978..6ac3f1dd424 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4362,10 +4362,38 @@ static void def_sh_vector_rotate(StructRNA *srna) static void def_sh_attribute(StructRNA *srna) { + static const EnumPropertyItem prop_attribute_type[] = { + {SHD_ATTRIBUTE_GEOMETRY, + "GEOMETRY", + 0, + "Geometry", + "The attribute is associated with the object geometry, and its value " + "varies from vertex to vertex, or within the object volume"}, + {SHD_ATTRIBUTE_OBJECT, + "OBJECT", + 0, + "Object", + "The attribute is associated with the object or mesh datablock itself, " + "and its value is uniform"}, + {SHD_ATTRIBUTE_INSTANCER, + "INSTANCER", + 0, + "Instancer", + "The attribute is associated with the instancer particle system or object, " + "falling back to the Object mode if the attribute isn't found, or the object " + "is not instanced"}, + {0, NULL, 0, NULL, NULL}, + }; PropertyRNA *prop; RNA_def_struct_sdna_from(srna, "NodeShaderAttribute", "storage"); + prop = RNA_def_property(srna, "attribute_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, prop_attribute_type); + RNA_def_property_ui_text(prop, "Attribute Type", "General type of the attribute"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + prop = RNA_def_property(srna, "attribute_name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Attribute Name", ""); @@ -4788,7 +4816,7 @@ static void def_sh_tex_voronoi(StructRNA *srna) {SHD_VORONOI_DISTANCE_TO_EDGE, "DISTANCE_TO_EDGE", 0, - "Distance To Edge", + "Distance to Edge", "Computes the distance to the edge of the voronoi cell"}, {SHD_VORONOI_N_SPHERE_RADIUS, "N_SPHERE_RADIUS", @@ -7090,7 +7118,7 @@ static void def_cmp_lensdist(StructRNA *srna) static void def_cmp_colorbalance(StructRNA *srna) { PropertyRNA *prop; - static float default_1[3] = {1.f, 1.f, 1.f}; + static float default_1[3] = {1.0f, 1.0f, 1.0f}; static const EnumPropertyItem type_items[] = { {0, "LIFT_GAMMA_GAIN", 0, "Lift/Gamma/Gain", ""}, @@ -7145,7 +7173,7 @@ static void def_cmp_colorbalance(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "power"); RNA_def_property_array(prop, 3); RNA_def_property_float_array_default(prop, default_1); - RNA_def_property_range(prop, 0.f, FLT_MAX); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Power", "Correction for Midtones"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl"); @@ -7154,7 +7182,7 @@ static void def_cmp_colorbalance(StructRNA *srna) RNA_def_property_float_sdna(prop, NULL, "slope"); RNA_def_property_array(prop, 3); RNA_def_property_float_array_default(prop, default_1); - RNA_def_property_range(prop, 0.f, FLT_MAX); + RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 2, 0.1, 3); RNA_def_property_ui_text(prop, "Slope", "Correction for Highlights"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeColorBalance_update_cdl"); @@ -7725,15 +7753,15 @@ static void def_cmp_viewer(StructRNA *srna) static const EnumPropertyItem tileorder_items[] = { {0, "CENTEROUT", 0, "Center", "Expand from center"}, {1, "RANDOM", 0, "Random", "Random tiles"}, - {2, "BOTTOMUP", 0, "Bottom up", "Expand from bottom"}, - {3, "RULE_OF_THIRDS", 0, "Rule of thirds", "Expand from 9 places"}, + {2, "BOTTOMUP", 0, "Bottom Up", "Expand from bottom"}, + {3, "RULE_OF_THIRDS", 0, "Rule of Thirds", "Expand from 9 places"}, {0, NULL, 0, NULL, NULL}, }; prop = RNA_def_property(srna, "tile_order", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, tileorder_items); - RNA_def_property_ui_text(prop, "Tile order", "Tile order"); + RNA_def_property_ui_text(prop, "Tile Order", "Tile order"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "center_x", PROP_FLOAT, PROP_NONE); @@ -8037,7 +8065,7 @@ static void def_cmp_sunbeams(StructRNA *srna) static void def_cmp_cryptomatte(StructRNA *srna) { PropertyRNA *prop; - static float default_1[3] = {1.f, 1.f, 1.f}; + static float default_1[3] = {1.0f, 1.0f, 1.0f}; RNA_def_struct_sdna_from(srna, "NodeCryptomatte", "storage"); prop = RNA_def_property(srna, "matte_id", PROP_STRING, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 8b227774d66..6f7116bfe22 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -2699,6 +2699,15 @@ static void rna_def_object(BlenderRNA *brna) prop, "Parent Bone", "Name of parent bone in case of a bone parenting relation"); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_dependency_update"); + prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna( + prop, NULL, "transflag", OB_TRANSFORM_ADJUST_ROOT_PARENT_FOR_VIEW_LOCK); + RNA_def_property_ui_text(prop, + "Camera Parent Lock", + "View Lock 3D viewport camera transformation affects the object's " + "parent instead"); + RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update"); + /* Track and Up flags */ /* XXX: these have been saved here for a bit longer (after old track was removed), * since some other tools still refer to this */ diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 2c740533dcd..19a367a0c55 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -2031,7 +2031,8 @@ static void rna_def_softbody(BlenderRNA *brna) prop = RNA_def_property(srna, "use_estimate_matrix", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "solverflags", SBSO_ESTIMATEIPO); - RNA_def_property_ui_text(prop, "Estimate Matrix", "Estimate matrix... split to COM, ROT, SCALE"); + RNA_def_property_ui_text( + prop, "Estimate Transforms", "Store the estimated transforms in the soft body settings"); /***********************************************************************************/ /* these are not exactly settings, but reading calculated results*/ @@ -2047,7 +2048,7 @@ static void rna_def_softbody(BlenderRNA *brna) prop = RNA_def_property(srna, "rotation_estimate", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "lrot"); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_3x3); - RNA_def_property_ui_text(prop, "Rot Matrix", "Estimated rotation matrix"); + RNA_def_property_ui_text(prop, "Rotation Matrix", "Estimated rotation matrix"); prop = RNA_def_property(srna, "scale_estimate", PROP_FLOAT, PROP_MATRIX); RNA_def_property_float_sdna(prop, NULL, "lscale"); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 543038eee8c..5987f52328d 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -1011,13 +1011,13 @@ static float rna_PartSettings_timestep_get(struct PointerRNA *ptr) static void rna_PartSetting_hairlength_set(struct PointerRNA *ptr, float value) { ParticleSettings *settings = (ParticleSettings *)ptr->data; - settings->normfac = value / 4.f; + settings->normfac = value / 4.0f; } static float rna_PartSetting_hairlength_get(struct PointerRNA *ptr) { ParticleSettings *settings = (ParticleSettings *)ptr->data; - return settings->normfac * 4.f; + return settings->normfac * 4.0f; } static void rna_PartSetting_linelentail_set(struct PointerRNA *ptr, float value) diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c index 942cd3d1a20..bc9aabbefe6 100644 --- a/source/blender/makesrna/intern/rna_pose.c +++ b/source/blender/makesrna/intern/rna_pose.c @@ -375,14 +375,14 @@ static void rna_Itasc_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerR if (itasc->feedback < 0.01f) { itasc->feedback = 0.01f; } - if (itasc->feedback > 100.f) { - itasc->feedback = 100.f; + if (itasc->feedback > 100.0f) { + itasc->feedback = 100.0f; } if (itasc->maxvel < 0.01f) { itasc->maxvel = 0.01f; } - if (itasc->maxvel > 100.f) { - itasc->maxvel = 100.f; + if (itasc->maxvel > 100.0f) { + itasc->maxvel = 100.0f; } BIK_update_param(ob->pose); @@ -1241,14 +1241,14 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop = RNA_def_property(srna, "use_ik_rotation_control", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_ROTCTL); - RNA_def_property_ui_text(prop, "IK rot control", "Apply channel rotation as IK constraint"); + RNA_def_property_ui_text(prop, "IK Rotation Control", "Apply channel rotation as IK constraint"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update"); prop = RNA_def_property(srna, "use_ik_linear_control", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "ikflag", BONE_IK_LINCTL); RNA_def_property_ui_text( - prop, "IK rot control", "Apply channel size as IK constraint if stretching is enabled"); + prop, "IK Linear Control", "Apply channel size as IK constraint if stretching is enabled"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_IK_update"); @@ -1325,7 +1325,7 @@ static void rna_def_pose_channel(BlenderRNA *brna) prop = RNA_def_property(srna, "ik_rotation_weight", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "ikrotweight"); RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "IK Rot Weight", "Weight of rotation constraint for IK"); + RNA_def_property_ui_text(prop, "IK Rotation Weight", "Weight of rotation constraint for IK"); RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update"); @@ -1504,7 +1504,7 @@ static void rna_def_pose_itasc(BlenderRNA *brna) prop = RNA_def_property(srna, "step_count", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "numstep"); - RNA_def_property_range(prop, 1.f, 50.f); + RNA_def_property_range(prop, 1.0f, 50.0f); RNA_def_property_ui_text(prop, "Num Steps", "Divide the frame interval into this many steps"); RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Itasc_update"); @@ -1695,6 +1695,8 @@ static void rna_def_pose(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "IK Param", "Parameters for IK solver"); + RNA_define_lib_overridable(true); + /* pose edit options */ prop = RNA_def_property(srna, "use_mirror_x", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", POSE_MIRROR_EDIT); @@ -1722,6 +1724,8 @@ static void rna_def_pose(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Pose_update"); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); + RNA_define_lib_overridable(false); + /* animviz */ rna_def_animviz_common(srna); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 24cff501b59..c132c434468 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -379,7 +379,7 @@ const EnumPropertyItem rna_enum_image_type_items[] = { {R_IMF_IMTYPE_FFMPEG, "FFMPEG", ICON_FILE_MOVIE, - "FFmpeg video", + "FFmpeg Video", "The most versatile way to output video files"}, #endif {0, NULL, 0, NULL, NULL}, @@ -680,7 +680,6 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = { # include "BKE_pointcache.h" # include "BKE_scene.h" # include "BKE_screen.h" -# include "BKE_sequencer.h" # include "BKE_unit.h" # include "ED_image.h" @@ -694,6 +693,8 @@ const EnumPropertyItem rna_enum_transform_orientation_items[] = { # include "DEG_depsgraph_build.h" # include "DEG_depsgraph_query.h" +# include "SEQ_sequencer.h" + # ifdef WITH_FREESTYLE # include "FRS_freestyle.h" # endif @@ -1157,7 +1158,7 @@ static int rna_RenderSettings_stereoViews_skip(CollectionPropertyIterator *iter, ListBaseIterator *internal = &iter->internal.listbase; SceneRenderView *srv = (SceneRenderView *)internal->link; - if ((STREQ(srv->name, STEREO_LEFT_NAME)) || (STREQ(srv->name, STEREO_RIGHT_NAME))) { + if (STR_ELEM(srv->name, STEREO_LEFT_NAME, STEREO_RIGHT_NAME)) { return 0; } @@ -2793,7 +2794,8 @@ static void rna_def_view3d_cursor(BlenderRNA *brna) prop = RNA_def_property(srna, "matrix", PROP_FLOAT, PROP_MATRIX); RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4); RNA_def_property_flag(prop, PROP_THICK_WRAP); /* no reference to original data */ - RNA_def_property_ui_text(prop, "Transform Matrix", "Matrix combining loc/rot of the cursor"); + RNA_def_property_ui_text( + prop, "Transform Matrix", "Matrix combining location and rotation of the cursor"); RNA_def_property_float_funcs( prop, "rna_View3DCursor_matrix_get", "rna_View3DCursor_matrix_set", NULL); } @@ -2864,13 +2866,13 @@ static void rna_def_tool_settings(BlenderRNA *brna) }; static const EnumPropertyItem gpencil_stroke_snap_items[] = { - {0, "NONE", 0, "All points", "Snap to all points"}, + {0, "NONE", 0, "All Points", "Snap to all points"}, {GP_PROJECT_DEPTH_STROKE_ENDPOINTS, "ENDS", 0, - "End points", + "End Points", "Snap to first and last points and interpolate"}, - {GP_PROJECT_DEPTH_STROKE_FIRST, "FIRST", 0, "First point", "Snap to first point"}, + {GP_PROJECT_DEPTH_STROKE_FIRST, "FIRST", 0, "First Point", "Snap to first point"}, {0, NULL, 0, NULL, NULL}, }; @@ -5510,12 +5512,12 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna) "Constant Bitrate", "Configure constant bit rate, rather than constant output quality"}, {FFM_CRF_LOSSLESS, "LOSSLESS", 0, "Lossless", ""}, - {FFM_CRF_PERC_LOSSLESS, "PERC_LOSSLESS", 0, "Perceptually lossless", ""}, - {FFM_CRF_HIGH, "HIGH", 0, "High quality", ""}, - {FFM_CRF_MEDIUM, "MEDIUM", 0, "Medium quality", ""}, - {FFM_CRF_LOW, "LOW", 0, "Low quality", ""}, - {FFM_CRF_VERYLOW, "VERYLOW", 0, "Very low quality", ""}, - {FFM_CRF_LOWEST, "LOWEST", 0, "Lowest quality", ""}, + {FFM_CRF_PERC_LOSSLESS, "PERC_LOSSLESS", 0, "Perceptually Lossless", ""}, + {FFM_CRF_HIGH, "HIGH", 0, "High Quality", ""}, + {FFM_CRF_MEDIUM, "MEDIUM", 0, "Medium Quality", ""}, + {FFM_CRF_LOW, "LOW", 0, "Low Quality", ""}, + {FFM_CRF_VERYLOW, "VERYLOW", 0, "Very Low Quality", ""}, + {FFM_CRF_LOWEST, "LOWEST", 0, "Lowest Quality", ""}, {0, NULL, 0, NULL, NULL}, }; @@ -5738,7 +5740,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) {0, "AUTO", 0, - "Auto-detect", + "Auto-Detect", "Automatically determine the number of threads, based on CPUs"}, {R_FIXED_THREADS, "FIXED", 0, "Fixed", "Manually determine the number of threads"}, {0, NULL, 0, NULL, NULL}, @@ -6537,7 +6539,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) prop = RNA_def_property(srna, "line_thickness", PROP_FLOAT, PROP_PIXEL); RNA_def_property_float_sdna(prop, NULL, "unit_line_thickness"); - RNA_def_property_range(prop, 0.f, 10000.f); + RNA_def_property_range(prop, 0.0f, 10000.0f); RNA_def_property_ui_text(prop, "Line Thickness", "Line thickness in pixels"); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_freestyle_update"); @@ -7359,9 +7361,9 @@ void RNA_def_scene(BlenderRNA *brna) }; static const EnumPropertyItem sync_mode_items[] = { - {0, "NONE", 0, "No Sync", "Do not sync, play every frame"}, + {0, "NONE", 0, "Play Every Frame", "Do not sync, play every frame"}, {SCE_FRAME_DROP, "FRAME_DROP", 0, "Frame Dropping", "Drop frames if playback is too slow"}, - {AUDIO_SYNC, "AUDIO_SYNC", 0, "AV-sync", "Sync to audio playback, dropping frames"}, + {AUDIO_SYNC, "AUDIO_SYNC", 0, "Sync to Audio", "Sync to audio playback, dropping frames"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c7bdf7a2dd6..e477bf6d284 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -1151,7 +1151,7 @@ static void rna_def_particle_edit(BlenderRNA *brna) static const EnumPropertyItem edit_type_items[] = { {PE_TYPE_PARTICLES, "PARTICLES", 0, "Particles", ""}, - {PE_TYPE_SOFTBODY, "SOFT_BODY", 0, "Soft body", ""}, + {PE_TYPE_SOFTBODY, "SOFT_BODY", 0, "Soft Body", ""}, {PE_TYPE_CLOTH, "CLOTH", 0, "Cloth", ""}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 9d322d0d09b..1882fce3f54 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -34,7 +34,6 @@ #include "BKE_anim_data.h" #include "BKE_animsys.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "IMB_metadata.h" @@ -47,6 +46,8 @@ #include "rna_internal.h" +#include "SEQ_sequencer.h" + #include "WM_types.h" typedef struct EffectInfo { @@ -469,35 +470,7 @@ static void rna_Sequence_channel_set(PointerRNA *ptr, int value) static void rna_Sequence_use_proxy_set(PointerRNA *ptr, bool value) { Sequence *seq = (Sequence *)ptr->data; - BKE_sequencer_proxy_set(seq, value != 0); -} - -static void rna_Sequence_use_translation_set(PointerRNA *ptr, bool value) -{ - Sequence *seq = (Sequence *)ptr->data; - if (value) { - seq->flag |= SEQ_USE_TRANSFORM; - if (seq->strip->transform == NULL) { - seq->strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform"); - } - } - else { - seq->flag &= ~SEQ_USE_TRANSFORM; - } -} - -static void rna_Sequence_use_crop_set(PointerRNA *ptr, bool value) -{ - Sequence *seq = (Sequence *)ptr->data; - if (value) { - seq->flag |= SEQ_USE_CROP; - if (seq->strip->crop == NULL) { - seq->strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop"); - } - } - else { - seq->flag &= ~SEQ_USE_CROP; - } + SEQ_proxy_set(seq, value != 0); } static int transform_seq_cmp_fn(Sequence *seq, void *arg_pt) @@ -1408,18 +1381,35 @@ static void rna_def_strip_transform(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "Sequence Transform", "Transform parameters for a sequence strip"); RNA_def_struct_sdna(srna, "StripTransform"); + prop = RNA_def_property(srna, "scale_x", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_sdna(prop, NULL, "scale_x"); + RNA_def_property_ui_text(prop, "Scale X", "Scale along X axis"); + RNA_def_property_ui_range(prop, 0, FLT_MAX, 3, 3); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); + + prop = RNA_def_property(srna, "scale_y", PROP_FLOAT, PROP_UNSIGNED); + RNA_def_property_float_sdna(prop, NULL, "scale_y"); + RNA_def_property_ui_text(prop, "Scale Y", "Scale along Y axis"); + RNA_def_property_ui_range(prop, 0, FLT_MAX, 3, 3); + RNA_def_property_float_default(prop, 1.0f); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); + prop = RNA_def_property(srna, "offset_x", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "xofs"); - RNA_def_property_ui_text( - prop, "Offset X", "Amount to move the input on the X axis within its boundaries"); - RNA_def_property_ui_range(prop, -4096, 4096, 1, -1); + RNA_def_property_ui_text(prop, "Translate X", "Move along X axis"); + RNA_def_property_ui_range(prop, INT_MIN, INT_MAX, 1, 6); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_PIXEL); RNA_def_property_int_sdna(prop, NULL, "yofs"); - RNA_def_property_ui_text( - prop, "Offset Y", "Amount to move the input on the Y axis within its boundaries"); - RNA_def_property_ui_range(prop, -4096, 4096, 1, -1); + RNA_def_property_ui_text(prop, "Translate Y", "Move along Y axis"); + RNA_def_property_ui_range(prop, INT_MIN, INT_MAX, 1, 6); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); + + prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rotation"); + RNA_def_property_ui_text(prop, "Rotation", "Rotate around image centr"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update"); RNA_def_struct_path_func(srna, "rna_SequenceTransform_path"); @@ -1936,7 +1926,7 @@ static void rna_def_sequence(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "cache_flag", SEQ_CACHE_STORE_PREPROCESSED); RNA_def_property_ui_text( prop, - "Cache Pre-processed", + "Cache Pre-Processed", "Cache pre-processed images, for faster tweaking of effects at the cost of memory usage"); prop = RNA_def_property(srna, "use_cache_composite", PROP_BOOLEAN, PROP_NONE); @@ -2100,7 +2090,7 @@ static void rna_def_editor(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, SEQ_CACHE_COST_MAX, 0.1f, 1); RNA_def_property_float_sdna(prop, NULL, "recycle_max_cost"); RNA_def_property_ui_text( - prop, "Recycle Up To Cost", "Only frames with cost lower than this value will be recycled"); + prop, "Recycle Up to Cost", "Only frames with cost lower than this value will be recycled"); } static void rna_def_filter_video(StructRNA *srna) @@ -2150,7 +2140,7 @@ static void rna_def_filter_video(StructRNA *srna) prop = RNA_def_property(srna, "use_reverse_frames", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_REVERSE_FRAMES); RNA_def_property_ui_text(prop, "Reverse Frames", "Reverse frame order"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); prop = RNA_def_property(srna, "color_multiply", PROP_FLOAT, PROP_UNSIGNED); RNA_def_property_float_sdna(prop, NULL, "mul"); @@ -2172,24 +2162,12 @@ static void rna_def_filter_video(StructRNA *srna) prop = RNA_def_property(srna, "strobe", PROP_FLOAT, PROP_NONE); RNA_def_property_range(prop, 1.0f, 30.0f); RNA_def_property_ui_text(prop, "Strobe", "Only display every nth frame"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - - prop = RNA_def_property(srna, "use_translation", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_TRANSFORM); - RNA_def_property_ui_text(prop, "Use Translation", "Translate image before processing"); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_translation_set"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); + RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL); prop = RNA_def_property(srna, "transform", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "strip->transform"); RNA_def_property_ui_text(prop, "Transform", ""); - prop = RNA_def_property(srna, "use_crop", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_USE_CROP); - RNA_def_property_ui_text(prop, "Use Crop", "Crop image before processing"); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Sequence_use_crop_set"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); - prop = RNA_def_property(srna, "crop", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "strip->crop"); RNA_def_property_ui_text(prop, "Crop", ""); @@ -2822,7 +2800,7 @@ static void rna_def_speed_control(StructRNA *srna) prop = RNA_def_property(srna, "use_frame_interpolate", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_USE_INTERPOLATION); RNA_def_property_ui_text( - prop, "Frame interpolation", "Do crossfade blending between current and next frame"); + prop, "Frame Interpolation", "Do crossfade blending between current and next frame"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); } diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index e93ca7bc019..9b8386dd1b1 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -46,12 +46,13 @@ # include "BKE_movieclip.h" # include "BKE_report.h" -# include "BKE_sequencer.h" # include "BKE_sound.h" # include "IMB_imbuf.h" # include "IMB_imbuf_types.h" +# include "SEQ_sequencer.h" + # include "WM_api.h" static void rna_Sequence_update_rnafunc(ID *id, Sequence *self, bool do_data) @@ -92,7 +93,7 @@ static Sequence *alloc_generic_sequence( strip->stripdata = se = MEM_callocN(sizeof(StripElem), "stripelem"); BLI_split_dirfile(file, strip->dir, se->name, sizeof(strip->dir), sizeof(se->name)); - BKE_sequence_init_colorspace(seq); + SEQ_render_init_colorspace(seq); } else { strip->stripdata = NULL; @@ -476,7 +477,7 @@ void RNA_api_sequence_strip(StructRNA *srna) RNA_def_function_ui_description(func, "Update the strip dimensions"); parm = RNA_def_boolean(func, "data", false, "Data", "Update strip data"); - func = RNA_def_function(srna, "strip_elem_from_frame", "BKE_sequencer_give_stripelem"); + func = RNA_def_function(srna, "strip_elem_from_frame", "SEQ_render_give_stripelem"); RNA_def_function_ui_description(func, "Return the strip element from a given frame or None"); parm = RNA_def_int(func, "frame", diff --git a/source/blender/makesrna/intern/rna_sound.c b/source/blender/makesrna/intern/rna_sound.c index 2fb50c2e89e..c5a53d4522d 100644 --- a/source/blender/makesrna/intern/rna_sound.c +++ b/source/blender/makesrna/intern/rna_sound.c @@ -29,11 +29,12 @@ #ifdef RNA_RUNTIME # include "BKE_context.h" -# include "BKE_sequencer.h" # include "BKE_sound.h" # include "DEG_depsgraph.h" +# include "SEQ_sequencer.h" + static void rna_Sound_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) { bSound *sound = (bSound *)ptr->data; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 3255f335e74..e0ee33bd234 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -29,7 +29,6 @@ #include "BKE_key.h" #include "BKE_movieclip.h" #include "BKE_node.h" -#include "BKE_sequencer.h" #include "BKE_studiolight.h" #include "ED_text.h" @@ -55,6 +54,8 @@ #include "rna_internal.h" +#include "SEQ_sequencer.h" + #include "WM_api.h" #include "WM_types.h" @@ -307,6 +308,22 @@ static const EnumPropertyItem multiview_camera_items[] = { #undef V3D_S3D_CAMERA_S3D #undef V3D_S3D_CAMERA_VIEWS +const EnumPropertyItem rna_enum_fileselect_params_sort_items[] = { + {FILE_SORT_ALPHA, "FILE_SORT_ALPHA", ICON_NONE, "Name", "Sort the file list alphabetically"}, + {FILE_SORT_EXTENSION, + "FILE_SORT_EXTENSION", + ICON_NONE, + "Extension", + "Sort the file list by extension/type"}, + {FILE_SORT_TIME, + "FILE_SORT_TIME", + ICON_NONE, + "Modified Date", + "Sort files by modification time"}, + {FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_NONE, "Size", "Sort files by size"}, + {0, NULL, 0, NULL, NULL}, +}; + #ifndef RNA_RUNTIME static const EnumPropertyItem stereo3d_eye_items[] = { {STEREO_LEFT_ID, "LEFT_EYE", ICON_NONE, "Left Eye"}, @@ -463,22 +480,6 @@ static const EnumPropertyItem fileselectparams_recursion_level_items[] = { {0, NULL, 0, NULL, NULL}, }; -const EnumPropertyItem rna_enum_file_sort_items[] = { - {FILE_SORT_ALPHA, "FILE_SORT_ALPHA", ICON_NONE, "Name", "Sort the file list alphabetically"}, - {FILE_SORT_EXTENSION, - "FILE_SORT_EXTENSION", - ICON_NONE, - "Extension", - "Sort the file list by extension/type"}, - {FILE_SORT_TIME, - "FILE_SORT_TIME", - ICON_NONE, - "Modified Date", - "Sort files by modification time"}, - {FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_NONE, "Size", "Sort files by size"}, - {0, NULL, 0, NULL, NULL}, -}; - static const EnumPropertyItem rna_enum_curve_display_handle_items[] = { {CURVE_HANDLE_NONE, "NONE", 0, "None", ""}, {CURVE_HANDLE_SELECTED, "SELECTED", 0, "Selected", ""}, @@ -2346,8 +2347,8 @@ static void rna_SpaceClipEditor_lock_selection_update(Main *UNUSED(bmain), { SpaceClip *sc = (SpaceClip *)(ptr->data); - sc->xlockof = 0.f; - sc->ylockof = 0.f; + sc->xlockof = 0.0f; + sc->ylockof = 0.0f; } static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), @@ -3049,6 +3050,7 @@ static void rna_def_space_outliner(BlenderRNA *brna) {SO_FILTER_OB_HIDDEN, "HIDDEN", 0, "Hidden", "Show hidden objects"}, {SO_FILTER_OB_SELECTED, "SELECTED", 0, "Selected", "Show selected objects"}, {SO_FILTER_OB_ACTIVE, "ACTIVE", 0, "Active", "Show only the active object"}, + {SO_FILTER_OB_SELECTABLE, "SELECTABLE", 0, "Selectable", "Show only selectable objects"}, {0, NULL, 0, NULL, NULL}, }; @@ -3210,7 +3212,7 @@ static void rna_def_space_outliner(BlenderRNA *brna) prop = RNA_def_property(srna, "filter_id_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "filter_id_type"); RNA_def_property_enum_items(prop, rna_enum_id_type_items); - RNA_def_property_ui_text(prop, "Filter ID Type", "Data-block type to show"); + RNA_def_property_ui_text(prop, "Filter by Type", "Data-block type to show"); RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID); } @@ -5185,7 +5187,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) prop = RNA_def_property(srna, "show_interpolation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SHOW_INTERPOLATION); RNA_def_property_ui_text(prop, - "Show Handles And Interpolation", + "Show Handles and Interpolation", "Display keyframe handle types and non-bezier interpolation modes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL); @@ -5208,7 +5210,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna) /* editing */ prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOTRANSKEYCULL); - RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Automatically merge nearby keyframes"); + RNA_def_property_ui_text(prop, "Auto-Merge Keyframes", "Automatically merge nearby keyframes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL); prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE); @@ -5826,7 +5828,7 @@ static void rna_def_fileselect_params(BlenderRNA *brna) prop = RNA_def_property(srna, "sort_method", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "sort"); - RNA_def_property_enum_items(prop, rna_enum_file_sort_items); + RNA_def_property_enum_items(prop, rna_enum_fileselect_params_sort_items); RNA_def_property_ui_text(prop, "Sort", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 4d5f0f6c2fa..fb6d40b3a55 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1074,8 +1074,8 @@ static void rna_def_texture_stucci(BlenderRNA *brna) static const EnumPropertyItem prop_stucci_stype[] = { {TEX_PLASTIC, "PLASTIC", 0, "Plastic", "Use standard stucci"}, - {TEX_WALLIN, "WALL_IN", 0, "Wall in", "Create Dimples"}, - {TEX_WALLOUT, "WALL_OUT", 0, "Wall out", "Create Ridges"}, + {TEX_WALLIN, "WALL_IN", 0, "Wall In", "Create Dimples"}, + {TEX_WALLOUT, "WALL_OUT", 0, "Wall Out", "Create Ridges"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 6d90a76a2c0..f9597fdd7af 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -889,38 +889,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}, }; - static const EnumPropertyItem refine_items[] = { - {0, "NONE", 0, "Nothing", "Do not refine camera intrinsics"}, - {REFINE_FOCAL_LENGTH, "FOCAL_LENGTH", 0, "Focal Length", "Refine focal length"}, - {REFINE_FOCAL_LENGTH | REFINE_RADIAL_DISTORTION_K1, - "FOCAL_LENGTH_RADIAL_K1", - 0, - "Focal length, K1", - "Refine focal length and radial distortion K1"}, - {REFINE_FOCAL_LENGTH | REFINE_RADIAL_DISTORTION_K1 | REFINE_RADIAL_DISTORTION_K2, - "FOCAL_LENGTH_RADIAL_K1_K2", - 0, - "Focal length, K1, K2", - "Refine focal length and radial distortion K1 and K2"}, - {REFINE_FOCAL_LENGTH | REFINE_PRINCIPAL_POINT | REFINE_RADIAL_DISTORTION_K1 | - REFINE_RADIAL_DISTORTION_K2, - "FOCAL_LENGTH_PRINCIPAL_POINT_RADIAL_K1_K2", - 0, - "Focal Length, Optical Center, K1, K2", - "Refine focal length, optical center and radial distortion K1 and K2"}, - {REFINE_FOCAL_LENGTH | REFINE_PRINCIPAL_POINT, - "FOCAL_LENGTH_PRINCIPAL_POINT", - 0, - "Focal Length, Optical Center", - "Refine focal length and optical center"}, - {REFINE_RADIAL_DISTORTION_K1 | REFINE_RADIAL_DISTORTION_K2, - "RADIAL_K1_K2", - 0, - "K1, K2", - "Refine radial distortion K1 and K2"}, - {0, NULL, 0, NULL, NULL}, - }; - srna = RNA_def_struct(brna, "MovieTrackingSettings", NULL); RNA_def_struct_ui_text(srna, "Movie tracking settings", "Match moving settings"); @@ -943,11 +911,35 @@ static void rna_def_trackingSettings(BlenderRNA *brna) "Automatically select keyframes when solving camera/object motion"); /* intrinsics refinement during bundle adjustment */ - prop = RNA_def_property(srna, "refine_intrinsics", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "refine_camera_intrinsics"); + + prop = RNA_def_property(srna, "refine_intrinsics_focal_length", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "refine_camera_intrinsics", REFINE_FOCAL_LENGTH); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, refine_items); - RNA_def_property_ui_text(prop, "Refine", "Refine intrinsics during camera solving"); + RNA_def_property_ui_text( + prop, "Refine Focal Length", "Refine focal length during camera solving"); + + prop = RNA_def_property(srna, "refine_intrinsics_principal_point", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "refine_camera_intrinsics", REFINE_PRINCIPAL_POINT); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text( + prop, "Refine Principal Point", "Refine principal point during camera solving"); + + prop = RNA_def_property(srna, "refine_intrinsics_radial_distortion", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "refine_camera_intrinsics", REFINE_RADIAL_DISTORTION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, + "Refine Radial", + "Refine radial coefficients of distortion model during camera solving"); + + prop = RNA_def_property( + srna, "refine_intrinsics_tangential_distortion", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna( + prop, NULL, "refine_camera_intrinsics", REFINE_TANGENTIAL_DISTORTION); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text( + prop, + "Refine Tangential", + "Refine tangential coefficients of distortion model during camera solving"); /* tool settings */ @@ -1194,7 +1186,7 @@ static void rna_def_trackingCamera(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "focal"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_range(prop, 0.0f, FLT_MAX); - RNA_def_property_ui_range(prop, 0.0f, 5000.f, 1, 2); + RNA_def_property_ui_range(prop, 0.0f, 5000.0f, 1, 2); RNA_def_property_ui_text(prop, "Focal Length", "Camera's focal length"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, NULL); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index c31766efe58..932aa260bd5 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -217,9 +217,10 @@ static void rna_userdef_version_get(PointerRNA *ptr, int *value) value[2] = userdef->subversionfile; } +/** Mark the preferences as being changed so they are saved on exit. */ # define USERDEF_TAG_DIRTY rna_userdef_is_dirty_update_impl() -/* Use single function so we can more easily breakpoint it. */ +/** Use single function so we can more easily break-point it. */ void rna_userdef_is_dirty_update_impl(void) { /* We can't use 'ptr->data' because this update function @@ -4222,7 +4223,7 @@ static void rna_def_userdef_solidlight(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - static float default_dir[3] = {0.f, 0.f, 1.f}; + static float default_dir[3] = {0.0f, 0.0f, 1.0f}; static float default_col[3] = {0.8f, 0.8f, 0.8f}; srna = RNA_def_struct(brna, "UserSolidLight", NULL); @@ -4283,26 +4284,26 @@ static void rna_def_userdef_walk_navigation(BlenderRNA *brna) "Speed factor for when looking around, high values mean faster mouse movement"); prop = RNA_def_property(srna, "walk_speed", PROP_FLOAT, PROP_VELOCITY); - RNA_def_property_range(prop, 0.01f, 100.f); + RNA_def_property_range(prop, 0.01f, 100.0f); RNA_def_property_ui_text(prop, "Walk Speed", "Base speed for walking and flying"); prop = RNA_def_property(srna, "walk_speed_factor", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01f, 10.f); + RNA_def_property_range(prop, 0.01f, 10.0f); RNA_def_property_ui_text( prop, "Speed Factor", "Multiplication factor when using the fast or slow modifiers"); prop = RNA_def_property(srna, "view_height", PROP_FLOAT, PROP_UNIT_LENGTH); - RNA_def_property_ui_range(prop, 0.1f, 10.f, 0.1, 2); - RNA_def_property_range(prop, 0.f, 1000.f); + RNA_def_property_ui_range(prop, 0.1f, 10.0f, 0.1, 2); + RNA_def_property_range(prop, 0.0f, 1000.0f); RNA_def_property_ui_text(prop, "View Height", "View distance from the floor when walking"); prop = RNA_def_property(srna, "jump_height", PROP_FLOAT, PROP_UNIT_LENGTH); - RNA_def_property_ui_range(prop, 0.1f, 10.f, 0.1, 2); - RNA_def_property_range(prop, 0.1f, 100.f); + RNA_def_property_ui_range(prop, 0.1f, 10.0f, 0.1, 2); + RNA_def_property_range(prop, 0.1f, 100.0f); RNA_def_property_ui_text(prop, "Jump Height", "Maximum height of a jump"); prop = RNA_def_property(srna, "teleport_time", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.f, 10.f); + RNA_def_property_range(prop, 0.0f, 10.0f); RNA_def_property_ui_text( prop, "Teleport Duration", "Interval of time warp when teleporting in navigation mode"); @@ -4389,7 +4390,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) static const EnumPropertyItem line_width[] = { {-1, "THIN", 0, "Thin", "Thinner lines than the default"}, - {0, "AUTO", 0, "Auto", "Automatic line width based on UI scale"}, + {0, "AUTO", 0, "Default", "Automatic line width based on UI scale"}, {1, "THICK", 0, "Thick", "Thicker lines than the default"}, {0, NULL, 0, NULL, NULL}, }; @@ -4403,7 +4404,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) {USER_RENDER_DISPLAY_SCREEN, "SCREEN", 0, - "Full Screen", + "Maximized Area", "Images are rendered in a maximized Image Editor"}, {USER_RENDER_DISPLAY_AREA, "AREA", @@ -4421,7 +4422,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) {USER_TEMP_SPACE_DISPLAY_FULLSCREEN, "SCREEN", /* Could be FULLSCREEN, but keeping it consistent with render_display_types */ 0, - "Full Screen", + "Maximized Area", "Open the temporary editor in a maximized screen"}, {USER_TEMP_SPACE_DISPLAY_WINDOW, "WINDOW", @@ -4453,8 +4454,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text( prop, "UI Line Width", - "Changes the thickness of widget outlines, lines and points in the interface, " - "for high DPI displays"); + "Changes the thickness of widget outlines, lines and dots in the interface"); RNA_def_property_update(prop, 0, "rna_userdef_dpi_update"); /* display */ @@ -4786,7 +4786,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) prop = RNA_def_property(srna, "font_path_ui_mono", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, NULL, "font_path_ui_mono"); - RNA_def_property_ui_text(prop, "Mono-space Font", "Path to interface mono-space Font"); + RNA_def_property_ui_text(prop, "Monospaced Font", "Path to interface monospaced Font"); RNA_def_property_update(prop, NC_WINDOW, "rna_userdef_font_update"); /* Language. */ @@ -5659,13 +5659,6 @@ static void rna_def_userdef_input(BlenderRNA *brna) "Auto Depth", "Use the depth under the mouse to improve view pan/rotate/zoom functionality"); - prop = RNA_def_property(srna, "use_camera_lock_parent", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "uiflag", USER_CAM_LOCK_NO_PARENT); - RNA_def_property_ui_text(prop, - "Camera Parent Lock", - "When the camera is locked to the view and in fly mode, " - "transform the parent rather than the camera"); - /* view zoom */ prop = RNA_def_property(srna, "use_zoom_to_mouse", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_ZOOM_TO_MOUSEPOS); @@ -5784,10 +5777,8 @@ static void rna_def_userdef_input(BlenderRNA *brna) prop = RNA_def_property(srna, "tablet_api", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, tablet_api); - RNA_def_property_ui_text(prop, - "Tablet API", - "Select the tablet API to use for pressure sensitivity (restart " - "Blender for changes to take effect)"); + RNA_def_property_ui_text( + prop, "Tablet API", "Select the tablet API to use for pressure sensitivity"); RNA_def_property_update(prop, 0, "rna_userdef_tablet_api_update"); # ifdef WITH_INPUT_NDOF diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c index 2cabc89feee..2c373eb8d46 100644 --- a/source/blender/makesrna/intern/rna_wm_api.c +++ b/source/blender/makesrna/intern/rna_wm_api.c @@ -1135,7 +1135,7 @@ void RNA_api_keymapitems(StructRNA *srna) RNA_def_boolean(func, "alt", 0, "Alt", ""); RNA_def_boolean(func, "oskey", 0, "OS Key", ""); RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", ""); - RNA_def_boolean(func, "repeat", true, "Repeat", "When set, accept key-repeat events"); + RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events"); RNA_def_boolean(func, "head", 0, @@ -1159,7 +1159,7 @@ void RNA_api_keymapitems(StructRNA *srna) RNA_def_boolean(func, "alt", 0, "Alt", ""); RNA_def_boolean(func, "oskey", 0, "OS Key", ""); RNA_def_enum(func, "key_modifier", rna_enum_event_type_items, 0, "Key Modifier", ""); - RNA_def_boolean(func, "repeat", true, "Repeat", "When set, accept key-repeat events"); + RNA_def_boolean(func, "repeat", false, "Repeat", "When set, accept key-repeat events"); parm = RNA_def_pointer(func, "item", "KeyMapItem", "Item", "Added key map item"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_wm_gizmo.c b/source/blender/makesrna/intern/rna_wm_gizmo.c index 27d46e4d25b..bb2f57dc723 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo.c @@ -558,6 +558,7 @@ static StructRNA *rna_Gizmo_refine(PointerRNA *mnp_ptr) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Gizmo Group API * \{ */ diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 324cac3df8b..38fb19e3233 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -258,7 +258,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "use_deform_preserve_volume", 0, NULL, ICON_NONE); uiItemR(col, ptr, "use_multi_modifier", 0, NULL, ICON_NONE); - col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind to")); + col = uiLayoutColumnWithHeading(layout, true, IFACE_("Bind To")); uiItemR(col, ptr, "use_vertex_groups", 0, IFACE_("Vertex Groups"), ICON_NONE); uiItemR(col, ptr, "use_bone_envelopes", 0, IFACE_("Bone Envelopes"), ICON_NONE); diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 7e21300f3c2..da1754b8ebd 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -69,7 +69,7 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(amd, DNA_struct_default_get(ArrayModifierData), modifier); /* Open the first subpanel by default, it corresspnds to Relative offset which is enabled too. */ - md->ui_expand_flag = (1 << 0) | (1 << 1); + md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1; } static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) @@ -481,7 +481,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* calculate the maximum number of copies which will fit within the * prescribed length */ - if (amd->fit_type == MOD_ARR_FITLENGTH || amd->fit_type == MOD_ARR_FITCURVE) { + if (ELEM(amd->fit_type, MOD_ARR_FITLENGTH, MOD_ARR_FITCURVE)) { const float float_epsilon = 1e-6f; bool offset_is_too_small = false; float dist = len_v3(offset[3]); @@ -508,6 +508,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (offset_is_too_small) { BKE_modifier_set_error( + ctx->object, &amd->modifier, "The offset is too small, we cannot generate the amount of geometry it would require"); } @@ -518,7 +519,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + (size_t)end_cap_nverts) > max_num_vertices) { count = 1; - BKE_modifier_set_error(&amd->modifier, + BKE_modifier_set_error(ctx->object, + &amd->modifier, "The amount of copies is too high, we cannot generate the amount of " "geometry it would require"); } diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index b84c8a186b5..04ddac338e5 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -208,7 +208,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * Object *ob = ctx->object; if (harden_normals && (ob->type == OB_MESH) && !(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) { - BKE_modifier_set_error(md, "Enable 'Auto Smooth' in Object Data Properties"); + BKE_modifier_set_error(ob, md, "Enable 'Auto Smooth' in Object Data Properties"); harden_normals = false; } diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c index ff06f09d9a6..1cf57669eb1 100644 --- a/source/blender/modifiers/intern/MOD_boolean.c +++ b/source/blender/modifiers/intern/MOD_boolean.c @@ -189,7 +189,7 @@ static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) return BM_elem_flag_test(f, BM_FACE_TAG) ? 1 : 0; } -static bool BMD_error_messages(ModifierData *md, Collection *col) +static bool BMD_error_messages(const Object *ob, ModifierData *md, Collection *col) { BooleanModifierData *bmd = (BooleanModifierData *)md; @@ -202,21 +202,21 @@ static bool BMD_error_messages(ModifierData *md, Collection *col) #ifndef WITH_GMP /* If compiled without GMP, return a error. */ if (use_exact) { - BKE_modifier_set_error(md, "Compiled without GMP, using fast solver"); + BKE_modifier_set_error(ob, md, "Compiled without GMP, using fast solver"); error_returns_result = false; } #endif /* If intersect is selected using fast solver, return a error. */ if (operand_collection && operation_intersect && !use_exact) { - BKE_modifier_set_error(md, "Cannot execute, intersect only available using exact solver"); + BKE_modifier_set_error(ob, md, "Cannot execute, intersect only available using exact solver"); error_returns_result = true; } /* If the selected collection is empty and using fast solver, return a error. */ if (operand_collection) { if (!use_exact && BKE_collection_is_empty(col)) { - BKE_modifier_set_error(md, "Cannot execute, fast solver and empty collection"); + BKE_modifier_set_error(ob, md, "Cannot execute, fast solver and empty collection"); error_returns_result = true; } @@ -225,7 +225,7 @@ static bool BMD_error_messages(ModifierData *md, Collection *col) FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (col, operand_ob) { if (operand_ob->type != OB_MESH) { BKE_modifier_set_error( - md, "Cannot execute, the selected collection contains non mesh objects"); + ob, md, "Cannot execute, the selected collection contains non mesh objects"); error_returns_result = true; } } @@ -587,7 +587,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return result; } - BMD_error_messages(md, NULL); + BMD_error_messages(ctx->object, md, NULL); Object *operand_ob = bmd->object; @@ -615,7 +615,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* if new mesh returned, return it; otherwise there was * an error, so delete the modifier object */ if (result == NULL) { - BKE_modifier_set_error(md, "Cannot execute boolean operation"); + BKE_modifier_set_error(object, md, "Cannot execute boolean operation"); } } } @@ -626,7 +626,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } /* Return result for certain errors. */ - if (BMD_error_messages(md, col) == confirm_return) { + if (BMD_error_messages(ctx->object, md, col) == confirm_return) { return result; } diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index eaf8c44a9be..5884ec0aa17 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -615,7 +615,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, csmd_orig->bind_coords_num = csmd->bind_coords_num; } else { - BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph"); } } @@ -625,7 +625,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, } if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) { - BKE_modifier_set_error(md, "Bind data required"); + BKE_modifier_set_error(ob, md, "Bind data required"); goto error; } @@ -633,14 +633,14 @@ static void correctivesmooth_modifier_do(ModifierData *md, if (csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { if (csmd->bind_coords_num != numVerts) { BKE_modifier_set_error( - md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts); + ob, md, "Bind vertex count mismatch: %u to %u", csmd->bind_coords_num, numVerts); goto error; } } else { /* MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO */ if (ob->type != OB_MESH) { - BKE_modifier_set_error(md, "Object is not a mesh"); + BKE_modifier_set_error(ob, md, "Object is not a mesh"); goto error; } else { @@ -648,7 +648,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, if (me_numVerts != numVerts) { BKE_modifier_set_error( - md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts); + ob, md, "Original vertex count mismatch: %u to %u", me_numVerts, numVerts); goto error; } } diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index d841ace2cce..d4c941d144d 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -232,16 +232,19 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (BKE_reports_contain(&reports, RPT_ERROR)) { const char *report_str = BKE_reports_string(&reports, RPT_ERROR); - BKE_modifier_set_error(md, "%s", report_str); + BKE_modifier_set_error(ctx->object, md, "%s", report_str); MEM_freeN((void *)report_str); } else if ((dtmd->data_types & DT_TYPE_LNOR) && !(me->flag & ME_AUTOSMOOTH)) { - BKE_modifier_set_error((ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties"); + BKE_modifier_set_error( + ctx->object, (ModifierData *)dtmd, "Enable 'Auto Smooth' in Object Data Properties"); } else if (result->totvert > HIGH_POLY_WARNING || ((Mesh *)(ob_source->data))->totvert > HIGH_POLY_WARNING) { BKE_modifier_set_error( - md, "Source or destination object has a high polygon count, computation might be slow"); + ctx->object, + md, + "Source or destination object has a high polygon count, computation might be slow"); } return result; diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 2532afc933e..10ed4f8d80b 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -140,7 +140,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (dmd->face_count <= 3) { - BKE_modifier_set_error(md, "Modifier requires more than 3 input faces"); + BKE_modifier_set_error(ctx->object, md, "Modifier requires more than 3 input faces"); return mesh; } diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 8eb9e97573d..a484b4d8147 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -666,8 +666,7 @@ static void LaplacianDeformModifier_do( sysdif = isSystemDifferent(lmd, ob, mesh, numVerts); sys = lmd->cache_system; if (sysdif) { - if (sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS || - sysdif == LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP) { + if (ELEM(sysdif, LAPDEFORM_SYSTEM_ONLY_CHANGE_ANCHORS, LAPDEFORM_SYSTEM_ONLY_CHANGE_GROUP)) { filevertexCos = MEM_malloc_arrayN(numVerts, sizeof(float[3]), "TempModDeformCoordinates"); memcpy(filevertexCos, lmd->vertexco, sizeof(float[3]) * numVerts); MEM_SAFE_FREE(lmd->vertexco); @@ -684,14 +683,15 @@ static void LaplacianDeformModifier_do( else { if (sysdif == LAPDEFORM_SYSTEM_CHANGE_VERTEXES) { BKE_modifier_set_error( - &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts); + ob, &lmd->modifier, "Vertices changed from %d to %d", lmd->total_verts, numVerts); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_EDGES) { BKE_modifier_set_error( - &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge); + ob, &lmd->modifier, "Edges changed from %d to %d", sys->total_edges, mesh->totedge); } else if (sysdif == LAPDEFORM_SYSTEM_CHANGE_NOT_VALID_GROUP) { - BKE_modifier_set_error(&lmd->modifier, + BKE_modifier_set_error(ob, + &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", sys->anchor_grp_name); } @@ -704,8 +704,10 @@ static void LaplacianDeformModifier_do( } else { if (!isValidVertexGroup(lmd, ob, mesh)) { - BKE_modifier_set_error( - &lmd->modifier, "Vertex group '%s' is not valid, or maybe empty", lmd->anchor_grp_name); + BKE_modifier_set_error(ob, + &lmd->modifier, + "Vertex group '%s' is not valid, or maybe empty", + lmd->anchor_grp_name); lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; } else if (lmd->total_verts > 0 && lmd->total_verts == numVerts) { @@ -725,7 +727,7 @@ static void LaplacianDeformModifier_do( } } if (sys && sys->is_matrix_computed && !sys->has_solution) { - BKE_modifier_set_error(&lmd->modifier, "The system did not find a solution"); + BKE_modifier_set_error(ob, &lmd->modifier, "The system did not find a solution"); } } diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index f7a8faf7a1c..d51f95bd18d 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -82,7 +82,7 @@ struct BLaplacianSystem { typedef struct BLaplacianSystem LaplacianSystem; static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks); -static bool is_disabled(const struct Scene *UNUSED(scene), ModifierData *md, bool useRenderParams); +static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams); static float compute_volume(const float center[3], float (*vertexCos)[3], const MPoly *mpoly, diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc index cc16da0fa80..426bba05d76 100644 --- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc +++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc @@ -273,8 +273,8 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo return volume; #else - UNUSED_VARS(md, ctx); - BKE_modifier_set_error(md, "Compiled without OpenVDB"); + UNUSED_VARS(md); + BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB"); return input_volume; #endif } diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 5d5b8b847d5..b808d738fe8 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -171,13 +171,13 @@ static void meshcache_do(MeshCacheModifierData *mcmd, /* we could support any object type */ if (UNLIKELY(ob->type != OB_MESH)) { - BKE_modifier_set_error(&mcmd->modifier, "'Integrate' only valid for Mesh objects"); + BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' only valid for Mesh objects"); } else if (UNLIKELY(me->totvert != numVerts)) { - BKE_modifier_set_error(&mcmd->modifier, "'Integrate' original mesh vertex mismatch"); + BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' original mesh vertex mismatch"); } else if (UNLIKELY(me->totpoly == 0)) { - BKE_modifier_set_error(&mcmd->modifier, "'Integrate' requires faces"); + BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' requires faces"); } else { /* the moons align! */ @@ -216,7 +216,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd, /* -------------------------------------------------------------------- */ /* Apply the transformation matrix (if needed) */ if (UNLIKELY(err_str)) { - BKE_modifier_set_error(&mcmd->modifier, "%s", err_str); + BKE_modifier_set_error(ob, &mcmd->modifier, "%s", err_str); } else if (ok) { bool use_matrix = false; diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index e2c8db07623..0e530312238 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -373,7 +373,7 @@ static void meshdeformModifier_do(ModifierData *md, Object *ob_target = mmd->object; cagemesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false); if (cagemesh == NULL) { - BKE_modifier_set_error(md, "Cannot get mesh from cage object"); + BKE_modifier_set_error(ctx->object, md, "Cannot get mesh from cage object"); return; } @@ -388,7 +388,7 @@ static void meshdeformModifier_do(ModifierData *md, if (!mmd->bindcagecos) { /* progress bar redraw can make this recursive .. */ if (!DEG_is_active(ctx->depsgraph)) { - BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph"); goto finally; } if (!recursive_bind_sentinel) { @@ -405,16 +405,16 @@ static void meshdeformModifier_do(ModifierData *md, totcagevert = BKE_mesh_wrapper_vert_len(cagemesh); if (mmd->totvert != totvert) { - BKE_modifier_set_error(md, "Vertices changed from %d to %d", mmd->totvert, totvert); + BKE_modifier_set_error(ob, md, "Vertices changed from %d to %d", mmd->totvert, totvert); goto finally; } else if (mmd->totcagevert != totcagevert) { BKE_modifier_set_error( - md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert); + ob, md, "Cage vertices changed from %d to %d", mmd->totcagevert, totcagevert); goto finally; } else if (mmd->bindcagecos == NULL) { - BKE_modifier_set_error(md, "Bind data missing"); + BKE_modifier_set_error(ob, md, "Bind data missing"); goto finally; } diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index 70732636d02..73106b2e816 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -127,7 +127,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BKE_cachefile_reader_open(cache_file, &mcmd->reader, ctx->object, mcmd->object_path); if (!mcmd->reader) { BKE_modifier_set_error( - md, "Could not create Alembic reader for file %s", cache_file->filepath); + ctx->object, md, "Could not create Alembic reader for file %s", cache_file->filepath); return mesh; } } @@ -170,7 +170,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (err_str) { - BKE_modifier_set_error(md, "%s", err_str); + BKE_modifier_set_error(ctx->object, md, "%s", err_str); } if (!ELEM(result, NULL, mesh) && (mesh != org_mesh)) { diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index e3a8d651183..9f99e036601 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -74,7 +74,7 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(mmd, DNA_struct_default_get(MultiresModifierData), modifier); /* Open subdivision panels by default. */ - md->ui_expand_flag = (1 << 0) | (1 << 1); + md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1; } static void requiredDataMask(Object *UNUSED(ob), @@ -216,7 +216,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * { Mesh *result = mesh; #if !defined(WITH_OPENSUBDIV) - BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); return result; #endif MultiresModifierData *mmd = (MultiresModifierData *)md; @@ -300,7 +300,7 @@ static void deformMatrices(ModifierData *md, { #if !defined(WITH_OPENSUBDIV) - BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); return; #endif @@ -478,7 +478,6 @@ static void advanced_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetActive(layout, !has_displacement); - uiItemR(layout, ptr, "subdivision_type", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "quality", 0, NULL, ICON_NONE); col = uiLayoutColumn(layout, false); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 1be74a8fed2..0ec564d2e2d 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -476,7 +476,15 @@ static bool is_valid_target(NormalEditModifierData *enmd) if ((enmd->mode == MOD_NORMALEDIT_MODE_DIRECTIONAL) && enmd->target) { return true; } - BKE_modifier_set_error((ModifierData *)enmd, "Invalid target settings"); + return false; +} + +static bool is_valid_target_with_error(const Object *ob, NormalEditModifierData *enmd) +{ + if (is_valid_target(enmd)) { + return true; + } + BKE_modifier_set_error(ob, (ModifierData *)enmd, "Invalid target settings"); return false; } @@ -491,7 +499,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, (enmd->mix_limit == (float)M_PI)); /* Do not run that modifier at all if autosmooth is disabled! */ - if (!is_valid_target(enmd) || mesh->totloop == 0) { + if (!is_valid_target_with_error(ctx->object, enmd) || mesh->totloop == 0) { return mesh; } @@ -506,7 +514,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) #endif { - BKE_modifier_set_error((ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties"); + BKE_modifier_set_error( + ob, (ModifierData *)enmd, "Enable 'Auto Smooth' in Object Data Properties"); return mesh; } diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 20445a7006a..6936f5a53f8 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -998,8 +998,8 @@ static void add_poly(SkinOutput *so, BMVert *v1, BMVert *v2, BMVert *v3, BMVert BMVert *verts[4] = {v1, v2, v3, v4}; BMFace *f; - BLI_assert(v1 != v2 && v1 != v3 && v1 != v4); - BLI_assert(v2 != v3 && v2 != v4); + BLI_assert(!ELEM(v1, v2, v3, v4)); + BLI_assert(!ELEM(v2, v3, v4)); BLI_assert(v3 != v4); BLI_assert(v1 && v2 && v3); @@ -1414,7 +1414,7 @@ static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4]) /* Find what the second tri has that the first doesn't */ for (i = 0; i < 3; i++) { - if (tri[1][i] != tri[0][0] && tri[1][i] != tri[0][1] && tri[1][i] != tri[0][2]) { + if (!ELEM(tri[1][i], tri[0][0], tri[0][1], tri[0][2])) { opp = tri[1][i]; break; } @@ -1760,13 +1760,19 @@ static bool skin_output_branch_hulls( return result; } +typedef enum eSkinErrorFlag { + SKIN_ERROR_NO_VALID_ROOT = (1 << 0), + SKIN_ERROR_HULL = (1 << 1), +} eSkinErrorFlag; + static BMesh *build_skin(SkinNode *skin_nodes, int totvert, const MeshElemMap *emap, const MEdge *medge, int totedge, const MDeformVert *input_dvert, - SkinModifierData *smd) + SkinModifierData *smd, + eSkinErrorFlag *r_error) { SkinOutput so; int v; @@ -1802,7 +1808,7 @@ static BMesh *build_skin(SkinNode *skin_nodes, skin_update_merged_vertices(skin_nodes, totvert); if (!skin_output_branch_hulls(&so, skin_nodes, totvert, emap, medge)) { - BKE_modifier_set_error(&smd->modifier, "Hull error"); + *r_error |= SKIN_ERROR_HULL; } /* Merge triangles here in the hope of providing better target @@ -1848,7 +1854,7 @@ static void skin_set_orig_indices(Mesh *mesh) * 2) Generate node frames * 3) Output vertices and polygons from frames, connections, and hulls */ -static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd) +static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_error) { Mesh *result; MVertSkin *nodes; @@ -1878,16 +1884,14 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd) MEM_freeN(emat); emat = NULL; - bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd); + bm = build_skin(skin_nodes, totvert, emap, medge, totedge, dvert, smd, r_error); MEM_freeN(skin_nodes); MEM_freeN(emap); MEM_freeN(emapmem); if (!has_valid_root) { - BKE_modifier_set_error( - &smd->modifier, - "No valid root vertex found (you need one per mesh island you want to skin)"); + *r_error |= SKIN_ERROR_NO_VALID_ROOT; } if (!bm) { @@ -1904,7 +1908,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd) return result; } -static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh) +static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh, eSkinErrorFlag *r_error) { Mesh *result; @@ -1914,7 +1918,7 @@ static Mesh *final_skin(SkinModifierData *smd, Mesh *mesh) } mesh = subdivide_base(mesh); - result = base_skin(mesh, smd); + result = base_skin(mesh, smd, r_error); BKE_id_free(NULL, mesh); return result; @@ -1934,11 +1938,25 @@ static void initData(ModifierData *md) md->mode |= eModifierMode_Editmode; } -static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { - Mesh *result; + eSkinErrorFlag error = 0; + Mesh *result = final_skin((SkinModifierData *)md, mesh, &error); + + if (error & SKIN_ERROR_NO_VALID_ROOT) { + error &= ~SKIN_ERROR_NO_VALID_ROOT; + BKE_modifier_set_error( + ctx->object, + md, + "No valid root vertex found (you need one per mesh island you want to skin)"); + } + if (error & SKIN_ERROR_HULL) { + error &= ~SKIN_ERROR_HULL; + BKE_modifier_set_error(ctx->object, md, "Hull error"); + } + BLI_assert(error == 0); - if (!(result = final_skin((SkinModifierData *)md, mesh))) { + if (result == NULL) { return mesh; } return result; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 47adb7ba0bd..8acf07f9181 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -2501,16 +2501,25 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(face_edges); } if (edge_index != numNewEdges) { - BKE_modifier_set_error( - md, "Internal Error: edges array wrong size: %u instead of %u", numNewEdges, edge_index); + BKE_modifier_set_error(ctx->object, + md, + "Internal Error: edges array wrong size: %u instead of %u", + numNewEdges, + edge_index); } if (poly_index != numNewPolys) { - BKE_modifier_set_error( - md, "Internal Error: polys array wrong size: %u instead of %u", numNewPolys, poly_index); + BKE_modifier_set_error(ctx->object, + md, + "Internal Error: polys array wrong size: %u instead of %u", + numNewPolys, + poly_index); } if (loop_index != numNewLoops) { - BKE_modifier_set_error( - md, "Internal Error: loops array wrong size: %u instead of %u", numNewLoops, loop_index); + BKE_modifier_set_error(ctx->object, + md, + "Internal Error: loops array wrong size: %u instead of %u", + numNewLoops, + loop_index); } BLI_assert(edge_index == numNewEdges); BLI_assert(poly_index == numNewPolys); diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index c30dd9f8765..1aa015682dd 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -254,7 +254,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * { Mesh *result = mesh; #if !defined(WITH_OPENSUBDIV) - BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); return result; #endif SubsurfModifierData *smd = (SubsurfModifierData *)md; @@ -309,7 +309,7 @@ static void deformMatrices(ModifierData *md, int num_verts) { #if !defined(WITH_OPENSUBDIV) - BKE_modifier_set_error(md, "Disabled, built without OpenSubdiv"); + BKE_modifier_set_error(ctx->object, md, "Disabled, built without OpenSubdiv"); return; #endif diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index aa48eaa6a32..5407397e3bf 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -70,6 +70,9 @@ typedef struct SDefAdjacencyArray { uint num; /* Careful, this is twice the number of polygons (avoids an extra loop) */ } SDefAdjacencyArray; +/** + * Polygons per edge (only 2, any more will exit calculation). + */ typedef struct SDefEdgePolys { uint polys[2], num; } SDefEdgePolys; @@ -83,37 +86,67 @@ typedef struct SDefBindCalcData { const MPoly *const mpoly; const MEdge *const medge; const MLoop *const mloop; + /** Coordinates to bind to, transformed into local space (compatible with `vertexCos`). */ float (*const targetCos)[3]; + /** Coordinates to bind (reference to the modifiers input argument). */ float (*const vertexCos)[3]; float imat[4][4]; const float falloff; int success; } SDefBindCalcData; +/** + * This represents the relationship between a point (a source coordinate) + * and the face-corner it's being bound to (from the target mesh). + * + * \note Some of these values could be de-duplicated however these are only + * needed once when running bind, so optimizing this structure isn't a priority. + */ typedef struct SDefBindPoly { + /** Coordinates copied directly from the modifiers inptut. */ float (*coords)[3]; + /** Coordinates projected into 2D space using `normal`. */ float (*coords_v2)[2]; + /** The point being queried projected into 2D space using `normal`. */ float point_v2[2]; float weight_angular; float weight_dist_proj; float weight_dist; float weight; float scales[2]; + /** Center of `coords` */ float centroid[3]; + /** Center of `coords_v2` */ float centroid_v2[2]; + /** + * The calculated normal of coords (could be shared between faces). + */ float normal[3]; float cent_edgemid_vecs_v2[2][2]; + /** + * The unsigned angle of this face-corner in `[0.0 .. PI]` range, + * where a small value is a thin corner. PI is is a straight line. + * Take care dividing by this value as it can approach zero. + */ float edgemid_angle; float point_edgemid_angles[2]; float corner_edgemid_angles[2]; float dominant_angle_weight; + /** Index of the input polygon. */ uint index; + /** Number of vertices in this face. */ uint numverts; + /** + * This polygons loop-start. + * \note that we could look this up from the polygon. + */ uint loopstart; uint edge_inds[2]; uint edge_vert_inds[2]; + /** The index of this corner in the face (starting at zero). */ uint corner_ind; uint dominant_edge; + /** When true `point_v2` is inside `coords_v2`. */ bool inside; } SDefBindPoly; @@ -256,7 +289,7 @@ static int buildAdjacencyMap(const MPoly *poly, { const MLoop *loop; - /* Fing polygons adjacent to edges */ + /* Find polygons adjacent to edges. */ for (int i = 0; i < numpoly; i++, poly++) { loop = &mloop[poly->loopstart]; @@ -466,7 +499,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bwdata->bind_polys = bpoly; /* Loop over all adjacent edges, - * and build the SDefBindPoly data for each poly adjacent to those. */ + * and build the #SDefBindPoly data for each poly adjacent to those. */ for (vedge = vert_edges; vedge; vedge = vedge->next) { uint edge_ind = vedge->index; @@ -475,7 +508,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly = bwdata->bind_polys; for (int j = 0; j < bwdata->numpoly; bpoly++, j++) { - /* If coords isn't allocated, we have reached the first uninitialized bpoly */ + /* If coords isn't allocated, we have reached the first uninitialized `bpoly`. */ if ((bpoly->index == edge_polys[edge_ind].polys[i]) || (!bpoly->coords)) { break; } @@ -530,7 +563,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, } } - /* Compute poly's parametric data */ + /* Compute polygons parametric data. */ mid_v3_v3_array(bpoly->centroid, bpoly->coords, poly->totloop); normal_poly_v3(bpoly->normal, bpoly->coords, poly->totloop); @@ -540,7 +573,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, cross_v3_v3v3(axis, bpoly->normal, world); normalize_v3(axis); - /* Map coords onto 2d normal plane */ + /* Map coords onto 2d normal plane. */ map_to_plane_axis_angle_v2_v3v3fl(bpoly->point_v2, point_co, axis, angle); zero_v2(bpoly->centroid_v2); @@ -595,7 +628,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly->corner_edgemid_angles[1] = angle_normalized_v2v2(tmp_vec_v2, bpoly->cent_edgemid_vecs_v2[1]); - /* Check for inifnite weights, and compute angular data otherwise */ + /* Check for infinite weights, and compute angular data otherwise. */ if (bpoly->weight_dist < FLT_EPSILON) { inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST_PROJ; inf_weight_flags |= MOD_SDEF_INFINITE_WEIGHT_DIST; @@ -665,10 +698,10 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, } } - /* Compute scalings and falloff. - * Scale all weights if no infinite weight is found, - * scale only unprojected weight if projected weight is infinite, - * scale none if both are infinite. */ + /* Compute scaling and falloff: + * - Scale all weights if no infinite weight is found. + * - Scale only un-projected weight if projected weight is infinite. + * - Scale none if both are infinite. */ if (!inf_weight_flags) { bpoly = bwdata->bind_polys; @@ -892,7 +925,7 @@ static void bindVert(void *__restrict userdata, interp_weights_poly_v2( sdbind->vert_weights, bpoly->coords_v2, bpoly->numverts, bpoly->point_v2); - /* Reproject vert based on weights and original poly verts, + /* Re-project vert based on weights and original poly verts, * to reintroduce poly non-planarity */ zero_v3(point_co_proj); for (int j = 0; j < bpoly->numverts; j++, loop++) { @@ -1010,7 +1043,8 @@ static void bindVert(void *__restrict userdata, freeBindData(bwdata); } -static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, +static bool surfacedeformBind(Object *ob, + SurfaceDeformModifierData *smd_orig, SurfaceDeformModifierData *smd_eval, float (*vertexCos)[3], uint numverts, @@ -1031,20 +1065,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, vert_edges = MEM_calloc_arrayN(tnumverts, sizeof(*vert_edges), "SDefVertEdgeMap"); if (vert_edges == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); return false; } adj_array = MEM_malloc_arrayN(tnumedges, 2 * sizeof(*adj_array), "SDefVertEdge"); if (adj_array == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); return false; } edge_polys = MEM_calloc_arrayN(tnumedges, sizeof(*edge_polys), "SDefEdgeFaceMap"); if (edge_polys == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); MEM_freeN(adj_array); return false; @@ -1052,14 +1086,14 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, smd_orig->verts = MEM_malloc_arrayN(numverts, sizeof(*smd_orig->verts), "SDefBindVerts"); if (smd_orig->verts == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); return false; } BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2); if (treeData.tree == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); MEM_freeN(smd_orig->verts); smd_orig->verts = NULL; @@ -1070,8 +1104,8 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, mpoly, medge, mloop, tnumpoly, tnumedges, vert_edges, adj_array, edge_polys); if (adj_result == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { - BKE_modifier_set_error((ModifierData *)smd_eval, - "Target has edges with more than two polygons"); + BKE_modifier_set_error( + ob, (ModifierData *)smd_eval, "Target has edges with more than two polygons"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); free_bvhtree_from_mesh(&treeData); MEM_freeN(smd_orig->verts); @@ -1098,7 +1132,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, }; if (data.targetCos == NULL) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeData((ModifierData *)smd_orig); return false; } @@ -1117,20 +1151,20 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, MEM_freeN(data.targetCos); if (data.success == MOD_SDEF_BIND_RESULT_MEM_ERR) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Out of memory"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_NONMANY_ERR) { - BKE_modifier_set_error((ModifierData *)smd_eval, - "Target has edges with more than two polygons"); + BKE_modifier_set_error( + ob, (ModifierData *)smd_eval, "Target has edges with more than two polygons"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_CONCAVE_ERR) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains concave polygons"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains concave polygons"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_OVERLAP_ERR) { - BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains overlapping vertices"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains overlapping vertices"); freeData((ModifierData *)smd_orig); } else if (data.success == MOD_SDEF_BIND_RESULT_GENERIC_ERR) { @@ -1138,7 +1172,7 @@ static bool surfacedeformBind(SurfaceDeformModifierData *smd_orig, * to explain this with a reasonably sized message. * Though it shouldn't really matter all that much, * because this is very unlikely to occur */ - BKE_modifier_set_error((ModifierData *)smd_eval, "Target contains invalid polygons"); + BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Target contains invalid polygons"); freeData((ModifierData *)smd_orig); } @@ -1235,7 +1269,7 @@ static void surfacedeformModifier_do(ModifierData *md, if (!(smd->flags & MOD_SDEF_BIND)) { if (smd->verts != NULL) { if (!DEG_is_active(ctx->depsgraph)) { - BKE_modifier_set_error(md, "Attempt to bind from inactive dependency graph"); + BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph"); return; } ModifierData *md_orig = BKE_modifier_get_original(md); @@ -1247,7 +1281,7 @@ static void surfacedeformModifier_do(ModifierData *md, Object *ob_target = smd->target; target = BKE_modifier_get_evaluated_mesh_from_evaluated_object(ob_target, false); if (!target) { - BKE_modifier_set_error(md, "No valid target mesh"); + BKE_modifier_set_error(ob, md, "No valid target mesh"); return; } @@ -1257,7 +1291,7 @@ static void surfacedeformModifier_do(ModifierData *md, /* If not bound, execute bind. */ if (smd->verts == NULL) { if (!DEG_is_active(ctx->depsgraph)) { - BKE_modifier_set_error(md, "Attempt to unbind from inactive dependency graph"); + BKE_modifier_set_error(ob, md, "Attempt to unbind from inactive dependency graph"); return; } @@ -1271,7 +1305,7 @@ static void surfacedeformModifier_do(ModifierData *md, /* Avoid converting edit-mesh data, binding is an exception. */ BKE_mesh_wrapper_ensure_mdata(target); - if (!surfacedeformBind(smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) { + if (!surfacedeformBind(ob, smd_orig, smd, vertexCos, numverts, tnumpoly, tnumverts, target)) { smd->flags &= ~MOD_SDEF_BIND; } /* Early abort, this is binding 'call', no need to perform whole evaluation. */ @@ -1280,17 +1314,17 @@ static void surfacedeformModifier_do(ModifierData *md, /* Poly count checks */ if (smd->numverts != numverts) { - BKE_modifier_set_error(md, "Vertices changed from %u to %u", smd->numverts, numverts); + BKE_modifier_set_error(ob, md, "Vertices changed from %u to %u", smd->numverts, numverts); return; } if (smd->numpoly != tnumpoly) { - BKE_modifier_set_error(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); + BKE_modifier_set_error( + ob, md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly); return; } - /* Early out if modifier would not affect input at all - still *after* the sanity checks (and - * potential binding) above. - */ + /* Early out if modifier would not affect input at all - still *after* the sanity checks + * (and potential binding) above. */ if (smd->strength == 0.0f) { return; } @@ -1454,8 +1488,7 @@ static void blendWrite(BlendWriter *writer, const ModifierData *md) BLO_write_uint32_array( writer, smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds); - if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID || - smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) { + if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { BLO_write_float3_array(writer, 1, smd->verts[i].binds[j].vert_weights); } else { @@ -1483,8 +1516,7 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) BLO_read_uint32_array( reader, smd->verts[i].binds[j].numverts, &smd->verts[i].binds[j].vert_inds); - if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID || - smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI) { + if (ELEM(smd->verts[i].binds[j].mode, MOD_SDEF_MODE_CENTROID, MOD_SDEF_MODE_LOOPTRI)) { BLO_read_float3_array(reader, 1, &smd->verts[i].binds[j].vert_weights); } else { diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c index bad76a0b559..ba43434aeb3 100644 --- a/source/blender/modifiers/intern/MOD_ui_common.c +++ b/source/blender/modifiers/intern/MOD_ui_common.c @@ -229,14 +229,14 @@ static void modifier_ops_extra_draw(bContext *C, uiLayout *layout, void *md_v) /* Apply as shapekey. */ if (BKE_modifier_is_same_topology(md) && !BKE_modifier_is_non_geometrical(md)) { uiItemBooleanO(layout, - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply As Shapekey"), + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply as Shape Key"), ICON_SHAPEKEY_DATA, "OBJECT_OT_modifier_apply_as_shapekey", "keep_modifier", false); uiItemBooleanO(layout, - CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save As Shapekey"), + CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Save as Shape Key"), ICON_SHAPEKEY_DATA, "OBJECT_OT_modifier_apply_as_shapekey", "keep_modifier", diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc index 22bf5cd4893..7293945312a 100644 --- a/source/blender/modifiers/intern/MOD_volume_displace.cc +++ b/source/blender/modifiers/intern/MOD_volume_displace.cc @@ -307,7 +307,7 @@ static Volume *modifyVolume(ModifierData *md, const ModifierEvalContext *ctx, Vo return volume; #else UNUSED_VARS(md, ctx); - BKE_modifier_set_error(md, "Compiled without OpenVDB"); + BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB"); return volume; #endif } diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc index 913a457c38d..8556271bf87 100644 --- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc +++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc @@ -293,7 +293,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BKE_volume_load(volume, DEG_get_bmain(ctx->depsgraph)); VolumeGrid *volume_grid = BKE_volume_grid_find(volume, vmmd->grid_name); if (volume_grid == nullptr) { - BKE_modifier_set_error(md, "Cannot find '%s' grid", vmmd->grid_name); + BKE_modifier_set_error(ctx->object, md, "Cannot find '%s' grid", vmmd->grid_name); return create_empty_mesh(input_mesh); } @@ -302,7 +302,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const VolumeGridType grid_type = BKE_volume_grid_type(volume_grid); VolumeToMeshOp to_mesh_op{*grid, *vmmd, *ctx}; if (!BKE_volume_grid_type_operation(grid_type, to_mesh_op)) { - BKE_modifier_set_error(md, "Expected a scalar grid"); + BKE_modifier_set_error(ctx->object, md, "Expected a scalar grid"); return create_empty_mesh(input_mesh); } @@ -313,8 +313,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } return mesh; #else - UNUSED_VARS(md, ctx); - BKE_modifier_set_error(md, "Compiled without OpenVDB"); + UNUSED_VARS(md); + BKE_modifier_set_error(ctx->object, md, "Compiled without OpenVDB"); return create_empty_mesh(input_mesh); #endif } diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index 65bb009fc58..bd15d909834 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -574,7 +574,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (!(((Mesh *)ob->data)->flag & ME_AUTOSMOOTH)) #endif { - BKE_modifier_set_error((ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties"); + BKE_modifier_set_error( + ctx->object, (ModifierData *)wnmd, "Enable 'Auto Smooth' in Object Data Properties"); return mesh; } diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c index ce0c1a91072..c8d2d993e75 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.c @@ -65,7 +65,7 @@ static void cryptomatte_add(NodeCryptomatte *n, float f) /* Find the next separator. */ char *token_end = strchr(n->matte_id + start, ','); - if (token_end == NULL || token_end == n->matte_id + start) { + if (ELEM(token_end, NULL, n->matte_id + start)) { token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ @@ -144,7 +144,7 @@ static void cryptomatte_remove(NodeCryptomatte *n, float f) /* Find the next separator. */ char *token_end = strchr(n->matte_id + start + 1, ','); - if (token_end == NULL || token_end == n->matte_id + start) { + if (ELEM(token_end, NULL, n->matte_id + start)) { token_end = n->matte_id + end; } /* Be aware that token_len still contains any trailing white space. */ diff --git a/source/blender/nodes/composite/nodes/node_composite_defocus.c b/source/blender/nodes/composite/nodes/node_composite_defocus.c index bd8aca3d2fd..3803f450f49 100644 --- a/source/blender/nodes/composite/nodes/node_composite_defocus.c +++ b/source/blender/nodes/composite/nodes/node_composite_defocus.c @@ -45,10 +45,10 @@ static void node_composit_init_defocus(bNodeTree *UNUSED(ntree), bNode *node) nbd->preview = 1; nbd->gamco = 0; nbd->samples = 16; - nbd->fstop = 128.f; + nbd->fstop = 128.0f; nbd->maxblur = 16; - nbd->bthresh = 1.f; - nbd->scale = 1.f; + nbd->bthresh = 1.0f; + nbd->scale = 1.0f; nbd->no_zbuf = 1; node->storage = nbd; } diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c index 477bc43d084..6dd60526edf 100644 --- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c @@ -23,7 +23,7 @@ #include "node_composite_util.h" -static bNodeSocketTemplate cmp_node_dblur_in[] = {{SOCK_RGBA, N_("Image"), 1.0f, 1.0f, 1.0f, 1.f}, +static bNodeSocketTemplate cmp_node_dblur_in[] = {{SOCK_RGBA, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, {-1, ""}}; static bNodeSocketTemplate cmp_node_dblur_out[] = {{SOCK_RGBA, N_("Image")}, {-1, ""}}; diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.c b/source/blender/nodes/composite/nodes/node_composite_lensdist.c index 89f61b59171..ce8c8c00e24 100644 --- a/source/blender/nodes/composite/nodes/node_composite_lensdist.c +++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.c @@ -25,8 +25,8 @@ static bNodeSocketTemplate cmp_node_lensdist_in[] = { {SOCK_RGBA, N_("Image"), 1.0f, 1.0f, 1.0f, 1.0f}, - {SOCK_FLOAT, N_("Distort"), 0.f, 0.f, 0.f, 0.f, -0.999f, 1.f, PROP_NONE}, - {SOCK_FLOAT, N_("Dispersion"), 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, PROP_NONE}, + {SOCK_FLOAT, N_("Distort"), 0.0f, 0.0f, 0.0f, 0.0f, -0.999f, 1.0f, PROP_NONE}, + {SOCK_FLOAT, N_("Dispersion"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE}, {-1, ""}, }; static bNodeSocketTemplate cmp_node_lensdist_out[] = { diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index aa1f23163a0..36b9098d972 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -47,7 +47,9 @@ enum { REFINE_BACKWARD = 1 << 1, }; -/**** Group ****/ +/* -------------------------------------------------------------------- */ +/** \name Node Group + * \{ */ bNodeSocket *node_group_find_input_socket(bNode *groupnode, const char *identifier) { @@ -193,7 +195,11 @@ void node_group_update(struct bNodeTree *ntree, struct bNode *node) } } -/**** FRAME ****/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node Frame + * \{ */ static void node_frame_init(bNodeTree *UNUSED(ntree), bNode *node) { @@ -219,7 +225,11 @@ void register_node_type_frame(void) nodeRegisterType(ntype); } -/* **************** REROUTE ******************** */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node Re-Route + * \{ */ /* simple, only a single input and output here */ static void node_reroute_update_internal_links(bNodeTree *ntree, bNode *node) @@ -403,7 +413,11 @@ void BKE_node_tree_unlink_id(ID *id, struct bNodeTree *ntree) } } -/**** GROUP_INPUT / GROUP_OUTPUT ****/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node #GROUP_INPUT / #GROUP_OUTPUT + * \{ */ static void node_group_input_init(bNodeTree *ntree, bNode *node) { @@ -599,3 +613,5 @@ void register_node_type_group_output(void) nodeRegisterType(ntype); } + +/** \} */ diff --git a/source/blender/nodes/intern/node_util.c b/source/blender/nodes/intern/node_util.c index b2309abe32e..a5d61332a90 100644 --- a/source/blender/nodes/intern/node_util.c +++ b/source/blender/nodes/intern/node_util.c @@ -43,7 +43,9 @@ #include "node_util.h" -/**** Storage Data ****/ +/* -------------------------------------------------------------------- */ +/** \name Storage Data + * \{ */ void node_free_curves(bNode *node) { @@ -77,7 +79,11 @@ void *node_initexec_curves(bNodeExecContext *UNUSED(context), return NULL; /* unused return */ } -/**** Updates ****/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Updates + * \{ */ void node_sock_label(bNodeSocket *sock, const char *name) { @@ -173,7 +179,11 @@ void node_math_update(bNodeTree *UNUSED(ntree), bNode *node) } } -/**** Labels ****/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Labels + * \{ */ void node_blend_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen) { @@ -222,7 +232,11 @@ void node_filter_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int m BLI_strncpy(label, IFACE_(name), maxlen); } -/*** Link Insertion ***/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Link Insertion + * \{ */ /* test if two sockets are interchangeable */ static bool node_link_socket_match(bNodeSocket *a, bNodeSocket *b) @@ -321,12 +335,17 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) } } -/**** Internal Links (mute and disconnect) ****/ +/** \} */ -/* common datatype priorities, works for compositor, shader and texture nodes alike +/* -------------------------------------------------------------------- */ +/** \name Internal Links (mute and disconnect) + * \{ */ + +/** + * Common datatype priorities, works for compositor, shader and texture nodes alike * defines priority of datatype connection based on output type (to): - * < 0 : never connect these types - * >= 0 : priority of connection (higher values chosen first) + * `< 0`: never connect these types. + * `>= 0`: priority of connection (higher values chosen first). */ static int node_datatype_priority(eNodeSocketDatatype from, eNodeSocketDatatype to) { @@ -507,7 +526,11 @@ void node_update_internal_links_default(bNodeTree *ntree, bNode *node) } } -/**** Default value RNA access ****/ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Default value RNA access + * \{ */ float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock) { @@ -556,3 +579,5 @@ void node_socket_set_vector(bNodeTree *ntree, RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); RNA_float_set_array(&ptr, "default_value", value); } + +/** \} */ diff --git a/source/blender/nodes/shader/nodes/node_shader_attribute.c b/source/blender/nodes/shader/nodes/node_shader_attribute.c index 4fd0ce4f1ef..9b3122e38e0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_attribute.c +++ b/source/blender/nodes/shader/nodes/node_shader_attribute.c @@ -25,6 +25,7 @@ static bNodeSocketTemplate sh_node_attribute_out[] = { {SOCK_RGBA, N_("Color")}, {SOCK_VECTOR, N_("Vector"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, {SOCK_FLOAT, N_("Fac"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_FACTOR}, + {SOCK_FLOAT, N_("Alpha"), 0.0f, 0.0f, 0.0f, 0.0f, -FLT_MAX, FLT_MAX, PROP_FACTOR}, {-1, ""}, }; @@ -41,8 +42,9 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, GPUNodeStack *out) { NodeShaderAttribute *attr = node->storage; + bool is_varying = attr->type == SHD_ATTRIBUTE_GEOMETRY; - if (GPU_material_is_volume_shader(mat)) { + if (GPU_material_is_volume_shader(mat) && is_varying) { if (out[0].hasoutput) { out[0].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); } @@ -52,11 +54,23 @@ static int node_shader_gpu_attribute(GPUMaterial *mat, if (out[2].hasoutput) { out[2].link = GPU_volume_grid(mat, attr->name, GPU_VOLUME_DEFAULT_0); } + if (out[3].hasoutput) { + static const float default_alpha = 1.0f; + out[3].link = GPU_constant(&default_alpha); + } return 1; } - GPUNodeLink *cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name); + GPUNodeLink *cd_attr; + + if (is_varying) { + cd_attr = GPU_attribute(mat, CD_AUTO_FROM_NAME, attr->name); + } + else { + cd_attr = GPU_uniform_attribute(mat, attr->name, attr->type == SHD_ATTRIBUTE_INSTANCER); + } + GPU_stack_link(mat, node, "node_attribute", in, out, cd_attr); /* for each output. */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c index 2f42b6429c7..e29b2ee1c5c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_hair_principled.c @@ -34,7 +34,7 @@ static bNodeSocketTemplate sh_node_bsdf_hair_principled_in[] = { {SOCK_FLOAT, N_("IOR"), 1.55f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f}, {SOCK_FLOAT, N_("Offset"), - 2.0f * ((float)M_PI) / 180.f, + 2.0f * ((float)M_PI) / 180.0f, 0.0f, 0.0f, 0.0f, diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c index 7dd2ee9a4ac..493acb06963 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c @@ -82,7 +82,7 @@ static int gpu_shader_normal_map(GPUMaterial *mat, } const char *color_to_normal_fnc_name = "color_to_normal_new_shading"; - if (nm->space == SHD_SPACE_BLENDER_OBJECT || nm->space == SHD_SPACE_BLENDER_WORLD) { + if (ELEM(nm->space, SHD_SPACE_BLENDER_OBJECT, SHD_SPACE_BLENDER_WORLD)) { color_to_normal_fnc_name = "color_to_blender_normal_new_shading"; } diff --git a/source/blender/python/generic/blf_py_api.c b/source/blender/python/generic/blf_py_api.c index 836f4f1a12c..0ec66e22fa9 100644 --- a/source/blender/python/generic/blf_py_api.c +++ b/source/blender/python/generic/blf_py_api.c @@ -373,7 +373,7 @@ static PyObject *py_blf_shadow(PyObject *UNUSED(self), PyObject *args) return NULL; } - if (level != 0 && level != 3 && level != 5) { + if (!ELEM(level, 0, 3, 5)) { PyErr_SetString(PyExc_TypeError, "blf.shadow expected arg to be in (0, 3, 5)"); return NULL; } diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 6c02e293789..d944cb435d0 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -893,18 +893,6 @@ void PyC_MainModule_Restore(PyObject *main_mod) */ void PyC_SetHomePath(const char *py_path_bundle) { - if (py_path_bundle == NULL) { - /* Common enough to have bundled *nix python but complain on OSX/Win */ -# if defined(__APPLE__) || defined(_WIN32) - fprintf(stderr, - "Warning! bundled python not found and is expected on this platform. " - "(if you built with CMake: 'install' target may have not been built)\n"); -# endif - return; - } - /* set the environment path */ - printf("found bundled python: %s\n", py_path_bundle); - # ifdef __APPLE__ /* OSX allow file/directory names to contain : character (represented as / in the Finder) * but current Python lib (release 3.1.1) doesn't handle these correctly */ @@ -915,19 +903,14 @@ void PyC_SetHomePath(const char *py_path_bundle) } # endif - { - wchar_t py_path_bundle_wchar[1024]; - - /* Can't use this, on linux gives bug: T23018, - * TODO: try LANG="en_US.UTF-8" /usr/bin/blender, suggested 2008 */ - /* mbstowcs(py_path_bundle_wchar, py_path_bundle, FILE_MAXDIR); */ + /* Set the environment path. */ + wchar_t py_path_bundle_wchar[1024]; - BLI_strncpy_wchar_from_utf8( - py_path_bundle_wchar, py_path_bundle, ARRAY_SIZE(py_path_bundle_wchar)); + /* Can't use `mbstowcs` on linux gives bug: T23018. */ + BLI_strncpy_wchar_from_utf8( + py_path_bundle_wchar, py_path_bundle, ARRAY_SIZE(py_path_bundle_wchar)); - Py_SetPythonHome(py_path_bundle_wchar); - // printf("found python (wchar_t) '%ls'\n", py_path_bundle_wchar); - } + Py_SetPythonHome(py_path_bundle_wchar); } bool PyC_IsInterpreterActive(void) diff --git a/source/blender/python/intern/bpy.h b/source/blender/python/intern/bpy.h index e2fe84f71c7..25a047edfb5 100644 --- a/source/blender/python/intern/bpy.h +++ b/source/blender/python/intern/bpy.h @@ -35,6 +35,7 @@ void BPY_atexit_unregister(void); extern struct CLG_LogRef *BPY_LOG_CONTEXT; extern struct CLG_LogRef *BPY_LOG_RNA; +extern struct CLG_LogRef *BPY_LOG_INTERFACE; #ifdef __cplusplus } diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index 8354e220b09..02ab001dbf6 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -82,6 +82,7 @@ static PyTypeObject BlenderAppType; static PyStructSequence_Field app_info_fields[] = { {"version", "The Blender version as a tuple of 3 numbers. eg. (2, 83, 1)"}, + {"version_file", "The blend file version, compatible with ``bpy.data.version``"}, {"version_string", "The Blender version formatted as a string"}, {"version_cycle", "The release status of this build alpha/beta/rc/release"}, {"version_char", "Deprecated, always an empty string"}, @@ -151,6 +152,8 @@ static PyObject *make_app_info(void) SetObjItem( PyC_Tuple_Pack_I32(BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_VERSION_PATCH)); + SetObjItem(PyC_Tuple_Pack_I32( + BLENDER_FILE_VERSION / 100, BLENDER_FILE_VERSION % 100, BLENDER_FILE_SUBVERSION)); SetStrItem(BKE_blender_version_string()); SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE)); diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c index 476ddf2019a..30e0d94939d 100644 --- a/source/blender/python/intern/bpy_app_translations.c +++ b/source/blender/python/intern/bpy_app_translations.c @@ -420,9 +420,9 @@ static BLT_i18n_contexts_descriptor _contexts[] = BLT_I18NCONTEXTS_DESC; static PyStructSequence_Field app_translations_contexts_fields[ARRAY_SIZE(_contexts)] = {{NULL}}; static PyStructSequence_Desc app_translations_contexts_desc = { - "bpy.app.translations.contexts", /* name */ - "This named tuple contains all pre-defined translation contexts", /* doc */ - app_translations_contexts_fields, /* fields */ + "bpy.app.translations.contexts", /* name */ + "This named tuple contains all predefined translation contexts", /* doc */ + app_translations_contexts_fields, /* fields */ ARRAY_SIZE(app_translations_contexts_fields) - 1, }; @@ -464,7 +464,7 @@ static PyObject *app_translations_contexts_make(void) * \{ */ PyDoc_STRVAR(app_translations_contexts_doc, - "A named tuple containing all pre-defined translation contexts.\n" + "A named tuple containing all predefined translation contexts.\n" "\n" ".. warning::\n" " Never use a (new) context starting with \"" BLT_I18NCONTEXT_DEFAULT_BPYRNA diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index d72c2ccfcff..0b11ac639c7 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -80,6 +80,7 @@ /* Logging types to use anywhere in the Python modules. */ CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_CONTEXT, "bpy.context"); +CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_INTERFACE, "bpy.interface"); CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_RNA, "bpy.rna"); /* for internal use, when starting and ending python scripts */ @@ -304,7 +305,6 @@ void BPY_python_start(bContext *C, int argc, const char **argv) { #ifndef WITH_PYTHON_MODULE PyThreadState *py_tstate = NULL; - const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); /* Needed for Python's initialization for portable Python installations. * We could use #Py_SetPath, but this overrides Python's internal logic @@ -321,8 +321,21 @@ void BPY_python_start(bContext *C, int argc, const char **argv) /* must run before python initializes */ PyImport_ExtendInittab(bpy_internal_modules); - /* allow to use our own included python */ - PyC_SetHomePath(py_path_bundle); + /* Allow to use our own included Python. `py_path_bundle` may be NULL. */ + { + const char *py_path_bundle = BKE_appdir_folder_id(BLENDER_SYSTEM_PYTHON, NULL); + if (py_path_bundle != NULL) { + PyC_SetHomePath(py_path_bundle); + } + else { + /* Common enough to use the system Python on Linux/Unix, warn on other systems. */ +# if defined(__APPLE__) || defined(_WIN32) + fprintf(stderr, + "Bundled Python not found and is expected on this platform " + "(the 'install' target may have not been built)\n"); +# endif + } + } /* Without this the `sys.stdout` may be set to 'ascii' * (it is on my system at least), where printing unicode values will raise @@ -343,17 +356,16 @@ void BPY_python_start(bContext *C, int argc, const char **argv) /* Initialize Python (also acquires lock). */ Py_Initialize(); - // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ - /* sigh, why do python guys not have a (char **) version anymore? */ + /* We could convert to #wchar_t then pass to #PySys_SetArgv (or use #PyConfig in Python 3.8+). + * However this risks introducing subtle changes in encoding that are hard to track down. + * + * So rely on #PyC_UnicodeFromByte since it's a tried & true way of getting paths + * that include non `utf-8` compatible characters, see: T20021. */ { - int i; PyObject *py_argv = PyList_New(argc); - for (i = 0; i < argc; i++) { - /* should fix bug T20021 - utf path name problems, by replacing - * PyUnicode_FromString, with this one */ + for (int i = 0; i < argc; i++) { PyList_SET_ITEM(py_argv, i, PyC_UnicodeFromByte(argv[i])); } - PySys_SetObject("argv", py_argv); Py_DECREF(py_argv); } diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c index 0c8728f70fc..5ac76ab9ac1 100644 --- a/source/blender/python/intern/bpy_operator.c +++ b/source/blender/python/intern/bpy_operator.c @@ -118,7 +118,7 @@ static PyObject *pyop_poll(PyObject *UNUSED(self), PyObject *args) } } - if (context_dict == NULL || context_dict == Py_None) { + if (ELEM(context_dict, NULL, Py_None)) { context_dict = NULL; } else if (!PyDict_Check(context_dict)) { @@ -220,7 +220,7 @@ static PyObject *pyop_call(PyObject *UNUSED(self), PyObject *args) } } - if (context_dict == NULL || context_dict == Py_None) { + if (ELEM(context_dict, NULL, Py_None)) { context_dict = NULL; } else if (!PyDict_Check(context_dict)) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index cd0ec44e2ad..75bf639b890 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -5431,7 +5431,7 @@ static PyObject *pyprop_array_foreach_getset(BPy_PropertyArrayRNA *self, /* Get/set both take the same args currently. */ PyObject *seq; - if (prop_type != PROP_INT && prop_type != PROP_FLOAT) { + if (!ELEM(prop_type, PROP_INT, PROP_FLOAT)) { PyErr_Format(PyExc_TypeError, "foreach_get/set available only for int and float"); return NULL; } diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c index a58e2bcb975..b460ef5e0c0 100644 --- a/source/blender/python/intern/bpy_utils_units.c +++ b/source/blender/python/intern/bpy_utils_units.c @@ -73,15 +73,15 @@ static PyStructSequence_Field bpyunits_systems_fields[ARRAY_SIZE(bpyunits_usyste static PyStructSequence_Field bpyunits_categories_fields[ARRAY_SIZE(bpyunits_ucategorie_items)]; static PyStructSequence_Desc bpyunits_systems_desc = { - "bpy.utils.units.systems", /* name */ - "This named tuple contains all pre-defined unit systems", /* doc */ - bpyunits_systems_fields, /* fields */ + "bpy.utils.units.systems", /* name */ + "This named tuple contains all predefined unit systems", /* doc */ + bpyunits_systems_fields, /* fields */ ARRAY_SIZE(bpyunits_systems_fields) - 1, }; static PyStructSequence_Desc bpyunits_categories_desc = { - "bpy.utils.units.categories", /* name */ - "This named tuple contains all pre-defined unit names", /* doc */ - bpyunits_categories_fields, /* fields */ + "bpy.utils.units.categories", /* name */ + "This named tuple contains all predefined unit names", /* doc */ + bpyunits_categories_fields, /* fields */ ARRAY_SIZE(bpyunits_categories_fields) - 1, }; diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 0b9fa1841ec..87d16656d70 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -514,7 +514,7 @@ static PyObject *C_Matrix_Rotation(PyObject *cls, PyObject *args) angle = angle_wrap_rad(angle); - if (matSize != 2 && matSize != 3 && matSize != 4) { + if (!ELEM(matSize, 2, 3, 4)) { PyErr_SetString(PyExc_ValueError, "Matrix.Rotation(): " "can only return a 2x2 3x3 or 4x4 matrix"); @@ -653,7 +653,7 @@ static PyObject *C_Matrix_Scale(PyObject *cls, PyObject *args) if (!PyArg_ParseTuple(args, "fi|O:Matrix.Scale", &factor, &matSize, &vec)) { return NULL; } - if (matSize != 2 && matSize != 3 && matSize != 4) { + if (!ELEM(matSize, 2, 3, 4)) { PyErr_SetString(PyExc_ValueError, "Matrix.Scale(): " "can only return a 2x2 3x3 or 4x4 matrix"); @@ -759,7 +759,7 @@ static PyObject *C_Matrix_OrthoProjection(PyObject *cls, PyObject *args) if (!PyArg_ParseTuple(args, "Oi:Matrix.OrthoProjection", &axis, &matSize)) { return NULL; } - if (matSize != 2 && matSize != 3 && matSize != 4) { + if (!ELEM(matSize, 2, 3, 4)) { PyErr_SetString(PyExc_ValueError, "Matrix.OrthoProjection(): " "can only return a 2x2 3x3 or 4x4 matrix"); @@ -895,7 +895,7 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args) if (!PyArg_ParseTuple(args, "siO:Matrix.Shear", &plane, &matSize, &fac)) { return NULL; } - if (matSize != 2 && matSize != 3 && matSize != 4) { + if (!ELEM(matSize, 2, 3, 4)) { PyErr_SetString(PyExc_ValueError, "Matrix.Shear(): " "can only return a 2x2 3x3 or 4x4 matrix"); diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index 49a3f114ebb..c24960f2d04 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -179,7 +179,7 @@ static float frand(void) y ^= (y << 15) & 0xefc60000UL; y ^= (y >> 18); - return (float)y / 4294967296.f; + return (float)y / 4294967296.0f; } /*------------------------------------------------------------*/ @@ -246,7 +246,8 @@ static void noise_vector(float x, float y, float z, int nb, float v[3]) /* Simply evaluate noise at 3 different positions */ const float *ofs = state_offset_vector; for (int j = 0; j < 3; j++) { - v[j] = (2.0f * BLI_gNoise(1.0f, x + ofs[0], y + ofs[1], z + ofs[2], 0, nb) - 1.0f); + v[j] = (2.0f * BLI_noise_generic_noise(1.0f, x + ofs[0], y + ofs[1], z + ofs[2], false, nb) - + 1.0f); ofs += 3; } } @@ -257,8 +258,8 @@ static float turb( { float amp, out, t; int i; - amp = 1.f; - out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); + amp = 1.0f; + out = (float)(2.0f * BLI_noise_generic_noise(1.0f, x, y, z, false, nb) - 1.0f); if (hard) { out = fabsf(out); } @@ -267,7 +268,7 @@ static float turb( x *= freqscale; y *= freqscale; z *= freqscale; - t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f)); + t = (float)(amp * (2.0f * BLI_noise_generic_noise(1.0f, x, y, z, false, nb) - 1.0f)); if (hard) { t = fabsf(t); } @@ -290,7 +291,7 @@ static void vTurb(float x, { float amp, t[3]; int i; - amp = 1.f; + amp = 1.0f; noise_vector(x, y, z, nb, v); if (hard) { v[0] = fabsf(v[0]); @@ -450,7 +451,8 @@ static PyObject *M_Noise_noise(PyObject *UNUSED(self), PyObject *args, PyObject } return PyFloat_FromDouble( - (2.0f * BLI_gNoise(1.0f, vec[0], vec[1], vec[2], 0, noise_basis_enum) - 1.0f)); + (2.0f * BLI_noise_generic_noise(1.0f, vec[0], vec[1], vec[2], false, noise_basis_enum) - + 1.0f)); } PyDoc_STRVAR(M_Noise_noise_vector_doc, @@ -659,7 +661,8 @@ static PyObject *M_Noise_fractal(PyObject *UNUSED(self), PyObject *args, PyObjec return NULL; } - return PyFloat_FromDouble(mg_fBm(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum)); + return PyFloat_FromDouble( + BLI_noise_mg_fbm(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum)); } PyDoc_STRVAR( @@ -713,7 +716,7 @@ static PyObject *M_Noise_multi_fractal(PyObject *UNUSED(self), PyObject *args, P } return PyFloat_FromDouble( - mg_MultiFractal(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum)); + BLI_noise_mg_multi_fractal(vec[0], vec[1], vec[2], H, lac, oct, noise_basis_enum)); } PyDoc_STRVAR(M_Noise_variable_lacunarity_doc, @@ -780,8 +783,8 @@ static PyObject *M_Noise_variable_lacunarity(PyObject *UNUSED(self), PyObject *a return NULL; } - return PyFloat_FromDouble( - mg_VLNoise(vec[0], vec[1], vec[2], d, noise_type1_enum, noise_type2_enum)); + return PyFloat_FromDouble(BLI_noise_mg_variable_lacunarity( + vec[0], vec[1], vec[2], d, noise_type1_enum, noise_type2_enum)); } PyDoc_STRVAR( @@ -838,7 +841,7 @@ static PyObject *M_Noise_hetero_terrain(PyObject *UNUSED(self), PyObject *args, } return PyFloat_FromDouble( - mg_HeteroTerrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, noise_basis_enum)); + BLI_noise_mg_hetero_terrain(vec[0], vec[1], vec[2], H, lac, oct, ofs, noise_basis_enum)); } PyDoc_STRVAR( @@ -899,8 +902,8 @@ static PyObject *M_Noise_hybrid_multi_fractal(PyObject *UNUSED(self), PyObject * return NULL; } - return PyFloat_FromDouble( - mg_HybridMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum)); + return PyFloat_FromDouble(BLI_noise_mg_hybrid_multi_fractal( + vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum)); } PyDoc_STRVAR( @@ -961,8 +964,8 @@ static PyObject *M_Noise_ridged_multi_fractal(PyObject *UNUSED(self), PyObject * return NULL; } - return PyFloat_FromDouble( - mg_RidgedMultiFractal(vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum)); + return PyFloat_FromDouble(BLI_noise_mg_ridged_multi_fractal( + vec[0], vec[1], vec[2], H, lac, oct, ofs, gn, noise_basis_enum)); } PyDoc_STRVAR(M_Noise_voronoi_doc, @@ -1008,7 +1011,7 @@ static PyObject *M_Noise_voronoi(PyObject *UNUSED(self), PyObject *args, PyObjec list = PyList_New(4); - voronoi(vec[0], vec[1], vec[2], da, pa, me, metric_enum); + BLI_noise_voronoi(vec[0], vec[1], vec[2], da, pa, me, metric_enum); for (i = 0; i < 4; i++) { PyObject *v = Vector_CreatePyObject(pa + 3 * i, 3, NULL); @@ -1042,7 +1045,7 @@ static PyObject *M_Noise_cell(PyObject *UNUSED(self), PyObject *args) return NULL; } - return PyFloat_FromDouble(cellNoise(vec[0], vec[1], vec[2])); + return PyFloat_FromDouble(BLI_noise_cell(vec[0], vec[1], vec[2])); } PyDoc_STRVAR(M_Noise_cell_vector_doc, @@ -1067,7 +1070,7 @@ static PyObject *M_Noise_cell_vector(PyObject *UNUSED(self), PyObject *args) return NULL; } - cellNoiseV(vec[0], vec[1], vec[2], r_vec); + BLI_noise_cell_v3(vec[0], vec[1], vec[2], r_vec); return Vector_CreatePyObject(r_vec, 3, NULL); } diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 598e6e019d4..41caee1a39c 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -101,8 +101,8 @@ endif() if(APPLE) # SSE math is enabled by default on x86_64 if(CMAKE_OSX_ARCHITECTURES MATCHES "i386") - set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -mfpmath=sse") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mfpmath=sse") + string(APPEND CMAKE_C_FLAGS_RELEASE " -mfpmath=sse") + string(APPEND CMAKE_CXX_FLAGS_RELEASE " -mfpmath=sse") endif() endif() diff --git a/source/blender/render/extern/include/RE_multires_bake.h b/source/blender/render/extern/include/RE_multires_bake.h index c48ce7bfd6e..fd200e85719 100644 --- a/source/blender/render/extern/include/RE_multires_bake.h +++ b/source/blender/render/extern/include/RE_multires_bake.h @@ -33,7 +33,6 @@ extern "C" { typedef struct MultiresBakeRender { Scene *scene; DerivedMesh *lores_dm, *hires_dm; - bool simple; int bake_filter; /* Bake-filter, aka margin */ int lvl, tot_lvl; short mode; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 089c7eb044b..4dd2b300700 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -159,7 +159,6 @@ typedef struct RenderResult { typedef struct RenderStats { int cfra; - int totface, totvert, totlamp, totpart; bool localview; double starttime, lastframetime; const char *infostr, *statstr; diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index 440c54f5eeb..b2121816932 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -674,7 +674,6 @@ bool RE_bake_engine(Render *re, /* set render info */ re->i.cfra = re->scene->r.cfra; BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name) - 2); - re->i.totface = re->i.totvert = re->i.totlamp = 0; /* render */ engine = re->engine; @@ -812,7 +811,6 @@ int RE_engine_render(Render *re, int do_all) /* set render info */ re->i.cfra = re->scene->r.cfra; BLI_strncpy(re->i.scene_name, re->scene->id.name + 2, sizeof(re->i.scene_name)); - re->i.totface = re->i.totvert = re->i.totlamp = 0; /* render */ engine = re->engine; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index dd179f9461b..31c169f621b 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -200,7 +200,7 @@ int imagewrap(Tex *tex, return retval; } } - else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) { + else if (ELEM(tex->extend, TEX_CLIP, TEX_CHECKER)) { if (x < 0 || y < 0 || x >= ibuf->x || y >= ibuf->y) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); @@ -282,9 +282,9 @@ int imagewrap(Tex *tex, * the normal used in the renderer points inward. It is generated * this way in calc_vertexnormals(). Should this ever change * this negate must be removed. */ - texres->nor[0] = -2.f * (texres->tr - 0.5f); - texres->nor[1] = 2.f * (texres->tg - 0.5f); - texres->nor[2] = 2.f * (texres->tb - 0.5f); + texres->nor[0] = -2.0f * (texres->tr - 0.5f); + texres->nor[1] = 2.0f * (texres->tg - 0.5f); + texres->nor[2] = 2.0f * (texres->tb - 0.5f); } else { /* bump: take three samples */ @@ -798,7 +798,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf col[0] = fp[0]; col[1] = fp[1]; col[2] = fp[2]; - col[3] = clip ? 0.f : (ibuf->channels == 4 ? fp[3] : 1.f); + col[3] = clip ? 0.0f : (ibuf->channels == 4 ? fp[3] : 1.0f); } } else { @@ -807,7 +807,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf col[0] = rect[0] * inv_alpha_fac; col[1] = rect[1] * inv_alpha_fac; col[2] = rect[2] * inv_alpha_fac; - col[3] = clip ? 0.f : rect[3] * (1.f / 255.f); + col[3] = clip ? 0.0f : rect[3] * (1.0f / 255.0f); } return clip; } @@ -820,7 +820,7 @@ static int ibuf_get_color_clip_bilerp( float c00[4], c01[4], c10[4], c11[4]; const float ufl = floorf(u -= 0.5f), vfl = floorf(v -= 0.5f); const float uf = u - ufl, vf = v - vfl; - const float w00 = (1.f - uf) * (1.f - vf), w10 = uf * (1.f - vf), w01 = (1.f - uf) * vf, + const float w00 = (1.0f - uf) * (1.0f - vf), w10 = uf * (1.0f - vf), w01 = (1.0f - uf) * vf, w11 = uf * vf; const int x1 = (int)ufl, y1 = (int)vfl, x2 = x1 + 1, y2 = y1 + 1; int clip = ibuf_get_color_clip(c00, ibuf, x1, y1, extflag); @@ -830,7 +830,7 @@ static int ibuf_get_color_clip_bilerp( col[0] = w00 * c00[0] + w10 * c10[0] + w01 * c01[0] + w11 * c11[0]; col[1] = w00 * c00[1] + w10 * c10[1] + w01 * c01[1] + w11 * c11[1]; col[2] = w00 * c00[2] + w10 * c10[2] + w01 * c01[2] + w11 * c11[2]; - col[3] = clip ? 0.f : w00 * c00[3] + w10 * c10[3] + w01 * c01[3] + w11 * c11[3]; + col[3] = clip ? 0.0f : w00 * c00[3] + w10 * c10[3] + w01 * c01[3] + w11 * c11[3]; return clip; } return ibuf_get_color_clip(col, ibuf, (int)u, (int)v, extflag); @@ -839,7 +839,7 @@ static int ibuf_get_color_clip_bilerp( static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD) { int xs, ys, clip = 0; - float tc[4], xsd, ysd, cw = 0.f; + float tc[4], xsd, ysd, cw = 0.0f; const float ux = ibuf->x * AFD->dxt[0], uy = ibuf->y * AFD->dxt[1]; const float vx = ibuf->x * AFD->dyt[0], vy = ibuf->y * AFD->dyt[1]; int xsam = (int)(0.5f * sqrtf(ux * ux + uy * uy) + 0.5f); @@ -847,9 +847,9 @@ static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata const int minsam = AFD->intpol ? 2 : 4; xsam = CLAMPIS(xsam, minsam, ibuf->x * 2); ysam = CLAMPIS(ysam, minsam, ibuf->y * 2); - xsd = 1.f / xsam; - ysd = 1.f / ysam; - texr->tr = texr->tg = texr->tb = texr->ta = 0.f; + xsd = 1.0f / xsam; + ysd = 1.0f / ysam; + texr->tr = texr->tg = texr->tb = texr->ta = 0.0f; for (ys = 0; ys < ysam; ys++) { for (xs = 0; xs < xsam; xs++) { const float su = (xs + ((ys & 1) + 0.5f) * 0.5f) * xsd - 0.5f; @@ -859,11 +859,11 @@ static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata const int out = ibuf_get_color_clip_bilerp( tc, ibuf, pu * ibuf->x, pv * ibuf->y, AFD->intpol, AFD->extflag); clip |= out; - cw += out ? 0.f : 1.f; + cw += out ? 0.0f : 1.0f; texr->tr += tc[0]; texr->tg += tc[1]; texr->tb += tc[2]; - texr->ta += texr->talpha ? tc[3] : 0.f; + texr->ta += texr->talpha ? tc[3] : 0.0f; } } xsd *= ysd; @@ -871,7 +871,7 @@ static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata texr->tg *= xsd; texr->tb *= xsd; /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */ - texr->ta = texr->talpha ? texr->ta * xsd : (clip ? cw * xsd : 1.f); + texr->ta = texr->talpha ? texr->ta * xsd : (clip ? cw * xsd : 1.0f); } typedef struct ReadEWAData { @@ -906,19 +906,19 @@ static void ewa_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t static void feline_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD) { const int maxn = AFD->iProbes - 1; - const float ll = ((AFD->majrad == AFD->minrad) ? 2.f * AFD->majrad : - 2.f * (AFD->majrad - AFD->minrad)) / - (maxn ? (float)maxn : 1.f); - float du = maxn ? cosf(AFD->theta) * ll : 0.f; - float dv = maxn ? sinf(AFD->theta) * ll : 0.f; + const float ll = ((AFD->majrad == AFD->minrad) ? 2.0f * AFD->majrad : + 2.0f * (AFD->majrad - AFD->minrad)) / + (maxn ? (float)maxn : 1.0f); + float du = maxn ? cosf(AFD->theta) * ll : 0.0f; + float dv = maxn ? sinf(AFD->theta) * ll : 0.0f; /* const float D = -0.5f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad); */ const float D = (EWA_MAXIDX + 1) * 0.25f * (du * du + dv * dv) / (AFD->majrad * AFD->majrad); - float d; /* TXF alpha: cw = 0.f; */ + float d; /* TXF alpha: cw = 0.0f; */ int n; /* TXF alpha: clip = 0; */ /* have to use same scaling for du/dv here as for Ux/Vx/Uy/Vy (*after* D calc.) */ du *= AFD->dusc; dv *= AFD->dvsc; - d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f; + d = texr->tr = texr->tb = texr->tg = texr->ta = 0.0f; for (n = -maxn; n <= maxn; n += 2) { float tc[4]; const float hn = n * 0.5f; @@ -932,20 +932,20 @@ static void feline_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata /*const int out =*/ibuf_get_color_clip_bilerp( tc, ibuf, ibuf->x * u, ibuf->y * v, AFD->intpol, AFD->extflag); /* TXF alpha: clip |= out; - * TXF alpha: cw += out ? 0.f : wt; */ + * TXF alpha: cw += out ? 0.0f : wt; */ texr->tr += tc[0] * wt; texr->tg += tc[1] * wt; texr->tb += tc[2] * wt; - texr->ta += texr->talpha ? tc[3] * wt : 0.f; + texr->ta += texr->talpha ? tc[3] * wt : 0.0f; d += wt; } - d = 1.f / d; + d = 1.0f / d; texr->tr *= d; texr->tg *= d; texr->tb *= d; /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */ - texr->ta = texr->talpha ? texr->ta * d : 1.f; // TXF alpha: (clip ? cw*d : 1.f); + texr->ta = texr->talpha ? texr->ta * d : 1.0f; // TXF alpha: (clip ? cw*d : 1.0f); } #undef EWA_MAXIDX @@ -1032,7 +1032,7 @@ static int imagewraposa_aniso(Tex *tex, filterfunc = area_sample; } - texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.f; + texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.0f; /* we need to set retval OK, otherwise texture code generates normals itself... */ retval = texres->nor ? (TEX_RGB | TEX_NOR) : TEX_RGB; @@ -1102,7 +1102,7 @@ static int imagewraposa_aniso(Tex *tex, miny = addval; } } - else if (tex->filtersize != 1.f) { + else if (tex->filtersize != 1.0f) { minx *= tex->filtersize; miny *= tex->filtersize; dxt[0] *= tex->filtersize; @@ -1196,8 +1196,8 @@ static int imagewraposa_aniso(Tex *tex, } } /* scale around center, (0.5, 0.5) */ - if (tex->checkerdist < 1.f) { - const float omcd = 1.f / (1.f - tex->checkerdist); + if (tex->checkerdist < 1.0f) { + const float omcd = 1.0f / (1.0f - tex->checkerdist); fx = (fx - 0.5f) * omcd + 0.5f; fy = (fy - 0.5f) * omcd + 0.5f; minx *= omcd; @@ -1206,16 +1206,16 @@ static int imagewraposa_aniso(Tex *tex, } if (tex->extend == TEX_CLIPCUBE) { - if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || - texvec[2] < -1.f || texvec[2] > 1.f) { + if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f || + texvec[2] < -1.0f || texvec[2] > 1.0f) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); } return retval; } } - else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) { - if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) { + else if (ELEM(tex->extend, TEX_CLIP, TEX_CHECKER)) { + if ((fx + minx) < 0.0f || (fy + miny) < 0.0f || (fx - minx) > 1.0f || (fy - miny) > 1.0f) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); } @@ -1224,8 +1224,8 @@ static int imagewraposa_aniso(Tex *tex, } else { if (tex->extend == TEX_EXTEND) { - fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx); - fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy); + fx = (fx > 1.0f) ? 1.0f : ((fx < 0.0f) ? 0.0f : fx); + fy = (fy > 1.0f) ? 1.0f : ((fy < 0.0f) ? 0.0f : fy); } else { fx -= floorf(fx); @@ -1264,7 +1264,7 @@ static int imagewraposa_aniso(Tex *tex, const float ff = sqrtf(ibuf->x), q = ibuf->y / ff; const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q; const float A = Vx * Vx + Vy * Vy; - const float B = -2.f * (Ux * Vx + Uy * Vy); + const float B = -2.0f * (Ux * Vx + Uy * Vy); const float C = Ux * Ux + Uy * Uy; const float F = A * C - B * B * 0.25f; float a, b, th, ecc; @@ -1275,16 +1275,16 @@ static int imagewraposa_aniso(Tex *tex, b *= ff; a = max_ff(a, 1.0f); b = max_ff(b, 1.0f); - fProbes = 2.f * (a / b) - 1.f; + fProbes = 2.0f * (a / b) - 1.0f; AFD.iProbes = round_fl_to_int(fProbes); AFD.iProbes = MIN2(AFD.iProbes, tex->afmax); if (AFD.iProbes < fProbes) { - b = 2.f * a / (float)(AFD.iProbes + 1); + b = 2.0f * a / (float)(AFD.iProbes + 1); } AFD.majrad = a / ff; AFD.minrad = b / ff; AFD.theta = th; - AFD.dusc = 1.f / ff; + AFD.dusc = 1.0f / ff; AFD.dvsc = ff / (float)ibuf->y; } else { /* EWA & area */ @@ -1308,13 +1308,13 @@ static int imagewraposa_aniso(Tex *tex, } /* mipmap level */ - if (levf < 0.f) { /* original image only */ + if (levf < 0.0f) { /* original image only */ previbuf = curibuf = mipmaps[0]; - levf = 0.f; + levf = 0.0f; } else if (levf >= maxlev - 1) { previbuf = curibuf = mipmaps[maxlev - 1]; - levf = 0.f; + levf = 0.0f; if (tex->texfilter == TXF_FELINE) { AFD.iProbes = 1; } @@ -1377,7 +1377,7 @@ static int imagewraposa_aniso(Tex *tex, const float ff = sqrtf(ibuf->x), q = ibuf->y / ff; const float Ux = dxt[0] * ff, Vx = dxt[1] * q, Uy = dyt[0] * ff, Vy = dyt[1] * q; const float A = Vx * Vx + Vy * Vy; - const float B = -2.f * (Ux * Vx + Uy * Vy); + const float B = -2.0f * (Ux * Vx + Uy * Vy); const float C = Ux * Ux + Uy * Uy; const float F = A * C - B * B * 0.25f; float a, b, th, ecc, fProbes; @@ -1386,16 +1386,16 @@ static int imagewraposa_aniso(Tex *tex, b *= ff; a = max_ff(a, 1.0f); b = max_ff(b, 1.0f); - fProbes = 2.f * (a / b) - 1.f; + fProbes = 2.0f * (a / b) - 1.0f; /* no limit to number of Probes here */ AFD.iProbes = round_fl_to_int(fProbes); if (AFD.iProbes < fProbes) { - b = 2.f * a / (float)(AFD.iProbes + 1); + b = 2.0f * a / (float)(AFD.iProbes + 1); } AFD.majrad = a / ff; AFD.minrad = b / ff; AFD.theta = th; - AFD.dusc = 1.f / ff; + AFD.dusc = 1.0f / ff; AFD.dvsc = ff / (float)ibuf->y; } if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) { @@ -1425,7 +1425,7 @@ static int imagewraposa_aniso(Tex *tex, texres->tin = texres->ta; } if (tex->flag & TEX_NEGALPHA) { - texres->ta = 1.f - texres->ta; + texres->ta = 1.0f - texres->ta; } if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) { /* normal from color */ @@ -1435,9 +1435,9 @@ static int imagewraposa_aniso(Tex *tex, * the normal used in the renderer points inward. It is generated * this way in calc_vertexnormals(). Should this ever change * this negate must be removed. */ - texres->nor[0] = -2.f * (texres->tr - 0.5f); - texres->nor[1] = 2.f * (texres->tg - 0.5f); - texres->nor[2] = 2.f * (texres->tb - 0.5f); + texres->nor[0] = -2.0f * (texres->tr - 0.5f); + texres->nor[1] = 2.0f * (texres->tg - 0.5f); + texres->nor[2] = 2.0f * (texres->tb - 0.5f); } /* de-premul, this is being premulled in shade_input_do_shade() @@ -1449,7 +1449,7 @@ static int imagewraposa_aniso(Tex *tex, /* do not de-premul for generated alpha, it is already in straight */ if (texres->ta != 1.0f && texres->ta > 1e-4f && !(tex->imaflag & TEX_CALCALPHA)) { - fx = 1.f / texres->ta; + fx = 1.0f / texres->ta; texres->tr *= fx; texres->tg *= fx; texres->tb *= fx; @@ -1699,7 +1699,7 @@ int imagewraposa(Tex *tex, return retval; } } - else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) { + else if (ELEM(tex->extend, TEX_CLIP, TEX_CHECKER)) { if (fx + minx < 0.0f || fy + miny < 0.0f || fx - minx > 1.0f || fy - miny > 1.0f) { if (ima) { BKE_image_pool_release_ibuf(ima, ibuf, pool); @@ -1964,9 +1964,9 @@ int imagewraposa(Tex *tex, * the normal used in the renderer points inward. It is generated * this way in calc_vertexnormals(). Should this ever change * this negate must be removed. */ - texres->nor[0] = -2.f * (texres->tr - 0.5f); - texres->nor[1] = 2.f * (texres->tg - 0.5f); - texres->nor[2] = 2.f * (texres->tb - 0.5f); + texres->nor[0] = -2.0f * (texres->tr - 0.5f); + texres->nor[1] = 2.0f * (texres->tg - 0.5f); + texres->nor[2] = 2.0f * (texres->tb - 0.5f); } /* de-premul, this is being premulled in shade_input_do_shade() */ diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index d1632dfeacd..7eeef79e527 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -268,9 +268,6 @@ void RE_parts_init(Render *re) re->parts = BLI_ghash_new( BLI_ghashutil_inthash_v4_p, BLI_ghashutil_inthash_v4_cmp, "render parts"); - /* this is render info for caller, is not reset when parts are freed! */ - re->i.totpart = 0; - /* just for readable code.. */ xminb = re->disprect.xmin; yminb = re->disprect.ymin; @@ -328,7 +325,6 @@ void RE_parts_init(Render *re) pa->recty = recty; BLI_ghash_insert(re->parts, &pa->disprect, pa); - re->i.totpart++; } } } diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c index f12b425ee8b..ea18f151e1e 100644 --- a/source/blender/render/intern/source/multires_bake.c +++ b/source/blender/render/intern/source/multires_bake.c @@ -766,10 +766,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS; smd.quality = 3; - if (bkr->simple) { - smd.subdivType = ME_SIMPLE_SUBSURF; - } - height_data->ssdm = subsurf_make_derived_from_derived( bkr->lores_dm, &smd, bkr->scene, NULL, 0); init_ccgdm_arrays(height_data->ssdm); diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 917193553dc..edf627c4e54 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -70,7 +70,6 @@ #include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_writeavi.h" /* <------ should be replaced once with generic movie module */ @@ -89,6 +88,8 @@ #include "RE_pipeline.h" #include "RE_render_ext.h" +#include "SEQ_sequencer.h" + #include "../../../windowmanager/WM_api.h" /* XXX */ #include "../../../windowmanager/wm_window.h" /* XXX */ #include "GPU_context.h" @@ -188,6 +189,10 @@ static int default_break(void *UNUSED(arg)) static void stats_background(void *UNUSED(arg), RenderStats *rs) { + if (rs->infostr == NULL) { + return; + } + uintptr_t mem_in_use, peak_memory; float megs_used_memory, megs_peak_memory; char info_time_str[32]; @@ -208,17 +213,7 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs) info_time_str, sizeof(info_time_str), PIL_check_seconds_timer() - rs->starttime); fprintf(stdout, TIP_("| Time:%s | "), info_time_str); - if (rs->infostr) { - fprintf(stdout, "%s", rs->infostr); - } - else { - fprintf(stdout, - TIP_("Sce: %s Ve:%d Fa:%d La:%d"), - rs->scene_name, - rs->totvert, - rs->totface, - rs->totlamp); - } + fprintf(stdout, "%s", rs->infostr); /* Flush stdout to be sure python callbacks are printing stuff after blender. */ fflush(stdout); @@ -1503,27 +1498,27 @@ static void do_render_seq(Render *re) tot_views = BKE_scene_multiview_num_views_get(&re->r); ibuf_arr = MEM_mallocN(sizeof(ImBuf *) * tot_views, "Sequencer Views ImBufs"); - BKE_sequencer_new_render_data(re->main, - re->pipeline_depsgraph, - re->scene, - re_x, - re_y, - SEQ_RENDER_SIZE_SCENE, - true, - &context); + SEQ_render_new_render_data(re->main, + re->pipeline_depsgraph, + re->scene, + re_x, + re_y, + SEQ_RENDER_SIZE_SCENE, + true, + &context); /* the renderresult gets destroyed during the rendering, so we first collect all ibufs * and then we populate the final renderesult */ for (view_id = 0; view_id < tot_views; view_id++) { context.view_id = view_id; - out = BKE_sequencer_give_ibuf(&context, cfra, 0); + out = SEQ_render_give_ibuf(&context, cfra, 0); if (out) { ibuf_arr[view_id] = IMB_dupImBuf(out); IMB_metadata_copy(ibuf_arr[view_id], out); IMB_freeImBuf(out); - BKE_sequencer_imbuf_from_sequencer_space(re->pipeline_scene_eval, ibuf_arr[view_id]); + SEQ_render_imbuf_from_sequencer_space(re->pipeline_scene_eval, ibuf_arr[view_id]); } else { ibuf_arr[view_id] = NULL; diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 12b80da9f59..e730aeb263d 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -656,13 +656,13 @@ static int pointdensity(PointDensity *pd, } if (pd->flag & TEX_PD_TURBULENCE) { - turb = BLI_gTurbulence(pd->noise_size, - texvec[0] + vec[0], - texvec[1] + vec[1], - texvec[2] + vec[2], - pd->noise_depth, - 0, - pd->noise_basis); + turb = BLI_noise_generic_turbulence(pd->noise_size, + texvec[0] + vec[0], + texvec[1] + vec[1], + texvec[2] + vec[2], + pd->noise_depth, + 0, + pd->noise_basis); turb -= 0.5f; /* re-center 0.0-1.0 range around 0 to prevent offsetting result */ diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c index db75cb5cfed..990373bafa0 100644 --- a/source/blender/render/intern/source/render_result.c +++ b/source/blender/render/intern/source/render_result.c @@ -992,9 +992,7 @@ bool RE_WriteRenderResult(ReportList *reports, /* We only store RGBA passes as half float, for * others precision loss can be problematic. */ bool pass_half_float = half_float && - (STREQ(rp->chan_id, "RGB") || STREQ(rp->chan_id, "RGBA") || - STREQ(rp->chan_id, "R") || STREQ(rp->chan_id, "G") || - STREQ(rp->chan_id, "B") || STREQ(rp->chan_id, "A")); + (STR_ELEM(rp->chan_id, "RGB", "RGBA", "R", "G", "B", "A")); for (int a = 0; a < rp->channels; a++) { /* Save Combined as RGBA if single layer save. */ diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 12abc0f9216..ff9c462f603 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -174,37 +174,37 @@ static int clouds(const Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; - texres->tin = BLI_gTurbulence(tex->noisesize, - texvec[0], - texvec[1], - texvec[2], - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + texres->tin = BLI_noise_generic_turbulence(tex->noisesize, + texvec[0], + texvec[1], + texvec[2], + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); if (texres->nor != NULL) { /* calculate bumpnormal */ - texres->nor[0] = BLI_gTurbulence(tex->noisesize, - texvec[0] + tex->nabla, - texvec[1], - texvec[2], - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); - texres->nor[1] = BLI_gTurbulence(tex->noisesize, - texvec[0], - texvec[1] + tex->nabla, - texvec[2], - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); - texres->nor[2] = BLI_gTurbulence(tex->noisesize, - texvec[0], - texvec[1], - texvec[2] + tex->nabla, - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + texres->nor[0] = BLI_noise_generic_turbulence(tex->noisesize, + texvec[0] + tex->nabla, + texvec[1], + texvec[2], + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); + texres->nor[1] = BLI_noise_generic_turbulence(tex->noisesize, + texvec[0], + texvec[1] + tex->nabla, + texvec[2], + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); + texres->nor[2] = BLI_noise_generic_turbulence(tex->noisesize, + texvec[0], + texvec[1], + texvec[2] + tex->nabla, + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); tex_normal_derivate(tex, texres); rv |= TEX_NOR; @@ -214,20 +214,20 @@ static int clouds(const Tex *tex, const float texvec[3], TexResult *texres) /* in this case, int. value should really be computed from color, * and bumpnormal from that, would be too slow, looks ok as is */ texres->tr = texres->tin; - texres->tg = BLI_gTurbulence(tex->noisesize, - texvec[1], - texvec[0], - texvec[2], - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); - texres->tb = BLI_gTurbulence(tex->noisesize, - texvec[1], - texvec[2], - texvec[0], - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + texres->tg = BLI_noise_generic_turbulence(tex->noisesize, + texvec[1], + texvec[0], + texvec[2], + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); + texres->tb = BLI_noise_generic_turbulence(tex->noisesize, + texvec[1], + texvec[2], + texvec[0], + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); BRICONTRGB; texres->ta = 1.0; return (rv | TEX_RGB); @@ -296,12 +296,14 @@ static float wood_int(const Tex *tex, float x, float y, float z) } else if (wt == TEX_BANDNOISE) { wi = tex->turbul * - BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis); + BLI_noise_generic_noise( + tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis); wi = waveform[wf]((x + y + z) * 10.0f + wi); } else if (wt == TEX_RINGNOISE) { wi = tex->turbul * - BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis); + BLI_noise_generic_noise( + tex->noisesize, x, y, z, (tex->noisetype != TEX_NOISESOFT), tex->noisebasis); wi = waveform[wf](sqrtf(x * x + y * y + z * z) * 20.0f + wi); } @@ -346,13 +348,13 @@ static float marble_int(const Tex *tex, float x, float y, float z) n = 5.0f * (x + y + z); - mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, - x, - y, - z, - tex->noisedepth, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + mi = n + tex->turbul * BLI_noise_generic_turbulence(tex->noisesize, + x, + y, + z, + tex->noisedepth, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); if (mt >= TEX_SOFT) { /* TEX_SOFT always true */ mi = waveform[wf](mi); @@ -472,36 +474,36 @@ static int stucci(const Tex *tex, const float texvec[3], TexResult *texres) float nor[3], b2, ofs; int retval = TEX_INT; - b2 = BLI_gNoise(tex->noisesize, - texvec[0], - texvec[1], - texvec[2], - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + b2 = BLI_noise_generic_noise(tex->noisesize, + texvec[0], + texvec[1], + texvec[2], + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); ofs = tex->turbul / 200.0f; if (tex->stype) { ofs *= (b2 * b2); } - nor[0] = BLI_gNoise(tex->noisesize, - texvec[0] + ofs, - texvec[1], - texvec[2], - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); - nor[1] = BLI_gNoise(tex->noisesize, - texvec[0], - texvec[1] + ofs, - texvec[2], - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); - nor[2] = BLI_gNoise(tex->noisesize, - texvec[0], - texvec[1], - texvec[2] + ofs, - (tex->noisetype != TEX_NOISESOFT), - tex->noisebasis); + nor[0] = BLI_noise_generic_noise(tex->noisesize, + texvec[0] + ofs, + texvec[1], + texvec[2], + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); + nor[1] = BLI_noise_generic_noise(tex->noisesize, + texvec[0], + texvec[1] + ofs, + texvec[2], + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); + nor[2] = BLI_noise_generic_noise(tex->noisesize, + texvec[0], + texvec[1], + texvec[2] + ofs, + (tex->noisetype != TEX_NOISESOFT), + tex->noisebasis); texres->tin = nor[2]; @@ -539,10 +541,10 @@ static int mg_mFractalOrfBmTex(const Tex *tex, const float texvec[3], TexResult float (*mgravefunc)(float, float, float, float, float, float, int); if (tex->stype == TEX_MFRACTAL) { - mgravefunc = mg_MultiFractal; + mgravefunc = BLI_noise_mg_multi_fractal; } else { - mgravefunc = mg_fBm; + mgravefunc = BLI_noise_mg_fbm; } texres->tin = tex->ns_outscale * mgravefunc(texvec[0], @@ -594,10 +596,10 @@ static int mg_ridgedOrHybridMFTex(const Tex *tex, const float texvec[3], TexResu float (*mgravefunc)(float, float, float, float, float, float, float, float, int); if (tex->stype == TEX_RIDGEDMF) { - mgravefunc = mg_RidgedMultiFractal; + mgravefunc = BLI_noise_mg_ridged_multi_fractal; } else { - mgravefunc = mg_HybridMultiFractal; + mgravefunc = BLI_noise_mg_hybrid_multi_fractal; } texres->tin = tex->ns_outscale * mgravefunc(texvec[0], @@ -655,43 +657,43 @@ static int mg_HTerrainTex(const Tex *tex, const float texvec[3], TexResult *texr { int rv = TEX_INT; - texres->tin = tex->ns_outscale * mg_HeteroTerrain(texvec[0], - texvec[1], - texvec[2], - tex->mg_H, - tex->mg_lacunarity, - tex->mg_octaves, - tex->mg_offset, - tex->noisebasis); + texres->tin = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0], + texvec[1], + texvec[2], + tex->mg_H, + tex->mg_lacunarity, + tex->mg_octaves, + tex->mg_offset, + tex->noisebasis); if (texres->nor != NULL) { float offs = tex->nabla / tex->noisesize; /* also scaling of texvec */ /* calculate bumpnormal */ - texres->nor[0] = tex->ns_outscale * mg_HeteroTerrain(texvec[0] + offs, - texvec[1], - texvec[2], - tex->mg_H, - tex->mg_lacunarity, - tex->mg_octaves, - tex->mg_offset, - tex->noisebasis); - texres->nor[1] = tex->ns_outscale * mg_HeteroTerrain(texvec[0], - texvec[1] + offs, - texvec[2], - tex->mg_H, - tex->mg_lacunarity, - tex->mg_octaves, - tex->mg_offset, - tex->noisebasis); - texres->nor[2] = tex->ns_outscale * mg_HeteroTerrain(texvec[0], - texvec[1], - texvec[2] + offs, - tex->mg_H, - tex->mg_lacunarity, - tex->mg_octaves, - tex->mg_offset, - tex->noisebasis); + texres->nor[0] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0] + offs, + texvec[1], + texvec[2], + tex->mg_H, + tex->mg_lacunarity, + tex->mg_octaves, + tex->mg_offset, + tex->noisebasis); + texres->nor[1] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0], + texvec[1] + offs, + texvec[2], + tex->mg_H, + tex->mg_lacunarity, + tex->mg_octaves, + tex->mg_offset, + tex->noisebasis); + texres->nor[2] = tex->ns_outscale * BLI_noise_mg_hetero_terrain(texvec[0], + texvec[1], + texvec[2] + offs, + tex->mg_H, + tex->mg_lacunarity, + tex->mg_octaves, + tex->mg_offset, + tex->noisebasis); tex_normal_derivate(tex, texres); rv |= TEX_NOR; @@ -706,31 +708,31 @@ static int mg_distNoiseTex(const Tex *tex, const float texvec[3], TexResult *tex { int rv = TEX_INT; - texres->tin = mg_VLNoise( + texres->tin = BLI_noise_mg_variable_lacunarity( texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); if (texres->nor != NULL) { float offs = tex->nabla / tex->noisesize; /* also scaling of texvec */ /* calculate bumpnormal */ - texres->nor[0] = mg_VLNoise(texvec[0] + offs, - texvec[1], - texvec[2], - tex->dist_amount, - tex->noisebasis, - tex->noisebasis2); - texres->nor[1] = mg_VLNoise(texvec[0], - texvec[1] + offs, - texvec[2], - tex->dist_amount, - tex->noisebasis, - tex->noisebasis2); - texres->nor[2] = mg_VLNoise(texvec[0], - texvec[1], - texvec[2] + offs, - tex->dist_amount, - tex->noisebasis, - tex->noisebasis2); + texres->nor[0] = BLI_noise_mg_variable_lacunarity(texvec[0] + offs, + texvec[1], + texvec[2], + tex->dist_amount, + tex->noisebasis, + tex->noisebasis2); + texres->nor[1] = BLI_noise_mg_variable_lacunarity(texvec[0], + texvec[1] + offs, + texvec[2], + tex->dist_amount, + tex->noisebasis, + tex->noisebasis2); + texres->nor[2] = BLI_noise_mg_variable_lacunarity(texvec[0], + texvec[1], + texvec[2] + offs, + tex->dist_amount, + tex->noisebasis, + tex->noisebasis2); tex_normal_derivate(tex, texres); rv |= TEX_NOR; @@ -756,28 +758,28 @@ static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres) float aw3 = fabsf(tex->vn_w3); float aw4 = fabsf(tex->vn_w4); float sc = (aw1 + aw2 + aw3 + aw4); - if (sc != 0.f) { + if (sc != 0.0f) { sc = tex->ns_outscale / sc; } - voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); + BLI_noise_voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); texres->tin = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); if (tex->vn_coltype) { float ca[3]; /* cell color */ - cellNoiseV(pa[0], pa[1], pa[2], ca); + BLI_noise_cell_v3(pa[0], pa[1], pa[2], ca); texres->tr = aw1 * ca[0]; texres->tg = aw1 * ca[1]; texres->tb = aw1 * ca[2]; - cellNoiseV(pa[3], pa[4], pa[5], ca); + BLI_noise_cell_v3(pa[3], pa[4], pa[5], ca); texres->tr += aw2 * ca[0]; texres->tg += aw2 * ca[1]; texres->tb += aw2 * ca[2]; - cellNoiseV(pa[6], pa[7], pa[8], ca); + BLI_noise_cell_v3(pa[6], pa[7], pa[8], ca); texres->tr += aw3 * ca[0]; texres->tg += aw3 * ca[1]; texres->tb += aw3 * ca[2]; - cellNoiseV(pa[9], pa[10], pa[11], ca); + BLI_noise_cell_v3(pa[9], pa[10], pa[11], ca); texres->tr += aw4 * ca[0]; texres->tg += aw4 * ca[1]; texres->tb += aw4 * ca[2]; @@ -807,11 +809,11 @@ static int voronoiTex(const Tex *tex, const float texvec[3], TexResult *texres) float offs = tex->nabla / tex->noisesize; /* also scaling of texvec */ /* calculate bumpnormal */ - voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); + BLI_noise_voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); texres->nor[0] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); - voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); + BLI_noise_voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); texres->nor[1] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); - voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm); + BLI_noise_voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm); texres->nor[2] = sc * fabsf(dot_v4v4(&tex->vn_w1, da)); tex_normal_derivate(tex, texres); diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt index 866eba9ca41..3841a6e6414 100644 --- a/source/blender/sequencer/CMakeLists.txt +++ b/source/blender/sequencer/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC . + intern ../blenkernel ../blenlib ../blentranslation @@ -39,13 +40,18 @@ set(INC_SYS ) set(SRC - BKE_sequencer.h + SEQ_sequencer.h - intern/sequencer.c - intern/image_cache.c intern/effects.c + intern/image_cache.c intern/modifier.c intern/prefetch.c + intern/proxy.c + intern/proxy.h + intern/render.c + intern/render.h + intern/sequencer.c + intern/sequencer.h ) set(LIB diff --git a/source/blender/sequencer/BKE_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index 04be46f0ccf..d969b43bd50 100644 --- a/source/blender/sequencer/BKE_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -20,7 +20,7 @@ #pragma once /** \file - * \ingroup bke + * \ingroup sequencer */ #ifdef __cplusplus @@ -36,23 +36,40 @@ struct Main; struct Mask; struct ReportList; struct Scene; +struct SeqIndexBuildContext; struct Sequence; struct SequenceModifierData; struct Stereo3dFormat; -struct StripColorBalance; struct StripElem; struct TextVars; struct bContext; struct bSound; -struct SeqIndexBuildContext; +/* Wipe effect */ +enum { + DO_SINGLE_WIPE, + DO_DOUBLE_WIPE, + /* DO_BOX_WIPE, */ /* UNUSED */ + /* DO_CROSS_WIPE, */ /* UNUSED */ + DO_IRIS_WIPE, + DO_CLOCK_WIPE, +}; -#define EARLY_NO_INPUT -1 -#define EARLY_DO_EFFECT 0 -#define EARLY_USE_INPUT_1 1 -#define EARLY_USE_INPUT_2 2 +/* RNA enums, just to be more readable */ +enum { + SEQ_SIDE_NONE = 0, + SEQ_SIDE_LEFT, + SEQ_SIDE_RIGHT, + SEQ_SIDE_BOTH, + SEQ_SIDE_NO_CHANGE, +}; -/* sequence iterator */ +/* ********************************************************************** + * sequencer.c + * + * Sequencer iterators + * ********************************************************************** + */ typedef struct SeqIterator { struct Sequence **array; @@ -62,12 +79,6 @@ typedef struct SeqIterator { int valid; } SeqIterator; -void BKE_sequence_iterator_begin(struct Editing *ed, - SeqIterator *iter, - const bool use_current_sequences); -void BKE_sequence_iterator_next(SeqIterator *iter); -void BKE_sequence_iterator_end(SeqIterator *iter); - #define SEQ_ALL_BEGIN(ed, _seq) \ { \ SeqIterator iter_macro; \ @@ -90,6 +101,19 @@ void BKE_sequence_iterator_end(SeqIterator *iter); #define SEQ_CURRENT_END SEQ_ALL_END +void BKE_sequence_iterator_begin(struct Editing *ed, + SeqIterator *iter, + const bool use_current_sequences); +void BKE_sequence_iterator_next(SeqIterator *iter); +void BKE_sequence_iterator_end(SeqIterator *iter); + +/* ********************************************************************** + * render.c + * + * Sequencer render functions + * ********************************************************************** + */ + typedef enum eSeqTaskId { SEQ_TASK_MAIN_RENDER, SEQ_TASK_PREFETCH_RENDER, @@ -118,141 +142,41 @@ typedef struct SeqRenderData { // bool gpu_full_samples; } SeqRenderData; -void BKE_sequencer_new_render_data(struct Main *bmain, - struct Depsgraph *depsgraph, - struct Scene *scene, - int rectx, - int recty, - int preview_render_size, - int for_render, - SeqRenderData *r_context); - -int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b); - -/* Wipe effect */ -enum { - DO_SINGLE_WIPE, - DO_DOUBLE_WIPE, - /* DO_BOX_WIPE, */ /* UNUSED */ - /* DO_CROSS_WIPE, */ /* UNUSED */ - DO_IRIS_WIPE, - DO_CLOCK_WIPE, -}; - -struct SeqEffectHandle { - bool multithreaded; - bool supports_mask; - - /* constructors & destructor */ - /* init is _only_ called on first creation */ - void (*init)(struct Sequence *seq); - - /* number of input strips needed - * (called directly after construction) */ - int (*num_inputs)(void); - - /* load is called first time after readblenfile in - * get_sequence_effect automatically */ - void (*load)(struct Sequence *seqconst); - - /* duplicate */ - void (*copy)(struct Sequence *dst, struct Sequence *src, const int flag); - - /* destruct */ - void (*free)(struct Sequence *seq, const bool do_id_user); - - /* returns: -1: no input needed, - * 0: no early out, - * 1: out = ibuf1, - * 2: out = ibuf2 */ - int (*early_out)(struct Sequence *seq, float facf0, float facf1); - - /* stores the y-range of the effect IPO */ - void (*store_icu_yrange)(struct Sequence *seq, short adrcode, float *ymin, float *ymax); - - /* stores the default facf0 and facf1 if no IPO is present */ - void (*get_default_fac)(struct Sequence *seq, float cfra, float *facf0, float *facf1); - - /* execute the effect - * sequence effects are only required to either support - * float-rects or byte-rects - * (mixed cases are handled one layer up...) */ - - struct ImBuf *(*execute)(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - float facf0, - float facf1, - struct ImBuf *ibuf1, - struct ImBuf *ibuf2, - struct ImBuf *ibuf3); - - struct ImBuf *(*init_execution)(const SeqRenderData *context, - struct ImBuf *ibuf1, - struct ImBuf *ibuf2, - struct ImBuf *ibuf3); - - void (*execute_slice)(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - float facf0, - float facf1, - struct ImBuf *ibuf1, - struct ImBuf *ibuf2, - struct ImBuf *ibuf3, - int start_line, - int total_lines, - struct ImBuf *out); -}; - -/* ********************* prototypes *************** */ +struct ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float cfra, int chanshown); +struct ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, + float cfra, + struct Sequence *seq); +void SEQ_render_init_colorspace(struct Sequence *seq); +void SEQ_render_new_render_data(struct Main *bmain, + struct Depsgraph *depsgraph, + struct Scene *scene, + int rectx, + int recty, + int preview_render_size, + int for_render, + SeqRenderData *r_context); +int SEQ_render_evaluate_frame(struct Scene *scene, int cfra); +struct StripElem *SEQ_render_give_stripelem(struct Sequence *seq, int cfra); /* ********************************************************************** - * sequencer.c + * render.c * - * sequencer render functions + * Sequencer color space functions * ********************************************************************** */ -double BKE_sequencer_rendersize_to_scale_factor(int size); - -struct ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown); -struct ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context, - float cfra, - struct Sequence *seq); -struct ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context, - float cfra, - int chan_shown, - struct ListBase *seqbasep); -struct ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh, - const SeqRenderData *context, - struct Sequence *seq, - float cfra, - float facf0, - float facf1, - struct ImBuf *ibuf1, - struct ImBuf *ibuf2, - struct ImBuf *ibuf3); + +void SEQ_render_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf); +void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]); /* ********************************************************************** * sequencer.c * - * sequencer color space functions + * Sequencer scene functions * ********************************************************************** */ -void BKE_sequencer_imbuf_to_sequencer_space(struct Scene *scene, - struct ImBuf *ibuf, - bool make_float); -void BKE_sequencer_imbuf_from_sequencer_space(struct Scene *scene, struct ImBuf *ibuf); -void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]); - -/* ********************************************************************** - * sequencer scene functions - * ********************************************************************** */ struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc); struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene); void BKE_sequencer_editing_free(struct Scene *scene, const bool do_id_user); - void BKE_sequencer_sort(struct Scene *scene); - struct Sequence *BKE_sequencer_from_elem(ListBase *seqbase, struct StripElem *se); struct Sequence *BKE_sequencer_active_get(struct Scene *scene); int BKE_sequencer_active_get_pair(struct Scene *scene, @@ -260,7 +184,6 @@ int BKE_sequencer_active_get_pair(struct Scene *scene, struct Sequence **seq_other); void BKE_sequencer_active_set(struct Scene *scene, struct Sequence *seq); struct Mask *BKE_sequencer_mask_get(struct Scene *scene); - /* apply functions recursively */ int BKE_sequencer_base_recursive_apply(struct ListBase *seqbase, int (*apply_fn)(struct Sequence *seq, void *), @@ -268,16 +191,14 @@ int BKE_sequencer_base_recursive_apply(struct ListBase *seqbase, int BKE_sequencer_recursive_apply(struct Sequence *seq, int (*apply_fn)(struct Sequence *, void *), void *arg); - +float BKE_sequence_get_fps(struct Scene *scene, struct Sequence *seq); +int BKE_sequencer_find_next_prev_edit(struct Scene *scene, + int cfra, + const short side, + const bool do_skip_mute, + const bool do_center, + const bool do_unselected); /* maintenance functions, mostly for RNA */ -/* extern */ - -void BKE_sequencer_free_clipboard(void); - -void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase); -void BKE_sequencer_base_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); -void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); - void BKE_sequence_free(struct Scene *scene, struct Sequence *seq, const bool do_clean_animdata); void BKE_sequence_free_anim(struct Sequence *seq); const char *BKE_sequence_give_name(struct Sequence *seq); @@ -293,123 +214,67 @@ void BKE_sequence_movie_reload_if_needed(struct Main *bmain, struct Sequence *seq, bool *r_was_reloaded, bool *r_can_produce_frames); -int BKE_sequencer_evaluate_frame(struct Scene *scene, int cfra); -int BKE_sequencer_get_shown_sequences(struct ListBase *seqbasep, - int cfra, - int chanshown, - struct Sequence **seq_arr_out); - -struct StripElem *BKE_sequencer_give_stripelem(struct Sequence *seq, int cfra); - -/* intern */ +void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq); void BKE_sequencer_update_changed_seq_and_deps(struct Scene *scene, struct Sequence *changed_seq, int len_change, int ibuf_change); -bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, - struct Sequence *seq, - float cfra); +bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports); +bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); +int BKE_sequencer_cmp_time_startdisp(const void *a, const void *b); -bool BKE_sequencer_proxy_rebuild_context(struct Main *bmain, - struct Depsgraph *depsgraph, - struct Scene *scene, - struct Sequence *seq, - struct GSet *file_list, - ListBase *queue); -void BKE_sequencer_proxy_rebuild(struct SeqIndexBuildContext *context, - short *stop, - short *do_update, - float *progress); -void BKE_sequencer_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop); - -void BKE_sequencer_proxy_set(struct Sequence *seq, bool value); /* ********************************************************************** - * seqcache.c + * proxy.c * - * Sequencer memory cache management functions + * Proxy functions * ********************************************************************** */ -#define SEQ_CACHE_COST_MAX 10.0f +bool SEQ_proxy_rebuild_context(struct Main *bmain, + struct Depsgraph *depsgraph, + struct Scene *scene, + struct Sequence *seq, + struct GSet *file_list, + ListBase *queue); +void SEQ_proxy_rebuild(struct SeqIndexBuildContext *context, + short *stop, + short *do_update, + float *progress); +void SEQ_proxy_rebuild_finish(struct SeqIndexBuildContext *context, bool stop); +void SEQ_proxy_set(struct Sequence *seq, bool value); +bool SEQ_can_use_proxy(struct Sequence *seq, int psize); +int SEQ_rendersize_to_proxysize(int render_size); +double SEQ_rendersize_to_scale_factor(int size); + +/* ********************************************************************** + * image_cache.c + * + * Sequencer memory cache management functions + * ********************************************************************** */ -struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - int type, - bool skip_disk_cache); -void BKE_sequencer_cache_put(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - int type, - struct ImBuf *i, - float cost, - bool skip_disk_cache); -bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - int type, - struct ImBuf *nval, - float cost, - bool skip_disk_cache); -bool BKE_sequencer_cache_recycle_item(struct Scene *scene); -void BKE_sequencer_cache_free_temp_cache(struct Scene *scene, short id, int cfra); -void BKE_sequencer_cache_destruct(struct Scene *scene); -void BKE_sequencer_cache_cleanup_all(struct Main *bmain); void BKE_sequencer_cache_cleanup(struct Scene *scene); -void BKE_sequencer_cache_cleanup_sequence(struct Scene *scene, - struct Sequence *seq, - struct Sequence *seq_changed, - int invalidate_types, - bool force_seq_changed_range); void BKE_sequencer_cache_iterate(struct Scene *scene, void *userdata, bool callback_init(void *userdata, size_t item_count), bool callback_iter(void *userdata, struct Sequence *seq, - int cfra, + int timeline_frame, int cache_type, float cost)); -bool BKE_sequencer_cache_is_full(struct Scene *scene); /* ********************************************************************** - * seqprefetch.c + * prefetch.c * * Sequencer frame prefetching * ********************************************************************** */ -void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, float cost); +#define SEQ_CACHE_COST_MAX 10.0f void BKE_sequencer_prefetch_stop_all(void); void BKE_sequencer_prefetch_stop(struct Scene *scene); -void BKE_sequencer_prefetch_free(struct Scene *scene); bool BKE_sequencer_prefetch_need_redraw(struct Main *bmain, struct Scene *scene); -bool BKE_sequencer_prefetch_job_is_running(struct Scene *scene); -void BKE_sequencer_prefetch_get_time_range(struct Scene *scene, int *start, int *end); -SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context); -struct Sequence *BKE_sequencer_prefetch_get_original_sequence(struct Sequence *seq, - struct Scene *scene); /* ********************************************************************** - * seqeffects.c + * sequencer.c * - * Sequencer effect strip management functions - * ********************************************************************** - */ - -/* intern */ -struct SeqEffectHandle BKE_sequence_get_blend(struct Sequence *seq); -void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, bool force); -float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context, - struct Sequence *seq, - float cfra, - int input); - -/* extern */ -struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq); -int BKE_sequence_effect_get_num_inputs(int seq_type); -int BKE_sequence_effect_get_supports_mask(int seq_type); -void BKE_sequencer_text_font_unload(struct TextVars *data, const bool do_id_user); -void BKE_sequencer_text_font_load(struct TextVars *data, const bool do_id_user); - -/* ********************************************************************** * Sequencer editing functions * ********************************************************************** */ @@ -426,13 +291,8 @@ bool BKE_sequence_single_check(struct Sequence *seq); void BKE_sequence_single_fix(struct Sequence *seq); bool BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test); void BKE_sequence_translate(struct Scene *scene, struct Sequence *seq, int delta); -void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq); const struct Sequence *BKE_sequencer_foreground_frame_get(const struct Scene *scene, int frame); struct ListBase *BKE_sequence_seqbase(struct ListBase *seqbase, struct Sequence *seq); -struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */, - struct Sequence *meta /* = NULL */, - struct Sequence *seq); - void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst); bool BKE_sequence_base_shuffle_ex(struct ListBase *seqbasep, @@ -454,26 +314,11 @@ struct Sequence *BKE_sequence_dupli_recursive(const struct Scene *scene_src, struct Sequence *seq, int dupe_flag); int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str); - -bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur); -void BKE_sequence_invalidate_cache_raw(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_cache_preprocessed(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_cache_composite(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq); -void BKE_sequence_invalidate_scene_strips(struct Main *bmain, struct Scene *scene_target); -void BKE_sequence_invalidate_movieclip_strips(struct Main *bmain, struct MovieClip *clip_target); -void BKE_sequence_invalidate_cache_in_range(struct Scene *scene, - struct Sequence *seq, - struct Sequence *range_mask, - int invalidate_types); - void BKE_sequencer_update_sound_bounds_all(struct Scene *scene); void BKE_sequencer_update_sound_bounds(struct Scene *scene, struct Sequence *seq); void BKE_sequencer_update_muting(struct Editing *ed); void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound); - void BKE_sequencer_refresh_sound_length(struct Main *bmain, struct Scene *scene); - void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq); void BKE_sequence_base_dupli_recursive(const struct Scene *scene_src, struct Scene *scene_dst, @@ -482,12 +327,39 @@ void BKE_sequence_base_dupli_recursive(const struct Scene *scene_src, int dupe_flag, const int flag); bool BKE_sequence_is_valid_check(struct Sequence *seq); - -void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); - struct Sequence *BKE_sequence_get_by_name(struct ListBase *seqbase, const char *name, bool recursive); +void BKE_sequencer_flag_for_removal(struct Scene *scene, + struct ListBase *seqbase, + struct Sequence *seq); +void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase); + +/* ********************************************************************** + * sequencer.c + * + * Cache invalidation + * ********************************************************************** + */ + +void BKE_sequence_invalidate_cache_raw(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_cache_preprocessed(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_cache_composite(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq); +void BKE_sequence_invalidate_scene_strips(struct Main *bmain, struct Scene *scene_target); +void BKE_sequence_invalidate_movieclip_strips(struct Main *bmain, struct MovieClip *clip_target); +void BKE_sequence_invalidate_cache_in_range(struct Scene *scene, + struct Sequence *seq, + struct Sequence *range_mask, + int invalidate_types); +void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra); + +/* ********************************************************************** + * sequencer.c + * + * Add strips + * ********************************************************************** + */ /* api for adding new sequence strips */ typedef struct SeqLoadInfo { @@ -529,31 +401,6 @@ typedef struct SeqLoadInfo { typedef struct Sequence *(*SeqLoadFn)(struct bContext *, ListBase *, struct SeqLoadInfo *); struct Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine, int type); - -/* Generate new UUID for the given sequence. */ -void BKE_sequence_session_uuid_generate(struct Sequence *sequence); - -void BKE_sequence_alpha_mode_from_extension(struct Sequence *seq); -void BKE_sequence_init_colorspace(struct Sequence *seq); - -float BKE_sequence_get_fps(struct Scene *scene, struct Sequence *seq); -float BKE_sequencer_give_stripelem_index(struct Sequence *seq, float cfra); - -/* RNA enums, just to be more readable */ -enum { - SEQ_SIDE_NONE = 0, - SEQ_SIDE_LEFT, - SEQ_SIDE_RIGHT, - SEQ_SIDE_BOTH, - SEQ_SIDE_NO_CHANGE, -}; -int BKE_sequencer_find_next_prev_edit(struct Scene *scene, - int cfra, - const short side, - const bool do_skip_mute, - const bool do_center, - const bool do_unselected); - struct Sequence *BKE_sequencer_add_image_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); @@ -564,11 +411,13 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); -/* copy/paste */ -extern ListBase seqbase_clipboard; -extern int seqbase_clipboard_frame; +/* ********************************************************************** + * modifier.c + * + * Modifiers + * ********************************************************************** + */ -/* modifiers */ typedef struct SequenceModifierTypeInfo { /* default name for the modifier */ char name[64]; /* MAX_NAME */ @@ -596,7 +445,6 @@ typedef struct SequenceModifierTypeInfo { } SequenceModifierTypeInfo; const struct SequenceModifierTypeInfo *BKE_sequence_modifier_type_info_get(int type); - struct SequenceModifierData *BKE_sequence_modifier_new(struct Sequence *seq, const char *name, int type); @@ -611,34 +459,111 @@ struct ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context, struct ImBuf *ibuf, int cfra); void BKE_sequence_modifier_list_copy(struct Sequence *seqn, struct Sequence *seq); - int BKE_sequence_supports_modifiers(struct Sequence *seq); -/* internal filters */ -struct ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, - int mask_input_type, - struct Sequence *mask_sequence, - struct Mask *mask_id, - int cfra, - int fra_offset, - bool make_float); -void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, - struct ImBuf *ibuf, - float mul, - bool make_float, - struct ImBuf *mask_input); +/* ********************************************************************** + * seqeffects.c + * + * Sequencer effect strip management functions + * ********************************************************************** + */ -void BKE_sequencer_all_free_anim_ibufs(struct Scene *scene, int cfra); -bool BKE_sequencer_check_scene_recursion(struct Scene *scene, struct ReportList *reports); -bool BKE_sequencer_render_loop_check(struct Sequence *seq_main, struct Sequence *seq); -void BKE_sequencer_flag_for_removal(struct Scene *scene, - struct ListBase *seqbase, - struct Sequence *seq); -void BKE_sequencer_remove_flagged_sequences(struct Scene *scene, struct ListBase *seqbase); +struct SeqEffectHandle { + bool multithreaded; + bool supports_mask; + + /* constructors & destructor */ + /* init is _only_ called on first creation */ + void (*init)(struct Sequence *seq); + + /* number of input strips needed + * (called directly after construction) */ + int (*num_inputs)(void); + + /* load is called first time after readblenfile in + * get_sequence_effect automatically */ + void (*load)(struct Sequence *seqconst); + + /* duplicate */ + void (*copy)(struct Sequence *dst, struct Sequence *src, const int flag); + + /* destruct */ + void (*free)(struct Sequence *seq, const bool do_id_user); + + /* returns: -1: no input needed, + * 0: no early out, + * 1: out = ibuf1, + * 2: out = ibuf2 */ + int (*early_out)(struct Sequence *seq, float facf0, float facf1); + + /* stores the y-range of the effect IPO */ + void (*store_icu_yrange)(struct Sequence *seq, short adrcode, float *ymin, float *ymax); + + /* stores the default facf0 and facf1 if no IPO is present */ + void (*get_default_fac)(struct Sequence *seq, float cfra, float *facf0, float *facf1); + + /* execute the effect + * sequence effects are only required to either support + * float-rects or byte-rects + * (mixed cases are handled one layer up...) */ + + struct ImBuf *(*execute)(const SeqRenderData *context, + struct Sequence *seq, + float cfra, + float facf0, + float facf1, + struct ImBuf *ibuf1, + struct ImBuf *ibuf2, + struct ImBuf *ibuf3); + + struct ImBuf *(*init_execution)(const SeqRenderData *context, + struct ImBuf *ibuf1, + struct ImBuf *ibuf2, + struct ImBuf *ibuf3); + + void (*execute_slice)(const SeqRenderData *context, + struct Sequence *seq, + float cfra, + float facf0, + float facf1, + struct ImBuf *ibuf1, + struct ImBuf *ibuf2, + struct ImBuf *ibuf3, + int start_line, + int total_lines, + struct ImBuf *out); +}; + +struct SeqEffectHandle BKE_sequence_get_effect(struct Sequence *seq); +int BKE_sequence_effect_get_num_inputs(int seq_type); +void BKE_sequencer_text_font_unload(struct TextVars *data, const bool do_id_user); +void BKE_sequencer_text_font_load(struct TextVars *data, const bool do_id_user); + +/* ********************************************************************** + * sequencer.c + * + * Clipboard + * ********************************************************************** + */ + +extern ListBase seqbase_clipboard; +extern int seqbase_clipboard_frame; +void BKE_sequencer_base_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); +void BKE_sequencer_base_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); +void BKE_sequencer_free_clipboard(void); + +/* ********************************************************************** + * sequencer.c + * + * Depsgraph + * ********************************************************************** + */ /* A debug and development function which checks whether sequences have unique UUIDs. * Errors will be reported to the console. */ void BKE_sequencer_check_uuids_unique_and_report(const struct Scene *scene); +/* Generate new UUID for the given sequence. */ +void BKE_sequence_session_uuid_generate(struct Sequence *sequence); #ifdef __cplusplus } diff --git a/source/blender/sequencer/intern/effects.c b/source/blender/sequencer/intern/effects.c index b4bc2d25155..039c18bf51d 100644 --- a/source/blender/sequencer/intern/effects.c +++ b/source/blender/sequencer/intern/effects.c @@ -46,7 +46,6 @@ #include "BKE_fcurve.h" #include "BKE_lib_id.h" #include "BKE_main.h" -#include "BKE_sequencer.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -59,8 +58,13 @@ #include "RE_pipeline.h" +#include "SEQ_sequencer.h" + #include "BLF_api.h" +#include "render.h" +#include "sequencer.h" + static struct SeqEffectHandle get_sequence_effect_impl(int seq_type); static void slice_get_byte_buffers(const SeqRenderData *context, @@ -148,15 +152,15 @@ static ImBuf *prepare_effect_imbufs(const SeqRenderData *context, if (out->rect_float) { if (ibuf1 && !ibuf1->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf1, true); + seq_imbuf_to_sequencer_space(scene, ibuf1, true); } if (ibuf2 && !ibuf2->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf2, true); + seq_imbuf_to_sequencer_space(scene, ibuf2, true); } if (ibuf3 && !ibuf3->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf3, true); + seq_imbuf_to_sequencer_space(scene, ibuf3, true); } IMB_colormanagement_assign_float_colorspace(out, scene->sequencer_colorspace_settings.name); @@ -2986,7 +2990,7 @@ static ImBuf *do_multicam(const SeqRenderData *context, return NULL; } - out = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep); + out = seq_render_give_ibuf_seqbase(context, cfra, seq->multicam_source, seqbasep); return out; } @@ -3015,7 +3019,7 @@ static ImBuf *do_adjustment_impl(const SeqRenderData *context, Sequence *seq, fl seqbasep = BKE_sequence_seqbase(&ed->seqbase, seq); if (seq->machine > 1) { - i = BKE_sequencer_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep); + i = seq_render_give_ibuf_seqbase(context, cfra, seq->machine - 1, seqbasep); } /* found nothing? so let's work the way up the metastrip stack, so @@ -3250,7 +3254,7 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context, float cfra, int input) { - int nr = BKE_sequencer_give_stripelem_index(seq, cfra); + int nr = seq_give_stripelem_index(seq, cfra); SpeedControlVars *s = (SpeedControlVars *)seq->effectdata; BKE_sequence_effect_speed_rebuild_map(context->scene, seq, false); @@ -3269,7 +3273,7 @@ float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context, static float speed_effect_interpolation_ratio_get(SpeedControlVars *s, Sequence *seq, float cfra) { - int nr = BKE_sequencer_give_stripelem_index(seq, cfra); + int nr = seq_give_stripelem_index(seq, cfra); return s->frameMap[nr] - floor(s->frameMap[nr]); } @@ -3290,7 +3294,7 @@ static ImBuf *do_speed_effect(const SeqRenderData *context, out = prepare_effect_imbufs(context, ibuf1, ibuf2, ibuf3); facf0 = facf1 = speed_effect_interpolation_ratio_get(s, seq, cfra); /* Current frame is ibuf1, next frame is ibuf2. */ - out = BKE_sequencer_effect_execute_threaded( + out = seq_render_effect_execute_threaded( &cross_effect, context, NULL, cfra, facf0, facf1, ibuf1, ibuf2, ibuf3); return out; } @@ -3902,7 +3906,7 @@ static ImBuf *do_text_effect(const SeqRenderData *context, /* Compensate text size for preview render size. */ proxy_size_comp = context->scene->r.size / 100.0; if (context->preview_render_size != SEQ_RENDER_SIZE_SCENE) { - proxy_size_comp *= BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size); + proxy_size_comp *= SEQ_rendersize_to_scale_factor(context->preview_render_size); } /* set before return */ diff --git a/source/blender/sequencer/intern/image_cache.c b/source/blender/sequencer/intern/image_cache.c index 7d2858050be..4bbf1838b4e 100644 --- a/source/blender/sequencer/intern/image_cache.c +++ b/source/blender/sequencer/intern/image_cache.c @@ -47,7 +47,11 @@ #include "BKE_global.h" #include "BKE_main.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" + +#include "SEQ_sequencer.h" + +#include "render.h" +#include "sequencer.h" /** * Sequencer Cache Design Notes @@ -155,17 +159,20 @@ typedef struct SeqCacheKey { struct SeqCacheKey *link_next; /* Used for linking intermediate items to final frame. */ struct Sequence *seq; SeqRenderData context; - float nfra; - float cost; /* In short: render time(s) divided by playback frame duration(s) */ - bool is_temp_cache; /* this cache entry will be freed before rendering next frame */ + float frame_index; /* Usually same as timeline_frame. Mapped to media for RAW entries. */ + float timeline_frame; /* Only for reference - used for freeing when cache is full. */ + float cost; /* In short: render time(s) divided by playback frame duration(s) */ + bool is_temp_cache; /* this cache entry will be freed before rendering next frame */ /* ID of task for asigning temp cache entries to particular task(thread, etc.) */ eSeqTaskId task_id; int type; } SeqCacheKey; static ThreadMutex cache_create_lock = BLI_MUTEX_INITIALIZER; -static float seq_cache_cfra_to_frame_index(Sequence *seq, float cfra); -static float seq_cache_frame_index_to_cfra(Sequence *seq, float nfra); +static float seq_cache_timeline_frame_to_frame_index(Sequence *seq, + float timeline_frame, + int type); +static float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index); static char *seq_disk_cache_base_dir(void) { @@ -376,7 +383,7 @@ static void seq_disk_cache_get_file_path(SeqDiskCache *disk_cache, size_t path_len) { seq_disk_cache_get_dir(disk_cache, key->context.scene, key->seq, path, path_len); - int frameno = (int)key->nfra / DCACHE_IMAGES_PER_FILE; + int frameno = (int)key->frame_index / DCACHE_IMAGES_PER_FILE; char cache_filename[FILE_MAXFILE]; sprintf(cache_filename, DCACHE_FNAME_FORMAT, @@ -445,8 +452,9 @@ static void seq_disk_cache_delete_invalid_files(SeqDiskCache *disk_cache, next_file = cache_file->next; if (cache_file->cache_type & invalidate_types) { if (STREQ(cache_dir, cache_file->dir)) { - int cfra_start = seq_cache_frame_index_to_cfra(seq, cache_file->start_frame); - if (cfra_start > range_start && cfra_start <= range_end) { + int timeline_frame_start = seq_cache_frame_index_to_timeline_frame( + seq, cache_file->start_frame); + if (timeline_frame_start > range_start && timeline_frame_start <= range_end) { seq_disk_cache_delete_file(disk_cache, cache_file); } } @@ -553,7 +561,7 @@ static int seq_disk_cache_add_header_entry(SeqCacheKey *key, ImBuf *ibuf, DiskCa } header->entry[i].offset = offset; - header->entry[i].frameno = key->nfra; + header->entry[i].frameno = key->frame_index; /* Store colorspace name of ibuf. */ const char *colorspace_name; @@ -574,7 +582,7 @@ static int seq_disk_cache_add_header_entry(SeqCacheKey *key, ImBuf *ibuf, DiskCa static int seq_disk_cache_get_header_entry(SeqCacheKey *key, DiskCacheHeader *header) { for (int i = 0; i < DCACHE_IMAGES_PER_FILE; i++) { - if (header->entry[i].frameno == key->nfra) { + if (header->entry[i].frameno == key->frame_index) { return i; } } @@ -710,7 +718,7 @@ static unsigned int seq_cache_hashhash(const void *key_) const SeqCacheKey *key = key_; unsigned int rval = seq_hash_render_data(&key->context); - rval ^= *(const unsigned int *)&key->nfra; + rval ^= *(const unsigned int *)&key->frame_index; rval += key->type; rval ^= ((intptr_t)key->seq) << 6; @@ -722,18 +730,25 @@ static bool seq_cache_hashcmp(const void *a_, const void *b_) const SeqCacheKey *a = a_; const SeqCacheKey *b = b_; - return ((a->seq != b->seq) || (a->nfra != b->nfra) || (a->type != b->type) || + return ((a->seq != b->seq) || (a->frame_index != b->frame_index) || (a->type != b->type) || seq_cmp_render_data(&a->context, &b->context)); } -static float seq_cache_cfra_to_frame_index(Sequence *seq, float cfra) +static float seq_cache_timeline_frame_to_frame_index(Sequence *seq, float timeline_frame, int type) { - return cfra - seq->start; + /* With raw images, map timeline_frame to strip input media frame range. This means that static + * images or extended frame range of movies will only generate one cache entry. No special + * treatment in converting frame index to timeline_frame is needed. */ + if (type == SEQ_CACHE_STORE_RAW) { + return seq_give_stripelem_index(seq, timeline_frame); + } + + return timeline_frame - seq->start; } -static float seq_cache_frame_index_to_cfra(Sequence *seq, float nfra) +static float seq_cache_frame_index_to_timeline_frame(Sequence *seq, float frame_index) { - return nfra + seq->start; + return frame_index + seq->start; } static SeqCache *seq_cache_get_from_scene(Scene *scene) @@ -846,15 +861,13 @@ static SeqCacheKey *seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCac BKE_sequencer_prefetch_get_time_range(scene, &pfjob_start, &pfjob_end); if (lkey) { - int lkey_cfra = seq_cache_frame_index_to_cfra(lkey->seq, lkey->nfra); - if (lkey_cfra < pfjob_start || lkey_cfra > pfjob_end) { + if (lkey->timeline_frame < pfjob_start || lkey->timeline_frame > pfjob_end) { return lkey; } } if (rkey) { - int rkey_cfra = seq_cache_frame_index_to_cfra(rkey->seq, rkey->nfra); - if (rkey_cfra < pfjob_start || rkey_cfra > pfjob_end) { + if (rkey->timeline_frame < pfjob_start || rkey->timeline_frame > pfjob_end) { return rkey; } } @@ -863,17 +876,14 @@ static SeqCacheKey *seq_cache_choose_key(Scene *scene, SeqCacheKey *lkey, SeqCac } if (rkey && lkey) { - int lkey_cfra = seq_cache_frame_index_to_cfra(lkey->seq, lkey->nfra); - int rkey_cfra = seq_cache_frame_index_to_cfra(rkey->seq, rkey->nfra); - - if (lkey_cfra > rkey_cfra) { + if (lkey->timeline_frame > rkey->timeline_frame) { SeqCacheKey *swapkey = lkey; lkey = rkey; rkey = swapkey; } - int l_diff = scene->r.cfra - lkey_cfra; - int r_diff = rkey_cfra - scene->r.cfra; + int l_diff = scene->r.cfra - lkey->timeline_frame; + int r_diff = rkey->timeline_frame - scene->r.cfra; if (l_diff > r_diff) { finalkey = lkey; @@ -953,8 +963,7 @@ static SeqCacheKey *seq_cache_get_item_for_removal(Scene *scene) if (key->cost <= scene->ed->recycle_max_cost) { cheap_count++; if (lkey) { - if (seq_cache_frame_index_to_cfra(key->seq, key->nfra) < - seq_cache_frame_index_to_cfra(lkey->seq, lkey->nfra)) { + if (key->timeline_frame < lkey->timeline_frame) { lkey = key; } } @@ -962,8 +971,7 @@ static SeqCacheKey *seq_cache_get_item_for_removal(Scene *scene) lkey = key; } if (rkey) { - if (seq_cache_frame_index_to_cfra(key->seq, key->nfra) > - seq_cache_frame_index_to_cfra(rkey->seq, rkey->nfra)) { + if (key->timeline_frame > rkey->timeline_frame) { rkey = key; } } @@ -1074,7 +1082,7 @@ static void seq_cache_create(Main *bmain, Scene *scene) /* ***************************** API ****************************** */ -void BKE_sequencer_cache_free_temp_cache(Scene *scene, short id, int cfra) +void BKE_sequencer_cache_free_temp_cache(Scene *scene, short id, int timeline_frame) { SeqCache *cache = seq_cache_get_from_scene(scene); if (!cache) { @@ -1089,9 +1097,14 @@ void BKE_sequencer_cache_free_temp_cache(Scene *scene, short id, int cfra) SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - if (key->is_temp_cache && key->task_id == id && - seq_cache_frame_index_to_cfra(key->seq, key->nfra) != cfra) { - BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); + if (key->is_temp_cache && key->task_id == id) { + /* Use frame_index here to avoid freeing raw images if they are used for multiple frames. */ + float frame_index = seq_cache_timeline_frame_to_frame_index( + key->seq, timeline_frame, key->type); + if (frame_index != key->frame_index || timeline_frame > key->seq->enddisp || + timeline_frame < key->seq->startdisp) { + BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); + } } } seq_cache_unlock(scene); @@ -1188,10 +1201,9 @@ void BKE_sequencer_cache_cleanup_sequence(Scene *scene, SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - int key_cfra = seq_cache_frame_index_to_cfra(key->seq, key->nfra); - /* Clean all final and composite in intersection of seq and seq_changed. */ - if (key->type & invalidate_composite && key_cfra >= range_start && key_cfra <= range_end) { + if (key->type & invalidate_composite && key->timeline_frame >= range_start && + key->timeline_frame <= range_end) { if (key->link_next || key->link_prev) { seq_cache_relink_keys(key->link_next, key->link_prev); } @@ -1199,8 +1211,9 @@ void BKE_sequencer_cache_cleanup_sequence(Scene *scene, BLI_ghash_remove(cache->hash, key, seq_cache_keyfree, seq_cache_valfree); } - if (key->type & invalidate_source && key->seq == seq && key_cfra >= seq_changed->startdisp && - key_cfra <= seq_changed->enddisp) { + if (key->type & invalidate_source && key->seq == seq && + key->timeline_frame >= seq_changed->startdisp && + key->timeline_frame <= seq_changed->enddisp) { if (key->link_next || key->link_prev) { seq_cache_relink_keys(key->link_next, key->link_prev); } @@ -1212,8 +1225,11 @@ void BKE_sequencer_cache_cleanup_sequence(Scene *scene, seq_cache_unlock(scene); } -struct ImBuf *BKE_sequencer_cache_get( - const SeqRenderData *context, Sequence *seq, float cfra, int type, bool skip_disk_cache) +struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, + Sequence *seq, + float timeline_frame, + int type, + bool skip_disk_cache) { if (context->skip_cache || context->is_proxy_render || !seq) { @@ -1245,7 +1261,7 @@ struct ImBuf *BKE_sequencer_cache_get( if (cache && seq) { key.seq = seq; key.context = *context; - key.nfra = seq_cache_cfra_to_frame_index(seq, cfra); + key.frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type); key.type = type; ibuf = seq_cache_get(cache, &key); @@ -1267,10 +1283,10 @@ struct ImBuf *BKE_sequencer_cache_get( BLI_mutex_unlock(&cache->disk_cache->read_write_mutex); if (ibuf) { if (key.type == SEQ_CACHE_STORE_FINAL_OUT) { - BKE_sequencer_cache_put_if_possible(context, seq, cfra, type, ibuf, 0.0f, true); + BKE_sequencer_cache_put_if_possible(context, seq, timeline_frame, type, ibuf, 0.0f, true); } else { - BKE_sequencer_cache_put(context, seq, cfra, type, ibuf, 0.0f, true); + BKE_sequencer_cache_put(context, seq, timeline_frame, type, ibuf, 0.0f, true); } } } @@ -1280,7 +1296,7 @@ struct ImBuf *BKE_sequencer_cache_get( bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, Sequence *seq, - float cfra, + float timeline_frame, int type, ImBuf *ibuf, float cost, @@ -1299,7 +1315,7 @@ bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, } if (BKE_sequencer_cache_recycle_item(scene)) { - BKE_sequencer_cache_put(context, seq, cfra, type, ibuf, cost, skip_disk_cache); + BKE_sequencer_cache_put(context, seq, timeline_frame, type, ibuf, cost, skip_disk_cache); return true; } @@ -1310,7 +1326,7 @@ bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, void BKE_sequencer_cache_put(const SeqRenderData *context, Sequence *seq, - float cfra, + float timeline_frame, int type, ImBuf *i, float cost, @@ -1330,7 +1346,7 @@ void BKE_sequencer_cache_put(const SeqRenderData *context, } /* Prevent reinserting, it breaks cache key linking. */ - ImBuf *test = BKE_sequencer_cache_get(context, seq, cfra, type, true); + ImBuf *test = BKE_sequencer_cache_get(context, seq, timeline_frame, type, true); if (test) { IMB_freeImBuf(test); return; @@ -1365,7 +1381,8 @@ void BKE_sequencer_cache_put(const SeqRenderData *context, key->cache_owner = cache; key->seq = seq; key->context = *context; - key->nfra = seq_cache_cfra_to_frame_index(seq, cfra); + key->frame_index = seq_cache_timeline_frame_to_frame_index(seq, timeline_frame, type); + key->timeline_frame = timeline_frame; key->type = type; key->cost = cost; key->link_prev = NULL; @@ -1415,11 +1432,14 @@ void BKE_sequencer_cache_put(const SeqRenderData *context, } } -void BKE_sequencer_cache_iterate( - struct Scene *scene, - void *userdata, - bool callback_init(void *userdata, size_t item_count), - bool callback_iter(void *userdata, struct Sequence *seq, int nfra, int cache_type, float cost)) +void BKE_sequencer_cache_iterate(struct Scene *scene, + void *userdata, + bool callback_init(void *userdata, size_t item_count), + bool callback_iter(void *userdata, + struct Sequence *seq, + int timeline_frame, + int cache_type, + float cost)) { SeqCache *cache = seq_cache_get_from_scene(scene); if (!cache) { @@ -1436,7 +1456,7 @@ void BKE_sequencer_cache_iterate( SeqCacheKey *key = BLI_ghashIterator_getKey(&gh_iter); BLI_ghashIterator_step(&gh_iter); - interrupt = callback_iter(userdata, key->seq, key->nfra, key->type, key->cost); + interrupt = callback_iter(userdata, key->seq, key->timeline_frame, key->type, key->cost); } cache->last_key = NULL; diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c index a38fe252731..cb15028cc23 100644 --- a/source/blender/sequencer/intern/modifier.c +++ b/source/blender/sequencer/intern/modifier.c @@ -39,12 +39,16 @@ #include "DNA_sequence_types.h" #include "BKE_colortools.h" -#include "BKE_sequencer.h" #include "IMB_colormanagement.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "SEQ_sequencer.h" + +#include "render.h" +#include "sequencer.h" + static SequenceModifierTypeInfo *modifiersTypes[NUM_SEQUENCE_MODIFIER_TYPES]; static bool modifierTypesInit = false; @@ -79,19 +83,58 @@ typedef struct ModifierThread { modifier_apply_threaded_cb apply_callback; } ModifierThread; +/** + * \a cfra is offset by \a fra_offset only in case we are using a real mask. + */ +static ImBuf *modifier_render_mask_input(const SeqRenderData *context, + int mask_input_type, + Sequence *mask_sequence, + Mask *mask_id, + int cfra, + int fra_offset, + bool make_float) +{ + ImBuf *mask_input = NULL; + + if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) { + if (mask_sequence) { + SeqRenderState state; + seq_render_state_init(&state); + + mask_input = seq_render_strip(context, &state, mask_sequence, cfra); + + if (make_float) { + if (!mask_input->rect_float) { + IMB_float_from_rect(mask_input); + } + } + else { + if (!mask_input->rect) { + IMB_rect_from_float(mask_input); + } + } + } + } + else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) { + mask_input = seq_render_mask(context, mask_id, cfra - fra_offset, make_float); + } + + return mask_input; +} + static ImBuf *modifier_mask_get(SequenceModifierData *smd, const SeqRenderData *context, int cfra, int fra_offset, bool make_float) { - return BKE_sequencer_render_mask_input(context, - smd->mask_input_type, - smd->mask_sequence, - smd->mask_id, - cfra, - fra_offset, - make_float); + return modifier_render_mask_input(context, + smd->mask_input_type, + smd->mask_sequence, + smd->mask_id, + cfra, + fra_offset, + make_float); } static void modifier_init_handle(void *handle_v, int start_line, int tot_line, void *init_data_v) @@ -171,6 +214,291 @@ static void modifier_apply_threaded(ImBuf *ibuf, /** \name Color Balance Modifier * \{ */ +static StripColorBalance calc_cb(StripColorBalance *cb_) +{ + StripColorBalance cb = *cb_; + int c; + + for (c = 0; c < 3; c++) { + cb.lift[c] = 2.0f - cb.lift[c]; + } + + if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) { + for (c = 0; c < 3; c++) { + /* tweak to give more subtle results + * values above 1.0 are scaled */ + if (cb.lift[c] > 1.0f) { + cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0; + } + + cb.lift[c] = 2.0f - cb.lift[c]; + } + } + + if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) { + for (c = 0; c < 3; c++) { + if (cb.gain[c] != 0.0f) { + cb.gain[c] = 1.0f / cb.gain[c]; + } + else { + cb.gain[c] = 1000000; /* should be enough :) */ + } + } + } + + if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) { + for (c = 0; c < 3; c++) { + if (cb.gamma[c] != 0.0f) { + cb.gamma[c] = 1.0f / cb.gamma[c]; + } + else { + cb.gamma[c] = 1000000; /* should be enough :) */ + } + } + } + + return cb; +} + +/* note: lift is actually 2-lift */ +MINLINE float color_balance_fl( + float in, const float lift, const float gain, const float gamma, const float mul) +{ + float x = (((in - 1.0f) * lift) + 1.0f) * gain; + + /* prevent NaN */ + if (x < 0.0f) { + x = 0.0f; + } + + x = powf(x, gamma) * mul; + CLAMP(x, FLT_MIN, FLT_MAX); + return x; +} + +static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul) +{ + int y; + + for (y = 0; y < 256; y++) { + float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); + + table[y] = v; + } +} + +static void color_balance_byte_byte(StripColorBalance *cb_, + unsigned char *rect, + unsigned char *mask_rect, + int width, + int height, + float mul) +{ + // unsigned char cb_tab[3][256]; + unsigned char *cp = rect; + unsigned char *e = cp + width * 4 * height; + unsigned char *m = mask_rect; + + StripColorBalance cb = calc_cb(cb_); + + while (cp < e) { + float p[4]; + int c; + + straight_uchar_to_premul_float(p, cp); + + for (c = 0; c < 3; c++) { + float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + + if (m) { + float m_normal = (float)m[c] / 255.0f; + + p[c] = p[c] * (1.0f - m_normal) + t * m_normal; + } + else { + p[c] = t; + } + } + + premul_float_to_straight_uchar(cp, p); + + cp += 4; + if (m) { + m += 4; + } + } +} + +static void color_balance_byte_float(StripColorBalance *cb_, + unsigned char *rect, + float *rect_float, + unsigned char *mask_rect, + int width, + int height, + float mul) +{ + float cb_tab[4][256]; + int c, i; + unsigned char *p = rect; + unsigned char *e = p + width * 4 * height; + unsigned char *m = mask_rect; + float *o; + StripColorBalance cb; + + o = rect_float; + + cb = calc_cb(cb_); + + for (c = 0; c < 3; c++) { + make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); + } + + for (i = 0; i < 256; i++) { + cb_tab[3][i] = ((float)i) * (1.0f / 255.0f); + } + + while (p < e) { + if (m) { + const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f}; + + p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]]; + p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]]; + p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]]; + + m += 4; + } + else { + o[0] = cb_tab[0][p[0]]; + o[1] = cb_tab[1][p[1]]; + o[2] = cb_tab[2][p[2]]; + } + + o[3] = cb_tab[3][p[3]]; + + p += 4; + o += 4; + } +} + +static void color_balance_float_float(StripColorBalance *cb_, + float *rect_float, + const float *mask_rect_float, + int width, + int height, + float mul) +{ + float *p = rect_float; + const float *e = rect_float + width * 4 * height; + const float *m = mask_rect_float; + StripColorBalance cb = calc_cb(cb_); + + while (p < e) { + int c; + for (c = 0; c < 3; c++) { + float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); + + if (m) { + p[c] = p[c] * (1.0f - m[c]) + t * m[c]; + } + else { + p[c] = t; + } + } + + p += 4; + if (m) { + m += 4; + } + } +} + +typedef struct ColorBalanceInitData { + StripColorBalance *cb; + ImBuf *ibuf; + float mul; + ImBuf *mask; + bool make_float; +} ColorBalanceInitData; + +typedef struct ColorBalanceThread { + StripColorBalance *cb; + float mul; + + int width, height; + + unsigned char *rect, *mask_rect; + float *rect_float, *mask_rect_float; + + bool make_float; +} ColorBalanceThread; + +static void color_balance_init_handle(void *handle_v, + int start_line, + int tot_line, + void *init_data_v) +{ + ColorBalanceThread *handle = (ColorBalanceThread *)handle_v; + ColorBalanceInitData *init_data = (ColorBalanceInitData *)init_data_v; + ImBuf *ibuf = init_data->ibuf; + ImBuf *mask = init_data->mask; + + int offset = 4 * start_line * ibuf->x; + + memset(handle, 0, sizeof(ColorBalanceThread)); + + handle->cb = init_data->cb; + handle->mul = init_data->mul; + handle->width = ibuf->x; + handle->height = tot_line; + handle->make_float = init_data->make_float; + + if (ibuf->rect) { + handle->rect = (unsigned char *)ibuf->rect + offset; + } + + if (ibuf->rect_float) { + handle->rect_float = ibuf->rect_float + offset; + } + + if (mask) { + if (mask->rect) { + handle->mask_rect = (unsigned char *)mask->rect + offset; + } + + if (mask->rect_float) { + handle->mask_rect_float = mask->rect_float + offset; + } + } + else { + handle->mask_rect = NULL; + handle->mask_rect_float = NULL; + } +} + +static void *color_balance_do_thread(void *thread_data_v) +{ + ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v; + StripColorBalance *cb = thread_data->cb; + int width = thread_data->width, height = thread_data->height; + unsigned char *rect = thread_data->rect; + unsigned char *mask_rect = thread_data->mask_rect; + float *rect_float = thread_data->rect_float; + float *mask_rect_float = thread_data->mask_rect_float; + float mul = thread_data->mul; + + if (rect_float) { + color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul); + } + else if (thread_data->make_float) { + color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul); + } + else { + color_balance_byte_byte(cb, rect, mask_rect, width, height, mul); + } + + return NULL; +} + static void colorBalance_init_data(SequenceModifierData *smd) { ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd; @@ -185,11 +513,41 @@ static void colorBalance_init_data(SequenceModifierData *smd) } } +static void modifier_color_balance_apply( + StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input) +{ + ColorBalanceInitData init_data; + + if (!ibuf->rect_float && make_float) { + imb_addrectfloatImBuf(ibuf); + } + + init_data.cb = cb; + init_data.ibuf = ibuf; + init_data.mul = mul; + init_data.make_float = make_float; + init_data.mask = mask_input; + + IMB_processor_apply_threaded(ibuf->y, + sizeof(ColorBalanceThread), + &init_data, + color_balance_init_handle, + color_balance_do_thread); + + /* color balance either happens on float buffer or byte buffer, but never on both, + * free byte buffer if there's float buffer since float buffer would be used for + * color balance in favor of byte buffer + */ + if (ibuf->rect_float && ibuf->rect) { + imb_freerectImBuf(ibuf); + } +} + static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask) { ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *)smd; - BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask); + modifier_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, false, mask); } static SequenceModifierTypeInfo seqModifier_ColorBalance = { @@ -492,7 +850,7 @@ static void hue_correct_apply_threaded(int width, /* adjust value, scaling returned default 0.5 up to 1 */ f = BKE_curvemapping_evaluateF(curve_mapping, 2, hsv[0]); - hsv[2] *= (f * 2.f); + hsv[2] *= (f * 2.0f); hsv[0] = hsv[0] - floorf(hsv[0]); /* mod 1.0 */ CLAMP(hsv[1], 0.0f, 1.0f); @@ -884,7 +1242,7 @@ static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, unsigned char *cp = (unsigned char *)ibuf->rect; float avl, maxl = -FLT_MAX, minl = FLT_MAX; const float sc = 1.0f / p; - float Lav = 0.f; + float Lav = 0.0f; float cav[4] = {0.0f, 0.0f, 0.0f, 0.0f}; while (p--) { float pixel[4]; @@ -1057,7 +1415,7 @@ ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context, if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) { processed_ibuf = IMB_dupImBuf(ibuf); - BKE_sequencer_imbuf_from_sequencer_space(context->scene, processed_ibuf); + SEQ_render_imbuf_from_sequencer_space(context->scene, processed_ibuf); } for (smd = seq->modifiers.first; smd; smd = smd->next) { @@ -1097,7 +1455,7 @@ ImBuf *BKE_sequence_modifier_apply_stack(const SeqRenderData *context, } if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) { - BKE_sequencer_imbuf_to_sequencer_space(context->scene, processed_ibuf, false); + seq_imbuf_to_sequencer_space(context->scene, processed_ibuf, false); } return processed_ibuf; diff --git a/source/blender/sequencer/intern/prefetch.c b/source/blender/sequencer/intern/prefetch.c index 65b2b6c02cf..6eac15dec52 100644 --- a/source/blender/sequencer/intern/prefetch.c +++ b/source/blender/sequencer/intern/prefetch.c @@ -47,13 +47,17 @@ #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_debug.h" #include "DEG_depsgraph_query.h" +#include "SEQ_sequencer.h" + +#include "render.h" +#include "sequencer.h" + typedef struct PrefetchJob { struct PrefetchJob *next, *prev; @@ -283,25 +287,25 @@ static void seq_prefetch_update_context(const SeqRenderData *context) PrefetchJob *pfjob; pfjob = seq_prefetch_job_get(context->scene); - BKE_sequencer_new_render_data(pfjob->bmain_eval, - pfjob->depsgraph, - pfjob->scene_eval, - context->rectx, - context->recty, - context->preview_render_size, - false, - &pfjob->context_cpy); + SEQ_render_new_render_data(pfjob->bmain_eval, + pfjob->depsgraph, + pfjob->scene_eval, + context->rectx, + context->recty, + context->preview_render_size, + false, + &pfjob->context_cpy); pfjob->context_cpy.is_prefetch_render = true; pfjob->context_cpy.task_id = SEQ_TASK_PREFETCH_RENDER; - BKE_sequencer_new_render_data(pfjob->bmain, - pfjob->depsgraph, - pfjob->scene, - context->rectx, - context->recty, - context->preview_render_size, - false, - &pfjob->context); + SEQ_render_new_render_data(pfjob->bmain, + pfjob->depsgraph, + pfjob->scene, + context->rectx, + context->recty, + context->preview_render_size, + false, + &pfjob->context); pfjob->context.is_prefetch_render = false; /* Same ID as prefetch context, because context will be swapped, but we still @@ -358,7 +362,7 @@ static bool seq_prefetch_do_skip_frame(Scene *scene) PrefetchJob *pfjob = seq_prefetch_job_get(scene); float cfra = seq_prefetch_cfra(pfjob); Sequence *seq_arr[MAXSEQ + 1]; - int count = BKE_sequencer_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr); + int count = seq_get_shown_sequences(ed->seqbasep, cfra, 0, seq_arr); SeqRenderData *ctx = &pfjob->context_cpy; ImBuf *ibuf = NULL; @@ -457,7 +461,7 @@ static void *seq_prefetch_frames(void *job) continue; } - ImBuf *ibuf = BKE_sequencer_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0); + ImBuf *ibuf = SEQ_render_give_ibuf(&pfjob->context_cpy, seq_prefetch_cfra(pfjob), 0); BKE_sequencer_cache_free_temp_cache( pfjob->scene, pfjob->context.task_id, seq_prefetch_cfra(pfjob)); IMB_freeImBuf(ibuf); diff --git a/source/blender/sequencer/intern/proxy.c b/source/blender/sequencer/intern/proxy.c new file mode 100644 index 00000000000..94d5f5b701d --- /dev/null +++ b/source/blender/sequencer/intern/proxy.c @@ -0,0 +1,570 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * - Blender Foundation, 2003-2009 + * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 + */ + +/** \file + * \ingroup bke + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_scene_types.h" +#include "DNA_sequence_types.h" +#include "DNA_space_types.h" + +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#ifdef WIN32 +# include "BLI_winstuff.h" +#else +# include <unistd.h> +#endif + +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_main.h" +#include "BKE_scene.h" + +#include "DEG_depsgraph.h" + +#include "SEQ_sequencer.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "IMB_metadata.h" + +#include "proxy.h" +#include "render.h" +#include "sequencer.h" + +typedef struct SeqIndexBuildContext { + struct IndexBuildContext *index_context; + + int tc_flags; + int size_flags; + int quality; + bool overwrite; + int view_id; + + Main *bmain; + Depsgraph *depsgraph; + Scene *scene; + Sequence *seq, *orig_seq; +} SeqIndexBuildContext; + +int SEQ_rendersize_to_proxysize(int render_size) +{ + switch (render_size) { + case SEQ_RENDER_SIZE_PROXY_25: + return IMB_PROXY_25; + case SEQ_RENDER_SIZE_PROXY_50: + return IMB_PROXY_50; + case SEQ_RENDER_SIZE_PROXY_75: + return IMB_PROXY_75; + case SEQ_RENDER_SIZE_PROXY_100: + return IMB_PROXY_100; + } + return IMB_PROXY_NONE; +} + +double SEQ_rendersize_to_scale_factor(int render_size) +{ + switch (render_size) { + case SEQ_RENDER_SIZE_PROXY_25: + return 0.25; + case SEQ_RENDER_SIZE_PROXY_50: + return 0.50; + case SEQ_RENDER_SIZE_PROXY_75: + return 0.75; + } + return 1.0; +} + +bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_id) +{ + char fname[FILE_MAXFILE]; + char suffix[24]; + StripProxy *proxy = seq->strip->proxy; + + if (proxy == NULL) { + return false; + } + + BLI_join_dirfile(fname, PROXY_MAXFILE, proxy->dir, proxy->file); + BLI_path_abs(fname, BKE_main_blendfile_path_from_global()); + + if (view_id > 0) { + BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id); + /* TODO(sergey): This will actually append suffix after extension + * which is weird but how was originally coded in multi-view branch. + */ + BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", fname, suffix); + } + else { + BLI_strncpy(name, fname, PROXY_MAXFILE); + } + + return true; +} + +static bool seq_proxy_get_fname(Editing *ed, + Sequence *seq, + int cfra, + eSpaceSeq_Proxy_RenderSize render_size, + char *name, + const int view_id) +{ + char dir[PROXY_MAXFILE]; + char suffix[24] = {'\0'}; + StripProxy *proxy = seq->strip->proxy; + + if (proxy == NULL) { + return false; + } + + /* Multi-view suffix. */ + if (view_id > 0) { + BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id); + } + + /* Per strip with Custom file situation is handled separately. */ + if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE && + ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE) { + if (seq_proxy_get_custom_file_fname(seq, name, view_id)) { + return true; + } + } + + if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) { + /* Per project default. */ + if (ed->proxy_dir[0] == 0) { + BLI_strncpy(dir, "//BL_proxy", sizeof(dir)); + } + else { /* Per project with custom dir. */ + BLI_strncpy(dir, ed->proxy_dir, sizeof(dir)); + } + BLI_path_abs(name, BKE_main_blendfile_path_from_global()); + } + else { + /* Pre strip with custom dir. */ + if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) { + BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir)); + } + else { /* Per strip default. */ + BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir); + } + } + + /* Proxy size number to be used in path. */ + int proxy_size_number = SEQ_rendersize_to_scale_factor(render_size) * 100; + + BLI_snprintf(name, + PROXY_MAXFILE, + "%s/images/%d/%s_proxy%s", + dir, + proxy_size_number, + SEQ_render_give_stripelem(seq, cfra)->name, + suffix); + BLI_path_abs(name, BKE_main_blendfile_path_from_global()); + strcat(name, ".jpg"); + + return true; +} + +bool SEQ_can_use_proxy(Sequence *seq, int psize) +{ + if (seq->strip->proxy == NULL) { + return false; + } + short size_flags = seq->strip->proxy->build_size_flags; + return (seq->flag & SEQ_USE_PROXY) != 0 && psize != IMB_PROXY_NONE && (size_flags & psize) != 0; +} + +ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra) +{ + char name[PROXY_MAXFILE]; + StripProxy *proxy = seq->strip->proxy; + const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size; + Editing *ed = context->scene->ed; + StripAnim *sanim; + + /* only use proxies, if they are enabled (even if present!) */ + if (!SEQ_can_use_proxy(seq, SEQ_rendersize_to_proxysize(psize))) { + return NULL; + } + + if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { + int frameno = (int)seq_give_stripelem_index(seq, cfra) + seq->anim_startofs; + if (proxy->anim == NULL) { + if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) { + return NULL; + } + + proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name); + } + if (proxy->anim == NULL) { + return NULL; + } + + seq_open_anim_file(context->scene, seq, true); + sanim = seq->anims.first; + + frameno = IMB_anim_index_get_frame_index( + sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno); + + return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); + } + + if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) { + return NULL; + } + + if (BLI_exists(name)) { + ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL); + + if (ibuf) { + seq_imbuf_assign_spaces(context->scene, ibuf); + } + + return ibuf; + } + + return NULL; +} + +static void seq_proxy_build_frame(const SeqRenderData *context, + SeqRenderState *state, + Sequence *seq, + int cfra, + int proxy_render_size, + const bool overwrite) +{ + char name[PROXY_MAXFILE]; + int quality; + int rectx, recty; + int ok; + ImBuf *ibuf_tmp, *ibuf; + Editing *ed = context->scene->ed; + + if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) { + return; + } + + if (!overwrite && BLI_exists(name)) { + return; + } + + ibuf_tmp = seq_render_strip(context, state, seq, cfra); + + rectx = (proxy_render_size * ibuf_tmp->x) / 100; + recty = (proxy_render_size * ibuf_tmp->y) / 100; + + if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) { + ibuf = IMB_dupImBuf(ibuf_tmp); + IMB_metadata_copy(ibuf, ibuf_tmp); + IMB_freeImBuf(ibuf_tmp); + IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty); + } + else { + ibuf = ibuf_tmp; + } + + /* depth = 32 is intentionally left in, otherwise ALPHA channels + * won't work... */ + quality = seq->strip->proxy->quality; + ibuf->ftype = IMB_FTYPE_JPG; + ibuf->foptions.quality = quality; + + /* unsupported feature only confuses other s/w */ + if (ibuf->planes == 32) { + ibuf->planes = 24; + } + + BLI_make_existing_file(name); + + ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); + if (ok == 0) { + perror(name); + } + + IMB_freeImBuf(ibuf); +} + +/** + * Returns whether the file this context would read from even exist, + * if not, don't create the context + */ +static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id) +{ + if ((scene->r.scemode & R_MULTIVIEW) == 0) { + return false; + } + + if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) { + static char prefix[FILE_MAX]; + static const char *ext = NULL; + char str[FILE_MAX]; + + if (view_id == 0) { + char path[FILE_MAX]; + BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name); + BLI_path_abs(path, BKE_main_blendfile_path_from_global()); + BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext); + } + else { + prefix[0] = '\0'; + } + + if (prefix[0] == '\0') { + return view_id != 0; + } + + seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX); + + if (BLI_access(str, R_OK) == 0) { + return false; + } + + return view_id != 0; + } + return false; +} + +/** + * This returns the maximum possible number of required contexts + */ +static int seq_proxy_context_count(Sequence *seq, Scene *scene) +{ + int num_views = 1; + + if ((scene->r.scemode & R_MULTIVIEW) == 0) { + return 1; + } + + switch (seq->type) { + case SEQ_TYPE_MOVIE: { + num_views = BLI_listbase_count(&seq->anims); + break; + } + case SEQ_TYPE_IMAGE: { + switch (seq->views_format) { + case R_IMF_VIEWS_INDIVIDUAL: + num_views = BKE_scene_multiview_num_views_get(&scene->r); + break; + case R_IMF_VIEWS_STEREO_3D: + num_views = 2; + break; + case R_IMF_VIEWS_MULTIVIEW: + /* not supported at the moment */ + /* pass through */ + default: + num_views = 1; + } + break; + } + } + + return num_views; +} + +bool SEQ_proxy_rebuild_context(Main *bmain, + Depsgraph *depsgraph, + Scene *scene, + Sequence *seq, + struct GSet *file_list, + ListBase *queue) +{ + SeqIndexBuildContext *context; + Sequence *nseq; + LinkData *link; + int num_files; + int i; + + if (!seq->strip || !seq->strip->proxy) { + return true; + } + + if (!(seq->flag & SEQ_USE_PROXY)) { + return true; + } + + num_files = seq_proxy_context_count(seq, scene); + + for (i = 0; i < num_files; i++) { + if (seq_proxy_multiview_context_invalid(seq, scene, i)) { + continue; + } + + context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context"); + + nseq = BKE_sequence_dupli_recursive(scene, scene, NULL, seq, 0); + + context->tc_flags = nseq->strip->proxy->build_tc_flags; + context->size_flags = nseq->strip->proxy->build_size_flags; + context->quality = nseq->strip->proxy->quality; + context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0; + + context->bmain = bmain; + context->depsgraph = depsgraph; + context->scene = scene; + context->orig_seq = seq; + context->seq = nseq; + + context->view_id = i; /* only for images */ + + if (nseq->type == SEQ_TYPE_MOVIE) { + StripAnim *sanim; + + seq_open_anim_file(scene, nseq, true); + sanim = BLI_findlink(&nseq->anims, i); + + if (sanim->anim) { + context->index_context = IMB_anim_index_rebuild_context(sanim->anim, + context->tc_flags, + context->size_flags, + context->quality, + context->overwrite, + file_list); + } + if (!context->index_context) { + MEM_freeN(context); + return false; + } + } + + link = BLI_genericNodeN(context); + BLI_addtail(queue, link); + } + return true; +} + +void SEQ_proxy_rebuild(SeqIndexBuildContext *context, + short *stop, + short *do_update, + float *progress) +{ + const bool overwrite = context->overwrite; + SeqRenderData render_context; + Sequence *seq = context->seq; + Scene *scene = context->scene; + Main *bmain = context->bmain; + int cfra; + + if (seq->type == SEQ_TYPE_MOVIE) { + if (context->index_context) { + IMB_anim_index_rebuild(context->index_context, stop, do_update, progress); + } + + return; + } + + if (!(seq->flag & SEQ_USE_PROXY)) { + return; + } + + /* that's why it is called custom... */ + if (seq->strip->proxy && seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { + return; + } + + /* fail safe code */ + + SEQ_render_new_render_data(bmain, + context->depsgraph, + context->scene, + roundf((scene->r.size * (float)scene->r.xsch) / 100.0f), + roundf((scene->r.size * (float)scene->r.ysch) / 100.0f), + 100, + false, + &render_context); + + render_context.skip_cache = true; + render_context.is_proxy_render = true; + render_context.view_id = context->view_id; + + SeqRenderState state; + seq_render_state_init(&state); + + for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) { + if (context->size_flags & IMB_PROXY_25) { + seq_proxy_build_frame(&render_context, &state, seq, cfra, 25, overwrite); + } + if (context->size_flags & IMB_PROXY_50) { + seq_proxy_build_frame(&render_context, &state, seq, cfra, 50, overwrite); + } + if (context->size_flags & IMB_PROXY_75) { + seq_proxy_build_frame(&render_context, &state, seq, cfra, 75, overwrite); + } + if (context->size_flags & IMB_PROXY_100) { + seq_proxy_build_frame(&render_context, &state, seq, cfra, 100, overwrite); + } + + *progress = (float)(cfra - seq->startdisp - seq->startstill) / + (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill); + *do_update = true; + + if (*stop || G.is_break) { + break; + } + } +} + +void SEQ_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop) +{ + if (context->index_context) { + StripAnim *sanim; + + for (sanim = context->seq->anims.first; sanim; sanim = sanim->next) { + IMB_close_anim_proxies(sanim->anim); + } + + for (sanim = context->orig_seq->anims.first; sanim; sanim = sanim->next) { + IMB_close_anim_proxies(sanim->anim); + } + + IMB_anim_index_rebuild_finish(context->index_context, stop); + } + + seq_free_sequence_recurse(NULL, context->seq, true); + + MEM_freeN(context); +} + +void SEQ_proxy_set(struct Sequence *seq, bool value) +{ + if (value) { + seq->flag |= SEQ_USE_PROXY; + if (seq->strip->proxy == NULL) { + seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy"); + seq->strip->proxy->quality = 90; + seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL; + seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25; + } + } + else { + seq->flag &= ~SEQ_USE_PROXY; + } +} diff --git a/source/blender/sequencer/intern/proxy.h b/source/blender/sequencer/intern/proxy.h new file mode 100644 index 00000000000..3777cea9317 --- /dev/null +++ b/source/blender/sequencer/intern/proxy.h @@ -0,0 +1,40 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + */ + +#pragma once + +/** \file + * \ingroup sequencer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct ImBuf; +struct SeqRenderData; +struct Sequence; + +#define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE) +struct ImBuf *seq_proxy_fetch(const struct SeqRenderData *context, struct Sequence *seq, int cfra); +bool seq_proxy_get_custom_file_fname(struct Sequence *seq, char *name, const int view_id); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c new file mode 100644 index 00000000000..c2e04ebeff8 --- /dev/null +++ b/source/blender/sequencer/intern/render.c @@ -0,0 +1,2106 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * - Blender Foundation, 2003-2009 + * - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006 + */ + +/** \file + * \ingroup bke + */ + +#include <time.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_anim_types.h" +#include "DNA_mask_types.h" +#include "DNA_scene_types.h" +#include "DNA_sequence_types.h" +#include "DNA_space_types.h" + +#include "BLI_linklist.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" + +#include "BKE_anim_data.h" +#include "BKE_animsys.h" +#include "BKE_fcurve.h" +#include "BKE_global.h" +#include "BKE_image.h" +#include "BKE_layer.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_mask.h" +#include "BKE_movieclip.h" +#include "BKE_scene.h" +#include "BKE_sequencer_offscreen.h" + +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + +#include "IMB_colormanagement.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "IMB_metadata.h" + +#include "RNA_access.h" + +#include "RE_engine.h" +#include "RE_pipeline.h" + +#include "SEQ_sequencer.h" + +#include "proxy.h" +#include "render.h" +#include "sequencer.h" + +static ImBuf *seq_render_strip_stack(const SeqRenderData *context, + SeqRenderState *state, + ListBase *seqbasep, + float cfra, + int chanshown); + +static ThreadMutex seq_render_mutex = BLI_MUTEX_INITIALIZER; +SequencerDrawView sequencer_view3d_fn = NULL; /* NULL in background mode */ + +/* -------------------------------------------------------------------- */ +/** \name Colorspace utility functions + * \{ */ +void seq_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) +{ +#if 0 + /* Bute buffer is supposed to be in sequencer working space already. */ + if (ibuf->rect != NULL) { + IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name); + } +#endif + if (ibuf->rect_float != NULL) { + IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name); + } +} + +void seq_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float) +{ + /* Early output check: if both buffers are NULL we have nothing to convert. */ + if (ibuf->rect_float == NULL && ibuf->rect == NULL) { + return; + } + /* Get common conversion settings. */ + const char *to_colorspace = scene->sequencer_colorspace_settings.name; + /* Perform actual conversion logic. */ + if (ibuf->rect_float == NULL) { + /* We are not requested to give float buffer and byte buffer is already + * in thee required colorspace. Can skip doing anything here. + */ + const char *from_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf); + if (!make_float && STREQ(from_colorspace, to_colorspace)) { + return; + } + if (false) { + /* The idea here is to provide as fast playback as possible and + * enforcing float buffer here (a) uses more cache memory (b) might + * make some other effects slower to apply. + * + * However, this might also have negative effect by adding weird + * artifacts which will then not happen in final render. + */ + IMB_colormanagement_transform_byte_threaded((unsigned char *)ibuf->rect, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + to_colorspace); + } + else { + /* We perform conversion to a float buffer so we don't worry about + * precision loss. + */ + imb_addrectfloatImBuf(ibuf); + IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float, + (unsigned char *)ibuf->rect, + ibuf->x, + ibuf->y, + ibuf->channels, + from_colorspace, + to_colorspace); + /* We don't need byte buffer anymore. */ + imb_freerectImBuf(ibuf); + } + } + else { + const char *from_colorspace = IMB_colormanagement_get_float_colorspace(ibuf); + /* Unknown input color space, can't perform conversion. */ + if (from_colorspace == NULL || from_colorspace[0] == '\0') { + return; + } + /* We don't want both byte and float buffers around: they'll either run + * out of sync or conversion of byte buffer will lose precision in there. + */ + if (ibuf->rect != NULL) { + imb_freerectImBuf(ibuf); + } + IMB_colormanagement_transform_threaded( + ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); + } + seq_imbuf_assign_spaces(scene, ibuf); +} + +void SEQ_render_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) +{ + const char *from_colorspace = scene->sequencer_colorspace_settings.name; + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( + COLOR_ROLE_SCENE_LINEAR); + + if (!ibuf->rect_float) { + return; + } + + if (to_colorspace && to_colorspace[0] != '\0') { + IMB_colormanagement_transform_threaded( + ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); + IMB_colormanagement_assign_float_colorspace(ibuf, to_colorspace); + } +} + +void SEQ_render_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]) +{ + const char *from_colorspace = scene->sequencer_colorspace_settings.name; + const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( + COLOR_ROLE_SCENE_LINEAR); + + if (to_colorspace && to_colorspace[0] != '\0') { + IMB_colormanagement_transform_v4(pixel, from_colorspace, to_colorspace); + } + else { + /* if no color management enables fallback to legacy conversion */ + srgb_to_linearrgb_v4(pixel, pixel); + } +} + +void SEQ_render_init_colorspace(Sequence *seq) +{ + if (seq->strip && seq->strip->stripdata) { + char name[FILE_MAX]; + ImBuf *ibuf; + + BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name); + BLI_path_abs(name, BKE_main_blendfile_path_from_global()); + + /* initialize input color space */ + if (seq->type == SEQ_TYPE_IMAGE) { + ibuf = IMB_loadiffname( + name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name); + + /* byte images are default to straight alpha, however sequencer + * works in premul space, so mark strip to be premultiplied first + */ + seq->alpha_mode = SEQ_ALPHA_STRAIGHT; + if (ibuf) { + if (ibuf->flags & IB_alphamode_premul) { + seq->alpha_mode = IMA_ALPHA_PREMUL; + } + + IMB_freeImBuf(ibuf); + } + } + } +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Rendering utility functions + * \{ */ +void SEQ_render_new_render_data(Main *bmain, + struct Depsgraph *depsgraph, + Scene *scene, + int rectx, + int recty, + int preview_render_size, + int for_render, + SeqRenderData *r_context) +{ + r_context->bmain = bmain; + r_context->depsgraph = depsgraph; + r_context->scene = scene; + r_context->rectx = rectx; + r_context->recty = recty; + r_context->preview_render_size = preview_render_size; + r_context->for_render = for_render; + r_context->motion_blur_samples = 0; + r_context->motion_blur_shutter = 0; + r_context->skip_cache = false; + r_context->is_proxy_render = false; + r_context->view_id = 0; + r_context->gpu_offscreen = NULL; + r_context->task_id = SEQ_TASK_MAIN_RENDER; + r_context->is_prefetch_render = false; +} + +void seq_render_state_init(SeqRenderState *state) +{ + state->scene_parents = NULL; +} + +float seq_give_stripelem_index(Sequence *seq, float cfra) +{ + float nr; + int sta = seq->start; + int end = seq->start + seq->len - 1; + + if (seq->type & SEQ_TYPE_EFFECT) { + end = seq->enddisp; + } + + if (end < sta) { + return -1; + } + + if (seq->flag & SEQ_REVERSE_FRAMES) { + /*reverse frame in this sequence */ + if (cfra <= sta) { + nr = end - sta; + } + else if (cfra >= end) { + nr = 0; + } + else { + nr = end - cfra; + } + } + else { + if (cfra <= sta) { + nr = 0; + } + else if (cfra >= end) { + nr = end - sta; + } + else { + nr = cfra - sta; + } + } + + if (seq->strobe < 1.0f) { + seq->strobe = 1.0f; + } + + if (seq->strobe > 1.0f) { + nr -= fmodf((double)nr, (double)seq->strobe); + } + + return nr; +} + +StripElem *SEQ_render_give_stripelem(Sequence *seq, int cfra) +{ + StripElem *se = seq->strip->stripdata; + + if (seq->type == SEQ_TYPE_IMAGE) { + /* only IMAGE strips use the whole array, MOVIE strips use only the first element, + * all other strips don't use this... + */ + + int nr = (int)seq_give_stripelem_index(seq, cfra); + + if (nr == -1 || se == NULL) { + return NULL; + } + + se += nr + seq->anim_startofs; + } + return se; +} + +static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra, int chanshown) +{ + /* Use arbitrary sized linked list, the size could be over MAXSEQ. */ + LinkNodePair effect_inputs = {NULL, NULL}; + int totseq = 0; + + memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1)); + + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + if ((seq->startdisp <= cfra) && (seq->enddisp > cfra)) { + if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SEQ_MUTE)) { + + if (seq->seq1) { + BLI_linklist_append_alloca(&effect_inputs, seq->seq1); + } + + if (seq->seq2) { + BLI_linklist_append_alloca(&effect_inputs, seq->seq2); + } + + if (seq->seq3) { + BLI_linklist_append_alloca(&effect_inputs, seq->seq3); + } + } + + seq_arr[seq->machine] = seq; + totseq++; + } + } + + /* Drop strips which are used for effect inputs, we don't want + * them to blend into render stack in any other way than effect + * string rendering. */ + for (LinkNode *seq_item = effect_inputs.list; seq_item; seq_item = seq_item->next) { + Sequence *seq = seq_item->link; + /* It's possible that effect strip would be placed to the same + * 'machine' as its inputs. We don't want to clear such strips + * from the stack. */ + if (seq_arr[seq->machine] && seq_arr[seq->machine]->type & SEQ_TYPE_EFFECT) { + continue; + } + /* If we're shown a specified channel, then we want to see the strips + * which belongs to this machine. */ + if (chanshown != 0 && chanshown <= seq->machine) { + continue; + } + seq_arr[seq->machine] = NULL; + } + + return totseq; +} + +int SEQ_render_evaluate_frame(Scene *scene, int cfra) +{ + Editing *ed = BKE_sequencer_editing_get(scene, false); + Sequence *seq_arr[MAXSEQ + 1]; + + if (ed == NULL) { + return 0; + } + + return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra, 0); +} + +static bool video_seq_is_rendered(Sequence *seq) +{ + return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM); +} + +int seq_get_shown_sequences(ListBase *seqbasep, int cfra, int chanshown, Sequence **seq_arr_out) +{ + Sequence *seq_arr[MAXSEQ + 1]; + int b = chanshown; + int cnt = 0; + + if (b > MAXSEQ) { + return 0; + } + + if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra, chanshown)) { + if (b == 0) { + b = MAXSEQ; + } + for (; b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + break; + } + } + } + + chanshown = b; + + for (; b > 0; b--) { + if (video_seq_is_rendered(seq_arr[b])) { + if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) { + break; + } + } + } + + for (; b <= chanshown && b >= 0; b++) { + if (video_seq_is_rendered(seq_arr[b])) { + seq_arr_out[cnt++] = seq_arr[b]; + } + } + + return cnt; +} + +/* Estimate time spent by the program rendering the strip */ +static clock_t seq_estimate_render_cost_begin(void) +{ + return clock(); +} + +static float seq_estimate_render_cost_end(Scene *scene, clock_t begin) +{ + clock_t end = clock(); + float time_spent = (float)(end - begin); + float time_max = (1.0f / scene->r.frs_sec) * CLOCKS_PER_SEC; + + if (time_max != 0) { + return time_spent / time_max; + } + + return 1; +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Preprocessing and effects + * \{ */ +/* + * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE + * + * Do all the things you can't really do afterwards using sequence effects + * (read: before rescaling to render resolution has been done) + * + * Order is important! + * + * - Deinterlace + * - Crop and transform in image source coordinate space + * - Flip X + Flip Y (could be done afterwards, backward compatibility) + * - Promote image to float data (affects pipeline operations afterwards) + * - Color balance (is most efficient in the byte -> float + * (future: half -> float should also work fine!) + * case, if done on load, since we can use lookup tables) + * - Premultiply + */ + +static bool sequencer_use_transform(const Sequence *seq) +{ + const StripTransform *transform = seq->strip->transform; + + if (transform->xofs != 0 || transform->yofs != 0 || transform->scale_x != 1 || + transform->scale_y != 1 || transform->rotation != 0) { + return true; + } + + return false; +} + +static bool sequencer_use_crop(const Sequence *seq) +{ + const StripCrop *crop = seq->strip->crop; + if (crop->left > 0 || crop->right > 0 || crop->top > 0 || crop->bottom > 0) { + return true; + } + + return false; +} + +static bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, + Sequence *seq, + float UNUSED(cfra)) +{ + float mul; + + if (context && context->is_proxy_render) { + return false; + } + + if ((seq->flag & (SEQ_FILTERY | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) || + sequencer_use_crop(seq) || sequencer_use_transform(seq)) { + return true; + } + + mul = seq->mul; + + if (seq->blend_mode == SEQ_BLEND_REPLACE) { + mul *= seq->blend_opacity / 100.0f; + } + + if (mul != 1.0f) { + return true; + } + + if (seq->sat != 1.0f) { + return true; + } + + if (seq->modifiers.first) { + return true; + } + + return false; +} + +typedef struct ImageTransformThreadInitData { + ImBuf *ibuf_source; + ImBuf *ibuf_out; + StripTransform *transform; + float scale_to_fit; + float image_scale_factor; + bool for_render; +} ImageTransformThreadInitData; + +typedef struct ImageTransformThreadData { + ImBuf *ibuf_source; + ImBuf *ibuf_out; + StripTransform *transform; + float scale_to_fit; + float image_scale_factor; + bool for_render; + int start_line; + int tot_line; +} ImageTransformThreadData; + +static void sequencer_image_transform_init(void *handle_v, + int start_line, + int tot_line, + void *init_data_v) +{ + ImageTransformThreadData *handle = (ImageTransformThreadData *)handle_v; + const ImageTransformThreadInitData *init_data = (ImageTransformThreadInitData *)init_data_v; + + handle->ibuf_source = init_data->ibuf_source; + handle->ibuf_out = init_data->ibuf_out; + handle->transform = init_data->transform; + handle->scale_to_fit = init_data->scale_to_fit; + handle->image_scale_factor = init_data->image_scale_factor; + handle->for_render = init_data->for_render; + + handle->start_line = start_line; + handle->tot_line = tot_line; +} + +static void *sequencer_image_transform_do_thread(void *data_v) +{ + const ImageTransformThreadData *data = (ImageTransformThreadData *)data_v; + const StripTransform *transform = data->transform; + const float scale_x = transform->scale_x * data->scale_to_fit; + const float scale_y = transform->scale_y * data->scale_to_fit; + const float scale_to_fit_offs_x = (data->ibuf_out->x - data->ibuf_source->x) / 2; + const float scale_to_fit_offs_y = (data->ibuf_out->y - data->ibuf_source->y) / 2; + const float translate_x = transform->xofs * data->image_scale_factor + scale_to_fit_offs_x; + const float translate_y = transform->yofs * data->image_scale_factor + scale_to_fit_offs_y; + const int width = data->ibuf_out->x; + const int height = data->ibuf_out->y; + const float pivot[2] = {width / 2 - scale_to_fit_offs_x, height / 2 - scale_to_fit_offs_y}; + float transform_matrix[3][3]; + loc_rot_size_to_mat3(transform_matrix, + (const float[]){translate_x, translate_y}, + transform->rotation, + (const float[]){scale_x, scale_y}); + invert_m3(transform_matrix); + transform_pivot_set_m3(transform_matrix, pivot); + + for (int yi = data->start_line; yi < data->start_line + data->tot_line; yi++) { + for (int xi = 0; xi < width; xi++) { + float uv[2] = {xi, yi}; + mul_v2_m3v2(uv, transform_matrix, uv); + + if (data->for_render) { + bilinear_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi); + } + else { + nearest_interpolation(data->ibuf_source, data->ibuf_out, uv[0], uv[1], xi, yi); + } + } + } + + return NULL; +} + +static void multibuf(ImBuf *ibuf, const float fmul) +{ + char *rt; + float *rt_float; + + int a; + + rt = (char *)ibuf->rect; + rt_float = ibuf->rect_float; + + if (rt) { + const int imul = (int)(256.0f * fmul); + a = ibuf->x * ibuf->y; + while (a--) { + rt[0] = min_ii((imul * rt[0]) >> 8, 255); + rt[1] = min_ii((imul * rt[1]) >> 8, 255); + rt[2] = min_ii((imul * rt[2]) >> 8, 255); + rt[3] = min_ii((imul * rt[3]) >> 8, 255); + + rt += 4; + } + } + if (rt_float) { + a = ibuf->x * ibuf->y; + while (a--) { + rt_float[0] *= fmul; + rt_float[1] *= fmul; + rt_float[2] *= fmul; + rt_float[3] *= fmul; + + rt_float += 4; + } + } +} + +static ImBuf *input_preprocess(const SeqRenderData *context, + Sequence *seq, + float cfra, + ImBuf *ibuf, + const bool UNUSED(is_proxy_image)) +{ + Scene *scene = context->scene; + ImBuf *preprocessed_ibuf = NULL; + + /* Deinterlace. */ + if ((seq->flag & SEQ_FILTERY) && !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) { + /* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */ + preprocessed_ibuf = IMB_makeSingleUser(ibuf); + ibuf = preprocessed_ibuf; + + IMB_filtery(preprocessed_ibuf); + } + + /* Calculate scale factor, so image fits in preview area with original aspect ratio. */ + const float scale_to_fit_factor = MIN2((float)context->rectx / (float)ibuf->x, + (float)context->recty / (float)ibuf->y); + + /* Get scale factor if preview resolution doesn't match project resolution. */ + float preview_scale_factor; + if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) { + preview_scale_factor = (float)scene->r.size / 100; + } + else { + preview_scale_factor = SEQ_rendersize_to_scale_factor(context->preview_render_size); + } + + if (sequencer_use_crop(seq)) { + /* Change original image pointer to avoid another duplication in SEQ_USE_TRANSFORM. */ + preprocessed_ibuf = IMB_makeSingleUser(ibuf); + ibuf = preprocessed_ibuf; + + const int width = ibuf->x; + const int height = ibuf->y; + const StripCrop *c = seq->strip->crop; + + const int left = c->left / scale_to_fit_factor * preview_scale_factor; + const int right = c->right / scale_to_fit_factor * preview_scale_factor; + const int top = c->top / scale_to_fit_factor * preview_scale_factor; + const int bottom = c->bottom / scale_to_fit_factor * preview_scale_factor; + const float col[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + + /* Left. */ + IMB_rectfill_area_replace(preprocessed_ibuf, col, 0, 0, left, height); + /* Bottom. */ + IMB_rectfill_area_replace(preprocessed_ibuf, col, left, 0, width, bottom); + /* Right. */ + IMB_rectfill_area_replace(preprocessed_ibuf, col, width - right, bottom, width, height); + /* Top. */ + IMB_rectfill_area_replace(preprocessed_ibuf, col, left, height - top, width - right, height); + } + + if (sequencer_use_transform(seq) || context->rectx != ibuf->x || context->recty != ibuf->y) { + const int x = context->rectx; + const int y = context->recty; + preprocessed_ibuf = IMB_allocImBuf(x, y, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); + + ImageTransformThreadInitData init_data = {NULL}; + init_data.ibuf_source = ibuf; + init_data.ibuf_out = preprocessed_ibuf; + init_data.transform = seq->strip->transform; + init_data.scale_to_fit = scale_to_fit_factor; + init_data.image_scale_factor = preview_scale_factor; + init_data.for_render = context->for_render; + IMB_processor_apply_threaded(context->recty, + sizeof(ImageTransformThreadData), + &init_data, + sequencer_image_transform_init, + sequencer_image_transform_do_thread); + seq_imbuf_assign_spaces(scene, preprocessed_ibuf); + IMB_metadata_copy(preprocessed_ibuf, ibuf); + IMB_freeImBuf(ibuf); + } + + /* Duplicate ibuf if we still have original. */ + if (preprocessed_ibuf == NULL) { + preprocessed_ibuf = IMB_makeSingleUser(ibuf); + } + + if (seq->flag & SEQ_FLIPX) { + IMB_flipx(preprocessed_ibuf); + } + + if (seq->flag & SEQ_FLIPY) { + IMB_flipy(preprocessed_ibuf); + } + + if (seq->sat != 1.0f) { + IMB_saturation(preprocessed_ibuf, seq->sat); + } + + if (seq->flag & SEQ_MAKE_FLOAT) { + if (!preprocessed_ibuf->rect_float) { + seq_imbuf_to_sequencer_space(scene, preprocessed_ibuf, true); + } + + if (preprocessed_ibuf->rect) { + imb_freerectImBuf(preprocessed_ibuf); + } + } + + float mul = seq->mul; + if (seq->blend_mode == SEQ_BLEND_REPLACE) { + mul *= seq->blend_opacity / 100.0f; + } + + if (mul != 1.0f) { + multibuf(preprocessed_ibuf, mul); + } + + if (seq->modifiers.first) { + ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, preprocessed_ibuf, cfra); + + if (ibuf_new != preprocessed_ibuf) { + IMB_metadata_copy(ibuf_new, preprocessed_ibuf); + IMB_freeImBuf(preprocessed_ibuf); + preprocessed_ibuf = ibuf_new; + } + } + + return preprocessed_ibuf; +} + +static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, + Sequence *seq, + ImBuf *ibuf, + float cfra, + clock_t begin, + bool use_preprocess, + const bool is_proxy_image) +{ + if (context->is_proxy_render == false && + (ibuf->x != context->rectx || ibuf->y != context->recty)) { + use_preprocess = true; + } + + if (use_preprocess) { + float cost = seq_estimate_render_cost_end(context->scene, begin); + + /* TODO(Richard): It should be possible to store in cache if image is proxy, + * but it adds quite a bit of complexity. Since proxies are fast to read, I would + * rather simplify existing code a bit. */ + if (!is_proxy_image) { + BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false); + } + + /* Reset timer so we can get partial render time. */ + begin = seq_estimate_render_cost_begin(); + ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image); + } + + float cost = seq_estimate_render_cost_end(context->scene, begin); + BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost, false); + return ibuf; +} + +typedef struct RenderEffectInitData { + struct SeqEffectHandle *sh; + const SeqRenderData *context; + Sequence *seq; + float cfra, facf0, facf1; + ImBuf *ibuf1, *ibuf2, *ibuf3; + + ImBuf *out; +} RenderEffectInitData; + +typedef struct RenderEffectThread { + struct SeqEffectHandle *sh; + const SeqRenderData *context; + Sequence *seq; + float cfra, facf0, facf1; + ImBuf *ibuf1, *ibuf2, *ibuf3; + + ImBuf *out; + int start_line, tot_line; +} RenderEffectThread; + +static void render_effect_execute_init_handle(void *handle_v, + int start_line, + int tot_line, + void *init_data_v) +{ + RenderEffectThread *handle = (RenderEffectThread *)handle_v; + RenderEffectInitData *init_data = (RenderEffectInitData *)init_data_v; + + handle->sh = init_data->sh; + handle->context = init_data->context; + handle->seq = init_data->seq; + handle->cfra = init_data->cfra; + handle->facf0 = init_data->facf0; + handle->facf1 = init_data->facf1; + handle->ibuf1 = init_data->ibuf1; + handle->ibuf2 = init_data->ibuf2; + handle->ibuf3 = init_data->ibuf3; + handle->out = init_data->out; + + handle->start_line = start_line; + handle->tot_line = tot_line; +} + +static void *render_effect_execute_do_thread(void *thread_data_v) +{ + RenderEffectThread *thread_data = (RenderEffectThread *)thread_data_v; + + thread_data->sh->execute_slice(thread_data->context, + thread_data->seq, + thread_data->cfra, + thread_data->facf0, + thread_data->facf1, + thread_data->ibuf1, + thread_data->ibuf2, + thread_data->ibuf3, + thread_data->start_line, + thread_data->tot_line, + thread_data->out); + + return NULL; +} + +ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, + const SeqRenderData *context, + Sequence *seq, + float cfra, + float facf0, + float facf1, + ImBuf *ibuf1, + ImBuf *ibuf2, + ImBuf *ibuf3) +{ + RenderEffectInitData init_data; + ImBuf *out = sh->init_execution(context, ibuf1, ibuf2, ibuf3); + + init_data.sh = sh; + init_data.context = context; + init_data.seq = seq; + init_data.cfra = cfra; + init_data.facf0 = facf0; + init_data.facf1 = facf1; + init_data.ibuf1 = ibuf1; + init_data.ibuf2 = ibuf2; + init_data.ibuf3 = ibuf3; + init_data.out = out; + + IMB_processor_apply_threaded(out->y, + sizeof(RenderEffectThread), + &init_data, + render_effect_execute_init_handle, + render_effect_execute_do_thread); + + return out; +} + +static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, + SeqRenderState *state, + Sequence *seq, + float cfra) +{ + Scene *scene = context->scene; + float fac, facf; + int early_out; + int i; + struct SeqEffectHandle sh = BKE_sequence_get_effect(seq); + FCurve *fcu = NULL; + ImBuf *ibuf[3]; + Sequence *input[3]; + ImBuf *out = NULL; + + ibuf[0] = ibuf[1] = ibuf[2] = NULL; + + input[0] = seq->seq1; + input[1] = seq->seq2; + input[2] = seq->seq3; + + if (!sh.execute && !(sh.execute_slice && sh.init_execution)) { + /* effect not supported in this version... */ + out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + return out; + } + + if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { + sh.get_default_fac(seq, cfra, &fac, &facf); + facf = fac; + } + else { + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL); + if (fcu) { + fac = facf = evaluate_fcurve(fcu, cfra); + } + else { + fac = facf = seq->effect_fader; + } + } + + early_out = sh.early_out(seq, fac, facf); + + switch (early_out) { + case EARLY_NO_INPUT: + out = sh.execute(context, seq, cfra, fac, facf, NULL, NULL, NULL); + break; + case EARLY_DO_EFFECT: + for (i = 0; i < 3; i++) { + /* Speed effect requires time remapping of `cfra` for input(s). */ + if (input[0] && seq->type == SEQ_TYPE_SPEED) { + float target_frame = BKE_sequencer_speed_effect_target_frame_get(context, seq, cfra, i); + ibuf[i] = seq_render_strip(context, state, input[0], target_frame); + } + else { /* Other effects. */ + if (input[i]) { + ibuf[i] = seq_render_strip(context, state, input[i], cfra); + } + } + } + + if (ibuf[0] && (ibuf[1] || BKE_sequence_effect_get_num_inputs(seq->type) == 1)) { + if (sh.multithreaded) { + out = seq_render_effect_execute_threaded( + &sh, context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]); + } + else { + out = sh.execute(context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]); + } + } + break; + case EARLY_USE_INPUT_1: + if (input[0]) { + out = seq_render_strip(context, state, input[0], cfra); + } + break; + case EARLY_USE_INPUT_2: + if (input[1]) { + out = seq_render_strip(context, state, input[1], cfra); + } + break; + } + + for (i = 0; i < 3; i++) { + IMB_freeImBuf(ibuf[i]); + } + + if (out == NULL) { + out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + } + + return out; +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Individual strip rendering functions + * \{ */ +/** + * Render individual view for multi-view or single (default view) for mono-view. + */ +static ImBuf *seq_render_image_strip_view(const SeqRenderData *context, + Sequence *seq, + char *name, + char *prefix, + const char *ext, + int view_id) +{ + + ImBuf *ibuf = NULL; + + int flag = IB_rect | IB_metadata; + if (seq->alpha_mode == SEQ_ALPHA_PREMUL) { + flag |= IB_alphamode_premul; + } + + if (prefix[0] == '\0') { + ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name); + } + else { + char str[FILE_MAX]; + BKE_scene_multiview_view_prefix_get(context->scene, name, prefix, &ext); + seq_multiview_name(context->scene, view_id, prefix, ext, str, FILE_MAX); + ibuf = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name); + } + + if (ibuf == NULL) { + return NULL; + } + + /* We don't need both (speed reasons)! */ + if (ibuf->rect_float != NULL && ibuf->rect != NULL) { + imb_freerectImBuf(ibuf); + } + + /* All sequencer color is done in SRGB space, linear gives odd cross-fades. */ + seq_imbuf_to_sequencer_space(context->scene, ibuf, false); + + return ibuf; +} + +static bool seq_image_strip_is_multiview_render( + Scene *scene, Sequence *seq, int totfiles, char *name, char *r_prefix, const char *r_ext) +{ + if (totfiles > 1) { + BKE_scene_multiview_view_prefix_get(scene, name, r_prefix, &r_ext); + if (r_prefix[0] == '\0') { + return false; + } + } + else { + r_prefix[0] = '\0'; + } + + return (seq->flag & SEQ_USE_VIEWS) != 0 && (scene->r.scemode & R_MULTIVIEW) != 0; +} + +static ImBuf *seq_render_image_strip(const SeqRenderData *context, + Sequence *seq, + float UNUSED(nr), + float cfra, + bool *r_is_proxy_image) +{ + char name[FILE_MAX]; + const char *ext = NULL; + char prefix[FILE_MAX]; + ImBuf *ibuf = NULL; + + StripElem *s_elem = SEQ_render_give_stripelem(seq, cfra); + if (s_elem == NULL) { + return NULL; + } + + BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name); + BLI_path_abs(name, BKE_main_blendfile_path_from_global()); + + /* Try to get a proxy image. */ + ibuf = seq_proxy_fetch(context, seq, cfra); + if (ibuf != NULL) { + s_elem->orig_width = ibuf->x; + s_elem->orig_height = ibuf->y; + *r_is_proxy_image = true; + return ibuf; + } + + /* Proxy not found, render original. */ + const int totfiles = seq_num_files(context->scene, seq->views_format, true); + bool is_multiview_render = seq_image_strip_is_multiview_render( + context->scene, seq, totfiles, name, prefix, ext); + + if (is_multiview_render) { + int totviews = BKE_scene_multiview_num_views_get(&context->scene->r); + ImBuf **ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); + + for (int view_id = 0; view_id < totfiles; view_id++) { + ibufs_arr[view_id] = seq_render_image_strip_view(context, seq, name, prefix, ext, view_id); + } + + if (ibufs_arr[0] == NULL) { + return NULL; + } + + if (seq->views_format == R_IMF_VIEWS_STEREO_3D) { + IMB_ImBufFromStereo3d(seq->stereo3d_format, ibufs_arr[0], &ibufs_arr[0], &ibufs_arr[1]); + } + + for (int view_id = 0; view_id < totviews; view_id++) { + SeqRenderData localcontext = *context; + localcontext.view_id = view_id; + + if (view_id != context->view_id) { + ibufs_arr[view_id] = seq_render_preprocess_ibuf( + &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false); + } + } + + /* Return the original requested ImBuf. */ + ibuf = ibufs_arr[context->view_id]; + + /* Remove the others (decrease their refcount). */ + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibufs_arr[view_id] != ibuf) { + IMB_freeImBuf(ibufs_arr[view_id]); + } + } + + MEM_freeN(ibufs_arr); + } + else { + ibuf = seq_render_image_strip_view(context, seq, name, prefix, ext, context->view_id); + } + + if (ibuf == NULL) { + return NULL; + } + + s_elem->orig_width = ibuf->x; + s_elem->orig_height = ibuf->y; + + return ibuf; +} + +static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *context, + Sequence *seq, + int cfra) +{ + char name[PROXY_MAXFILE]; + StripProxy *proxy = seq->strip->proxy; + + if (proxy->anim == NULL) { + if (seq_proxy_get_custom_file_fname(seq, name, context->view_id)) { + proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name); + } + if (proxy->anim == NULL) { + return NULL; + } + } + + int frameno = (int)seq_give_stripelem_index(seq, cfra) + seq->anim_startofs; + return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); +} + +/** + * Render individual view for multi-view or single (default view) for mono-view. + */ +static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context, + Sequence *seq, + float nr, + float cfra, + StripAnim *sanim, + bool *r_is_proxy_image) +{ + ImBuf *ibuf = NULL; + IMB_Proxy_Size psize = SEQ_rendersize_to_proxysize(context->preview_render_size); + + IMB_anim_set_preseek(sanim->anim, seq->anim_preseek); + + if (SEQ_can_use_proxy(seq, psize)) { + /* Try to get a proxy image. + * Movie proxies are handled by ImBuf module with exception of `custom file` setting. */ + if (context->scene->ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE && + seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { + ibuf = seq_render_movie_strip_custom_file_proxy(context, seq, cfra); + } + else { + ibuf = IMB_anim_absolute(sanim->anim, + nr + seq->anim_startofs, + seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, + psize); + } + + if (ibuf != NULL) { + *r_is_proxy_image = true; + } + } + + /* Fetching for requested proxy size failed, try fetching the original instead. */ + if (ibuf == NULL) { + ibuf = IMB_anim_absolute(sanim->anim, + nr + seq->anim_startofs, + seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, + IMB_PROXY_NONE); + } + if (ibuf == NULL) { + return NULL; + } + + seq_imbuf_to_sequencer_space(context->scene, ibuf, false); + + /* We don't need both (speed reasons)! */ + if (ibuf->rect_float != NULL && ibuf->rect != NULL) { + imb_freerectImBuf(ibuf); + } + + return ibuf; +} + +static ImBuf *seq_render_movie_strip( + const SeqRenderData *context, Sequence *seq, float nr, float cfra, bool *r_is_proxy_image) +{ + /* Load all the videos. */ + seq_open_anim_file(context->scene, seq, false); + + ImBuf *ibuf = NULL; + StripAnim *sanim = seq->anims.first; + const int totfiles = seq_num_files(context->scene, seq->views_format, true); + bool is_multiview_render = (seq->flag & SEQ_USE_VIEWS) != 0 && + (context->scene->r.scemode & R_MULTIVIEW) != 0 && + BLI_listbase_count_at_most(&seq->anims, totfiles + 1) == totfiles; + + if (is_multiview_render) { + ImBuf **ibuf_arr; + int totviews = BKE_scene_multiview_num_views_get(&context->scene->r); + ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); + int ibuf_view_id; + + for (ibuf_view_id = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, ibuf_view_id++) { + if (sanim->anim) { + ibuf_arr[ibuf_view_id] = seq_render_movie_strip_view( + context, seq, nr, cfra, sanim, r_is_proxy_image); + } + } + + if (seq->views_format == R_IMF_VIEWS_STEREO_3D) { + if (ibuf_arr[0] == NULL) { + /* Probably proxy hasn't been created yet. */ + MEM_freeN(ibuf_arr); + return NULL; + } + + IMB_ImBufFromStereo3d(seq->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); + } + + for (int view_id = 0; view_id < totviews; view_id++) { + SeqRenderData localcontext = *context; + localcontext.view_id = view_id; + + if (view_id != context->view_id) { + ibuf_arr[view_id] = seq_render_preprocess_ibuf( + &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false); + } + } + + /* Return the original requested ImBuf. */ + ibuf = ibuf_arr[context->view_id]; + + /* Remove the others (decrease their refcount). */ + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibuf_arr[view_id] != ibuf) { + IMB_freeImBuf(ibuf_arr[view_id]); + } + } + + MEM_freeN(ibuf_arr); + } + else { + ibuf = seq_render_movie_strip_view(context, seq, nr, cfra, sanim, r_is_proxy_image); + } + + if (ibuf == NULL) { + return NULL; + } + + seq->strip->stripdata->orig_width = ibuf->x; + seq->strip->stripdata->orig_height = ibuf->y; + + return ibuf; +} + +static ImBuf *seq_get_movieclip_ibuf(Sequence *seq, MovieClipUser user) +{ + ImBuf *ibuf = NULL; + float tloc[2], tscale, tangle; + if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_STABILIZED) { + ibuf = BKE_movieclip_get_stable_ibuf(seq->clip, &user, tloc, &tscale, &tangle, 0); + } + else { + ibuf = BKE_movieclip_get_ibuf_flag(seq->clip, &user, seq->clip->flag, MOVIECLIP_CACHE_SKIP); + } + return ibuf; +} + +static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context, + Sequence *seq, + float nr, + bool *r_is_proxy_image) +{ + ImBuf *ibuf = NULL; + MovieClipUser user; + IMB_Proxy_Size psize = SEQ_rendersize_to_proxysize(context->preview_render_size); + + if (!seq->clip) { + return NULL; + } + + memset(&user, 0, sizeof(MovieClipUser)); + + BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs + seq->clip->start_frame); + + user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + switch (psize) { + case IMB_PROXY_NONE: + user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; + break; + case IMB_PROXY_100: + user.render_size = MCLIP_PROXY_RENDER_SIZE_100; + break; + case IMB_PROXY_75: + user.render_size = MCLIP_PROXY_RENDER_SIZE_75; + break; + case IMB_PROXY_50: + user.render_size = MCLIP_PROXY_RENDER_SIZE_50; + break; + case IMB_PROXY_25: + user.render_size = MCLIP_PROXY_RENDER_SIZE_25; + break; + } + + if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_UNDISTORTED) { + user.render_flag |= MCLIP_PROXY_RENDER_UNDISTORT; + } + + /* Try to get a proxy image. */ + ibuf = seq_get_movieclip_ibuf(seq, user); + + if (ibuf != NULL && psize != IMB_PROXY_NONE) { + *r_is_proxy_image = true; + } + + /* If proxy is not found, grab full-size frame. */ + if (ibuf == NULL) { + user.render_flag |= MCLIP_PROXY_RENDER_USE_FALLBACK_RENDER; + ibuf = seq_get_movieclip_ibuf(seq, user); + } + + return ibuf; +} + +ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float) +{ + /* TODO - add option to rasterize to alpha imbuf? */ + ImBuf *ibuf = NULL; + float *maskbuf; + int i; + + if (!mask) { + return NULL; + } + + AnimData *adt; + Mask *mask_temp; + MaskRasterHandle *mr_handle; + + mask_temp = (Mask *)BKE_id_copy_ex( + NULL, &mask->id, NULL, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA); + + BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); + + /* anim-data */ + adt = BKE_animdata_from_id(&mask->id); + const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( + context->depsgraph, mask->sfra + nr); + BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false); + + maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); + + mr_handle = BKE_maskrasterize_handle_new(); + + BKE_maskrasterize_handle_init( + mr_handle, mask_temp, context->rectx, context->recty, true, true, true); + + BKE_id_free(NULL, &mask_temp->id); + + BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf); + + BKE_maskrasterize_handle_free(mr_handle); + + if (make_float) { + /* pixels */ + const float *fp_src; + float *fp_dst; + + ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rectfloat); + + fp_src = maskbuf; + fp_dst = ibuf->rect_float; + i = context->rectx * context->recty; + while (--i) { + fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src; + fp_dst[3] = 1.0f; + + fp_src += 1; + fp_dst += 4; + } + } + else { + /* pixels */ + const float *fp_src; + unsigned char *ub_dst; + + ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + + fp_src = maskbuf; + ub_dst = (unsigned char *)ibuf->rect; + i = context->rectx * context->recty; + while (--i) { + ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */ + ub_dst[3] = 255; + + fp_src += 1; + ub_dst += 4; + } + } + + MEM_freeN(maskbuf); + + return ibuf; +} + +static ImBuf *seq_render_mask_strip(const SeqRenderData *context, Sequence *seq, float nr) +{ + bool make_float = (seq->flag & SEQ_MAKE_FLOAT) != 0; + + return seq_render_mask(context, seq->mask, nr, make_float); +} + +static ImBuf *seq_render_scene_strip(const SeqRenderData *context, + Sequence *seq, + float nr, + float cfra) +{ + ImBuf *ibuf = NULL; + double frame; + Object *camera; + + struct { + int scemode; + int cfra; + float subframe; + +#ifdef DURIAN_CAMERA_SWITCH + int mode; +#endif + } orig_data; + + /* Old info: + * Hack! This function can be called from do_render_seq(), in that case + * the seq->scene can already have a Render initialized with same name, + * so we have to use a default name. (compositor uses scene name to + * find render). + * However, when called from within the UI (image preview in sequencer) + * we do want to use scene Render, that way the render result is defined + * for display in render/imagewindow + * + * Hmm, don't see, why we can't do that all the time, + * and since G.is_rendering is uhm, gone... (Peter) + */ + + /* New info: + * Using the same name for the renders works just fine as the do_render_seq() + * render is not used while the scene strips are rendered. + * + * However rendering from UI (through sequencer_preview_area_draw) can crash in + * very many cases since other renders (material preview, an actual render etc.) + * can be started while this sequence preview render is running. The only proper + * solution is to make the sequencer preview render a proper job, which can be + * stopped when needed. This would also give a nice progress bar for the preview + * space so that users know there's something happening. + * + * As a result the active scene now only uses OpenGL rendering for the sequencer + * preview. This is far from nice, but is the only way to prevent crashes at this + * time. + * + * -jahka + */ + + const bool is_rendering = G.is_rendering; + const bool is_background = G.background; + const bool do_seq_gl = is_rendering ? 0 : (context->scene->r.seq_prev_type) != OB_RENDER; + bool have_comp = false; + bool use_gpencil = true; + /* do we need to re-evaluate the frame after rendering? */ + bool is_frame_update = false; + Scene *scene; + int is_thread_main = BLI_thread_is_main(); + + /* don't refer to seq->scene above this point!, it can be NULL */ + if (seq->scene == NULL) { + return NULL; + } + + /* Prevent rendering scene recursively. */ + if (seq->scene == context->scene) { + return NULL; + } + + scene = seq->scene; + frame = (double)scene->r.sfra + (double)nr + (double)seq->anim_startofs; + +#if 0 /* UNUSED */ + have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first); +#endif + have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree; + + /* Get view layer for the strip. */ + ViewLayer *view_layer = BKE_view_layer_default_render(scene); + /* Depsgraph will be NULL when doing rendering. */ + Depsgraph *depsgraph = NULL; + + orig_data.scemode = scene->r.scemode; + orig_data.cfra = scene->r.cfra; + orig_data.subframe = scene->r.subframe; +#ifdef DURIAN_CAMERA_SWITCH + orig_data.mode = scene->r.mode; +#endif + + BKE_scene_frame_set(scene, frame); + + if (seq->scene_camera) { + camera = seq->scene_camera; + } + else { + BKE_scene_camera_switch_update(scene); + camera = scene->camera; + } + + if (have_comp == false && camera == NULL) { + goto finally; + } + + if (seq->flag & SEQ_SCENE_NO_GPENCIL) { + use_gpencil = false; + } + + /* prevent eternal loop */ + scene->r.scemode &= ~R_DOSEQ; + +#ifdef DURIAN_CAMERA_SWITCH + /* stooping to new low's in hackyness :( */ + scene->r.mode |= R_NO_CAMERA_SWITCH; +#endif + + is_frame_update = (orig_data.cfra != scene->r.cfra) || (orig_data.subframe != scene->r.subframe); + + if ((sequencer_view3d_fn && do_seq_gl && camera) && is_thread_main) { + char err_out[256] = "unknown"; + const int width = (scene->r.xsch * scene->r.size) / 100; + const int height = (scene->r.ysch * scene->r.size) / 100; + const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id); + + unsigned int draw_flags = V3D_OFSDRAW_NONE; + draw_flags |= (use_gpencil) ? V3D_OFSDRAW_SHOW_ANNOTATION : 0; + draw_flags |= (context->scene->r.seq_flag & R_SEQ_OVERRIDE_SCENE_SETTINGS) ? + V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS : + 0; + + /* for old scene this can be uninitialized, + * should probably be added to do_versions at some point if the functionality stays */ + if (context->scene->r.seq_prev_type == 0) { + context->scene->r.seq_prev_type = 3 /* == OB_SOLID */; + } + + /* opengl offscreen render */ + depsgraph = BKE_scene_ensure_depsgraph(context->bmain, scene, view_layer); + BKE_scene_graph_update_for_newframe(depsgraph); + ibuf = sequencer_view3d_fn( + /* set for OpenGL render (NULL when scrubbing) */ + depsgraph, + scene, + &context->scene->display.shading, + context->scene->r.seq_prev_type, + camera, + width, + height, + IB_rect, + draw_flags, + scene->r.alphamode, + viewname, + context->gpu_offscreen, + err_out); + if (ibuf == NULL) { + fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); + } + } + else { + Render *re = RE_GetSceneRender(scene); + const int totviews = BKE_scene_multiview_num_views_get(&scene->r); + ImBuf **ibufs_arr; + + ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); + + /* XXX: this if can be removed when sequence preview rendering uses the job system + * + * disable rendered preview for sequencer while rendering -- it's very much possible + * that preview render will went into conflict with final render + * + * When rendering from command line renderer is called from main thread, in this + * case it's always safe to render scene here + */ + if (!is_thread_main || is_rendering == false || is_background || context->for_render) { + if (re == NULL) { + re = RE_NewSceneRender(scene); + } + + RE_RenderFrame( + re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, false); + + /* restore previous state after it was toggled on & off by RE_RenderFrame */ + G.is_rendering = is_rendering; + } + + for (int view_id = 0; view_id < totviews; view_id++) { + SeqRenderData localcontext = *context; + RenderResult rres; + + localcontext.view_id = view_id; + + RE_AcquireResultImage(re, &rres, view_id); + + if (rres.rectf) { + ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); + memcpy(ibufs_arr[view_id]->rect_float, + rres.rectf, + sizeof(float[4]) * rres.rectx * rres.recty); + + if (rres.rectz) { + addzbuffloatImBuf(ibufs_arr[view_id]); + memcpy( + ibufs_arr[view_id]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty); + } + + /* float buffers in the sequencer are not linear */ + seq_imbuf_to_sequencer_space(context->scene, ibufs_arr[view_id], false); + } + else if (rres.rect32) { + ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); + memcpy(ibufs_arr[view_id]->rect, rres.rect32, 4 * rres.rectx * rres.recty); + } + + if (view_id != context->view_id) { + BKE_sequencer_cache_put( + &localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id], 0, false); + } + + RE_ReleaseResultImage(re); + } + + /* return the original requested ImBuf */ + ibuf = ibufs_arr[context->view_id]; + + /* "remove" the others (decrease their refcount) */ + for (int view_id = 0; view_id < totviews; view_id++) { + if (ibufs_arr[view_id] != ibuf) { + IMB_freeImBuf(ibufs_arr[view_id]); + } + } + MEM_freeN(ibufs_arr); + } + +finally: + /* restore */ + scene->r.scemode = orig_data.scemode; + scene->r.cfra = orig_data.cfra; + scene->r.subframe = orig_data.subframe; + + if (is_frame_update && (depsgraph != NULL)) { + BKE_scene_graph_update_for_newframe(depsgraph); + } + +#ifdef DURIAN_CAMERA_SWITCH + /* stooping to new low's in hackyness :( */ + scene->r.mode &= orig_data.mode | ~R_NO_CAMERA_SWITCH; +#endif + + return ibuf; +} + +/** + * Used for meta-strips & scenes with #SEQ_SCENE_STRIPS flag set. + */ +static ImBuf *do_render_strip_seqbase(const SeqRenderData *context, + SeqRenderState *state, + Sequence *seq, + float nr) +{ + ImBuf *ibuf = NULL; + ListBase *seqbase = NULL; + int offset; + + seqbase = BKE_sequence_seqbase_get(seq, &offset); + + if (seqbase && !BLI_listbase_is_empty(seqbase)) { + + if (seq->flag & SEQ_SCENE_STRIPS && seq->scene) { + BKE_animsys_evaluate_all_animation(context->bmain, context->depsgraph, nr + offset); + } + + ibuf = seq_render_strip_stack(context, + state, + seqbase, + /* scene strips don't have their start taken into account */ + nr + offset, + 0); + } + + return ibuf; +} +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Strip stack rendering functions + * \{ */ +static ImBuf *do_render_strip_uncached(const SeqRenderData *context, + SeqRenderState *state, + Sequence *seq, + float cfra, + bool *r_is_proxy_image) +{ + ImBuf *ibuf = NULL; + float nr = seq_give_stripelem_index(seq, cfra); + int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type; + switch (type) { + case SEQ_TYPE_META: { + ibuf = do_render_strip_seqbase(context, state, seq, nr); + break; + } + + case SEQ_TYPE_SCENE: { + if (seq->flag & SEQ_SCENE_STRIPS) { + if (seq->scene && (context->scene != seq->scene)) { + /* recursive check */ + if (BLI_linklist_index(state->scene_parents, seq->scene) != -1) { + break; + } + LinkNode scene_parent = { + .next = state->scene_parents, + .link = seq->scene, + }; + state->scene_parents = &scene_parent; + /* end check */ + + /* Use the Scene Seq's scene for the context when rendering the scene's sequences + * (necessary for Multicam Selector among others). + */ + SeqRenderData local_context = *context; + local_context.scene = seq->scene; + local_context.skip_cache = true; + + ibuf = do_render_strip_seqbase(&local_context, state, seq, nr); + + /* step back in the list */ + state->scene_parents = state->scene_parents->next; + } + } + else { + /* scene can be NULL after deletions */ + ibuf = seq_render_scene_strip(context, seq, nr, cfra); + } + + break; + } + + case SEQ_TYPE_EFFECT: { + ibuf = seq_render_effect_strip_impl(context, state, seq, cfra); + break; + } + + case SEQ_TYPE_IMAGE: { + ibuf = seq_render_image_strip(context, seq, nr, cfra, r_is_proxy_image); + break; + } + + case SEQ_TYPE_MOVIE: { + ibuf = seq_render_movie_strip(context, seq, nr, cfra, r_is_proxy_image); + break; + } + + case SEQ_TYPE_MOVIECLIP: { + ibuf = seq_render_movieclip_strip(context, seq, nr, r_is_proxy_image); + + if (ibuf) { + /* duplicate frame so movie cache wouldn't be confused by sequencer's stuff */ + ImBuf *i = IMB_dupImBuf(ibuf); + IMB_freeImBuf(ibuf); + ibuf = i; + + if (ibuf->rect_float) { + seq_imbuf_to_sequencer_space(context->scene, ibuf, false); + } + } + + break; + } + + case SEQ_TYPE_MASK: { + /* ibuf is always new */ + ibuf = seq_render_mask_strip(context, seq, nr); + break; + } + } + + if (ibuf) { + seq_imbuf_assign_spaces(context->scene, ibuf); + } + + return ibuf; +} + +ImBuf *seq_render_strip(const SeqRenderData *context, + SeqRenderState *state, + Sequence *seq, + float cfra) +{ + ImBuf *ibuf = NULL; + bool use_preprocess = false; + bool is_proxy_image = false; + + clock_t begin = seq_estimate_render_cost_begin(); + + ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, false); + if (ibuf != NULL) { + return ibuf; + } + + ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_RAW, false); + if (ibuf == NULL) { + ibuf = do_render_strip_uncached(context, state, seq, cfra, &is_proxy_image); + } + + if (ibuf) { + use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra); + ibuf = seq_render_preprocess_ibuf( + context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image); + } + + if (ibuf == NULL) { + ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + seq_imbuf_assign_spaces(context->scene, ibuf); + } + + return ibuf; +} + +static bool seq_must_swap_input_in_blend_mode(Sequence *seq) +{ + bool swap_input = false; + + /* bad hack, to fix crazy input ordering of + * those two effects */ + + if (ELEM(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) { + swap_input = true; + } + + return swap_input; +} + +static int seq_get_early_out_for_blend_mode(Sequence *seq) +{ + struct SeqEffectHandle sh = BKE_sequence_get_blend(seq); + float facf = seq->blend_opacity / 100.0f; + int early_out = sh.early_out(seq, facf, facf); + + if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) { + return early_out; + } + + if (seq_must_swap_input_in_blend_mode(seq)) { + if (early_out == EARLY_USE_INPUT_2) { + return EARLY_USE_INPUT_1; + } + if (early_out == EARLY_USE_INPUT_1) { + return EARLY_USE_INPUT_2; + } + } + return early_out; +} + +static ImBuf *seq_render_strip_stack_apply_effect( + const SeqRenderData *context, Sequence *seq, float cfra, ImBuf *ibuf1, ImBuf *ibuf2) +{ + ImBuf *out; + struct SeqEffectHandle sh = BKE_sequence_get_blend(seq); + float facf = seq->blend_opacity / 100.0f; + int swap_input = seq_must_swap_input_in_blend_mode(seq); + + if (swap_input) { + if (sh.multithreaded) { + out = seq_render_effect_execute_threaded( + &sh, context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL); + } + else { + out = sh.execute(context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL); + } + } + else { + if (sh.multithreaded) { + out = seq_render_effect_execute_threaded( + &sh, context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL); + } + else { + out = sh.execute(context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL); + } + } + + return out; +} + +static ImBuf *seq_render_strip_stack(const SeqRenderData *context, + SeqRenderState *state, + ListBase *seqbasep, + float cfra, + int chanshown) +{ + Sequence *seq_arr[MAXSEQ + 1]; + int count; + int i; + ImBuf *out = NULL; + clock_t begin; + + count = seq_get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr); + + if (count == 0) { + return NULL; + } + + for (i = count - 1; i >= 0; i--) { + int early_out; + Sequence *seq = seq_arr[i]; + + out = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_COMPOSITE, false); + + if (out) { + break; + } + if (seq->blend_mode == SEQ_BLEND_REPLACE) { + out = seq_render_strip(context, state, seq, cfra); + break; + } + + early_out = seq_get_early_out_for_blend_mode(seq); + + switch (early_out) { + case EARLY_NO_INPUT: + case EARLY_USE_INPUT_2: + out = seq_render_strip(context, state, seq, cfra); + break; + case EARLY_USE_INPUT_1: + if (i == 0) { + out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + } + break; + case EARLY_DO_EFFECT: + if (i == 0) { + begin = seq_estimate_render_cost_begin(); + + ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); + ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); + + out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); + + float cost = seq_estimate_render_cost_end(context->scene, begin); + BKE_sequencer_cache_put( + context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false); + + IMB_freeImBuf(ibuf1); + IMB_freeImBuf(ibuf2); + } + break; + } + if (out) { + break; + } + } + + i++; + for (; i < count; i++) { + begin = seq_estimate_render_cost_begin(); + Sequence *seq = seq_arr[i]; + + if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) { + ImBuf *ibuf1 = out; + ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); + + out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); + + IMB_freeImBuf(ibuf1); + IMB_freeImBuf(ibuf2); + } + + float cost = seq_estimate_render_cost_end(context->scene, begin); + BKE_sequencer_cache_put( + context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false); + } + + return out; +} + +/* + * returned ImBuf is refed! + * you have to free after usage! + */ + +ImBuf *SEQ_render_give_ibuf(const SeqRenderData *context, float cfra, int chanshown) +{ + Scene *scene = context->scene; + Editing *ed = BKE_sequencer_editing_get(scene, false); + ListBase *seqbasep; + + if (ed == NULL) { + return NULL; + } + + if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) { + int count = BLI_listbase_count(&ed->metastack); + count = max_ii(count + chanshown, 0); + seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep; + } + else { + seqbasep = ed->seqbasep; + } + + SeqRenderState state; + seq_render_state_init(&state); + ImBuf *out = NULL; + Sequence *seq_arr[MAXSEQ + 1]; + int count; + + count = seq_get_shown_sequences(seqbasep, cfra, chanshown, seq_arr); + + if (count) { + out = BKE_sequencer_cache_get( + context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, false); + } + + BKE_sequencer_cache_free_temp_cache(context->scene, context->task_id, cfra); + + clock_t begin = seq_estimate_render_cost_begin(); + float cost = 0; + + if (count && !out) { + BLI_mutex_lock(&seq_render_mutex); + out = seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown); + cost = seq_estimate_render_cost_end(context->scene, begin); + + if (context->is_prefetch_render) { + BKE_sequencer_cache_put( + context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false); + } + else { + BKE_sequencer_cache_put_if_possible( + context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false); + } + BLI_mutex_unlock(&seq_render_mutex); + } + + BKE_sequencer_prefetch_start(context, cfra, cost); + + return out; +} + +ImBuf *seq_render_give_ibuf_seqbase(const SeqRenderData *context, + float cfra, + int chan_shown, + ListBase *seqbasep) +{ + SeqRenderState state; + seq_render_state_init(&state); + + return seq_render_strip_stack(context, &state, seqbasep, cfra, chan_shown); +} + +ImBuf *SEQ_render_give_ibuf_direct(const SeqRenderData *context, float cfra, Sequence *seq) +{ + SeqRenderState state; + seq_render_state_init(&state); + + ImBuf *ibuf = seq_render_strip(context, &state, seq, cfra); + + return ibuf; +} +/** \} */ diff --git a/source/blender/sequencer/intern/render.h b/source/blender/sequencer/intern/render.h new file mode 100644 index 00000000000..83214934e05 --- /dev/null +++ b/source/blender/sequencer/intern/render.h @@ -0,0 +1,75 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + */ + +#pragma once + +/** \file + * \ingroup sequencer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct Editing; +struct ImBuf; +struct ListBase; +struct Scene; +struct SeqRenderData; +struct Sequence; + +/* mutable state for sequencer */ +typedef struct SeqRenderState { + struct LinkNode *scene_parents; +} SeqRenderState; + +void seq_render_state_init(SeqRenderState *state); + +struct ImBuf *seq_render_give_ibuf_seqbase(const struct SeqRenderData *context, + float cfra, + int chan_shown, + struct ListBase *seqbasep); +struct ImBuf *seq_render_effect_execute_threaded(struct SeqEffectHandle *sh, + const SeqRenderData *context, + struct Sequence *seq, + float cfra, + float facf0, + float facf1, + struct ImBuf *ibuf1, + struct ImBuf *ibuf2, + struct ImBuf *ibuf3); +void seq_imbuf_to_sequencer_space(struct Scene *scene, struct ImBuf *ibuf, bool make_float); +float seq_give_stripelem_index(struct Sequence *seq, float cfra); +int seq_get_shown_sequences(struct ListBase *seqbasep, + int cfra, + int chanshown, + struct Sequence **seq_arr_out); +struct ImBuf *seq_render_strip(const struct SeqRenderData *context, + struct SeqRenderState *state, + struct Sequence *seq, + float cfra); +struct ImBuf *seq_render_mask(const struct SeqRenderData *context, + struct Mask *mask, + float nr, + bool make_float); +void seq_imbuf_assign_spaces(struct Scene *scene, struct ImBuf *ibuf); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/sequencer/intern/sequencer.c b/source/blender/sequencer/intern/sequencer.c index 068d836d1e6..89709c54942 100644 --- a/source/blender/sequencer/intern/sequencer.c +++ b/source/blender/sequencer/intern/sequencer.c @@ -74,7 +74,6 @@ #include "BKE_movieclip.h" #include "BKE_report.h" #include "BKE_scene.h" -#include "BKE_sequencer.h" #include "BKE_sequencer_offscreen.h" #include "DEG_depsgraph.h" @@ -84,6 +83,8 @@ #include "RE_pipeline.h" +#include "SEQ_sequencer.h" + #include <pthread.h> #include "IMB_colormanagement.h" @@ -96,45 +97,20 @@ #include "RE_engine.h" +#include "sequencer.h" + #ifdef WITH_AUDASPACE # include <AUD_Special.h> #endif -/* mutable state for sequencer */ -typedef struct SeqRenderState { - LinkNode *scene_parents; -} SeqRenderState; - -static ImBuf *seq_render_strip_stack(const SeqRenderData *context, - SeqRenderState *state, - ListBase *seqbasep, - float cfra, - int chanshown); -static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, - Sequence *seq, - ImBuf *ibuf, - float cfra, - clock_t begin, - bool use_preprocess, - const bool is_proxy_image); -static ImBuf *seq_render_strip(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - float cfra); static void seq_free_animdata(Scene *scene, Sequence *seq); -static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float); -static int seq_num_files(Scene *scene, char views_format, const bool is_multiview); static void seq_anim_add_suffix(Scene *scene, struct anim *anim, const int view_id); -static ThreadMutex seq_render_mutex = BLI_MUTEX_INITIALIZER; - /* **** XXX ******** */ #define SELECT 1 ListBase seqbase_clipboard; int seqbase_clipboard_frame; -SequencerDrawView sequencer_view3d_fn = NULL; /* NULL in background mode */ - #if 0 /* unused function */ static void printf_strip(Sequence *seq) { @@ -159,11 +135,6 @@ static void printf_strip(Sequence *seq) } #endif -static void sequencer_state_init(SeqRenderState *state) -{ - state->scene_parents = NULL; -} - int BKE_sequencer_base_recursive_apply(ListBase *seqbase, int (*apply_fn)(Sequence *seq, void *), void *arg) @@ -330,7 +301,7 @@ void BKE_sequence_free_anim(Sequence *seq) /* cache must be freed before calling this function * since it leaves the seqbase in an invalid state */ -static void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user) +void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user) { Sequence *iseq, *iseq_next; @@ -520,147 +491,6 @@ void BKE_sequencer_editing_free(Scene *scene, const bool do_id_user) scene->ed = NULL; } -/*********************** Sequencer color space functions *************************/ - -static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf) -{ -#if 0 - /* Bute buffer is supposed to be in sequencer working space already. */ - if (ibuf->rect != NULL) { - IMB_colormanagement_assign_rect_colorspace(ibuf, scene->sequencer_colorspace_settings.name); - } -#endif - if (ibuf->rect_float != NULL) { - IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name); - } -} - -void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, bool make_float) -{ - /* Early output check: if both buffers are NULL we have nothing to convert. */ - if (ibuf->rect_float == NULL && ibuf->rect == NULL) { - return; - } - /* Get common conversion settings. */ - const char *to_colorspace = scene->sequencer_colorspace_settings.name; - /* Perform actual conversion logic. */ - if (ibuf->rect_float == NULL) { - /* We are not requested to give float buffer and byte buffer is already - * in thee required colorspace. Can skip doing anything here. - */ - const char *from_colorspace = IMB_colormanagement_get_rect_colorspace(ibuf); - if (!make_float && STREQ(from_colorspace, to_colorspace)) { - return; - } - if (false) { - /* The idea here is to provide as fast playback as possible and - * enforcing float buffer here (a) uses more cache memory (b) might - * make some other effects slower to apply. - * - * However, this might also have negative effect by adding weird - * artifacts which will then not happen in final render. - */ - IMB_colormanagement_transform_byte_threaded((unsigned char *)ibuf->rect, - ibuf->x, - ibuf->y, - ibuf->channels, - from_colorspace, - to_colorspace); - } - else { - /* We perform conversion to a float buffer so we don't worry about - * precision loss. - */ - imb_addrectfloatImBuf(ibuf); - IMB_colormanagement_transform_from_byte_threaded(ibuf->rect_float, - (unsigned char *)ibuf->rect, - ibuf->x, - ibuf->y, - ibuf->channels, - from_colorspace, - to_colorspace); - /* We don't need byte buffer anymore. */ - imb_freerectImBuf(ibuf); - } - } - else { - const char *from_colorspace = IMB_colormanagement_get_float_colorspace(ibuf); - /* Unknown input color space, can't perform conversion. */ - if (from_colorspace == NULL || from_colorspace[0] == '\0') { - return; - } - /* We don't want both byte and float buffers around: they'll either run - * out of sync or conversion of byte buffer will lose precision in there. - */ - if (ibuf->rect != NULL) { - imb_freerectImBuf(ibuf); - } - IMB_colormanagement_transform_threaded( - ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); - } - sequencer_imbuf_assign_spaces(scene, ibuf); -} - -void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf) -{ - const char *from_colorspace = scene->sequencer_colorspace_settings.name; - const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( - COLOR_ROLE_SCENE_LINEAR); - - if (!ibuf->rect_float) { - return; - } - - if (to_colorspace && to_colorspace[0] != '\0') { - IMB_colormanagement_transform_threaded( - ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels, from_colorspace, to_colorspace, true); - IMB_colormanagement_assign_float_colorspace(ibuf, to_colorspace); - } -} - -void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4]) -{ - const char *from_colorspace = scene->sequencer_colorspace_settings.name; - const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get( - COLOR_ROLE_SCENE_LINEAR); - - if (to_colorspace && to_colorspace[0] != '\0') { - IMB_colormanagement_transform_v4(pixel, from_colorspace, to_colorspace); - } - else { - /* if no color management enables fallback to legacy conversion */ - srgb_to_linearrgb_v4(pixel, pixel); - } -} - -/*********************** sequencer pipeline functions *************************/ - -void BKE_sequencer_new_render_data(Main *bmain, - struct Depsgraph *depsgraph, - Scene *scene, - int rectx, - int recty, - int preview_render_size, - int for_render, - SeqRenderData *r_context) -{ - r_context->bmain = bmain; - r_context->depsgraph = depsgraph; - r_context->scene = scene; - r_context->rectx = rectx; - r_context->recty = recty; - r_context->preview_render_size = preview_render_size; - r_context->for_render = for_render; - r_context->motion_blur_samples = 0; - r_context->motion_blur_shutter = 0; - r_context->skip_cache = false; - r_context->is_proxy_render = false; - r_context->view_id = 0; - r_context->gpu_offscreen = NULL; - r_context->task_id = SEQ_TASK_MAIN_RENDER; - r_context->is_prefetch_render = false; -} - /* ************************* iterator ************************** */ /* *************** (replaces old WHILE_SEQ) ********************* */ /* **************** use now SEQ_ALL_BEGIN () SEQ_ALL_END ***************** */ @@ -908,12 +738,12 @@ void BKE_sequence_calc(Scene *scene, Sequence *seq) } } -static void seq_multiview_name(Scene *scene, - const int view_id, - const char *prefix, - const char *ext, - char *r_path, - size_t r_size) +void seq_multiview_name(Scene *scene, + const int view_id, + const char *prefix, + const char *ext, + char *r_path, + size_t r_size) { const char *suffix = BKE_scene_multiview_view_id_suffix_get(&scene->r, view_id); BLI_assert(ext != NULL && suffix != NULL && prefix != NULL); @@ -1391,273 +1221,8 @@ ListBase *BKE_sequence_seqbase_get(Sequence *seq, int *r_offset) return seqbase; } -/*********************** DO THE SEQUENCE *************************/ - -static void multibuf(ImBuf *ibuf, const float fmul) -{ - char *rt; - float *rt_float; - - int a; - - rt = (char *)ibuf->rect; - rt_float = ibuf->rect_float; - - if (rt) { - const int imul = (int)(256.0f * fmul); - a = ibuf->x * ibuf->y; - while (a--) { - rt[0] = min_ii((imul * rt[0]) >> 8, 255); - rt[1] = min_ii((imul * rt[1]) >> 8, 255); - rt[2] = min_ii((imul * rt[2]) >> 8, 255); - rt[3] = min_ii((imul * rt[3]) >> 8, 255); - - rt += 4; - } - } - if (rt_float) { - a = ibuf->x * ibuf->y; - while (a--) { - rt_float[0] *= fmul; - rt_float[1] *= fmul; - rt_float[2] *= fmul; - rt_float[3] *= fmul; - - rt_float += 4; - } - } -} - -float BKE_sequencer_give_stripelem_index(Sequence *seq, float cfra) -{ - float nr; - int sta = seq->start; - int end = seq->start + seq->len - 1; - - if (seq->type & SEQ_TYPE_EFFECT) { - end = seq->enddisp; - } - - if (end < sta) { - return -1; - } - - if (seq->flag & SEQ_REVERSE_FRAMES) { - /*reverse frame in this sequence */ - if (cfra <= sta) { - nr = end - sta; - } - else if (cfra >= end) { - nr = 0; - } - else { - nr = end - cfra; - } - } - else { - if (cfra <= sta) { - nr = 0; - } - else if (cfra >= end) { - nr = end - sta; - } - else { - nr = cfra - sta; - } - } - - if (seq->strobe < 1.0f) { - seq->strobe = 1.0f; - } - - if (seq->strobe > 1.0f) { - nr -= fmodf((double)nr, (double)seq->strobe); - } - - return nr; -} - -StripElem *BKE_sequencer_give_stripelem(Sequence *seq, int cfra) -{ - StripElem *se = seq->strip->stripdata; - - if (seq->type == SEQ_TYPE_IMAGE) { - /* only IMAGE strips use the whole array, MOVIE strips use only the first element, - * all other strips don't use this... - */ - - int nr = (int)BKE_sequencer_give_stripelem_index(seq, cfra); - - if (nr == -1 || se == NULL) { - return NULL; - } - - se += nr + seq->anim_startofs; - } - return se; -} - -static int evaluate_seq_frame_gen(Sequence **seq_arr, ListBase *seqbase, int cfra, int chanshown) -{ - /* Use arbitrary sized linked list, the size could be over MAXSEQ. */ - LinkNodePair effect_inputs = {NULL, NULL}; - int totseq = 0; - - memset(seq_arr, 0, sizeof(Sequence *) * (MAXSEQ + 1)); - - LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if ((seq->startdisp <= cfra) && (seq->enddisp > cfra)) { - if ((seq->type & SEQ_TYPE_EFFECT) && !(seq->flag & SEQ_MUTE)) { - - if (seq->seq1) { - BLI_linklist_append_alloca(&effect_inputs, seq->seq1); - } - - if (seq->seq2) { - BLI_linklist_append_alloca(&effect_inputs, seq->seq2); - } - - if (seq->seq3) { - BLI_linklist_append_alloca(&effect_inputs, seq->seq3); - } - } - - seq_arr[seq->machine] = seq; - totseq++; - } - } - - /* Drop strips which are used for effect inputs, we don't want - * them to blend into render stack in any other way than effect - * string rendering. */ - for (LinkNode *seq_item = effect_inputs.list; seq_item; seq_item = seq_item->next) { - Sequence *seq = seq_item->link; - /* It's possible that effect strip would be placed to the same - * 'machine' as its inputs. We don't want to clear such strips - * from the stack. */ - if (seq_arr[seq->machine] && seq_arr[seq->machine]->type & SEQ_TYPE_EFFECT) { - continue; - } - /* If we're shown a specified channel, then we want to see the strips - * which belongs to this machine. */ - if (chanshown != 0 && chanshown <= seq->machine) { - continue; - } - seq_arr[seq->machine] = NULL; - } - - return totseq; -} - -int BKE_sequencer_evaluate_frame(Scene *scene, int cfra) -{ - Editing *ed = BKE_sequencer_editing_get(scene, false); - Sequence *seq_arr[MAXSEQ + 1]; - - if (ed == NULL) { - return 0; - } - - return evaluate_seq_frame_gen(seq_arr, ed->seqbasep, cfra, 0); -} - -static bool video_seq_is_rendered(Sequence *seq) -{ - return (seq && !(seq->flag & SEQ_MUTE) && seq->type != SEQ_TYPE_SOUND_RAM); -} - -int BKE_sequencer_get_shown_sequences(ListBase *seqbasep, - int cfra, - int chanshown, - Sequence **seq_arr_out) -{ - Sequence *seq_arr[MAXSEQ + 1]; - int b = chanshown; - int cnt = 0; - - if (b > MAXSEQ) { - return 0; - } - - if (evaluate_seq_frame_gen(seq_arr, seqbasep, cfra, chanshown)) { - if (b == 0) { - b = MAXSEQ; - } - for (; b > 0; b--) { - if (video_seq_is_rendered(seq_arr[b])) { - break; - } - } - } - - chanshown = b; - - for (; b > 0; b--) { - if (video_seq_is_rendered(seq_arr[b])) { - if (seq_arr[b]->blend_mode == SEQ_BLEND_REPLACE) { - break; - } - } - } - - for (; b <= chanshown && b >= 0; b++) { - if (video_seq_is_rendered(seq_arr[b])) { - seq_arr_out[cnt++] = seq_arr[b]; - } - } - - return cnt; -} - -/*********************** proxy management *************************/ - -typedef struct SeqIndexBuildContext { - struct IndexBuildContext *index_context; - - int tc_flags; - int size_flags; - int quality; - bool overwrite; - int view_id; - - Main *bmain; - Depsgraph *depsgraph; - Scene *scene; - Sequence *seq, *orig_seq; -} SeqIndexBuildContext; - -#define PROXY_MAXFILE (2 * FILE_MAXDIR + FILE_MAXFILE) - -static IMB_Proxy_Size seq_rendersize_to_proxysize(int render_size) -{ - switch (render_size) { - case SEQ_RENDER_SIZE_PROXY_25: - return IMB_PROXY_25; - case SEQ_RENDER_SIZE_PROXY_50: - return IMB_PROXY_50; - case SEQ_RENDER_SIZE_PROXY_75: - return IMB_PROXY_75; - case SEQ_RENDER_SIZE_PROXY_100: - return IMB_PROXY_100; - } - return IMB_PROXY_NONE; -} - -double BKE_sequencer_rendersize_to_scale_factor(int render_size) -{ - switch (render_size) { - case SEQ_RENDER_SIZE_PROXY_25: - return 0.25; - case SEQ_RENDER_SIZE_PROXY_50: - return 0.50; - case SEQ_RENDER_SIZE_PROXY_75: - return 0.75; - } - return 1.0; -} - /* the number of files will vary according to the stereo format */ -static int seq_num_files(Scene *scene, char views_format, const bool is_multiview) +int seq_num_files(Scene *scene, char views_format, const bool is_multiview) { if (!is_multiview) { return 1; @@ -1670,7 +1235,7 @@ static int seq_num_files(Scene *scene, char views_format, const bool is_multivie return BKE_scene_multiview_num_views_get(&scene->r); } -static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir) +void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir) { char dir[FILE_MAX]; char fname[FILE_MAXFILE]; @@ -1681,7 +1246,7 @@ static void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir) IMB_anim_set_index_dir(anim, dir); } -static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile) +void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile) { char dir[FILE_MAX]; char name[FILE_MAX]; @@ -1810,2362 +1375,6 @@ static void seq_open_anim_file(Scene *scene, Sequence *seq, bool openfile) } } -static bool seq_proxy_get_custom_file_fname(Sequence *seq, char *name, const int view_id) -{ - char fname[FILE_MAXFILE]; - char suffix[24]; - StripProxy *proxy = seq->strip->proxy; - - if (proxy == NULL) { - return false; - } - - BLI_join_dirfile(fname, PROXY_MAXFILE, proxy->dir, proxy->file); - BLI_path_abs(fname, BKE_main_blendfile_path_from_global()); - - if (view_id > 0) { - BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id); - /* TODO(sergey): This will actually append suffix after extension - * which is weird but how was originally coded in multi-view branch. - */ - BLI_snprintf(name, PROXY_MAXFILE, "%s_%s", fname, suffix); - } - else { - BLI_strncpy(name, fname, PROXY_MAXFILE); - } - - return true; -} - -static bool seq_proxy_get_fname(Editing *ed, - Sequence *seq, - int cfra, - eSpaceSeq_Proxy_RenderSize render_size, - char *name, - const int view_id) -{ - char dir[PROXY_MAXFILE]; - char suffix[24] = {'\0'}; - StripProxy *proxy = seq->strip->proxy; - - if (proxy == NULL) { - return false; - } - - /* Multi-view suffix. */ - if (view_id > 0) { - BLI_snprintf(suffix, sizeof(suffix), "_%d", view_id); - } - - /* Per strip with Custom file situation is handled separately. */ - if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE && - ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE) { - if (seq_proxy_get_custom_file_fname(seq, name, view_id)) { - return true; - } - } - - if (ed->proxy_storage == SEQ_EDIT_PROXY_DIR_STORAGE) { - /* Per project default. */ - if (ed->proxy_dir[0] == 0) { - BLI_strncpy(dir, "//BL_proxy", sizeof(dir)); - } - else { /* Per project with custom dir. */ - BLI_strncpy(dir, ed->proxy_dir, sizeof(dir)); - } - BLI_path_abs(name, BKE_main_blendfile_path_from_global()); - } - else { - /* Pre strip with custom dir. */ - if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_DIR) { - BLI_strncpy(dir, seq->strip->proxy->dir, sizeof(dir)); - } - else { /* Per strip default. */ - BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir); - } - } - - /* Proxy size number to be used in path. */ - int proxy_size_number = BKE_sequencer_rendersize_to_scale_factor(render_size) * 100; - - BLI_snprintf(name, - PROXY_MAXFILE, - "%s/images/%d/%s_proxy%s", - dir, - proxy_size_number, - BKE_sequencer_give_stripelem(seq, cfra)->name, - suffix); - BLI_path_abs(name, BKE_main_blendfile_path_from_global()); - strcat(name, ".jpg"); - - return true; -} - -static bool seq_can_use_proxy(Sequence *seq, IMB_Proxy_Size psize) -{ - if (seq->strip->proxy == NULL) { - return false; - } - short size_flags = seq->strip->proxy->build_size_flags; - return (seq->flag & SEQ_USE_PROXY) != 0 && psize != IMB_PROXY_NONE && (size_flags & psize) != 0; -} - -static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int cfra) -{ - char name[PROXY_MAXFILE]; - StripProxy *proxy = seq->strip->proxy; - const eSpaceSeq_Proxy_RenderSize psize = context->preview_render_size; - Editing *ed = context->scene->ed; - StripAnim *sanim; - - /* only use proxies, if they are enabled (even if present!) */ - if (!seq_can_use_proxy(seq, seq_rendersize_to_proxysize(psize))) { - return NULL; - } - - if (proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - int frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs; - if (proxy->anim == NULL) { - if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) { - return NULL; - } - - proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name); - } - if (proxy->anim == NULL) { - return NULL; - } - - seq_open_anim_file(context->scene, seq, true); - sanim = seq->anims.first; - - frameno = IMB_anim_index_get_frame_index( - sanim ? sanim->anim : NULL, seq->strip->proxy->tc, frameno); - - return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); - } - - if (seq_proxy_get_fname(ed, seq, cfra, psize, name, context->view_id) == 0) { - return NULL; - } - - if (BLI_exists(name)) { - ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL); - - if (ibuf) { - sequencer_imbuf_assign_spaces(context->scene, ibuf); - } - - return ibuf; - } - - return NULL; -} - -static void seq_proxy_build_frame(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - int cfra, - int proxy_render_size, - const bool overwrite) -{ - char name[PROXY_MAXFILE]; - int quality; - int rectx, recty; - int ok; - ImBuf *ibuf_tmp, *ibuf; - Editing *ed = context->scene->ed; - - if (!seq_proxy_get_fname(ed, seq, cfra, proxy_render_size, name, context->view_id)) { - return; - } - - if (!overwrite && BLI_exists(name)) { - return; - } - - ibuf_tmp = seq_render_strip(context, state, seq, cfra); - - rectx = (proxy_render_size * ibuf_tmp->x) / 100; - recty = (proxy_render_size * ibuf_tmp->y) / 100; - - if (ibuf_tmp->x != rectx || ibuf_tmp->y != recty) { - ibuf = IMB_dupImBuf(ibuf_tmp); - IMB_metadata_copy(ibuf, ibuf_tmp); - IMB_freeImBuf(ibuf_tmp); - IMB_scalefastImBuf(ibuf, (short)rectx, (short)recty); - } - else { - ibuf = ibuf_tmp; - } - - /* depth = 32 is intentionally left in, otherwise ALPHA channels - * won't work... */ - quality = seq->strip->proxy->quality; - ibuf->ftype = IMB_FTYPE_JPG; - ibuf->foptions.quality = quality; - - /* unsupported feature only confuses other s/w */ - if (ibuf->planes == 32) { - ibuf->planes = 24; - } - - BLI_make_existing_file(name); - - ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); - if (ok == 0) { - perror(name); - } - - IMB_freeImBuf(ibuf); -} - -/** - * Returns whether the file this context would read from even exist, - * if not, don't create the context - */ -static bool seq_proxy_multiview_context_invalid(Sequence *seq, Scene *scene, const int view_id) -{ - if ((scene->r.scemode & R_MULTIVIEW) == 0) { - return false; - } - - if ((seq->type == SEQ_TYPE_IMAGE) && (seq->views_format == R_IMF_VIEWS_INDIVIDUAL)) { - static char prefix[FILE_MAX]; - static const char *ext = NULL; - char str[FILE_MAX]; - - if (view_id == 0) { - char path[FILE_MAX]; - BLI_join_dirfile(path, sizeof(path), seq->strip->dir, seq->strip->stripdata->name); - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - BKE_scene_multiview_view_prefix_get(scene, path, prefix, &ext); - } - else { - prefix[0] = '\0'; - } - - if (prefix[0] == '\0') { - return view_id != 0; - } - - seq_multiview_name(scene, view_id, prefix, ext, str, FILE_MAX); - - if (BLI_access(str, R_OK) == 0) { - return false; - } - - return view_id != 0; - } - return false; -} - -/** - * This returns the maximum possible number of required contexts - */ -static int seq_proxy_context_count(Sequence *seq, Scene *scene) -{ - int num_views = 1; - - if ((scene->r.scemode & R_MULTIVIEW) == 0) { - return 1; - } - - switch (seq->type) { - case SEQ_TYPE_MOVIE: { - num_views = BLI_listbase_count(&seq->anims); - break; - } - case SEQ_TYPE_IMAGE: { - switch (seq->views_format) { - case R_IMF_VIEWS_INDIVIDUAL: - num_views = BKE_scene_multiview_num_views_get(&scene->r); - break; - case R_IMF_VIEWS_STEREO_3D: - num_views = 2; - break; - case R_IMF_VIEWS_MULTIVIEW: - /* not supported at the moment */ - /* pass through */ - default: - num_views = 1; - } - break; - } - } - - return num_views; -} - -bool BKE_sequencer_proxy_rebuild_context(Main *bmain, - Depsgraph *depsgraph, - Scene *scene, - Sequence *seq, - struct GSet *file_list, - ListBase *queue) -{ - SeqIndexBuildContext *context; - Sequence *nseq; - LinkData *link; - int num_files; - int i; - - if (!seq->strip || !seq->strip->proxy) { - return true; - } - - if (!(seq->flag & SEQ_USE_PROXY)) { - return true; - } - - num_files = seq_proxy_context_count(seq, scene); - - for (i = 0; i < num_files; i++) { - if (seq_proxy_multiview_context_invalid(seq, scene, i)) { - continue; - } - - context = MEM_callocN(sizeof(SeqIndexBuildContext), "seq proxy rebuild context"); - - nseq = BKE_sequence_dupli_recursive(scene, scene, NULL, seq, 0); - - context->tc_flags = nseq->strip->proxy->build_tc_flags; - context->size_flags = nseq->strip->proxy->build_size_flags; - context->quality = nseq->strip->proxy->quality; - context->overwrite = (nseq->strip->proxy->build_flags & SEQ_PROXY_SKIP_EXISTING) == 0; - - context->bmain = bmain; - context->depsgraph = depsgraph; - context->scene = scene; - context->orig_seq = seq; - context->seq = nseq; - - context->view_id = i; /* only for images */ - - if (nseq->type == SEQ_TYPE_MOVIE) { - StripAnim *sanim; - - seq_open_anim_file(scene, nseq, true); - sanim = BLI_findlink(&nseq->anims, i); - - if (sanim->anim) { - context->index_context = IMB_anim_index_rebuild_context(sanim->anim, - context->tc_flags, - context->size_flags, - context->quality, - context->overwrite, - file_list); - } - if (!context->index_context) { - MEM_freeN(context); - return false; - } - } - - link = BLI_genericNodeN(context); - BLI_addtail(queue, link); - } - return true; -} - -void BKE_sequencer_proxy_rebuild(SeqIndexBuildContext *context, - short *stop, - short *do_update, - float *progress) -{ - const bool overwrite = context->overwrite; - SeqRenderData render_context; - Sequence *seq = context->seq; - Scene *scene = context->scene; - Main *bmain = context->bmain; - int cfra; - - if (seq->type == SEQ_TYPE_MOVIE) { - if (context->index_context) { - IMB_anim_index_rebuild(context->index_context, stop, do_update, progress); - } - - return; - } - - if (!(seq->flag & SEQ_USE_PROXY)) { - return; - } - - /* that's why it is called custom... */ - if (seq->strip->proxy && seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - return; - } - - /* fail safe code */ - - BKE_sequencer_new_render_data(bmain, - context->depsgraph, - context->scene, - roundf((scene->r.size * (float)scene->r.xsch) / 100.0f), - roundf((scene->r.size * (float)scene->r.ysch) / 100.0f), - 100, - false, - &render_context); - - render_context.skip_cache = true; - render_context.is_proxy_render = true; - render_context.view_id = context->view_id; - - SeqRenderState state; - sequencer_state_init(&state); - - for (cfra = seq->startdisp + seq->startstill; cfra < seq->enddisp - seq->endstill; cfra++) { - if (context->size_flags & IMB_PROXY_25) { - seq_proxy_build_frame(&render_context, &state, seq, cfra, 25, overwrite); - } - if (context->size_flags & IMB_PROXY_50) { - seq_proxy_build_frame(&render_context, &state, seq, cfra, 50, overwrite); - } - if (context->size_flags & IMB_PROXY_75) { - seq_proxy_build_frame(&render_context, &state, seq, cfra, 75, overwrite); - } - if (context->size_flags & IMB_PROXY_100) { - seq_proxy_build_frame(&render_context, &state, seq, cfra, 100, overwrite); - } - - *progress = (float)(cfra - seq->startdisp - seq->startstill) / - (seq->enddisp - seq->endstill - seq->startdisp - seq->startstill); - *do_update = true; - - if (*stop || G.is_break) { - break; - } - } -} - -void BKE_sequencer_proxy_rebuild_finish(SeqIndexBuildContext *context, bool stop) -{ - if (context->index_context) { - StripAnim *sanim; - - for (sanim = context->seq->anims.first; sanim; sanim = sanim->next) { - IMB_close_anim_proxies(sanim->anim); - } - - for (sanim = context->orig_seq->anims.first; sanim; sanim = sanim->next) { - IMB_close_anim_proxies(sanim->anim); - } - - IMB_anim_index_rebuild_finish(context->index_context, stop); - } - - seq_free_sequence_recurse(NULL, context->seq, true); - - MEM_freeN(context); -} - -void BKE_sequencer_proxy_set(struct Sequence *seq, bool value) -{ - if (value) { - seq->flag |= SEQ_USE_PROXY; - if (seq->strip->proxy == NULL) { - seq->strip->proxy = MEM_callocN(sizeof(struct StripProxy), "StripProxy"); - seq->strip->proxy->quality = 90; - seq->strip->proxy->build_tc_flags = SEQ_PROXY_TC_ALL; - seq->strip->proxy->build_size_flags = SEQ_PROXY_IMAGE_SIZE_25; - } - } - else { - seq->flag &= ~SEQ_USE_PROXY; - } -} - -/*********************** color balance *************************/ - -static StripColorBalance calc_cb(StripColorBalance *cb_) -{ - StripColorBalance cb = *cb_; - int c; - - for (c = 0; c < 3; c++) { - cb.lift[c] = 2.0f - cb.lift[c]; - } - - if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_LIFT) { - for (c = 0; c < 3; c++) { - /* tweak to give more subtle results - * values above 1.0 are scaled */ - if (cb.lift[c] > 1.0f) { - cb.lift[c] = pow(cb.lift[c] - 1.0f, 2.0) + 1.0; - } - - cb.lift[c] = 2.0f - cb.lift[c]; - } - } - - if (cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAIN) { - for (c = 0; c < 3; c++) { - if (cb.gain[c] != 0.0f) { - cb.gain[c] = 1.0f / cb.gain[c]; - } - else { - cb.gain[c] = 1000000; /* should be enough :) */ - } - } - } - - if (!(cb.flag & SEQ_COLOR_BALANCE_INVERSE_GAMMA)) { - for (c = 0; c < 3; c++) { - if (cb.gamma[c] != 0.0f) { - cb.gamma[c] = 1.0f / cb.gamma[c]; - } - else { - cb.gamma[c] = 1000000; /* should be enough :) */ - } - } - } - - return cb; -} - -/* note: lift is actually 2-lift */ -MINLINE float color_balance_fl( - float in, const float lift, const float gain, const float gamma, const float mul) -{ - float x = (((in - 1.0f) * lift) + 1.0f) * gain; - - /* prevent NaN */ - if (x < 0.f) { - x = 0.f; - } - - x = powf(x, gamma) * mul; - CLAMP(x, FLT_MIN, FLT_MAX); - return x; -} - -static void make_cb_table_float(float lift, float gain, float gamma, float *table, float mul) -{ - int y; - - for (y = 0; y < 256; y++) { - float v = color_balance_fl((float)y * (1.0f / 255.0f), lift, gain, gamma, mul); - - table[y] = v; - } -} - -static void color_balance_byte_byte(StripColorBalance *cb_, - unsigned char *rect, - unsigned char *mask_rect, - int width, - int height, - float mul) -{ - // unsigned char cb_tab[3][256]; - unsigned char *cp = rect; - unsigned char *e = cp + width * 4 * height; - unsigned char *m = mask_rect; - - StripColorBalance cb = calc_cb(cb_); - - while (cp < e) { - float p[4]; - int c; - - straight_uchar_to_premul_float(p, cp); - - for (c = 0; c < 3; c++) { - float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); - - if (m) { - float m_normal = (float)m[c] / 255.0f; - - p[c] = p[c] * (1.0f - m_normal) + t * m_normal; - } - else { - p[c] = t; - } - } - - premul_float_to_straight_uchar(cp, p); - - cp += 4; - if (m) { - m += 4; - } - } -} - -static void color_balance_byte_float(StripColorBalance *cb_, - unsigned char *rect, - float *rect_float, - unsigned char *mask_rect, - int width, - int height, - float mul) -{ - float cb_tab[4][256]; - int c, i; - unsigned char *p = rect; - unsigned char *e = p + width * 4 * height; - unsigned char *m = mask_rect; - float *o; - StripColorBalance cb; - - o = rect_float; - - cb = calc_cb(cb_); - - for (c = 0; c < 3; c++) { - make_cb_table_float(cb.lift[c], cb.gain[c], cb.gamma[c], cb_tab[c], mul); - } - - for (i = 0; i < 256; i++) { - cb_tab[3][i] = ((float)i) * (1.0f / 255.0f); - } - - while (p < e) { - if (m) { - const float t[3] = {m[0] / 255.0f, m[1] / 255.0f, m[2] / 255.0f}; - - p[0] = p[0] * (1.0f - t[0]) + t[0] * cb_tab[0][p[0]]; - p[1] = p[1] * (1.0f - t[1]) + t[1] * cb_tab[1][p[1]]; - p[2] = p[2] * (1.0f - t[2]) + t[2] * cb_tab[2][p[2]]; - - m += 4; - } - else { - o[0] = cb_tab[0][p[0]]; - o[1] = cb_tab[1][p[1]]; - o[2] = cb_tab[2][p[2]]; - } - - o[3] = cb_tab[3][p[3]]; - - p += 4; - o += 4; - } -} - -static void color_balance_float_float(StripColorBalance *cb_, - float *rect_float, - const float *mask_rect_float, - int width, - int height, - float mul) -{ - float *p = rect_float; - const float *e = rect_float + width * 4 * height; - const float *m = mask_rect_float; - StripColorBalance cb = calc_cb(cb_); - - while (p < e) { - int c; - for (c = 0; c < 3; c++) { - float t = color_balance_fl(p[c], cb.lift[c], cb.gain[c], cb.gamma[c], mul); - - if (m) { - p[c] = p[c] * (1.0f - m[c]) + t * m[c]; - } - else { - p[c] = t; - } - } - - p += 4; - if (m) { - m += 4; - } - } -} - -typedef struct ColorBalanceInitData { - StripColorBalance *cb; - ImBuf *ibuf; - float mul; - ImBuf *mask; - bool make_float; -} ColorBalanceInitData; - -typedef struct ColorBalanceThread { - StripColorBalance *cb; - float mul; - - int width, height; - - unsigned char *rect, *mask_rect; - float *rect_float, *mask_rect_float; - - bool make_float; -} ColorBalanceThread; - -static void color_balance_init_handle(void *handle_v, - int start_line, - int tot_line, - void *init_data_v) -{ - ColorBalanceThread *handle = (ColorBalanceThread *)handle_v; - ColorBalanceInitData *init_data = (ColorBalanceInitData *)init_data_v; - ImBuf *ibuf = init_data->ibuf; - ImBuf *mask = init_data->mask; - - int offset = 4 * start_line * ibuf->x; - - memset(handle, 0, sizeof(ColorBalanceThread)); - - handle->cb = init_data->cb; - handle->mul = init_data->mul; - handle->width = ibuf->x; - handle->height = tot_line; - handle->make_float = init_data->make_float; - - if (ibuf->rect) { - handle->rect = (unsigned char *)ibuf->rect + offset; - } - - if (ibuf->rect_float) { - handle->rect_float = ibuf->rect_float + offset; - } - - if (mask) { - if (mask->rect) { - handle->mask_rect = (unsigned char *)mask->rect + offset; - } - - if (mask->rect_float) { - handle->mask_rect_float = mask->rect_float + offset; - } - } - else { - handle->mask_rect = NULL; - handle->mask_rect_float = NULL; - } -} - -static void *color_balance_do_thread(void *thread_data_v) -{ - ColorBalanceThread *thread_data = (ColorBalanceThread *)thread_data_v; - StripColorBalance *cb = thread_data->cb; - int width = thread_data->width, height = thread_data->height; - unsigned char *rect = thread_data->rect; - unsigned char *mask_rect = thread_data->mask_rect; - float *rect_float = thread_data->rect_float; - float *mask_rect_float = thread_data->mask_rect_float; - float mul = thread_data->mul; - - if (rect_float) { - color_balance_float_float(cb, rect_float, mask_rect_float, width, height, mul); - } - else if (thread_data->make_float) { - color_balance_byte_float(cb, rect, rect_float, mask_rect, width, height, mul); - } - else { - color_balance_byte_byte(cb, rect, mask_rect, width, height, mul); - } - - return NULL; -} - -/** - * \a cfra is offset by \a fra_offset only in case we are using a real mask. - */ -ImBuf *BKE_sequencer_render_mask_input(const SeqRenderData *context, - int mask_input_type, - Sequence *mask_sequence, - Mask *mask_id, - int cfra, - int fra_offset, - bool make_float) -{ - ImBuf *mask_input = NULL; - - if (mask_input_type == SEQUENCE_MASK_INPUT_STRIP) { - if (mask_sequence) { - SeqRenderState state; - sequencer_state_init(&state); - - mask_input = seq_render_strip(context, &state, mask_sequence, cfra); - - if (make_float) { - if (!mask_input->rect_float) { - IMB_float_from_rect(mask_input); - } - } - else { - if (!mask_input->rect) { - IMB_rect_from_float(mask_input); - } - } - } - } - else if (mask_input_type == SEQUENCE_MASK_INPUT_ID) { - mask_input = seq_render_mask(context, mask_id, cfra - fra_offset, make_float); - } - - return mask_input; -} - -void BKE_sequencer_color_balance_apply( - StripColorBalance *cb, ImBuf *ibuf, float mul, bool make_float, ImBuf *mask_input) -{ - ColorBalanceInitData init_data; - - if (!ibuf->rect_float && make_float) { - imb_addrectfloatImBuf(ibuf); - } - - init_data.cb = cb; - init_data.ibuf = ibuf; - init_data.mul = mul; - init_data.make_float = make_float; - init_data.mask = mask_input; - - IMB_processor_apply_threaded(ibuf->y, - sizeof(ColorBalanceThread), - &init_data, - color_balance_init_handle, - color_balance_do_thread); - - /* color balance either happens on float buffer or byte buffer, but never on both, - * free byte buffer if there's float buffer since float buffer would be used for - * color balance in favor of byte buffer - */ - if (ibuf->rect_float && ibuf->rect) { - imb_freerectImBuf(ibuf); - } -} - -/* - * input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE - * - * Do all the things you can't really do afterwards using sequence effects - * (read: before rescaling to render resolution has been done) - * - * Order is important! - * - * - Deinterlace - * - Crop and transform in image source coordinate space - * - Flip X + Flip Y (could be done afterwards, backward compatibility) - * - Promote image to float data (affects pipeline operations afterwards) - * - Color balance (is most efficient in the byte -> float - * (future: half -> float should also work fine!) - * case, if done on load, since we can use lookup tables) - * - Premultiply - */ - -bool BKE_sequencer_input_have_to_preprocess(const SeqRenderData *context, - Sequence *seq, - float UNUSED(cfra)) -{ - float mul; - - if (context && context->is_proxy_render) { - return false; - } - - if (seq->flag & - (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_FLOAT)) { - return true; - } - - mul = seq->mul; - - if (seq->blend_mode == SEQ_BLEND_REPLACE) { - mul *= seq->blend_opacity / 100.0f; - } - - if (mul != 1.0f) { - return true; - } - - if (seq->sat != 1.0f) { - return true; - } - - if (seq->modifiers.first) { - return true; - } - - return false; -} - -static ImBuf *input_preprocess(const SeqRenderData *context, - Sequence *seq, - float cfra, - ImBuf *ibuf, - const bool is_proxy_image) -{ - Scene *scene = context->scene; - float mul; - - ibuf = IMB_makeSingleUser(ibuf); - - if ((seq->flag & SEQ_FILTERY) && !ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP)) { - IMB_filtery(ibuf); - } - - if (seq->flag & (SEQ_USE_CROP | SEQ_USE_TRANSFORM)) { - StripCrop c = {0}; - StripTransform t = {0}; - - if (seq->flag & SEQ_USE_CROP && seq->strip->crop) { - c = *seq->strip->crop; - } - if (seq->flag & SEQ_USE_TRANSFORM && seq->strip->transform) { - t = *seq->strip->transform; - } - - /* Calculate scale factor for current image if needed. */ - double scale_factor, image_scale_factor = 1.0; - if (context->preview_render_size == SEQ_RENDER_SIZE_SCENE) { - scale_factor = image_scale_factor = (double)scene->r.size / 100; - } - else { - scale_factor = BKE_sequencer_rendersize_to_scale_factor(context->preview_render_size); - if (!is_proxy_image) { - image_scale_factor = scale_factor; - } - } - - if (image_scale_factor != 1.0) { - if (context->for_render) { - IMB_scaleImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor); - } - else { - IMB_scalefastImBuf(ibuf, ibuf->x * image_scale_factor, ibuf->y * image_scale_factor); - } - } - - t.xofs *= scale_factor; - t.yofs *= scale_factor; - c.left *= scale_factor; - c.right *= scale_factor; - c.top *= scale_factor; - c.bottom *= scale_factor; - - int sx, sy, dx, dy; - sx = ibuf->x - c.left - c.right; - sy = ibuf->y - c.top - c.bottom; - - if (seq->flag & SEQ_USE_TRANSFORM) { - dx = context->rectx; - dy = context->recty; - } - else { - dx = sx; - dy = sy; - } - - if (c.top + c.bottom >= ibuf->y || c.left + c.right >= ibuf->x || t.xofs >= dx || - t.yofs >= dy) { - return NULL; - } - - ImBuf *i = IMB_allocImBuf(dx, dy, 32, ibuf->rect_float ? IB_rectfloat : IB_rect); - IMB_rectcpy(i, ibuf, t.xofs, t.yofs, c.left, c.bottom, sx, sy); - sequencer_imbuf_assign_spaces(scene, i); - IMB_metadata_copy(i, ibuf); - IMB_freeImBuf(ibuf); - ibuf = i; - } - - if (seq->flag & SEQ_FLIPX) { - IMB_flipx(ibuf); - } - - if (seq->flag & SEQ_FLIPY) { - IMB_flipy(ibuf); - } - - if (seq->sat != 1.0f) { - IMB_saturation(ibuf, seq->sat); - } - - mul = seq->mul; - - if (seq->blend_mode == SEQ_BLEND_REPLACE) { - mul *= seq->blend_opacity / 100.0f; - } - - if (seq->flag & SEQ_MAKE_FLOAT) { - if (!ibuf->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(scene, ibuf, true); - } - - if (ibuf->rect) { - imb_freerectImBuf(ibuf); - } - } - - if (mul != 1.0f) { - multibuf(ibuf, mul); - } - - if (ibuf->x != context->rectx || ibuf->y != context->recty) { - if (context->for_render) { - IMB_scaleImBuf(ibuf, (short)context->rectx, (short)context->recty); - } - else { - IMB_scalefastImBuf(ibuf, (short)context->rectx, (short)context->recty); - } - } - - if (seq->modifiers.first) { - ImBuf *ibuf_new = BKE_sequence_modifier_apply_stack(context, seq, ibuf, cfra); - - if (ibuf_new != ibuf) { - IMB_metadata_copy(ibuf_new, ibuf); - IMB_freeImBuf(ibuf); - ibuf = ibuf_new; - } - } - - return ibuf; -} - -/*********************** strip rendering functions *************************/ - -typedef struct RenderEffectInitData { - struct SeqEffectHandle *sh; - const SeqRenderData *context; - Sequence *seq; - float cfra, facf0, facf1; - ImBuf *ibuf1, *ibuf2, *ibuf3; - - ImBuf *out; -} RenderEffectInitData; - -typedef struct RenderEffectThread { - struct SeqEffectHandle *sh; - const SeqRenderData *context; - Sequence *seq; - float cfra, facf0, facf1; - ImBuf *ibuf1, *ibuf2, *ibuf3; - - ImBuf *out; - int start_line, tot_line; -} RenderEffectThread; - -static void render_effect_execute_init_handle(void *handle_v, - int start_line, - int tot_line, - void *init_data_v) -{ - RenderEffectThread *handle = (RenderEffectThread *)handle_v; - RenderEffectInitData *init_data = (RenderEffectInitData *)init_data_v; - - handle->sh = init_data->sh; - handle->context = init_data->context; - handle->seq = init_data->seq; - handle->cfra = init_data->cfra; - handle->facf0 = init_data->facf0; - handle->facf1 = init_data->facf1; - handle->ibuf1 = init_data->ibuf1; - handle->ibuf2 = init_data->ibuf2; - handle->ibuf3 = init_data->ibuf3; - handle->out = init_data->out; - - handle->start_line = start_line; - handle->tot_line = tot_line; -} - -static void *render_effect_execute_do_thread(void *thread_data_v) -{ - RenderEffectThread *thread_data = (RenderEffectThread *)thread_data_v; - - thread_data->sh->execute_slice(thread_data->context, - thread_data->seq, - thread_data->cfra, - thread_data->facf0, - thread_data->facf1, - thread_data->ibuf1, - thread_data->ibuf2, - thread_data->ibuf3, - thread_data->start_line, - thread_data->tot_line, - thread_data->out); - - return NULL; -} - -ImBuf *BKE_sequencer_effect_execute_threaded(struct SeqEffectHandle *sh, - const SeqRenderData *context, - Sequence *seq, - float cfra, - float facf0, - float facf1, - ImBuf *ibuf1, - ImBuf *ibuf2, - ImBuf *ibuf3) -{ - RenderEffectInitData init_data; - ImBuf *out = sh->init_execution(context, ibuf1, ibuf2, ibuf3); - - init_data.sh = sh; - init_data.context = context; - init_data.seq = seq; - init_data.cfra = cfra; - init_data.facf0 = facf0; - init_data.facf1 = facf1; - init_data.ibuf1 = ibuf1; - init_data.ibuf2 = ibuf2; - init_data.ibuf3 = ibuf3; - init_data.out = out; - - IMB_processor_apply_threaded(out->y, - sizeof(RenderEffectThread), - &init_data, - render_effect_execute_init_handle, - render_effect_execute_do_thread); - - return out; -} - -static ImBuf *seq_render_effect_strip_impl(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - float cfra) -{ - Scene *scene = context->scene; - float fac, facf; - int early_out; - int i; - struct SeqEffectHandle sh = BKE_sequence_get_effect(seq); - FCurve *fcu = NULL; - ImBuf *ibuf[3]; - Sequence *input[3]; - ImBuf *out = NULL; - - ibuf[0] = ibuf[1] = ibuf[2] = NULL; - - input[0] = seq->seq1; - input[1] = seq->seq2; - input[2] = seq->seq3; - - if (!sh.execute && !(sh.execute_slice && sh.init_execution)) { - /* effect not supported in this version... */ - out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - return out; - } - - if (seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) { - sh.get_default_fac(seq, cfra, &fac, &facf); - facf = fac; - } - else { - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL); - if (fcu) { - fac = facf = evaluate_fcurve(fcu, cfra); - } - else { - fac = facf = seq->effect_fader; - } - } - - early_out = sh.early_out(seq, fac, facf); - - switch (early_out) { - case EARLY_NO_INPUT: - out = sh.execute(context, seq, cfra, fac, facf, NULL, NULL, NULL); - break; - case EARLY_DO_EFFECT: - for (i = 0; i < 3; i++) { - /* Speed effect requires time remapping of `cfra` for input(s). */ - if (input[0] && seq->type == SEQ_TYPE_SPEED) { - float target_frame = BKE_sequencer_speed_effect_target_frame_get(context, seq, cfra, i); - ibuf[i] = seq_render_strip(context, state, input[0], target_frame); - } - else { /* Other effects. */ - if (input[i]) { - ibuf[i] = seq_render_strip(context, state, input[i], cfra); - } - } - } - - if (ibuf[0] && (ibuf[1] || BKE_sequence_effect_get_num_inputs(seq->type) == 1)) { - if (sh.multithreaded) { - out = BKE_sequencer_effect_execute_threaded( - &sh, context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]); - } - else { - out = sh.execute(context, seq, cfra, fac, facf, ibuf[0], ibuf[1], ibuf[2]); - } - } - break; - case EARLY_USE_INPUT_1: - if (input[0]) { - out = seq_render_strip(context, state, input[0], cfra); - } - break; - case EARLY_USE_INPUT_2: - if (input[1]) { - out = seq_render_strip(context, state, input[1], cfra); - } - break; - } - - for (i = 0; i < 3; i++) { - IMB_freeImBuf(ibuf[i]); - } - - if (out == NULL) { - out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - } - - return out; -} - -/** - * Render individual view for multi-view or single (default view) for mono-view. - */ -static ImBuf *seq_render_image_strip_view(const SeqRenderData *context, - Sequence *seq, - char *name, - char *prefix, - const char *ext, - int view_id) -{ - - ImBuf *ibuf = NULL; - - int flag = IB_rect | IB_metadata; - if (seq->alpha_mode == SEQ_ALPHA_PREMUL) { - flag |= IB_alphamode_premul; - } - - if (prefix[0] == '\0') { - ibuf = IMB_loadiffname(name, flag, seq->strip->colorspace_settings.name); - } - else { - char str[FILE_MAX]; - BKE_scene_multiview_view_prefix_get(context->scene, name, prefix, &ext); - seq_multiview_name(context->scene, view_id, prefix, ext, str, FILE_MAX); - ibuf = IMB_loadiffname(str, flag, seq->strip->colorspace_settings.name); - } - - if (ibuf == NULL) { - return NULL; - } - - /* We don't need both (speed reasons)! */ - if (ibuf->rect_float != NULL && ibuf->rect != NULL) { - imb_freerectImBuf(ibuf); - } - - /* All sequencer color is done in SRGB space, linear gives odd cross-fades. */ - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false); - - return ibuf; -} - -static bool seq_image_strip_is_multiview_render( - Scene *scene, Sequence *seq, int totfiles, char *name, char *r_prefix, const char *r_ext) -{ - if (totfiles > 1) { - BKE_scene_multiview_view_prefix_get(scene, name, r_prefix, &r_ext); - if (r_prefix[0] == '\0') { - return false; - } - } - else { - r_prefix[0] = '\0'; - } - - return (seq->flag & SEQ_USE_VIEWS) != 0 && (scene->r.scemode & R_MULTIVIEW) != 0; -} - -static ImBuf *seq_render_image_strip(const SeqRenderData *context, - Sequence *seq, - float UNUSED(nr), - float cfra, - bool *r_is_proxy_image) -{ - char name[FILE_MAX]; - const char *ext = NULL; - char prefix[FILE_MAX]; - ImBuf *ibuf = NULL; - - StripElem *s_elem = BKE_sequencer_give_stripelem(seq, cfra); - if (s_elem == NULL) { - return NULL; - } - - BLI_join_dirfile(name, sizeof(name), seq->strip->dir, s_elem->name); - BLI_path_abs(name, BKE_main_blendfile_path_from_global()); - - /* Try to get a proxy image. */ - ibuf = seq_proxy_fetch(context, seq, cfra); - if (ibuf != NULL) { - s_elem->orig_width = ibuf->x; - s_elem->orig_height = ibuf->y; - *r_is_proxy_image = true; - return ibuf; - } - - /* Proxy not found, render original. */ - const int totfiles = seq_num_files(context->scene, seq->views_format, true); - bool is_multiview_render = seq_image_strip_is_multiview_render( - context->scene, seq, totfiles, name, prefix, ext); - - if (is_multiview_render) { - int totviews = BKE_scene_multiview_num_views_get(&context->scene->r); - ImBuf **ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); - - for (int view_id = 0; view_id < totfiles; view_id++) { - ibufs_arr[view_id] = seq_render_image_strip_view(context, seq, name, prefix, ext, view_id); - } - - if (ibufs_arr[0] == NULL) { - return NULL; - } - - if (seq->views_format == R_IMF_VIEWS_STEREO_3D) { - IMB_ImBufFromStereo3d(seq->stereo3d_format, ibufs_arr[0], &ibufs_arr[0], &ibufs_arr[1]); - } - - for (int view_id = 0; view_id < totviews; view_id++) { - SeqRenderData localcontext = *context; - localcontext.view_id = view_id; - - if (view_id != context->view_id) { - ibufs_arr[view_id] = seq_render_preprocess_ibuf( - &localcontext, seq, ibufs_arr[view_id], cfra, clock(), true, false); - } - } - - /* Return the original requested ImBuf. */ - ibuf = ibufs_arr[context->view_id]; - - /* Remove the others (decrease their refcount). */ - for (int view_id = 0; view_id < totviews; view_id++) { - if (ibufs_arr[view_id] != ibuf) { - IMB_freeImBuf(ibufs_arr[view_id]); - } - } - - MEM_freeN(ibufs_arr); - } - else { - ibuf = seq_render_image_strip_view(context, seq, name, prefix, ext, context->view_id); - } - - if (ibuf == NULL) { - return NULL; - } - - s_elem->orig_width = ibuf->x; - s_elem->orig_height = ibuf->y; - - return ibuf; -} - -static ImBuf *seq_render_movie_strip_custom_file_proxy(const SeqRenderData *context, - Sequence *seq, - int cfra) -{ - char name[PROXY_MAXFILE]; - StripProxy *proxy = seq->strip->proxy; - - if (proxy->anim == NULL) { - if (seq_proxy_get_custom_file_fname(seq, name, context->view_id)) { - proxy->anim = openanim(name, IB_rect, 0, seq->strip->colorspace_settings.name); - } - if (proxy->anim == NULL) { - return NULL; - } - } - - int frameno = (int)BKE_sequencer_give_stripelem_index(seq, cfra) + seq->anim_startofs; - return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE); -} - -/** - * Render individual view for multi-view or single (default view) for mono-view. - */ -static ImBuf *seq_render_movie_strip_view(const SeqRenderData *context, - Sequence *seq, - float nr, - float cfra, - StripAnim *sanim, - bool *r_is_proxy_image) -{ - ImBuf *ibuf = NULL; - IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size); - - IMB_anim_set_preseek(sanim->anim, seq->anim_preseek); - - if (seq_can_use_proxy(seq, psize)) { - /* Try to get a proxy image. - * Movie proxies are handled by ImBuf module with exception of `custom file` setting. */ - if (context->scene->ed->proxy_storage != SEQ_EDIT_PROXY_DIR_STORAGE && - seq->strip->proxy->storage & SEQ_STORAGE_PROXY_CUSTOM_FILE) { - ibuf = seq_render_movie_strip_custom_file_proxy(context, seq, cfra); - } - else { - ibuf = IMB_anim_absolute(sanim->anim, - nr + seq->anim_startofs, - seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, - psize); - } - - if (ibuf != NULL) { - *r_is_proxy_image = true; - } - } - - /* Fetching for requested proxy size failed, try fetching the original instead. */ - if (ibuf == NULL) { - ibuf = IMB_anim_absolute(sanim->anim, - nr + seq->anim_startofs, - seq->strip->proxy ? seq->strip->proxy->tc : IMB_TC_RECORD_RUN, - IMB_PROXY_NONE); - } - if (ibuf == NULL) { - return NULL; - } - - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false); - - /* We don't need both (speed reasons)! */ - if (ibuf->rect_float != NULL && ibuf->rect != NULL) { - imb_freerectImBuf(ibuf); - } - - return ibuf; -} - -static ImBuf *seq_render_movie_strip( - const SeqRenderData *context, Sequence *seq, float nr, float cfra, bool *r_is_proxy_image) -{ - /* Load all the videos. */ - seq_open_anim_file(context->scene, seq, false); - - ImBuf *ibuf = NULL; - StripAnim *sanim = seq->anims.first; - const int totfiles = seq_num_files(context->scene, seq->views_format, true); - bool is_multiview_render = (seq->flag & SEQ_USE_VIEWS) != 0 && - (context->scene->r.scemode & R_MULTIVIEW) != 0 && - BLI_listbase_count_at_most(&seq->anims, totfiles + 1) == totfiles; - - if (is_multiview_render) { - ImBuf **ibuf_arr; - int totviews = BKE_scene_multiview_num_views_get(&context->scene->r); - ibuf_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); - int ibuf_view_id; - - for (ibuf_view_id = 0, sanim = seq->anims.first; sanim; sanim = sanim->next, ibuf_view_id++) { - if (sanim->anim) { - ibuf_arr[ibuf_view_id] = seq_render_movie_strip_view( - context, seq, nr, cfra, sanim, r_is_proxy_image); - } - } - - if (seq->views_format == R_IMF_VIEWS_STEREO_3D) { - if (ibuf_arr[0] == NULL) { - /* Probably proxy hasn't been created yet. */ - MEM_freeN(ibuf_arr); - return NULL; - } - - IMB_ImBufFromStereo3d(seq->stereo3d_format, ibuf_arr[0], &ibuf_arr[0], &ibuf_arr[1]); - } - - for (int view_id = 0; view_id < totviews; view_id++) { - SeqRenderData localcontext = *context; - localcontext.view_id = view_id; - - if (view_id != context->view_id) { - ibuf_arr[view_id] = seq_render_preprocess_ibuf( - &localcontext, seq, ibuf_arr[view_id], cfra, clock(), true, false); - } - } - - /* Return the original requested ImBuf. */ - ibuf = ibuf_arr[context->view_id]; - - /* Remove the others (decrease their refcount). */ - for (int view_id = 0; view_id < totviews; view_id++) { - if (ibuf_arr[view_id] != ibuf) { - IMB_freeImBuf(ibuf_arr[view_id]); - } - } - - MEM_freeN(ibuf_arr); - } - else { - ibuf = seq_render_movie_strip_view(context, seq, nr, cfra, sanim, r_is_proxy_image); - } - - if (ibuf == NULL) { - return NULL; - } - - seq->strip->stripdata->orig_width = ibuf->x; - seq->strip->stripdata->orig_height = ibuf->y; - - return ibuf; -} - -static ImBuf *seq_get_movieclip_ibuf(Sequence *seq, MovieClipUser user) -{ - ImBuf *ibuf = NULL; - float tloc[2], tscale, tangle; - if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_STABILIZED) { - ibuf = BKE_movieclip_get_stable_ibuf(seq->clip, &user, tloc, &tscale, &tangle, 0); - } - else { - ibuf = BKE_movieclip_get_ibuf_flag(seq->clip, &user, seq->clip->flag, MOVIECLIP_CACHE_SKIP); - } - return ibuf; -} - -static ImBuf *seq_render_movieclip_strip(const SeqRenderData *context, - Sequence *seq, - float nr, - bool *r_is_proxy_image) -{ - ImBuf *ibuf = NULL; - MovieClipUser user; - IMB_Proxy_Size psize = seq_rendersize_to_proxysize(context->preview_render_size); - - if (!seq->clip) { - return NULL; - } - - memset(&user, 0, sizeof(MovieClipUser)); - - BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs + seq->clip->start_frame); - - user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; - switch (psize) { - case IMB_PROXY_NONE: - user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL; - break; - case IMB_PROXY_100: - user.render_size = MCLIP_PROXY_RENDER_SIZE_100; - break; - case IMB_PROXY_75: - user.render_size = MCLIP_PROXY_RENDER_SIZE_75; - break; - case IMB_PROXY_50: - user.render_size = MCLIP_PROXY_RENDER_SIZE_50; - break; - case IMB_PROXY_25: - user.render_size = MCLIP_PROXY_RENDER_SIZE_25; - break; - } - - if (seq->clip_flag & SEQ_MOVIECLIP_RENDER_UNDISTORTED) { - user.render_flag |= MCLIP_PROXY_RENDER_UNDISTORT; - } - - /* Try to get a proxy image. */ - ibuf = seq_get_movieclip_ibuf(seq, user); - - if (ibuf != NULL && psize != IMB_PROXY_NONE) { - *r_is_proxy_image = true; - } - - /* If proxy is not found, grab full-size frame. */ - if (ibuf == NULL) { - user.render_flag |= MCLIP_PROXY_RENDER_USE_FALLBACK_RENDER; - ibuf = seq_get_movieclip_ibuf(seq, user); - } - - return ibuf; -} - -static ImBuf *seq_render_mask(const SeqRenderData *context, Mask *mask, float nr, bool make_float) -{ - /* TODO - add option to rasterize to alpha imbuf? */ - ImBuf *ibuf = NULL; - float *maskbuf; - int i; - - if (!mask) { - return NULL; - } - - AnimData *adt; - Mask *mask_temp; - MaskRasterHandle *mr_handle; - - mask_temp = (Mask *)BKE_id_copy_ex( - NULL, &mask->id, NULL, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_NO_ANIMDATA); - - BKE_mask_evaluate(mask_temp, mask->sfra + nr, true); - - /* anim-data */ - adt = BKE_animdata_from_id(&mask->id); - const AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct( - context->depsgraph, mask->sfra + nr); - BKE_animsys_evaluate_animdata(&mask_temp->id, adt, &anim_eval_context, ADT_RECALC_ANIM, false); - - maskbuf = MEM_mallocN(sizeof(float) * context->rectx * context->recty, __func__); - - mr_handle = BKE_maskrasterize_handle_new(); - - BKE_maskrasterize_handle_init( - mr_handle, mask_temp, context->rectx, context->recty, true, true, true); - - BKE_id_free(NULL, &mask_temp->id); - - BKE_maskrasterize_buffer(mr_handle, context->rectx, context->recty, maskbuf); - - BKE_maskrasterize_handle_free(mr_handle); - - if (make_float) { - /* pixels */ - const float *fp_src; - float *fp_dst; - - ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rectfloat); - - fp_src = maskbuf; - fp_dst = ibuf->rect_float; - i = context->rectx * context->recty; - while (--i) { - fp_dst[0] = fp_dst[1] = fp_dst[2] = *fp_src; - fp_dst[3] = 1.0f; - - fp_src += 1; - fp_dst += 4; - } - } - else { - /* pixels */ - const float *fp_src; - unsigned char *ub_dst; - - ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - - fp_src = maskbuf; - ub_dst = (unsigned char *)ibuf->rect; - i = context->rectx * context->recty; - while (--i) { - ub_dst[0] = ub_dst[1] = ub_dst[2] = (unsigned char)(*fp_src * 255.0f); /* already clamped */ - ub_dst[3] = 255; - - fp_src += 1; - ub_dst += 4; - } - } - - MEM_freeN(maskbuf); - - return ibuf; -} - -static ImBuf *seq_render_mask_strip(const SeqRenderData *context, Sequence *seq, float nr) -{ - bool make_float = (seq->flag & SEQ_MAKE_FLOAT) != 0; - - return seq_render_mask(context, seq->mask, nr, make_float); -} - -static ImBuf *seq_render_scene_strip(const SeqRenderData *context, - Sequence *seq, - float nr, - float cfra) -{ - ImBuf *ibuf = NULL; - double frame; - Object *camera; - - struct { - int scemode; - int cfra; - float subframe; - -#ifdef DURIAN_CAMERA_SWITCH - int mode; -#endif - } orig_data; - - /* Old info: - * Hack! This function can be called from do_render_seq(), in that case - * the seq->scene can already have a Render initialized with same name, - * so we have to use a default name. (compositor uses scene name to - * find render). - * However, when called from within the UI (image preview in sequencer) - * we do want to use scene Render, that way the render result is defined - * for display in render/imagewindow - * - * Hmm, don't see, why we can't do that all the time, - * and since G.is_rendering is uhm, gone... (Peter) - */ - - /* New info: - * Using the same name for the renders works just fine as the do_render_seq() - * render is not used while the scene strips are rendered. - * - * However rendering from UI (through sequencer_preview_area_draw) can crash in - * very many cases since other renders (material preview, an actual render etc.) - * can be started while this sequence preview render is running. The only proper - * solution is to make the sequencer preview render a proper job, which can be - * stopped when needed. This would also give a nice progress bar for the preview - * space so that users know there's something happening. - * - * As a result the active scene now only uses OpenGL rendering for the sequencer - * preview. This is far from nice, but is the only way to prevent crashes at this - * time. - * - * -jahka - */ - - const bool is_rendering = G.is_rendering; - const bool is_background = G.background; - const bool do_seq_gl = is_rendering ? 0 : (context->scene->r.seq_prev_type) != OB_RENDER; - bool have_comp = false; - bool use_gpencil = true; - /* do we need to re-evaluate the frame after rendering? */ - bool is_frame_update = false; - Scene *scene; - int is_thread_main = BLI_thread_is_main(); - - /* don't refer to seq->scene above this point!, it can be NULL */ - if (seq->scene == NULL) { - return NULL; - } - - /* Prevent rendering scene recursively. */ - if (seq->scene == context->scene) { - return NULL; - } - - scene = seq->scene; - frame = (double)scene->r.sfra + (double)nr + (double)seq->anim_startofs; - -#if 0 /* UNUSED */ - have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first); -#endif - have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree; - - /* Get view layer for the strip. */ - ViewLayer *view_layer = BKE_view_layer_default_render(scene); - /* Depsgraph will be NULL when doing rendering. */ - Depsgraph *depsgraph = NULL; - - orig_data.scemode = scene->r.scemode; - orig_data.cfra = scene->r.cfra; - orig_data.subframe = scene->r.subframe; -#ifdef DURIAN_CAMERA_SWITCH - orig_data.mode = scene->r.mode; -#endif - - BKE_scene_frame_set(scene, frame); - - if (seq->scene_camera) { - camera = seq->scene_camera; - } - else { - BKE_scene_camera_switch_update(scene); - camera = scene->camera; - } - - if (have_comp == false && camera == NULL) { - goto finally; - } - - if (seq->flag & SEQ_SCENE_NO_GPENCIL) { - use_gpencil = false; - } - - /* prevent eternal loop */ - scene->r.scemode &= ~R_DOSEQ; - -#ifdef DURIAN_CAMERA_SWITCH - /* stooping to new low's in hackyness :( */ - scene->r.mode |= R_NO_CAMERA_SWITCH; -#endif - - is_frame_update = (orig_data.cfra != scene->r.cfra) || (orig_data.subframe != scene->r.subframe); - - if ((sequencer_view3d_fn && do_seq_gl && camera) && is_thread_main) { - char err_out[256] = "unknown"; - const int width = (scene->r.xsch * scene->r.size) / 100; - const int height = (scene->r.ysch * scene->r.size) / 100; - const char *viewname = BKE_scene_multiview_render_view_name_get(&scene->r, context->view_id); - - unsigned int draw_flags = V3D_OFSDRAW_NONE; - draw_flags |= (use_gpencil) ? V3D_OFSDRAW_SHOW_ANNOTATION : 0; - draw_flags |= (context->scene->r.seq_flag & R_SEQ_OVERRIDE_SCENE_SETTINGS) ? - V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS : - 0; - - /* for old scene this can be uninitialized, - * should probably be added to do_versions at some point if the functionality stays */ - if (context->scene->r.seq_prev_type == 0) { - context->scene->r.seq_prev_type = 3 /* == OB_SOLID */; - } - - /* opengl offscreen render */ - depsgraph = BKE_scene_ensure_depsgraph(context->bmain, scene, view_layer); - BKE_scene_graph_update_for_newframe(depsgraph); - ibuf = sequencer_view3d_fn( - /* set for OpenGL render (NULL when scrubbing) */ - depsgraph, - scene, - &context->scene->display.shading, - context->scene->r.seq_prev_type, - camera, - width, - height, - IB_rect, - draw_flags, - scene->r.alphamode, - viewname, - context->gpu_offscreen, - err_out); - if (ibuf == NULL) { - fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out); - } - } - else { - Render *re = RE_GetSceneRender(scene); - const int totviews = BKE_scene_multiview_num_views_get(&scene->r); - ImBuf **ibufs_arr; - - ibufs_arr = MEM_callocN(sizeof(ImBuf *) * totviews, "Sequence Image Views Imbufs"); - - /* XXX: this if can be removed when sequence preview rendering uses the job system - * - * disable rendered preview for sequencer while rendering -- it's very much possible - * that preview render will went into conflict with final render - * - * When rendering from command line renderer is called from main thread, in this - * case it's always safe to render scene here - */ - if (!is_thread_main || is_rendering == false || is_background || context->for_render) { - if (re == NULL) { - re = RE_NewSceneRender(scene); - } - - RE_RenderFrame( - re, context->bmain, scene, have_comp ? NULL : view_layer, camera, frame, false); - - /* restore previous state after it was toggled on & off by RE_RenderFrame */ - G.is_rendering = is_rendering; - } - - for (int view_id = 0; view_id < totviews; view_id++) { - SeqRenderData localcontext = *context; - RenderResult rres; - - localcontext.view_id = view_id; - - RE_AcquireResultImage(re, &rres, view_id); - - if (rres.rectf) { - ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rectfloat); - memcpy(ibufs_arr[view_id]->rect_float, - rres.rectf, - sizeof(float[4]) * rres.rectx * rres.recty); - - if (rres.rectz) { - addzbuffloatImBuf(ibufs_arr[view_id]); - memcpy( - ibufs_arr[view_id]->zbuf_float, rres.rectz, sizeof(float) * rres.rectx * rres.recty); - } - - /* float buffers in the sequencer are not linear */ - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibufs_arr[view_id], false); - } - else if (rres.rect32) { - ibufs_arr[view_id] = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect); - memcpy(ibufs_arr[view_id]->rect, rres.rect32, 4 * rres.rectx * rres.recty); - } - - if (view_id != context->view_id) { - BKE_sequencer_cache_put( - &localcontext, seq, cfra, SEQ_CACHE_STORE_RAW, ibufs_arr[view_id], 0, false); - } - - RE_ReleaseResultImage(re); - } - - /* return the original requested ImBuf */ - ibuf = ibufs_arr[context->view_id]; - - /* "remove" the others (decrease their refcount) */ - for (int view_id = 0; view_id < totviews; view_id++) { - if (ibufs_arr[view_id] != ibuf) { - IMB_freeImBuf(ibufs_arr[view_id]); - } - } - MEM_freeN(ibufs_arr); - } - -finally: - /* restore */ - scene->r.scemode = orig_data.scemode; - scene->r.cfra = orig_data.cfra; - scene->r.subframe = orig_data.subframe; - - if (is_frame_update && (depsgraph != NULL)) { - BKE_scene_graph_update_for_newframe(depsgraph); - } - -#ifdef DURIAN_CAMERA_SWITCH - /* stooping to new low's in hackyness :( */ - scene->r.mode &= orig_data.mode | ~R_NO_CAMERA_SWITCH; -#endif - - return ibuf; -} - -/** - * Used for meta-strips & scenes with #SEQ_SCENE_STRIPS flag set. - */ -static ImBuf *do_render_strip_seqbase(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - float nr) -{ - ImBuf *ibuf = NULL; - ListBase *seqbase = NULL; - int offset; - - seqbase = BKE_sequence_seqbase_get(seq, &offset); - - if (seqbase && !BLI_listbase_is_empty(seqbase)) { - - if (seq->flag & SEQ_SCENE_STRIPS && seq->scene) { - BKE_animsys_evaluate_all_animation(context->bmain, context->depsgraph, nr + offset); - } - - ibuf = seq_render_strip_stack(context, - state, - seqbase, - /* scene strips don't have their start taken into account */ - nr + offset, - 0); - } - - return ibuf; -} - -static ImBuf *do_render_strip_uncached(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - float cfra, - bool *r_is_proxy_image) -{ - ImBuf *ibuf = NULL; - float nr = BKE_sequencer_give_stripelem_index(seq, cfra); - int type = (seq->type & SEQ_TYPE_EFFECT) ? SEQ_TYPE_EFFECT : seq->type; - switch (type) { - case SEQ_TYPE_META: { - ibuf = do_render_strip_seqbase(context, state, seq, nr); - break; - } - - case SEQ_TYPE_SCENE: { - if (seq->flag & SEQ_SCENE_STRIPS) { - if (seq->scene && (context->scene != seq->scene)) { - /* recursive check */ - if (BLI_linklist_index(state->scene_parents, seq->scene) != -1) { - break; - } - LinkNode scene_parent = { - .next = state->scene_parents, - .link = seq->scene, - }; - state->scene_parents = &scene_parent; - /* end check */ - - /* Use the Scene Seq's scene for the context when rendering the scene's sequences - * (necessary for Multicam Selector among others). - */ - SeqRenderData local_context = *context; - local_context.scene = seq->scene; - local_context.skip_cache = true; - - ibuf = do_render_strip_seqbase(&local_context, state, seq, nr); - - /* step back in the list */ - state->scene_parents = state->scene_parents->next; - } - } - else { - /* scene can be NULL after deletions */ - ibuf = seq_render_scene_strip(context, seq, nr, cfra); - } - - break; - } - - case SEQ_TYPE_EFFECT: { - ibuf = seq_render_effect_strip_impl(context, state, seq, cfra); - break; - } - - case SEQ_TYPE_IMAGE: { - ibuf = seq_render_image_strip(context, seq, nr, cfra, r_is_proxy_image); - break; - } - - case SEQ_TYPE_MOVIE: { - ibuf = seq_render_movie_strip(context, seq, nr, cfra, r_is_proxy_image); - break; - } - - case SEQ_TYPE_MOVIECLIP: { - ibuf = seq_render_movieclip_strip(context, seq, nr, r_is_proxy_image); - - if (ibuf) { - /* duplicate frame so movie cache wouldn't be confused by sequencer's stuff */ - ImBuf *i = IMB_dupImBuf(ibuf); - IMB_freeImBuf(ibuf); - ibuf = i; - - if (ibuf->rect_float) { - BKE_sequencer_imbuf_to_sequencer_space(context->scene, ibuf, false); - } - } - - break; - } - - case SEQ_TYPE_MASK: { - /* ibuf is always new */ - ibuf = seq_render_mask_strip(context, seq, nr); - break; - } - } - - if (ibuf) { - sequencer_imbuf_assign_spaces(context->scene, ibuf); - } - - return ibuf; -} - -/* Estimate time spent by the program rendering the strip */ -static clock_t seq_estimate_render_cost_begin(void) -{ - return clock(); -} - -static float seq_estimate_render_cost_end(Scene *scene, clock_t begin) -{ - clock_t end = clock(); - float time_spent = (float)(end - begin); - float time_max = (1.0f / scene->r.frs_sec) * CLOCKS_PER_SEC; - - if (time_max != 0) { - return time_spent / time_max; - } - - return 1; -} - -static ImBuf *seq_render_preprocess_ibuf(const SeqRenderData *context, - Sequence *seq, - ImBuf *ibuf, - float cfra, - clock_t begin, - bool use_preprocess, - const bool is_proxy_image) -{ - if (context->is_proxy_render == false && - (ibuf->x != context->rectx || ibuf->y != context->recty)) { - use_preprocess = true; - } - - if (use_preprocess) { - float cost = seq_estimate_render_cost_end(context->scene, begin); - - /* TODO(Richard): It should be possible to store in cache if image is proxy, - * but it adds quite a bit of complexity. Since proxies are fast to read, I would - * rather simplify existing code a bit. */ - if (!is_proxy_image) { - BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_RAW, ibuf, cost, false); - } - - /* Reset timer so we can get partial render time. */ - begin = seq_estimate_render_cost_begin(); - ibuf = input_preprocess(context, seq, cfra, ibuf, is_proxy_image); - } - - float cost = seq_estimate_render_cost_end(context->scene, begin); - BKE_sequencer_cache_put(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, ibuf, cost, false); - return ibuf; -} - -static ImBuf *seq_render_strip(const SeqRenderData *context, - SeqRenderState *state, - Sequence *seq, - float cfra) -{ - ImBuf *ibuf = NULL; - bool use_preprocess = false; - bool is_proxy_image = false; - - clock_t begin = seq_estimate_render_cost_begin(); - - ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_PREPROCESSED, false); - if (ibuf != NULL) { - return ibuf; - } - - ibuf = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_RAW, false); - if (ibuf == NULL) { - ibuf = do_render_strip_uncached(context, state, seq, cfra, &is_proxy_image); - } - - if (ibuf) { - use_preprocess = BKE_sequencer_input_have_to_preprocess(context, seq, cfra); - ibuf = seq_render_preprocess_ibuf( - context, seq, ibuf, cfra, begin, use_preprocess, is_proxy_image); - } - - if (ibuf == NULL) { - ibuf = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - sequencer_imbuf_assign_spaces(context->scene, ibuf); - } - - return ibuf; -} - -/*********************** strip stack rendering functions *************************/ - -static bool seq_must_swap_input_in_blend_mode(Sequence *seq) -{ - bool swap_input = false; - - /* bad hack, to fix crazy input ordering of - * those two effects */ - - if (ELEM(seq->blend_mode, SEQ_TYPE_ALPHAOVER, SEQ_TYPE_ALPHAUNDER, SEQ_TYPE_OVERDROP)) { - swap_input = true; - } - - return swap_input; -} - -static int seq_get_early_out_for_blend_mode(Sequence *seq) -{ - struct SeqEffectHandle sh = BKE_sequence_get_blend(seq); - float facf = seq->blend_opacity / 100.0f; - int early_out = sh.early_out(seq, facf, facf); - - if (ELEM(early_out, EARLY_DO_EFFECT, EARLY_NO_INPUT)) { - return early_out; - } - - if (seq_must_swap_input_in_blend_mode(seq)) { - if (early_out == EARLY_USE_INPUT_2) { - return EARLY_USE_INPUT_1; - } - if (early_out == EARLY_USE_INPUT_1) { - return EARLY_USE_INPUT_2; - } - } - return early_out; -} - -static ImBuf *seq_render_strip_stack_apply_effect( - const SeqRenderData *context, Sequence *seq, float cfra, ImBuf *ibuf1, ImBuf *ibuf2) -{ - ImBuf *out; - struct SeqEffectHandle sh = BKE_sequence_get_blend(seq); - float facf = seq->blend_opacity / 100.0f; - int swap_input = seq_must_swap_input_in_blend_mode(seq); - - if (swap_input) { - if (sh.multithreaded) { - out = BKE_sequencer_effect_execute_threaded( - &sh, context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL); - } - else { - out = sh.execute(context, seq, cfra, facf, facf, ibuf2, ibuf1, NULL); - } - } - else { - if (sh.multithreaded) { - out = BKE_sequencer_effect_execute_threaded( - &sh, context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL); - } - else { - out = sh.execute(context, seq, cfra, facf, facf, ibuf1, ibuf2, NULL); - } - } - - return out; -} - -static ImBuf *seq_render_strip_stack(const SeqRenderData *context, - SeqRenderState *state, - ListBase *seqbasep, - float cfra, - int chanshown) -{ - Sequence *seq_arr[MAXSEQ + 1]; - int count; - int i; - ImBuf *out = NULL; - clock_t begin; - - count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, (Sequence **)&seq_arr); - - if (count == 0) { - return NULL; - } - - for (i = count - 1; i >= 0; i--) { - int early_out; - Sequence *seq = seq_arr[i]; - - out = BKE_sequencer_cache_get(context, seq, cfra, SEQ_CACHE_STORE_COMPOSITE, false); - - if (out) { - break; - } - if (seq->blend_mode == SEQ_BLEND_REPLACE) { - out = seq_render_strip(context, state, seq, cfra); - break; - } - - early_out = seq_get_early_out_for_blend_mode(seq); - - switch (early_out) { - case EARLY_NO_INPUT: - case EARLY_USE_INPUT_2: - out = seq_render_strip(context, state, seq, cfra); - break; - case EARLY_USE_INPUT_1: - if (i == 0) { - out = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - } - break; - case EARLY_DO_EFFECT: - if (i == 0) { - begin = seq_estimate_render_cost_begin(); - - ImBuf *ibuf1 = IMB_allocImBuf(context->rectx, context->recty, 32, IB_rect); - ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); - - out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); - - float cost = seq_estimate_render_cost_end(context->scene, begin); - BKE_sequencer_cache_put( - context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false); - - IMB_freeImBuf(ibuf1); - IMB_freeImBuf(ibuf2); - } - break; - } - if (out) { - break; - } - } - - i++; - for (; i < count; i++) { - begin = seq_estimate_render_cost_begin(); - Sequence *seq = seq_arr[i]; - - if (seq_get_early_out_for_blend_mode(seq) == EARLY_DO_EFFECT) { - ImBuf *ibuf1 = out; - ImBuf *ibuf2 = seq_render_strip(context, state, seq, cfra); - - out = seq_render_strip_stack_apply_effect(context, seq, cfra, ibuf1, ibuf2); - - IMB_freeImBuf(ibuf1); - IMB_freeImBuf(ibuf2); - } - - float cost = seq_estimate_render_cost_end(context->scene, begin); - BKE_sequencer_cache_put( - context, seq_arr[i], cfra, SEQ_CACHE_STORE_COMPOSITE, out, cost, false); - } - - return out; -} - -/* - * returned ImBuf is refed! - * you have to free after usage! - */ - -ImBuf *BKE_sequencer_give_ibuf(const SeqRenderData *context, float cfra, int chanshown) -{ - Scene *scene = context->scene; - Editing *ed = BKE_sequencer_editing_get(scene, false); - ListBase *seqbasep; - - if (ed == NULL) { - return NULL; - } - - if ((chanshown < 0) && !BLI_listbase_is_empty(&ed->metastack)) { - int count = BLI_listbase_count(&ed->metastack); - count = max_ii(count + chanshown, 0); - seqbasep = ((MetaStack *)BLI_findlink(&ed->metastack, count))->oldbasep; - } - else { - seqbasep = ed->seqbasep; - } - - SeqRenderState state; - sequencer_state_init(&state); - ImBuf *out = NULL; - Sequence *seq_arr[MAXSEQ + 1]; - int count; - - count = BKE_sequencer_get_shown_sequences(seqbasep, cfra, chanshown, seq_arr); - - if (count) { - out = BKE_sequencer_cache_get( - context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, false); - } - - BKE_sequencer_cache_free_temp_cache(context->scene, context->task_id, cfra); - - clock_t begin = seq_estimate_render_cost_begin(); - float cost = 0; - - if (count && !out) { - BLI_mutex_lock(&seq_render_mutex); - out = seq_render_strip_stack(context, &state, seqbasep, cfra, chanshown); - cost = seq_estimate_render_cost_end(context->scene, begin); - - if (context->is_prefetch_render) { - BKE_sequencer_cache_put( - context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false); - } - else { - BKE_sequencer_cache_put_if_possible( - context, seq_arr[count - 1], cfra, SEQ_CACHE_STORE_FINAL_OUT, out, cost, false); - } - BLI_mutex_unlock(&seq_render_mutex); - } - - BKE_sequencer_prefetch_start(context, cfra, cost); - - return out; -} - -ImBuf *BKE_sequencer_give_ibuf_seqbase(const SeqRenderData *context, - float cfra, - int chan_shown, - ListBase *seqbasep) -{ - SeqRenderState state; - sequencer_state_init(&state); - - return seq_render_strip_stack(context, &state, seqbasep, cfra, chan_shown); -} - -ImBuf *BKE_sequencer_give_ibuf_direct(const SeqRenderData *context, float cfra, Sequence *seq) -{ - SeqRenderState state; - sequencer_state_init(&state); - - ImBuf *ibuf = seq_render_strip(context, &state, seq, cfra); - - return ibuf; -} - /* check whether sequence cur depends on seq */ bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur) { @@ -5344,6 +2553,8 @@ static Strip *seq_strip_alloc(int type) if (ELEM(type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) == 0) { strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform"); + strip->transform->scale_x = 1; + strip->transform->scale_y = 1; strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop"); } @@ -5394,35 +2605,6 @@ void BKE_sequence_alpha_mode_from_extension(Sequence *seq) } } -void BKE_sequence_init_colorspace(Sequence *seq) -{ - if (seq->strip && seq->strip->stripdata) { - char name[FILE_MAX]; - ImBuf *ibuf; - - BLI_join_dirfile(name, sizeof(name), seq->strip->dir, seq->strip->stripdata->name); - BLI_path_abs(name, BKE_main_blendfile_path_from_global()); - - /* initialize input color space */ - if (seq->type == SEQ_TYPE_IMAGE) { - ibuf = IMB_loadiffname( - name, IB_test | IB_alphamode_detect, seq->strip->colorspace_settings.name); - - /* byte images are default to straight alpha, however sequencer - * works in premul space, so mark strip to be premultiplied first - */ - seq->alpha_mode = SEQ_ALPHA_STRAIGHT; - if (ibuf) { - if (ibuf->flags & IB_alphamode_premul) { - seq->alpha_mode = IMA_ALPHA_PREMUL; - } - - IMB_freeImBuf(ibuf); - } - } - } -} - float BKE_sequence_get_fps(Scene *scene, Sequence *seq) { switch (seq->type) { diff --git a/source/blender/sequencer/intern/sequencer.h b/source/blender/sequencer/intern/sequencer.h new file mode 100644 index 00000000000..a7217e45ddf --- /dev/null +++ b/source/blender/sequencer/intern/sequencer.h @@ -0,0 +1,149 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2004 Blender Foundation. + * All rights reserved. + */ + +#pragma once + +/** \file + * \ingroup sequencer + */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct Editing; +struct ImBuf; +struct Main; +struct Mask; +struct Scene; +struct Sequence; +struct StripColorBalance; +struct StripElem; + +#define EARLY_NO_INPUT -1 +#define EARLY_DO_EFFECT 0 +#define EARLY_USE_INPUT_1 1 +#define EARLY_USE_INPUT_2 2 + +/* ********************************************************************** + * sequencer.c + * + * sequencer scene functions + * ********************************************************************** */ + +void BKE_sequencer_base_clipboard_pointers_free(struct ListBase *seqbase); +/* ********************************************************************** + * image_cache.c + * + * Sequencer memory cache management functions + * ********************************************************************** */ + +struct ImBuf *BKE_sequencer_cache_get(const SeqRenderData *context, + struct Sequence *seq, + float timeline_frame, + int type, + bool skip_disk_cache); +void BKE_sequencer_cache_put(const SeqRenderData *context, + struct Sequence *seq, + float timeline_frame, + int type, + struct ImBuf *i, + float cost, + bool skip_disk_cache); +bool BKE_sequencer_cache_put_if_possible(const SeqRenderData *context, + struct Sequence *seq, + float cfra, + int type, + struct ImBuf *nval, + float cost, + bool skip_disk_cache); +bool BKE_sequencer_cache_recycle_item(struct Scene *scene); +void BKE_sequencer_cache_free_temp_cache(struct Scene *scene, short id, int timeline_frame); +void BKE_sequencer_cache_destruct(struct Scene *scene); +void BKE_sequencer_cache_cleanup_all(struct Main *bmain); +void BKE_sequencer_cache_cleanup_sequence(struct Scene *scene, + struct Sequence *seq, + struct Sequence *seq_changed, + int invalidate_types, + bool force_seq_changed_range); +bool BKE_sequencer_cache_is_full(struct Scene *scene); + +/* ********************************************************************** + * prefetch.c + * + * Sequencer frame prefetching + * ********************************************************************** */ + +void BKE_sequencer_prefetch_start(const SeqRenderData *context, float cfra, float cost); +void BKE_sequencer_prefetch_free(struct Scene *scene); +bool BKE_sequencer_prefetch_job_is_running(struct Scene *scene); +void BKE_sequencer_prefetch_get_time_range(struct Scene *scene, int *start, int *end); +SeqRenderData *BKE_sequencer_prefetch_get_original_context(const SeqRenderData *context); +struct Sequence *BKE_sequencer_prefetch_get_original_sequence(struct Sequence *seq, + struct Scene *scene); + +/* ********************************************************************** + * seqeffects.c + * + * Sequencer effect strip management functions + * ********************************************************************** + */ + +struct SeqEffectHandle BKE_sequence_get_blend(struct Sequence *seq); +void BKE_sequence_effect_speed_rebuild_map(struct Scene *scene, struct Sequence *seq, bool force); +float BKE_sequencer_speed_effect_target_frame_get(const SeqRenderData *context, + struct Sequence *seq, + float cfra, + int input); + +/* ********************************************************************** + * sequencer.c + * + * Sequencer editing functions + * ********************************************************************** + */ + +void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq); +struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */, + struct Sequence *meta /* = NULL */, + struct Sequence *seq); +void seq_free_sequence_recurse(struct Scene *scene, struct Sequence *seq, const bool do_id_user); +void seq_multiview_name(struct Scene *scene, + const int view_id, + const char *prefix, + const char *ext, + char *r_path, + size_t r_size); +int seq_num_files(struct Scene *scene, char views_format, const bool is_multiview); +void seq_open_anim_file(struct Scene *scene, struct Sequence *seq, bool openfile); +void seq_proxy_index_dir_set(struct anim *anim, const char *base_dir); + +/* ********************************************************************** + * sequencer.c + * + * Unused + * ********************************************************************** + */ +bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur); +void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce); +int BKE_sequence_effect_get_supports_mask(int seq_type); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/simulation/SIM_mass_spring.h b/source/blender/simulation/SIM_mass_spring.h index 219ead477c2..42d7c86b539 100644 --- a/source/blender/simulation/SIM_mass_spring.h +++ b/source/blender/simulation/SIM_mass_spring.h @@ -18,7 +18,7 @@ */ /** \file - * \ingroup bph + * \ingroup sim */ #pragma once diff --git a/source/blender/simulation/intern/ConstrainedConjugateGradient.h b/source/blender/simulation/intern/ConstrainedConjugateGradient.h index 0dc80c03bb5..11dc3ebe91b 100644 --- a/source/blender/simulation/intern/ConstrainedConjugateGradient.h +++ b/source/blender/simulation/intern/ConstrainedConjugateGradient.h @@ -19,6 +19,10 @@ #pragma once +/** \file + * \ingroup sim + */ + #include <Eigen/Core> namespace Eigen { diff --git a/source/blender/simulation/intern/SIM_mass_spring.cpp b/source/blender/simulation/intern/SIM_mass_spring.cpp index 42cfb11a15a..57276be469c 100644 --- a/source/blender/simulation/intern/SIM_mass_spring.cpp +++ b/source/blender/simulation/intern/SIM_mass_spring.cpp @@ -18,7 +18,7 @@ */ /** \file - * \ingroup bph + * \ingroup sim */ #include "MEM_guardedalloc.h" @@ -317,8 +317,7 @@ static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), float len, c, l, vec[3]; spring = (ClothSpring *)node->link; - if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && - spring->type != CLOTH_SPRING_TYPE_SHEAR) { + if (!ELEM(spring->type, CLOTH_SPRING_TYPE_STRUCTURAL, CLOTH_SPRING_TYPE_SHEAR)) { continue; } diff --git a/source/blender/simulation/intern/eigen_utils.h b/source/blender/simulation/intern/eigen_utils.h index 897ba8b2a67..a5d7d5bc808 100644 --- a/source/blender/simulation/intern/eigen_utils.h +++ b/source/blender/simulation/intern/eigen_utils.h @@ -20,7 +20,7 @@ #pragma once /** \file - * \ingroup bph + * \ingroup sim */ #if defined(__GNUC__) && !defined(__clang__) diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp index c24b7154d13..49868296295 100644 --- a/source/blender/simulation/intern/hair_volume.cpp +++ b/source/blender/simulation/intern/hair_volume.cpp @@ -18,7 +18,7 @@ */ /** \file - * \ingroup bph + * \ingroup sim */ #include "MEM_guardedalloc.h" diff --git a/source/blender/simulation/intern/implicit.h b/source/blender/simulation/intern/implicit.h index c5afa90aa91..a8693c61018 100644 --- a/source/blender/simulation/intern/implicit.h +++ b/source/blender/simulation/intern/implicit.h @@ -20,7 +20,7 @@ #pragma once /** \file - * \ingroup bph + * \ingroup sim */ #include "stdio.h" diff --git a/source/blender/simulation/intern/implicit_blender.c b/source/blender/simulation/intern/implicit_blender.c index df8c4782acd..4c4d3e8a821 100644 --- a/source/blender/simulation/intern/implicit_blender.c +++ b/source/blender/simulation/intern/implicit_blender.c @@ -18,7 +18,7 @@ */ /** \file - * \ingroup bph + * \ingroup sim */ #include "implicit.h" diff --git a/source/blender/simulation/intern/implicit_eigen.cpp b/source/blender/simulation/intern/implicit_eigen.cpp index b30a46909b9..ea1729589d6 100644 --- a/source/blender/simulation/intern/implicit_eigen.cpp +++ b/source/blender/simulation/intern/implicit_eigen.cpp @@ -18,7 +18,7 @@ */ /** \file - * \ingroup bph + * \ingroup sim */ #include "implicit.h" diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 8d4ef29af74..b81ef14f21c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -729,6 +729,7 @@ enum { WM_JOB_TYPE_LIGHT_BAKE, WM_JOB_TYPE_FSMENU_BOOKMARK_VALIDATE, WM_JOB_TYPE_QUADRIFLOW_REMESH, + WM_JOB_TYPE_TRACE_IMAGE, /* add as needed, bake, seq proxy build * if having hard coded values is a problem */ }; diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c index b81b12a1b06..a56a506b1ab 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo.c @@ -611,6 +611,7 @@ void WM_gizmo_calc_matrix_final(const wmGizmo *gz, float r_mat[4][4]) r_mat); } +/* -------------------------------------------------------------------- */ /** \name Gizmo Property Access * * Matches `WM_operator_properties` conventions. @@ -755,6 +756,7 @@ void WM_gizmo_properties_free(PointerRNA *ptr) /** \} */ +/* -------------------------------------------------------------------- */ /** \name General Utilities * * \{ */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index eea046cd1cf..e9a1b5e3df0 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -344,6 +344,7 @@ bool wm_gizmogroup_is_any_selected(const wmGizmoGroup *gzgroup) /** \} */ +/* -------------------------------------------------------------------- */ /** \name Gizmo operators * * Basic operators for gizmo interaction with user configurable keymaps. diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c index f594ced6b66..a9e24867351 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.c @@ -38,6 +38,7 @@ #include "wm_gizmo_intern.h" #include "wm_gizmo_wmapi.h" +/* -------------------------------------------------------------------- */ /** \name GizmoGroup Type Append * * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends. diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c index 3956ff8fd36..efd7a13d02a 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.c @@ -45,6 +45,7 @@ #include "wm_gizmo_intern.h" #include "wm_gizmo_wmapi.h" +/* -------------------------------------------------------------------- */ /** \name Gizmo Type Append * * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends. diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index e7010461c68..68547323761 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -120,6 +120,8 @@ IDTypeInfo IDType_ID_WM = { .blend_read_data = NULL, .blend_read_lib = NULL, .blend_read_expand = NULL, + + .blend_read_undo_preserve = NULL, }; #define MAX_OP_REGISTERED 32 diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index 3449c6974f5..b11dae27d19 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -103,7 +103,7 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region) continue; } - if ((pc->region_type != RGN_TYPE_ANY) && (region->regiontype != pc->region_type)) { + if (!ELEM(pc->region_type, RGN_TYPE_ANY, region->regiontype)) { continue; } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 8f141a8e23b..071951abda3 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1731,8 +1731,21 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) BLI_assert(handler_base->type != 0); if (handler_base->type == WM_HANDLER_TYPE_OP) { wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base; + if (handler->op) { wmWindow *win = CTX_wm_window(C); + + if (handler->is_fileselect) { + /* Exit File Browsers referring to this handler/operator. */ + LISTBASE_FOREACH (wmWindow *, temp_win, &wm->windows) { + ScrArea *file_area = ED_fileselect_handler_area_find(temp_win, handler->op); + if (!file_area) { + continue; + } + ED_area_exit(C, file_area); + } + } + if (handler->op->type->cancel) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); @@ -3471,25 +3484,15 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) if (handler->is_fileselect == false) { continue; } - bScreen *screen = CTX_wm_screen(C); - bool cancel_handler = true; - /* Find the area with the file selector for this handler. */ - ED_screen_areas_iter (win, screen, area) { - if (area->spacetype == SPACE_FILE) { - SpaceFile *sfile = area->spacedata.first; + ScrArea *file_area = ED_fileselect_handler_area_find(win, handler->op); - if (sfile->op == handler->op) { - CTX_wm_area_set(C, area); - wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL); - cancel_handler = false; - break; - } - } + if (file_area) { + CTX_wm_area_set(C, file_area); + wm_handler_fileselect_do(C, &win->modalhandlers, handler, EVT_FILESELECT_CANCEL); } - /* If not found we stop the handler without changing the screen. */ - if (cancel_handler) { + else { wm_handler_fileselect_do( C, &win->modalhandlers, handler, EVT_FILESELECT_EXTERNAL_CANCEL); } @@ -4397,7 +4400,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void wm_event_add(win, &event); break; } - /* ,ouse button, */ + /* Mouse button. */ case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd = customdata; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a862d221815..4706287a3a9 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -2482,7 +2482,7 @@ void WM_OT_open_mainfile(wmOperatorType *ot) FILE_OPENFILE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean( ot->srna, "load_ui", true, "Load UI", "Load user interface setup in the .blend file"); @@ -2804,7 +2804,7 @@ void WM_OT_save_as_mainfile(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", @@ -2874,7 +2874,7 @@ void WM_OT_save_mainfile(wmOperatorType *ot) FILE_SAVE, WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); RNA_def_boolean(ot->srna, "relative_remap", @@ -3190,8 +3190,13 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points); const int dialog_width = icon_size + (text_points_max * 34 * U.dpi_fac); + /* By default, the space between icon and text/buttons will be equal to the 'columnspace', + this extra padding will add some space by increasing the left column width, + making the icon placement more symmetrical, between the block edge and the text. */ + const float icon_padding = 6.0f * U.dpi_fac; /* Calculate icon column factor. */ - const float split_factor = (float)icon_size / (float)(dialog_width - style->columnspace); + const float split_factor = ((float)icon_size + icon_padding) / + (float)(dialog_width - style->columnspace); uiBlock *block = UI_block_begin(C, region, close_file_dialog_name, UI_EMBOSS); @@ -3207,8 +3212,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false); /* Alert Icon. */ - uiLayout *layout = uiLayoutColumn(split_block, false); - uiDefButAlert(block, ALERT_ICON_QUESTION, 0, 0, 0, icon_size); + uiLayout *layout = uiLayoutRow(split_block, false); + /* Using 'align_left' with 'row' avoids stretching the icon along the width of column. */ + uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_LEFT); + uiDefButAlert(block, ALERT_ICON_QUESTION, 0, 0, icon_size, icon_size); /* The rest of the content on the right. */ layout = uiLayoutColumn(split_block, false); @@ -3221,10 +3228,9 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, char filename[FILE_MAX]; if (blendfile_pathpath[0] != '\0') { BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename)); - BLI_path_extension_replace(filename, sizeof(filename), ""); } else { - STRNCPY(filename, IFACE_("Untitled")); + STRNCPY(filename, IFACE_("untitled.blend")); } uiItemL(layout, filename, ICON_NONE); @@ -3236,7 +3242,7 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, LISTBASE_FOREACH (Report *, report, &reports.list) { uiLayout *row = uiLayoutColumn(layout, false); uiLayoutSetScaleY(row, 0.6f); - uiItemS_ex(row, 1.2f); + uiItemS(row); /* Error messages created in ED_image_save_all_modified_info() can be long, * but are made to separate into two parts at first colon between text and paths. @@ -3259,12 +3265,8 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, /* Modified Images Checkbox. */ if (modified_images_count > 0) { char message[64]; - BLI_snprintf(message, - sizeof(message), - (modified_images_count == 1) ? "Save %u modified image" : - "Save %u modified images", - modified_images_count); - uiItemS_ex(layout, 2.0f); + BLI_snprintf(message, sizeof(message), "Save %u modified image(s)", modified_images_count); + uiItemS(layout); uiDefButBitC(block, UI_BTYPE_CHECKBOX, 1, @@ -3284,7 +3286,7 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, BKE_reports_clear(&reports); - uiItemS_ex(layout, 1.0f); + uiItemS_ex(layout, modified_images_count > 0 ? 2.0f : 4.0f); /* Buttons. */ #ifdef _WIN32 @@ -3296,13 +3298,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, if (windows_layout) { /* Windows standard layout. */ - uiLayout *split = uiLayoutSplit(block_layout, 0.174f, true); + uiLayout *split = uiLayoutSplit(layout, 0.0f, true); uiLayoutSetScaleY(split, 1.2f); uiLayoutColumn(split, false); - uiItemS(layout); - - uiLayoutColumn(split, false); wm_block_file_close_save_button(block, post_action); uiLayoutColumn(split, false); @@ -3314,21 +3313,16 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, else { /* Non-Windows layout (macOS and Linux). */ - uiLayout *split = uiLayoutSplit(block_layout, 0.167f, true); + uiLayout *split = uiLayoutSplit(layout, 0.3f, true); uiLayoutSetScaleY(split, 1.2f); - layout = uiLayoutColumn(split, false); - uiItemS(layout); - - /* Split button area into two sections: 40/60. */ - uiLayout *split_left = uiLayoutSplit(split, 0.40f, true); - - /* First button uses 75% of left side (30% of original). */ - uiLayoutSplit(split_left, 0.75f, true); + uiLayoutColumn(split, false); wm_block_file_close_discard_button(block, post_action); - /* The right side is split 50/50 (each 30% of original). */ - uiLayout *split_right = uiLayoutSplit(split_left, 0.50f, true); + uiLayout *split_right = uiLayoutSplit(split, 0.1f, true); + + uiLayoutColumn(split_right, false); + /* Empty space. */ uiLayoutColumn(split_right, false); wm_block_file_close_cancel_button(block, post_action); diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c index cfbc037d19c..49ac250d9a3 100644 --- a/source/blender/windowmanager/intern/wm_files_link.c +++ b/source/blender/windowmanager/intern/wm_files_link.c @@ -598,7 +598,7 @@ void WM_OT_link(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); wm_link_append_properties_common(ot, true); } @@ -622,7 +622,7 @@ void WM_OT_append(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_FILES | WM_FILESEL_SHOW_PROPS, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); wm_link_append_properties_common(ot, false); RNA_def_boolean(ot->srna, @@ -1172,7 +1172,7 @@ void WM_OT_lib_relocate(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_FILES | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } static int wm_lib_reload_exec(bContext *C, wmOperator *op) @@ -1202,7 +1202,7 @@ void WM_OT_lib_reload(wmOperatorType *ot) WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH, FILE_DEFAULTDISPLAY, - FILE_SORT_ALPHA); + FILE_SORT_DEFAULT); } /** \} */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index ac9d3848f3a..926e61f4a0e 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -72,15 +72,16 @@ #include "BKE_addon.h" #include "BKE_appdir.h" -#include "BKE_mask.h" /* free mask clipboard */ -#include "BKE_material.h" /* BKE_material_copybuf_clear */ -#include "BKE_sequencer.h" /* free seq clipboard */ +#include "BKE_mask.h" /* free mask clipboard */ +#include "BKE_material.h" /* BKE_material_copybuf_clear */ #include "BKE_studiolight.h" #include "BKE_tracking.h" /* free tracking clipboard */ #include "RE_engine.h" #include "RE_pipeline.h" /* RE_ free stuff */ +#include "SEQ_sequencer.h" /* free seq clipboard */ + #include "IMB_thumbs.h" #ifdef WITH_PYTHON diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index 361b3ed3d7f..a1140c01d44 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -35,7 +35,8 @@ #include "BKE_context.h" #include "BKE_global.h" -#include "BKE_sequencer.h" + +#include "SEQ_sequencer.h" #include "WM_api.h" #include "WM_types.h" @@ -226,7 +227,7 @@ bool WM_jobs_test(wmWindowManager *wm, void *owner, int job_type) /* job can be running or about to run (suspended) */ for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) { if (wm_job->owner == owner) { - if (job_type == WM_JOB_TYPE_ANY || (wm_job->job_type == job_type)) { + if (ELEM(job_type, WM_JOB_TYPE_ANY, wm_job->job_type)) { if (wm_job->running || wm_job->suspended) { return true; } @@ -250,7 +251,7 @@ float WM_jobs_progress(wmWindowManager *wm, void *owner) static void wm_jobs_update_progress_bars(wmWindowManager *wm) { - float total_progress = 0.f; + float total_progress = 0.0f; float jobs_progress = 0; LISTBASE_FOREACH (wmJob *, wm_job, &wm->jobs) { @@ -586,7 +587,7 @@ void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type) next_job = wm_job->next; if (!owner || wm_job->owner == owner) { - if (job_type == WM_JOB_TYPE_ANY || wm_job->job_type == job_type) { + if (ELEM(job_type, WM_JOB_TYPE_ANY, wm_job->job_type)) { wm_jobs_kill_job(wm, wm_job); } } diff --git a/source/blender/windowmanager/intern/wm_operator_props.c b/source/blender/windowmanager/intern/wm_operator_props.c index 62294d70306..631a4d23eb5 100644 --- a/source/blender/windowmanager/intern/wm_operator_props.c +++ b/source/blender/windowmanager/intern/wm_operator_props.c @@ -48,6 +48,30 @@ void WM_operator_properties_confirm_or_exec(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } +/** + * Extends rna_enum_fileselect_params_sort_items with a default item for operators to use. + */ +static const EnumPropertyItem *wm_operator_properties_filesel_sort_items_itemf( + struct bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) +{ + EnumPropertyItem *items; + const EnumPropertyItem default_item = { + FILE_SORT_DEFAULT, + "DEFAULT", + 0, + "Default", + "Automatically determine sort method for files", + }; + int totitem = 0; + + RNA_enum_item_add(&items, &totitem, &default_item); + RNA_enum_items_add(&items, &totitem, rna_enum_fileselect_params_sort_items); + RNA_enum_item_end(&items, &totitem); + *r_free = true; + + return items; +} + /* default properties for fileselect */ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, @@ -204,8 +228,8 @@ void WM_operator_properties_filesel(wmOperatorType *ot, prop = RNA_def_enum(ot->srna, "display_type", file_display_items, display, "Display Type", ""); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - prop = RNA_def_enum( - ot->srna, "sort_method", rna_enum_file_sort_items, sort, "File sorting mode", ""); + prop = RNA_def_enum(ot->srna, "sort_method", DummyRNA_NULL_items, sort, "File sorting mode", ""); + RNA_def_enum_funcs(prop, wm_operator_properties_filesel_sort_items_itemf); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } @@ -260,12 +284,12 @@ void WM_operator_properties_select_random(wmOperatorType *ot) { RNA_def_float_percentage(ot->srna, "percent", - 50.f, + 50.0f, 0.0f, 100.0f, "Percent", "Percentage of objects to select randomly", - 0.f, + 0.0f, 100.0f); RNA_def_int(ot->srna, "seed", diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index cde0cb77678..7621862708e 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -95,6 +95,7 @@ void WM_operatortype_iter(GHashIterator *ghi) BLI_ghashIterator_init(ghi, global_ops_hash); } +/* -------------------------------------------------------------------- */ /** \name Operator Type Append * \{ */ @@ -324,13 +325,11 @@ static int wm_macro_end(wmOperator *op, int retval) /* macro exec only runs exec calls */ static int wm_macro_exec(bContext *C, wmOperator *op) { - wmOperator *opm; int retval = OPERATOR_FINISHED; wm_macro_start(op); - for (opm = op->macro.first; opm; opm = opm->next) { - + LISTBASE_FOREACH (wmOperator *, opm, &op->macro) { if (opm->type->exec) { retval = opm->type->exec(C, opm); OPERATOR_RETVAL_CHECK(retval); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 613de5a9b17..7b1d69e83c7 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1810,7 +1810,7 @@ static void WM_OT_call_menu(wmOperatorType *ot) { ot->name = "Call Menu"; ot->idname = "WM_OT_call_menu"; - ot->description = "Call (draw) a pre-defined menu"; + ot->description = "Call (draw) a predefined menu"; ot->exec = wm_call_menu_exec; ot->poll = WM_operator_winactive; @@ -1841,7 +1841,7 @@ static void WM_OT_call_menu_pie(wmOperatorType *ot) { ot->name = "Call Pie Menu"; ot->idname = "WM_OT_call_menu_pie"; - ot->description = "Call (draw) a pre-defined pie menu"; + ot->description = "Call (draw) a predefined pie menu"; ot->invoke = wm_call_pie_menu_invoke; ot->exec = wm_call_pie_menu_exec; @@ -1875,7 +1875,7 @@ static void WM_OT_call_panel(wmOperatorType *ot) { ot->name = "Call Panel"; ot->idname = "WM_OT_call_panel"; - ot->description = "Call (draw) a pre-defined panel"; + ot->description = "Call (draw) a predefined panel"; ot->exec = wm_call_panel_exec; ot->poll = WM_operator_winactive; @@ -2886,7 +2886,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even case PROP_FACTOR: new_value = (WM_RADIAL_CONTROL_DISPLAY_SIZE - dist) / WM_RADIAL_CONTROL_DISPLAY_WIDTH; if (snap) { - new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f; + new_value = ((int)ceil(new_value * 10.0f) * 10.0f) / 100.0f; } /* Invert new value to increase the factor moving the mouse to the right */ new_value = 1 - new_value; @@ -3771,7 +3771,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) {GESTURE_MODAL_CIRCLE_SIZE, "SIZE", 0, "Size", ""}, {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, - {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""}, + {GESTURE_MODAL_DESELECT, "DESELECT", 0, "Deselect", ""}, {GESTURE_MODAL_NOP, "NOP", 0, "No Operation", ""}, {0, NULL, 0, NULL, NULL}, @@ -3834,7 +3834,7 @@ static void gesture_box_modal_keymap(wmKeyConfig *keyconf) static const EnumPropertyItem modal_items[] = { {GESTURE_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, {GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""}, - {GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""}, + {GESTURE_MODAL_DESELECT, "DESELECT", 0, "Deselect", ""}, {GESTURE_MODAL_BEGIN, "BEGIN", 0, "Begin", ""}, {GESTURE_MODAL_MOVE, "MOVE", 0, "Move", ""}, {0, NULL, 0, NULL, NULL}, diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 5d1607fe506..ee6aee1fb7a 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -1274,7 +1274,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv) g_WS.ghost_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_WS.ghost_system, consumer); - playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y); + playanim_window_open("Blender Animation Player", start_x, start_y, ibuf->x, ibuf->y); } GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &maxwinx, &maxwiny); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 6c9b6915da8..589b8e2f156 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1767,7 +1767,7 @@ static char *wm_clipboard_text_get_ex(bool selection, int *r_len, bool firstline if (firstline) { /* will return an over-alloc'ed value in the case there are newlines */ for (char *p = buf; *p; p++) { - if ((*p != '\n') && (*p != '\r')) { + if (!ELEM(*p, '\n', '\r')) { *(p2++) = *p; } else { diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 74c2797856d..7f4f8d47688 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -152,32 +152,47 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) # -------------------------------------------------------------------------- # These defines could all be moved into the header below - string(REPLACE " " "\ " BUILDINFO_CFLAGS "${CMAKE_C_FLAGS}") - string(REPLACE " " "\ " BUILDINFO_CXXFLAGS "${CMAKE_CXX_FLAGS}") - string(REPLACE " " "\ " BUILDINFO_LINKFLAGS "${PLATFORM_LINKFLAGS}") - add_definitions( - # # define in header now, else these get out of date on rebuilds. - # -DBUILD_DATE="${BUILD_DATE}" - # -DBUILD_TIME="${BUILD_TIME}" - # -DBUILD_COMMIT_TIMESTAMP="${BUILD_COMMIT_TIMESTAMP}" - # -DBUILD_COMMIT_TIME="${BUILD_COMMIT_TIME}" - # -DBUILD_COMMIT_DATE="${BUILD_COMMIT_DATE}" - # -DBUILD_HASH="${BUILD_HASH}" - # -DBUILD_BRANCH="${BUILD_BRANCH}" - -DWITH_BUILDINFO_HEADER # alternative to lines above - -DBUILD_PLATFORM="${CMAKE_SYSTEM_NAME}" - -DBUILD_TYPE="${CMAKE_BUILD_TYPE}" - -DBUILD_CFLAGS="${BUILDINFO_CFLAGS}" - -DBUILD_CXXFLAGS="${BUILDINFO_CXXFLAGS}" - -DBUILD_LINKFLAGS="${BUILDINFO_LINKFLAGS}" - -DBUILD_SYSTEM="CMake" + + # Write strings into a separate header since we can escape C-strings + # in a way that's not practical when passing defines. + set(BUILD_PLATFORM "${CMAKE_SYSTEM_NAME}") + set(BUILD_TYPE "${CMAKE_BUILD_TYPE}") + set(BUILD_CFLAGS "${CMAKE_C_FLAGS}") + set(BUILD_CXXFLAGS "${CMAKE_CXX_FLAGS}") + set(BUILD_LINKFLAGS "${PLATFORM_LINKFLAGS}") + set(BUILD_SYSTEM "CMake") + + if(WITH_COMPILER_SHORT_FILE_MACRO) + # It's not necessary to include path information + # about the system building Blender in the executable. + string(REPLACE "${PLATFORM_CFLAGS_FMACRO_PREFIX_MAP}" " " BUILD_CFLAGS "${BUILD_CFLAGS}") + string(REPLACE "${PLATFORM_CFLAGS_FMACRO_PREFIX_MAP}" " " BUILD_CXXFLAGS "${BUILD_CXXFLAGS}") + endif() + + # Use `configure_file` instead of definitions since properly + # escaping the multiple command line arguments which themselves + # contain strings and spaces becomes overly error-prone & complicated. + configure_file( + "${CMAKE_SOURCE_DIR}/build_files/cmake/buildinfo_static.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/buildinfo_static.h" + ESCAPE_QUOTES + @ONLY ) + unset(BUILD_PLATFORM) + unset(BUILD_TYPE) + unset(BUILD_CFLAGS) + unset(BUILD_CXXFLAGS) + unset(BUILD_LINKFLAGS) + unset(BUILD_SYSTEM) + # -------------------------------------------------------------------------- # write header for values that change each build # note, generaed file is in build dir's source/creator # except when used as an include path. + add_definitions(-DWITH_BUILDINFO_HEADER) + # include the output directory, where the buildinfo.h file is generated include_directories(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/source/creator/creator.c b/source/creator/creator.c index 65610ea9b70..3365dad75d1 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -163,7 +163,7 @@ static void callback_main_atexit(void *user_data) struct CreatorAtExitData *app_init_data = user_data; if (app_init_data->ba) { - BLI_argsFree(app_init_data->ba); + BLI_args_destroy(app_init_data->ba); app_init_data->ba = NULL; } @@ -349,7 +349,7 @@ int main(int argc, #if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) && !defined(WITH_HEADLESS) /* Patch to ignore argument finder gives us (PID?) */ - if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) { + if (argc == 2 && STRPREFIX(argv[1], "-psn_")) { extern int GHOST_HACK_getFirstFile(char buf[]); static char firstfilebuf[512]; @@ -392,7 +392,7 @@ int main(int argc, /* First test for background-mode (#Global.background) */ #ifndef WITH_PYTHON_MODULE - ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */ + ba = BLI_args_create(argc, (const char **)argv); /* skip binary path */ /* Ensure we free on early exit. */ app_init_data.ba = ba; @@ -403,35 +403,42 @@ int main(int argc, * (such as '--version' & '--help') don't report leaks. */ MEM_use_memleak_detection(false); - BLI_argsParse(ba, 1, NULL, NULL); - - main_signal_setup(); + /* Parse environment handling arguments. */ + BLI_args_parse(ba, ARG_PASS_ENVIRONMENT, NULL, NULL); #else /* Using preferences or user startup makes no sense for #WITH_PYTHON_MODULE. */ G.factory_startup = true; #endif - /* After parsing the first level of arguments as `--env-*` impact BKE_appdir behavior. */ + /* After parsing #ARG_PASS_ENVIRONMENT such as `--env-*`, + * since they impact `BKE_appdir` behavior. */ BKE_appdir_init(); /* After parsing number of threads argument. */ BLI_task_scheduler_init(); - /* After parsing `--env-system-datafiles` which control where paths are searched - * (color-management) uses BKE_appdir to initialize. */ + /* Initialize sub-systems that use `BKE_appdir.h`. */ IMB_init(); +#ifndef WITH_PYTHON_MODULE + /* First test for background-mode (#Global.background) */ + BLI_args_parse(ba, ARG_PASS_SETTINGS, NULL, NULL); + + main_signal_setup(); +#endif + #ifdef WITH_FFMPEG + /* Keep after #ARG_PASS_SETTINGS since debug flags are checked. */ IMB_ffmpeg_init(); #endif - /* After level 1 arguments, this is so #WM_main_playanim skips #RNA_init. */ + /* After #ARG_PASS_SETTINGS arguments, this is so #WM_main_playanim skips #RNA_init. */ RNA_init(); RE_engines_init(); - init_nodesystem(); - psys_init_rng(); + BKE_node_system_init(); + BKE_particle_init_rng(); /* End second initialization. */ #if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS) @@ -452,20 +459,15 @@ int main(int argc, BKE_materials_init(); - if (G.background == 0) { #ifndef WITH_PYTHON_MODULE - BLI_argsParse(ba, 2, NULL, NULL); - BLI_argsParse(ba, 3, NULL, NULL); -#endif - WM_init(C, argc, (const char **)argv); + if (G.background == 0) { + BLI_args_parse(ba, ARG_PASS_SETTINGS_GUI, NULL, NULL); } - else { -#ifndef WITH_PYTHON_MODULE - BLI_argsParse(ba, 3, NULL, NULL); + BLI_args_parse(ba, ARG_PASS_SETTINGS_FORCE, NULL, NULL); #endif - WM_init(C, argc, (const char **)argv); - } + WM_init(C, argc, (const char **)argv); + #ifndef WITH_PYTHON printf( "\n* WARNING * - Blender compiled without Python!\n" @@ -483,6 +485,7 @@ int main(int argc, /* OK we are ready for it */ #ifndef WITH_PYTHON_MODULE + /* Handles #ARG_PASS_FINAL. */ main_args_setup_post(C, ba); #endif diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 3b54811657d..077eb4e6821 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -48,7 +48,6 @@ # include "BKE_blender_version.h" # include "BKE_context.h" -# include "BKE_appdir.h" # include "BKE_global.h" # include "BKE_image.h" # include "BKE_lib_id.h" @@ -57,7 +56,9 @@ # include "BKE_scene.h" # include "BKE_sound.h" -# include "IMB_imbuf.h" +# ifdef WITH_FFMPEG +# include "IMB_imbuf.h" +# endif # ifdef WITH_PYTHON # include "BPY_extern_python.h" @@ -342,7 +343,7 @@ static int (*parse_int_range_relative_clamp_n(const char *str, while (true) { const char *str_end_range; const char *str_end = strchr(str, sep); - if ((*str == sep) || (*str == '\0')) { + if (ELEM(*str, sep, '\0')) { static const char *msg = "incorrect comma use"; *r_err_msg = msg; goto fail; @@ -516,128 +517,128 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo printf("Usage: blender [args ...] [file] [args ...]\n\n"); printf("Render Options:\n"); - BLI_argsPrintArgDoc(ba, "--background"); - BLI_argsPrintArgDoc(ba, "--render-anim"); - BLI_argsPrintArgDoc(ba, "--scene"); - BLI_argsPrintArgDoc(ba, "--render-frame"); - BLI_argsPrintArgDoc(ba, "--frame-start"); - BLI_argsPrintArgDoc(ba, "--frame-end"); - BLI_argsPrintArgDoc(ba, "--frame-jump"); - BLI_argsPrintArgDoc(ba, "--render-output"); - BLI_argsPrintArgDoc(ba, "--engine"); - BLI_argsPrintArgDoc(ba, "--threads"); + BLI_args_print_arg_doc(ba, "--background"); + BLI_args_print_arg_doc(ba, "--render-anim"); + BLI_args_print_arg_doc(ba, "--scene"); + BLI_args_print_arg_doc(ba, "--render-frame"); + BLI_args_print_arg_doc(ba, "--frame-start"); + BLI_args_print_arg_doc(ba, "--frame-end"); + BLI_args_print_arg_doc(ba, "--frame-jump"); + BLI_args_print_arg_doc(ba, "--render-output"); + BLI_args_print_arg_doc(ba, "--engine"); + BLI_args_print_arg_doc(ba, "--threads"); printf("\n"); printf("Format Options:\n"); - BLI_argsPrintArgDoc(ba, "--render-format"); - BLI_argsPrintArgDoc(ba, "--use-extension"); + BLI_args_print_arg_doc(ba, "--render-format"); + BLI_args_print_arg_doc(ba, "--use-extension"); printf("\n"); printf("Animation Playback Options:\n"); - BLI_argsPrintArgDoc(ba, "-a"); + BLI_args_print_arg_doc(ba, "-a"); printf("\n"); printf("Window Options:\n"); - BLI_argsPrintArgDoc(ba, "--window-border"); - BLI_argsPrintArgDoc(ba, "--window-fullscreen"); - BLI_argsPrintArgDoc(ba, "--window-geometry"); - BLI_argsPrintArgDoc(ba, "--window-maximized"); - BLI_argsPrintArgDoc(ba, "--start-console"); - BLI_argsPrintArgDoc(ba, "--no-native-pixels"); - BLI_argsPrintArgDoc(ba, "--no-window-focus"); + BLI_args_print_arg_doc(ba, "--window-border"); + BLI_args_print_arg_doc(ba, "--window-fullscreen"); + BLI_args_print_arg_doc(ba, "--window-geometry"); + BLI_args_print_arg_doc(ba, "--window-maximized"); + BLI_args_print_arg_doc(ba, "--start-console"); + BLI_args_print_arg_doc(ba, "--no-native-pixels"); + BLI_args_print_arg_doc(ba, "--no-window-focus"); printf("\n"); printf("Python Options:\n"); - BLI_argsPrintArgDoc(ba, "--enable-autoexec"); - BLI_argsPrintArgDoc(ba, "--disable-autoexec"); + BLI_args_print_arg_doc(ba, "--enable-autoexec"); + BLI_args_print_arg_doc(ba, "--disable-autoexec"); printf("\n"); - BLI_argsPrintArgDoc(ba, "--python"); - BLI_argsPrintArgDoc(ba, "--python-text"); - BLI_argsPrintArgDoc(ba, "--python-expr"); - BLI_argsPrintArgDoc(ba, "--python-console"); - BLI_argsPrintArgDoc(ba, "--python-exit-code"); - BLI_argsPrintArgDoc(ba, "--python-use-system-env"); - BLI_argsPrintArgDoc(ba, "--addons"); + BLI_args_print_arg_doc(ba, "--python"); + BLI_args_print_arg_doc(ba, "--python-text"); + BLI_args_print_arg_doc(ba, "--python-expr"); + BLI_args_print_arg_doc(ba, "--python-console"); + BLI_args_print_arg_doc(ba, "--python-exit-code"); + BLI_args_print_arg_doc(ba, "--python-use-system-env"); + BLI_args_print_arg_doc(ba, "--addons"); printf("\n"); printf("Logging Options:\n"); - BLI_argsPrintArgDoc(ba, "--log"); - BLI_argsPrintArgDoc(ba, "--log-level"); - BLI_argsPrintArgDoc(ba, "--log-show-basename"); - BLI_argsPrintArgDoc(ba, "--log-show-backtrace"); - BLI_argsPrintArgDoc(ba, "--log-show-timestamp"); - BLI_argsPrintArgDoc(ba, "--log-file"); + BLI_args_print_arg_doc(ba, "--log"); + BLI_args_print_arg_doc(ba, "--log-level"); + BLI_args_print_arg_doc(ba, "--log-show-basename"); + BLI_args_print_arg_doc(ba, "--log-show-backtrace"); + BLI_args_print_arg_doc(ba, "--log-show-timestamp"); + BLI_args_print_arg_doc(ba, "--log-file"); printf("\n"); printf("Debug Options:\n"); - BLI_argsPrintArgDoc(ba, "--debug"); - BLI_argsPrintArgDoc(ba, "--debug-value"); + BLI_args_print_arg_doc(ba, "--debug"); + BLI_args_print_arg_doc(ba, "--debug-value"); printf("\n"); - BLI_argsPrintArgDoc(ba, "--debug-events"); + BLI_args_print_arg_doc(ba, "--debug-events"); # ifdef WITH_FFMPEG - BLI_argsPrintArgDoc(ba, "--debug-ffmpeg"); + BLI_args_print_arg_doc(ba, "--debug-ffmpeg"); # endif - BLI_argsPrintArgDoc(ba, "--debug-handlers"); + BLI_args_print_arg_doc(ba, "--debug-handlers"); # ifdef WITH_LIBMV - BLI_argsPrintArgDoc(ba, "--debug-libmv"); + BLI_args_print_arg_doc(ba, "--debug-libmv"); # endif # ifdef WITH_CYCLES_LOGGING - BLI_argsPrintArgDoc(ba, "--debug-cycles"); + BLI_args_print_arg_doc(ba, "--debug-cycles"); # endif - BLI_argsPrintArgDoc(ba, "--debug-memory"); - BLI_argsPrintArgDoc(ba, "--debug-jobs"); - BLI_argsPrintArgDoc(ba, "--debug-python"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-eval"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-build"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-tag"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-no-threads"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-time"); - BLI_argsPrintArgDoc(ba, "--debug-depsgraph-pretty"); - BLI_argsPrintArgDoc(ba, "--debug-gpu"); - BLI_argsPrintArgDoc(ba, "--debug-gpumem"); - BLI_argsPrintArgDoc(ba, "--debug-gpu-shaders"); - BLI_argsPrintArgDoc(ba, "--debug-gpu-force-workarounds"); - BLI_argsPrintArgDoc(ba, "--debug-wm"); + BLI_args_print_arg_doc(ba, "--debug-memory"); + BLI_args_print_arg_doc(ba, "--debug-jobs"); + BLI_args_print_arg_doc(ba, "--debug-python"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-eval"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-build"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-tag"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-no-threads"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-time"); + BLI_args_print_arg_doc(ba, "--debug-depsgraph-pretty"); + BLI_args_print_arg_doc(ba, "--debug-gpu"); + BLI_args_print_arg_doc(ba, "--debug-gpumem"); + BLI_args_print_arg_doc(ba, "--debug-gpu-shaders"); + BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds"); + BLI_args_print_arg_doc(ba, "--debug-wm"); # ifdef WITH_XR_OPENXR - BLI_argsPrintArgDoc(ba, "--debug-xr"); - BLI_argsPrintArgDoc(ba, "--debug-xr-time"); + BLI_args_print_arg_doc(ba, "--debug-xr"); + BLI_args_print_arg_doc(ba, "--debug-xr-time"); # endif - BLI_argsPrintArgDoc(ba, "--debug-all"); - BLI_argsPrintArgDoc(ba, "--debug-io"); + BLI_args_print_arg_doc(ba, "--debug-all"); + BLI_args_print_arg_doc(ba, "--debug-io"); printf("\n"); - BLI_argsPrintArgDoc(ba, "--debug-fpe"); - BLI_argsPrintArgDoc(ba, "--disable-crash-handler"); - BLI_argsPrintArgDoc(ba, "--disable-abort-handler"); + BLI_args_print_arg_doc(ba, "--debug-fpe"); + BLI_args_print_arg_doc(ba, "--disable-crash-handler"); + BLI_args_print_arg_doc(ba, "--disable-abort-handler"); printf("\n"); printf("Misc Options:\n"); - BLI_argsPrintArgDoc(ba, "--app-template"); - BLI_argsPrintArgDoc(ba, "--factory-startup"); - BLI_argsPrintArgDoc(ba, "--enable-event-simulate"); + BLI_args_print_arg_doc(ba, "--app-template"); + BLI_args_print_arg_doc(ba, "--factory-startup"); + BLI_args_print_arg_doc(ba, "--enable-event-simulate"); printf("\n"); - BLI_argsPrintArgDoc(ba, "--env-system-datafiles"); - BLI_argsPrintArgDoc(ba, "--env-system-scripts"); - BLI_argsPrintArgDoc(ba, "--env-system-python"); + BLI_args_print_arg_doc(ba, "--env-system-datafiles"); + BLI_args_print_arg_doc(ba, "--env-system-scripts"); + BLI_args_print_arg_doc(ba, "--env-system-python"); printf("\n"); - BLI_argsPrintArgDoc(ba, "-noaudio"); - BLI_argsPrintArgDoc(ba, "-setaudio"); + BLI_args_print_arg_doc(ba, "-noaudio"); + BLI_args_print_arg_doc(ba, "-setaudio"); printf("\n"); - BLI_argsPrintArgDoc(ba, "--help"); + BLI_args_print_arg_doc(ba, "--help"); /* WIN32 only (ignored for non-win32) */ - BLI_argsPrintArgDoc(ba, "-R"); - BLI_argsPrintArgDoc(ba, "-r"); + BLI_args_print_arg_doc(ba, "-R"); + BLI_args_print_arg_doc(ba, "-r"); - BLI_argsPrintArgDoc(ba, "--version"); + BLI_args_print_arg_doc(ba, "--version"); - BLI_argsPrintArgDoc(ba, "--"); + BLI_args_print_arg_doc(ba, "--"); // printf("\n"); // printf("Experimental Features:\n"); @@ -645,7 +646,7 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo /* Other options _must_ be last (anything not handled will show here) */ printf("\n"); printf("Other Options:\n"); - BLI_argsPrintOtherDoc(ba); + BLI_args_print_other_doc(ba); printf("\n"); printf("Argument Parsing:\n"); @@ -933,7 +934,7 @@ static int arg_handle_debug_mode_set(int UNUSED(argc), const char **UNUSED(argv) printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type); # endif - BLI_argsPrint(data); + BLI_args_print(data); return 0; } @@ -1204,8 +1205,6 @@ static int arg_handle_playback_mode(int argc, const char **argv, void *UNUSED(da { /* not if -b was given first */ if (G.background == 0) { - BKE_appdir_init(); - IMB_init(); # ifdef WITH_FFMPEG /* Setup FFmpeg with current debug flags. */ IMB_ffmpeg_init(); @@ -2054,239 +2053,232 @@ void main_args_setup(bContext *C, bArgs *ba) # define CB(a) a##_doc, a # define CB_EX(a, b) a##_doc_##b, a - // BLI_argsAdd(ba, pass, short_arg, long_arg, doc, cb, C); - /* end argument processing after -- */ - BLI_argsAdd(ba, -1, "--", NULL, CB(arg_handle_arguments_end), NULL); - - /* first pass: background mode, disable python and commands that exit after usage */ - BLI_argsAdd(ba, 1, "-h", "--help", CB(arg_handle_print_help), ba); + BLI_args_pass_set(ba, -1); + BLI_args_add(ba, "--", NULL, CB(arg_handle_arguments_end), NULL); + + /* Pass: Environment Setup + * + * It's important these run before any initialization is done, since they set up + * the environment used to access data-files, which are be used when initializing + * sub-systems such as color management. */ + BLI_args_pass_set(ba, ARG_PASS_ENVIRONMENT); + BLI_args_add( + ba, NULL, "--python-use-system-env", CB(arg_handle_python_use_system_env_set), NULL); + + /* Note that we could add used environment variables too. */ + BLI_args_add( + ba, NULL, "--env-system-datafiles", CB_EX(arg_handle_env_system_set, datafiles), NULL); + BLI_args_add(ba, NULL, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), NULL); + BLI_args_add(ba, NULL, "--env-system-python", CB_EX(arg_handle_env_system_set, python), NULL); + + BLI_args_add(ba, "-t", "--threads", CB(arg_handle_threads_set), NULL); + + /* Pass: Background Mode & Settings + * + * Also and commands that exit after usage. */ + BLI_args_pass_set(ba, ARG_PASS_SETTINGS); + BLI_args_add(ba, "-h", "--help", CB(arg_handle_print_help), ba); /* Windows only */ - BLI_argsAdd(ba, 1, "/?", NULL, CB_EX(arg_handle_print_help, win32), ba); + BLI_args_add(ba, "/?", NULL, CB_EX(arg_handle_print_help, win32), ba); - BLI_argsAdd(ba, 1, "-v", "--version", CB(arg_handle_print_version), NULL); + BLI_args_add(ba, "-v", "--version", CB(arg_handle_print_version), NULL); - BLI_argsAdd( - ba, 1, "-y", "--enable-autoexec", CB_EX(arg_handle_python_set, enable), (void *)true); - BLI_argsAdd( - ba, 1, "-Y", "--disable-autoexec", CB_EX(arg_handle_python_set, disable), (void *)false); + BLI_args_add(ba, "-y", "--enable-autoexec", CB_EX(arg_handle_python_set, enable), (void *)true); + BLI_args_add( + ba, "-Y", "--disable-autoexec", CB_EX(arg_handle_python_set, disable), (void *)false); - BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", CB(arg_handle_crash_handler_disable), NULL); - BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", CB(arg_handle_abort_handler_disable), NULL); + BLI_args_add(ba, NULL, "--disable-crash-handler", CB(arg_handle_crash_handler_disable), NULL); + BLI_args_add(ba, NULL, "--disable-abort-handler", CB(arg_handle_abort_handler_disable), NULL); - BLI_argsAdd(ba, 1, "-b", "--background", CB(arg_handle_background_mode_set), NULL); + BLI_args_add(ba, "-b", "--background", CB(arg_handle_background_mode_set), NULL); - BLI_argsAdd(ba, 1, "-a", NULL, CB(arg_handle_playback_mode), NULL); + BLI_args_add(ba, "-a", NULL, CB(arg_handle_playback_mode), NULL); - BLI_argsAdd(ba, 1, NULL, "--log", CB(arg_handle_log_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log-level", CB(arg_handle_log_level_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log-show-basename", CB(arg_handle_log_show_basename_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log-show-backtrace", CB(arg_handle_log_show_backtrace_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log-show-timestamp", CB(arg_handle_log_show_timestamp_set), ba); - BLI_argsAdd(ba, 1, NULL, "--log-file", CB(arg_handle_log_file_set), ba); + BLI_args_add(ba, NULL, "--log", CB(arg_handle_log_set), ba); + BLI_args_add(ba, NULL, "--log-level", CB(arg_handle_log_level_set), ba); + BLI_args_add(ba, NULL, "--log-show-basename", CB(arg_handle_log_show_basename_set), ba); + BLI_args_add(ba, NULL, "--log-show-backtrace", CB(arg_handle_log_show_backtrace_set), ba); + BLI_args_add(ba, NULL, "--log-show-timestamp", CB(arg_handle_log_show_timestamp_set), ba); + BLI_args_add(ba, NULL, "--log-file", CB(arg_handle_log_file_set), ba); - BLI_argsAdd(ba, 1, "-d", "--debug", CB(arg_handle_debug_mode_set), ba); + BLI_args_add(ba, "-d", "--debug", CB(arg_handle_debug_mode_set), ba); # ifdef WITH_FFMPEG - BLI_argsAdd(ba, - 1, - NULL, - "--debug-ffmpeg", - CB_EX(arg_handle_debug_mode_generic_set, ffmpeg), - (void *)G_DEBUG_FFMPEG); + BLI_args_add(ba, + NULL, + "--debug-ffmpeg", + CB_EX(arg_handle_debug_mode_generic_set, ffmpeg), + (void *)G_DEBUG_FFMPEG); # endif # ifdef WITH_FREESTYLE - BLI_argsAdd(ba, - 1, - NULL, - "--debug-freestyle", - CB_EX(arg_handle_debug_mode_generic_set, freestyle), - (void *)G_DEBUG_FREESTYLE); + BLI_args_add(ba, + + NULL, + "--debug-freestyle", + CB_EX(arg_handle_debug_mode_generic_set, freestyle), + (void *)G_DEBUG_FREESTYLE); # endif - BLI_argsAdd(ba, - 1, - NULL, - "--debug-python", - CB_EX(arg_handle_debug_mode_generic_set, python), - (void *)G_DEBUG_PYTHON); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-events", - CB_EX(arg_handle_debug_mode_generic_set, events), - (void *)G_DEBUG_EVENTS); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-handlers", - CB_EX(arg_handle_debug_mode_generic_set, handlers), - (void *)G_DEBUG_HANDLERS); - BLI_argsAdd( - ba, 1, NULL, "--debug-wm", CB_EX(arg_handle_debug_mode_generic_set, wm), (void *)G_DEBUG_WM); + BLI_args_add(ba, + + NULL, + "--debug-python", + CB_EX(arg_handle_debug_mode_generic_set, python), + (void *)G_DEBUG_PYTHON); + BLI_args_add(ba, + + NULL, + "--debug-events", + CB_EX(arg_handle_debug_mode_generic_set, events), + (void *)G_DEBUG_EVENTS); + BLI_args_add(ba, + + NULL, + "--debug-handlers", + CB_EX(arg_handle_debug_mode_generic_set, handlers), + (void *)G_DEBUG_HANDLERS); + BLI_args_add( + ba, NULL, "--debug-wm", CB_EX(arg_handle_debug_mode_generic_set, wm), (void *)G_DEBUG_WM); # ifdef WITH_XR_OPENXR - BLI_argsAdd( - ba, 1, NULL, "--debug-xr", CB_EX(arg_handle_debug_mode_generic_set, xr), (void *)G_DEBUG_XR); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-xr-time", - CB_EX(arg_handle_debug_mode_generic_set, xr_time), - (void *)G_DEBUG_XR_TIME); + BLI_args_add( + ba, NULL, "--debug-xr", CB_EX(arg_handle_debug_mode_generic_set, xr), (void *)G_DEBUG_XR); + BLI_args_add(ba, + + NULL, + "--debug-xr-time", + CB_EX(arg_handle_debug_mode_generic_set, xr_time), + (void *)G_DEBUG_XR_TIME); # endif - BLI_argsAdd(ba, - 1, - NULL, - "--debug-ghost", - CB_EX(arg_handle_debug_mode_generic_set, handlers), - (void *)G_DEBUG_GHOST); - BLI_argsAdd(ba, 1, NULL, "--debug-all", CB(arg_handle_debug_mode_all), NULL); + BLI_args_add(ba, + NULL, + "--debug-ghost", + CB_EX(arg_handle_debug_mode_generic_set, handlers), + (void *)G_DEBUG_GHOST); + BLI_args_add(ba, NULL, "--debug-all", CB(arg_handle_debug_mode_all), NULL); - BLI_argsAdd(ba, 1, NULL, "--debug-io", CB(arg_handle_debug_mode_io), NULL); + BLI_args_add(ba, NULL, "--debug-io", CB(arg_handle_debug_mode_io), NULL); - BLI_argsAdd(ba, 1, NULL, "--debug-fpe", CB(arg_handle_debug_fpe_set), NULL); + BLI_args_add(ba, NULL, "--debug-fpe", CB(arg_handle_debug_fpe_set), NULL); # ifdef WITH_LIBMV - BLI_argsAdd(ba, 1, NULL, "--debug-libmv", CB(arg_handle_debug_mode_libmv), NULL); + BLI_args_add(ba, NULL, "--debug-libmv", CB(arg_handle_debug_mode_libmv), NULL); # endif # ifdef WITH_CYCLES_LOGGING - BLI_argsAdd(ba, 1, NULL, "--debug-cycles", CB(arg_handle_debug_mode_cycles), NULL); + BLI_args_add(ba, NULL, "--debug-cycles", CB(arg_handle_debug_mode_cycles), NULL); # endif - BLI_argsAdd(ba, 1, NULL, "--debug-memory", CB(arg_handle_debug_mode_memory_set), NULL); - - BLI_argsAdd(ba, 1, NULL, "--debug-value", CB(arg_handle_debug_value_set), NULL); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-jobs", - CB_EX(arg_handle_debug_mode_generic_set, jobs), - (void *)G_DEBUG_JOBS); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-gpu", - CB_EX(arg_handle_debug_mode_generic_set, gpu), - (void *)G_DEBUG_GPU); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph), - (void *)G_DEBUG_DEPSGRAPH); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-build", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), - (void *)G_DEBUG_DEPSGRAPH_BUILD); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-eval", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_eval), - (void *)G_DEBUG_DEPSGRAPH_EVAL); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-tag", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_tag), - (void *)G_DEBUG_DEPSGRAPH_TAG); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-time", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_time), - (void *)G_DEBUG_DEPSGRAPH_TIME); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-no-threads", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads), - (void *)G_DEBUG_DEPSGRAPH_NO_THREADS); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-pretty", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty), - (void *)G_DEBUG_DEPSGRAPH_PRETTY); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-depsgraph-uuid", - CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), - (void *)G_DEBUG_DEPSGRAPH_UUID); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-gpumem", - CB_EX(arg_handle_debug_mode_generic_set, gpumem), - (void *)G_DEBUG_GPU_MEM); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-gpu-shaders", - CB_EX(arg_handle_debug_mode_generic_set, gpumem), - (void *)G_DEBUG_GPU_SHADERS); - BLI_argsAdd(ba, - 1, - NULL, - "--debug-gpu-force-workarounds", - CB_EX(arg_handle_debug_mode_generic_set, gpumem), - (void *)G_DEBUG_GPU_FORCE_WORKAROUNDS); - BLI_argsAdd(ba, 1, NULL, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), NULL); - - BLI_argsAdd(ba, 1, NULL, "--verbose", CB(arg_handle_verbosity_set), NULL); - - BLI_argsAdd(ba, 1, NULL, "--app-template", CB(arg_handle_app_template), NULL); - BLI_argsAdd(ba, 1, NULL, "--factory-startup", CB(arg_handle_factory_startup_set), NULL); - BLI_argsAdd(ba, 1, NULL, "--enable-event-simulate", CB(arg_handle_enable_event_simulate), NULL); - - /* TODO, add user env vars? */ - BLI_argsAdd( - ba, 1, NULL, "--env-system-datafiles", CB_EX(arg_handle_env_system_set, datafiles), NULL); - BLI_argsAdd( - ba, 1, NULL, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), NULL); - BLI_argsAdd(ba, 1, NULL, "--env-system-python", CB_EX(arg_handle_env_system_set, python), NULL); - - BLI_argsAdd( - ba, 1, NULL, "--python-use-system-env", CB(arg_handle_python_use_system_env_set), NULL); - - /* second pass: custom window stuff */ - BLI_argsAdd(ba, 2, "-p", "--window-geometry", CB(arg_handle_window_geometry), NULL); - BLI_argsAdd(ba, 2, "-w", "--window-border", CB(arg_handle_with_borders), NULL); - BLI_argsAdd(ba, 2, "-W", "--window-fullscreen", CB(arg_handle_without_borders), NULL); - BLI_argsAdd(ba, 2, "-M", "--window-maximized", CB(arg_handle_window_maximized), NULL); - BLI_argsAdd(ba, 2, NULL, "--no-window-focus", CB(arg_handle_no_window_focus), NULL); - BLI_argsAdd(ba, 2, "-con", "--start-console", CB(arg_handle_start_with_console), NULL); - BLI_argsAdd(ba, 2, "-R", NULL, CB(arg_handle_register_extension), NULL); - BLI_argsAdd(ba, 2, "-r", NULL, CB_EX(arg_handle_register_extension, silent), ba); - BLI_argsAdd(ba, 2, NULL, "--no-native-pixels", CB(arg_handle_native_pixels_set), ba); - - /* third pass: disabling things and forcing settings */ - BLI_argsAddCase(ba, 3, "-noaudio", 1, NULL, 0, CB(arg_handle_audio_disable), NULL); - BLI_argsAddCase(ba, 3, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL); - - /* fourth pass: processing arguments */ - BLI_argsAdd(ba, 4, "-f", "--render-frame", CB(arg_handle_render_frame), C); - BLI_argsAdd(ba, 4, "-a", "--render-anim", CB(arg_handle_render_animation), C); - BLI_argsAdd(ba, 4, "-S", "--scene", CB(arg_handle_scene_set), C); - BLI_argsAdd(ba, 4, "-s", "--frame-start", CB(arg_handle_frame_start_set), C); - BLI_argsAdd(ba, 4, "-e", "--frame-end", CB(arg_handle_frame_end_set), C); - BLI_argsAdd(ba, 4, "-j", "--frame-jump", CB(arg_handle_frame_skip_set), C); - BLI_argsAdd(ba, 4, "-P", "--python", CB(arg_handle_python_file_run), C); - BLI_argsAdd(ba, 4, NULL, "--python-text", CB(arg_handle_python_text_run), C); - BLI_argsAdd(ba, 4, NULL, "--python-expr", CB(arg_handle_python_expr_run), C); - BLI_argsAdd(ba, 4, NULL, "--python-console", CB(arg_handle_python_console_run), C); - BLI_argsAdd(ba, 4, NULL, "--python-exit-code", CB(arg_handle_python_exit_code_set), NULL); - BLI_argsAdd(ba, 4, NULL, "--addons", CB(arg_handle_addons_set), C); - - BLI_argsAdd(ba, 4, "-o", "--render-output", CB(arg_handle_output_set), C); - BLI_argsAdd(ba, 4, "-E", "--engine", CB(arg_handle_engine_set), C); - - BLI_argsAdd(ba, 4, "-F", "--render-format", CB(arg_handle_image_type_set), C); - BLI_argsAdd(ba, 1, "-t", "--threads", CB(arg_handle_threads_set), NULL); - BLI_argsAdd(ba, 4, "-x", "--use-extension", CB(arg_handle_extension_set), C); + BLI_args_add(ba, NULL, "--debug-memory", CB(arg_handle_debug_mode_memory_set), NULL); + + BLI_args_add(ba, NULL, "--debug-value", CB(arg_handle_debug_value_set), NULL); + BLI_args_add(ba, + NULL, + "--debug-jobs", + CB_EX(arg_handle_debug_mode_generic_set, jobs), + (void *)G_DEBUG_JOBS); + BLI_args_add( + ba, NULL, "--debug-gpu", CB_EX(arg_handle_debug_mode_generic_set, gpu), (void *)G_DEBUG_GPU); + BLI_args_add(ba, + NULL, + "--debug-depsgraph", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph), + (void *)G_DEBUG_DEPSGRAPH); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-build", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), + (void *)G_DEBUG_DEPSGRAPH_BUILD); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-eval", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_eval), + (void *)G_DEBUG_DEPSGRAPH_EVAL); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-tag", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_tag), + (void *)G_DEBUG_DEPSGRAPH_TAG); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-time", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_time), + (void *)G_DEBUG_DEPSGRAPH_TIME); + BLI_args_add(ba, + + NULL, + "--debug-depsgraph-no-threads", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_no_threads), + (void *)G_DEBUG_DEPSGRAPH_NO_THREADS); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-pretty", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_pretty), + (void *)G_DEBUG_DEPSGRAPH_PRETTY); + BLI_args_add(ba, + NULL, + "--debug-depsgraph-uuid", + CB_EX(arg_handle_debug_mode_generic_set, depsgraph_build), + (void *)G_DEBUG_DEPSGRAPH_UUID); + BLI_args_add(ba, + NULL, + "--debug-gpumem", + CB_EX(arg_handle_debug_mode_generic_set, gpumem), + (void *)G_DEBUG_GPU_MEM); + BLI_args_add(ba, + NULL, + "--debug-gpu-shaders", + CB_EX(arg_handle_debug_mode_generic_set, gpumem), + (void *)G_DEBUG_GPU_SHADERS); + BLI_args_add(ba, + NULL, + "--debug-gpu-force-workarounds", + CB_EX(arg_handle_debug_mode_generic_set, gpumem), + (void *)G_DEBUG_GPU_FORCE_WORKAROUNDS); + BLI_args_add(ba, NULL, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), NULL); + + BLI_args_add(ba, NULL, "--verbose", CB(arg_handle_verbosity_set), NULL); + + BLI_args_add(ba, NULL, "--app-template", CB(arg_handle_app_template), NULL); + BLI_args_add(ba, NULL, "--factory-startup", CB(arg_handle_factory_startup_set), NULL); + BLI_args_add(ba, NULL, "--enable-event-simulate", CB(arg_handle_enable_event_simulate), NULL); + + /* Pass: Custom Window Stuff. */ + BLI_args_pass_set(ba, ARG_PASS_SETTINGS_GUI); + BLI_args_add(ba, "-p", "--window-geometry", CB(arg_handle_window_geometry), NULL); + BLI_args_add(ba, "-w", "--window-border", CB(arg_handle_with_borders), NULL); + BLI_args_add(ba, "-W", "--window-fullscreen", CB(arg_handle_without_borders), NULL); + BLI_args_add(ba, "-M", "--window-maximized", CB(arg_handle_window_maximized), NULL); + BLI_args_add(ba, NULL, "--no-window-focus", CB(arg_handle_no_window_focus), NULL); + BLI_args_add(ba, "-con", "--start-console", CB(arg_handle_start_with_console), NULL); + BLI_args_add(ba, "-R", NULL, CB(arg_handle_register_extension), NULL); + BLI_args_add(ba, "-r", NULL, CB_EX(arg_handle_register_extension, silent), ba); + BLI_args_add(ba, NULL, "--no-native-pixels", CB(arg_handle_native_pixels_set), ba); + + /* Pass: Disabling Things & Forcing Settings. */ + BLI_args_pass_set(ba, ARG_PASS_SETTINGS_FORCE); + BLI_args_add_case(ba, "-noaudio", 1, NULL, 0, CB(arg_handle_audio_disable), NULL); + BLI_args_add_case(ba, "-setaudio", 1, NULL, 0, CB(arg_handle_audio_set), NULL); + + /* Pass: Processing Arguments. */ + BLI_args_pass_set(ba, ARG_PASS_FINAL); + BLI_args_add(ba, "-f", "--render-frame", CB(arg_handle_render_frame), C); + BLI_args_add(ba, "-a", "--render-anim", CB(arg_handle_render_animation), C); + BLI_args_add(ba, "-S", "--scene", CB(arg_handle_scene_set), C); + BLI_args_add(ba, "-s", "--frame-start", CB(arg_handle_frame_start_set), C); + BLI_args_add(ba, "-e", "--frame-end", CB(arg_handle_frame_end_set), C); + BLI_args_add(ba, "-j", "--frame-jump", CB(arg_handle_frame_skip_set), C); + BLI_args_add(ba, "-P", "--python", CB(arg_handle_python_file_run), C); + BLI_args_add(ba, NULL, "--python-text", CB(arg_handle_python_text_run), C); + BLI_args_add(ba, NULL, "--python-expr", CB(arg_handle_python_expr_run), C); + BLI_args_add(ba, NULL, "--python-console", CB(arg_handle_python_console_run), C); + BLI_args_add(ba, NULL, "--python-exit-code", CB(arg_handle_python_exit_code_set), NULL); + BLI_args_add(ba, NULL, "--addons", CB(arg_handle_addons_set), C); + + BLI_args_add(ba, "-o", "--render-output", CB(arg_handle_output_set), C); + BLI_args_add(ba, "-E", "--engine", CB(arg_handle_engine_set), C); + + BLI_args_add(ba, "-F", "--render-format", CB(arg_handle_image_type_set), C); + BLI_args_add(ba, "-x", "--use-extension", CB(arg_handle_extension_set), C); # undef CB # undef CB_EX @@ -2297,7 +2289,7 @@ void main_args_setup(bContext *C, bArgs *ba) */ void main_args_setup_post(bContext *C, bArgs *ba) { - BLI_argsParse(ba, 4, arg_handle_load_file, C); + BLI_args_parse(ba, ARG_PASS_FINAL, arg_handle_load_file, C); } /** \} */ diff --git a/source/creator/creator_intern.h b/source/creator/creator_intern.h index 7ff3247e17e..0a13f45eef1 100644 --- a/source/creator/creator_intern.h +++ b/source/creator/creator_intern.h @@ -38,7 +38,7 @@ void main_signal_setup_fpe(void); #endif /* WITH_PYTHON_MODULE */ -/* Shared data for argument handlers to store state in */ +/** Shared data for argument handlers to store state in. */ struct ApplicationState { struct { bool use_crash_handler; @@ -52,6 +52,24 @@ struct ApplicationState { }; extern struct ApplicationState app_state; /* creator.c */ +/** + * Passes for use by #main_args_setup. + * Keep in order of execution. + */ +enum { + /** Run before sub-system initialization. */ + ARG_PASS_ENVIRONMENT = 1, + /** General settings parsing, also animation player. */ + ARG_PASS_SETTINGS = 2, + /** Windowing & graphical settings (ignored in background mode). */ + ARG_PASS_SETTINGS_GUI = 3, + /** Currently use for audio devices. */ + ARG_PASS_SETTINGS_FORCE = 4, + + /** Actions & fall back to loading blend file. */ + ARG_PASS_FINAL = 5, +}; + /* for the callbacks: */ #ifndef WITH_PYTHON_MODULE # define BLEND_VERSION_FMT "Blender %d.%02d.%d" @@ -80,4 +98,4 @@ extern char build_cflags[]; extern char build_cxxflags[]; extern char build_linkflags[]; extern char build_system[]; -#endif +#endif /* BUILD_DATE */ diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 9ff44ac8fe9..22426a6d6fc 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -699,6 +699,30 @@ if(WITH_CODEC_FFMPEG) ) endif() + +# ------------------------------------------------------------------------------ +# SEQUENCER RENDER TESTS + +if(NOT OPENIMAGEIO_IDIFF) + MESSAGE(STATUS "Disabling sequencer render tests because OIIO idiff does not exist") +else() + set(render_tests + transform + ) + + foreach(render_test ${render_tests}) + add_python_test( + sequencer_render_${render_test} + ${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py + -blender "${TEST_BLENDER_EXE}" + -testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}" + -idiff "${OPENIMAGEIO_IDIFF}" + -outdir "${TEST_OUT_DIR}/sequence_editing" + ) + endforeach() +endif() + + add_subdirectory(collada) # TODO: disabled for now after collection unification diff --git a/tests/python/sequencer_render_tests.py b/tests/python/sequencer_render_tests.py new file mode 100644 index 00000000000..54c9d68817b --- /dev/null +++ b/tests/python/sequencer_render_tests.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Apache License, Version 2.0 + +import argparse +import os +import shlex +import shutil +import subprocess +import sys +from pathlib import Path + + +def get_arguments(filepath, output_filepath): + dirname = os.path.dirname(filepath) + basedir = os.path.dirname(dirname) + + args = [ + "--background", + "-noaudio", + "--factory-startup", + "--enable-autoexec", + "--debug-memory", + "--debug-exit-on-error", + filepath, + "-o", output_filepath, + "-f", "1", + "-F", "PNG"] + + return args + + +def create_argparse(): + parser = argparse.ArgumentParser() + parser.add_argument("-blender", nargs="+") + parser.add_argument("-testdir", nargs=1) + parser.add_argument("-outdir", nargs=1) + parser.add_argument("-idiff", nargs=1) + return parser + + +def main(): + parser = create_argparse() + args = parser.parse_args() + + blender = args.blender[0] + test_dir = args.testdir[0] + idiff = args.idiff[0] + output_dir = args.outdir[0] + + from modules import render_report + report = render_report.Report("Sequencer", output_dir, idiff) + report.set_pixelated(True) + report.set_reference_dir("reference") + + test_dir_name = Path(test_dir).name + ok = report.run(test_dir, blender, get_arguments, batch=True) + + sys.exit(not ok) + + +if __name__ == "__main__": + main() |