diff --git a/build_files/build_environment/cmake/dpcpp.cmake b/build_files/build_environment/cmake/dpcpp.cmake index 34a0b3a5e04..f04b83c93ed 100644 --- a/build_files/build_environment/cmake/dpcpp.cmake +++ b/build_files/build_environment/cmake/dpcpp.cmake @@ -108,10 +108,7 @@ ExternalProject_Add(external_dpcpp PATCH_COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/dpcpp/src/external_dpcpp < - ${PATCH_DIR}/dpcpp.diff && - ${PATCH_CMD} -p 1 -d - ${BUILD_DIR}/dpcpp/src/external_dpcpp < - ${PATCH_DIR}/dpcpp_13328.diff + ${PATCH_DIR}/dpcpp.diff INSTALL_DIR ${LIBDIR}/dpcpp ) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index fb06d5ed0db..10ea6097299 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -96,7 +96,7 @@ set(BOOST_VERSION 1.82.0) set(BOOST_VERSION_SHORT 1.82) set(BOOST_VERSION_NODOTS 1_82_0) set(BOOST_VERSION_NODOTS_SHORT 1_82) -set(BOOST_URI https://archives.boost.io/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz) +set(BOOST_URI https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION}/source/boost_${BOOST_VERSION_NODOTS}.tar.gz) set(BOOST_HASH f7050f554a65f6a42ece221eaeec1660) set(BOOST_HASH_TYPE MD5) set(BOOST_FILE boost_${BOOST_VERSION_NODOTS}.tar.gz) diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake index be9e485e989..1109c08eb18 100644 --- a/build_files/buildbot/config/blender_linux.cmake +++ b/build_files/buildbot/config/blender_linux.cmake @@ -15,4 +15,4 @@ set(WITH_DOC_MANPAGE OFF CACHE BOOL "" FORCE) set(WITH_CYCLES_TEST_OSL ON CACHE BOOL "" FORCE) set(HIPRT_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) -set(SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) +set(SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) \ No newline at end of file diff --git a/build_files/buildbot/config/blender_windows.cmake b/build_files/buildbot/config/blender_windows.cmake index da0becd4efb..5d90dee6027 100644 --- a/build_files/buildbot/config/blender_windows.cmake +++ b/build_files/buildbot/config/blender_windows.cmake @@ -7,4 +7,4 @@ include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/config/blender_release.cmake") set(WITH_CYCLES_TEST_OSL ON CACHE BOOL "" FORCE) set(HIPRT_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) -set(SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) +set(SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 6 CACHE STRING "" FORCE) \ No newline at end of file diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 80f5ed56a34..efd5e19fa27 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -569,13 +569,7 @@ macro(TEST_SSE_SUPPORT check_c_source_runs(" #include #include - #include - int main(void) { - __m128i v = _mm_setzero_si128(); - v = _mm_cmpgt_epi64(v,v); - if (_mm_test_all_zeros(v, v)) return 0; - return 1; - }" + int main(void) { __m128i v = _mm_setzero_si128(); v = _mm_cmpgt_epi64(v,v); return 0; }" SUPPORT_SSE42_BUILD) endif() diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index ef7d190bf5a..1dbc4034e35 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -360,24 +360,15 @@ endif() # CMake FindOpenMP doesn't know about AppleClang before 3.12, so provide custom flags. if(WITH_OPENMP) if(CMAKE_C_COMPILER_ID MATCHES "Clang") - if(${CMAKE_C_COMPILER_VERSION} VERSION_GREATER_EQUAL 17.0) - if(WITH_STRICT_BUILD_OPTIONS) - message(SEND_ERROR "OpenMP library is not compatible with the current Clang version") - else() - message(WARNING "OpenMP library is not compatible with the current Clang version, disabling") - endif() - set(WITH_OPENMP OFF) - else() - # Use OpenMP from our precompiled libraries. - message(STATUS "Using ${LIBDIR}/openmp for OpenMP") - set(OPENMP_CUSTOM ON) - 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(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/") - set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp") - set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib") - endif() + # Use OpenMP from our precompiled libraries. + message(STATUS "Using ${LIBDIR}/openmp for OpenMP") + set(OPENMP_CUSTOM ON) + 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(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/") + set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp") + set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib") endif() endif() add_bundled_libraries(openmp/lib) diff --git a/build_files/cmake/testing.cmake b/build_files/cmake/testing.cmake index 387f1a2584b..243da792295 100644 --- a/build_files/cmake/testing.cmake +++ b/build_files/cmake/testing.cmake @@ -170,14 +170,14 @@ function(blender_add_ctests) TEST_PREFIX ${ARGS_SUITE_NAME} WORKING_DIRECTORY "${TEST_INSTALL_DIR}" EXTRA_ARGS - --test-assets-dir "${CMAKE_SOURCE_DIR}/tests/files" + --test-assets-dir "${CMAKE_SOURCE_DIR}/tests/data" --test-release-dir "${_test_release_dir}" ) else() add_test( NAME ${ARGS_SUITE_NAME} COMMAND ${ARGS_TARGET} - --test-assets-dir "${CMAKE_SOURCE_DIR}/tests/files" + --test-assets-dir "${CMAKE_SOURCE_DIR}/tests/data" --test-release-dir "${_test_release_dir}" WORKING_DIRECTORY ${TEST_INSTALL_DIR} ) diff --git a/build_files/utils/make_bpy_wheel.py b/build_files/utils/make_bpy_wheel.py index 4b284c910bd..616b52d2e06 100755 --- a/build_files/utils/make_bpy_wheel.py +++ b/build_files/utils/make_bpy_wheel.py @@ -46,16 +46,6 @@ long_description = """# Blender This package provides Blender as a Python module for use in studio pipelines, web services, scientific research, and more. -### Archived Versions - -Blender versions outside the current LTS window are removed from PyPI but are available at [https://download.blender.org/pypi/bpy/](https://download.blender.org/pypi/bpy/). - -These versions can still be installed manually. For example, to install version 3.6.0: - -```bash -pip install bpy==3.6.0 --extra-index-url https://download.blender.org/pypi/ -``` - ## Documentation * [Blender Python API](https://docs.blender.org/api/current/) diff --git a/build_files/utils/make_source_archive.py b/build_files/utils/make_source_archive.py index 4cbada12781..c811a45988f 100755 --- a/build_files/utils/make_source_archive.py +++ b/build_files/utils/make_source_archive.py @@ -3,26 +3,13 @@ # # SPDX-License-Identifier: GPL-2.0-or-later -__all__ = ( - "main", -) - import argparse import make_utils import os import subprocess import sys from pathlib import Path - -from typing import ( - TextIO, - Any, - Tuple, - Union, - # Proxies for `collections.abc` - Iterable, - List, -) +from typing import Iterable, TextIO, Optional, Any, Union # This script can run from any location, # output is created in the $CWD @@ -30,24 +17,15 @@ from typing import ( # NOTE: while the Python part of this script is portable, # it relies on external commands typically found on GNU/Linux. # Support for other platforms could be added by moving GNU `tar` & `md5sum` use to Python. -# This also relies on having a Unix shell (sh) to run some git commands. -SKIP_NAMES: Tuple[str, ...] = ( +SKIP_NAMES = { ".gitignore", ".gitmodules", ".gitattributes", ".git-blame-ignore-revs", ".arcconfig", ".svn", -) - -# Tuple with folder names relative to the main repository root that are to be excluded. -SKIP_FOLDERS: Tuple[str, ...] = ( -) - -# Generated list of Paths to be ignored based on the SKIP_FOLDERS and some rum-time rules like -# the type of package that is being created. -SKIP_PATHS: List[Path] = [] +} def main() -> None: @@ -57,8 +35,7 @@ def main() -> None: description="Create a tarball of the Blender sources, optionally including sources of dependencies.", epilog="This script is intended to be run by `make source_archive_complete`.", ) - group = cli_parser.add_mutually_exclusive_group() - group.add_argument( + cli_parser.add_argument( "-p", "--include-packages", type=Path, @@ -66,12 +43,6 @@ def main() -> None: metavar="PACKAGE_PATH", help="Include all source files from the given package directory as well.", ) - group.add_argument( - "-t", - "--package-test-data", - action='store_true', - help="Package all test data into its own archive", - ) cli_args = cli_parser.parse_args() @@ -81,10 +52,6 @@ def main() -> None: os.chdir(curdir) blender_srcdir = blender_srcdir.relative_to(curdir) - # Update our SKIP_FOLDERS blacklist with the source directory name - global SKIP_PATHS - SKIP_PATHS = [blender_srcdir / entry for entry in SKIP_FOLDERS] - print(f"Output dir: {curdir}") version = make_utils.parse_blender_version() @@ -92,13 +59,7 @@ def main() -> None: manifest = manifest_path(tarball) packages_dir = packages_path(curdir, cli_args) - if cli_args.package_test_data: - print("Creating an archive of all test data.") - create_manifest(version, manifest, blender_srcdir / "tests/files", packages_dir) - else: - SKIP_PATHS.append(blender_srcdir / "tests/files") - create_manifest(version, manifest, blender_srcdir, packages_dir) - + create_manifest(version, manifest, blender_srcdir, packages_dir) create_tarball(version, tarball, manifest, blender_srcdir, packages_dir) create_checksum_file(tarball) cleanup(manifest) @@ -109,8 +70,6 @@ def tarball_path(output_dir: Path, version: make_utils.BlenderVersion, cli_args: extra = "" if cli_args.include_packages: extra = "-with-libraries" - elif cli_args.package_test_data: - extra = "-test-data" return output_dir / f"blender{extra}-{version}.tar.xz" @@ -119,24 +78,24 @@ def manifest_path(tarball: Path) -> Path: """Return the manifest path for the given tarball path. >>> from pathlib import Path - >>> tarball = Path("/home/user/workspace/blender-git/blender-test.tar.gz") + >>> tarball = Path("/home/sybren/workspace/blender-git/blender-test.tar.gz") >>> manifest_path(tarball).as_posix() - '/home/user/workspace/blender-git/blender-test-manifest.txt' + '/home/sybren/workspace/blender-git/blender-test-manifest.txt' """ - # Note that `.tar.gz` is seen as two suffixes. + # ".tar.gz" is seen as two suffixes. without_suffix = tarball.with_suffix("").with_suffix("") name = without_suffix.name return without_suffix.with_name(f"{name}-manifest.txt") -def packages_path(current_directory: Path, cli_args: Any) -> Union[Path, None]: +def packages_path(current_directory: Path, cli_args: Any) -> Optional[Path]: if not cli_args.include_packages: return None abspath = cli_args.include_packages.absolute() - # `os.path.relpath()` can return paths like "../../packages", where - # `Path.relative_to()` will not go up directories (so its return value never + # os.path.relpath() can return paths like "../../packages", where + # Path.relative_to() will not go up directories (so its return value never # has "../" in there). relpath = os.path.relpath(abspath, current_directory) @@ -150,12 +109,12 @@ def create_manifest( version: make_utils.BlenderVersion, outpath: Path, blender_srcdir: Path, - packages_dir: Union[Path, None], - exclude: List[Path] = [] + packages_dir: Optional[Path], ) -> None: print(f'Building manifest of files: "{outpath}"...', end="", flush=True) with outpath.open("w", encoding="utf-8") as outfile: main_files_to_manifest(blender_srcdir, outfile) + assets_to_manifest(blender_srcdir, outfile) if packages_dir: packages_to_manifest(outfile, packages_dir) @@ -164,9 +123,20 @@ def create_manifest( def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None: assert not blender_srcdir.is_absolute() - for git_repo in git_gather_all_folders_to_package(blender_srcdir): - for path in git_ls_files(git_repo): - print(path, file=outfile) + for path in git_ls_files(blender_srcdir): + print(path, file=outfile) + + +def assets_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None: + assert not blender_srcdir.is_absolute() + + assets_dir = blender_srcdir.parent / "lib" / "assets" + for path in assets_dir.glob("*"): + if path.name == "working": + continue + if path.name in SKIP_NAMES: + continue + print(path, file=outfile) def packages_to_manifest(outfile: TextIO, packages_dir: Path) -> None: @@ -187,7 +157,7 @@ def create_tarball( tarball: Path, manifest: Path, blender_srcdir: Path, - packages_dir: Union[Path, None], + packages_dir: Optional[Path], ) -> None: print(f'Creating archive: "{tarball}" ...', end="", flush=True) @@ -204,6 +174,8 @@ def create_tarball( command += [ "--transform", f"s,^{blender_srcdir.name}/,blender-{version}/,g", + "--transform", + f"s,^lib/assets/,blender-{version}/release/datafiles/assets/,g", "--use-compress-program=xz -1", "--create", f"--file={tarball}", @@ -246,63 +218,28 @@ def cleanup(manifest: Path) -> None: # Low-level commands -def git_gather_all_folders_to_package(directory: Path = Path(".")) -> Iterable[Path]: - """Generator, yields lines which represents each directory to gather git files from. - - Each directory represents either the top level git repository or a submodule. - All submodules that have the 'update = none' setting will be excluded from this list. - - The directory path given to this function will be included in the yielded paths - """ - - # For each submodule (recurse into submodules within submodules if they exist) - git_main_command = "submodule --quiet foreach --recursive" - # Return the path to the submodule and what the value is of their "update" setting - # If the "update" setting doesn't exist, only the path to the submodule is returned - git_command_args = "'echo $displaypath $(git config --file \"$toplevel/.gitmodules\" --get submodule.$name.update)'" - - # Yield the root directory as this is our top level git repo - yield directory - - for line in git_command(f"-C '{directory}' {git_main_command} {git_command_args}"): - # Check if we shouldn't include the directory on this line - split_line = line.rsplit(maxsplit=1) - if len(split_line) > 1 and split_line[-1] == "none": - continue - path = directory / split_line[0] - yield path - - -def is_path_ignored(file: Path) -> bool: - for skip_folder in SKIP_PATHS: - if file.is_relative_to(skip_folder): - return True - return False - - def git_ls_files(directory: Path = Path(".")) -> Iterable[Path]: """Generator, yields lines of output from 'git ls-files'. Only lines that are actually files (so no directories, sockets, etc.) are returned, and never one from SKIP_NAMES. """ - for line in git_command(f"-C '{directory}' ls-files"): + for line in git_command("-C", str(directory), "ls-files"): path = directory / line if not path.is_file() or path.name in SKIP_NAMES: continue - if not is_path_ignored(path): - yield path + yield path -def git_command(cli_args: str) -> Iterable[str]: +def git_command(*cli_args: Union[bytes, str, Path]) -> Iterable[str]: """Generator, yields lines of output from a Git command.""" - command = "git " + cli_args + command = ("git", *cli_args) # import shlex # print(">", " ".join(shlex.quote(arg) for arg in command)) git = subprocess.run( - command, stdout=subprocess.PIPE, shell=True, check=True, text=True, timeout=30 + command, stdout=subprocess.PIPE, check=True, text=True, timeout=30 ) for line in git.stdout.split("\n"): if line: diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index cfe9b7e21a1..21e1c07b342 100644 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -5,7 +5,7 @@ """ "make update" for all platforms, updating Git LFS submodules for libraries and -Blender git repository. +tests, and Blender git repository. For release branches, this will check out the appropriate branches of submodules and libraries. @@ -48,7 +48,7 @@ def parse_arguments() -> argparse.Namespace: parser.add_argument("--no-libraries", action="store_true") parser.add_argument("--no-blender", action="store_true") parser.add_argument("--no-submodules", action="store_true") - parser.add_argument("--no-lfs-fallback", action="store_true") + parser.add_argument("--use-tests", action="store_true") parser.add_argument("--git-command", default="git") parser.add_argument("--use-linux-libraries", action="store_true") parser.add_argument("--architecture", type=str, @@ -203,6 +203,21 @@ def initialize_precompiled_libraries(args: argparse.Namespace) -> str: return "" +def initialize_tests_data_files(args: argparse.Namespace) -> str: + """ + Configure submodule with files used by regression tests + """ + + print_stage("Configuring Tests Data Files") + + submodule_dir = "tests/data" + + print(f"* Enabling tests data at {submodule_dir}") + make_utils.git_enable_submodule(args.git_command, Path(submodule_dir)) + + return "" + + def git_update_skip(args: argparse.Namespace, check_remote_exists: bool = True) -> str: """Test if git repo can be updated.""" @@ -502,6 +517,21 @@ def floating_checkout_update( return skip_msg +def external_scripts_update( + args: argparse.Namespace, + repo_name: str, + directory_name: str, + branch: Optional[str], +) -> str: + return floating_checkout_update( + args, + repo_name, + Path("scripts") / directory_name, + branch, + old_submodules_dir=Path("release") / "scripts" / directory_name, + ) + + def floating_libraries_update(args: argparse.Namespace, branch: Optional[str]) -> str: """Update libraries checkouts which are floating (not attached as Git submodules)""" msg = "" @@ -577,34 +607,8 @@ def submodules_lib_update(args: argparse.Namespace, branch: Optional[str]) -> st return msg -def lfs_fallback_setup(args: argparse.Namespace) -> None: - """ - Set up an additional projects.blender.org remote, for LFS fetching fallback - in case the fork does not include LFS files. - """ - remotes = make_utils.git_get_remotes(args.git_command) - add_fallback_remote = True - fallback_remote = "lfs-fallback" - - for remote in remotes: - url = make_utils.git_get_remote_url(args.git_command, remote) - if "projects.blender.org" not in url: - make_utils.git_set_config(args.git_command, f"lfs.{remote}.searchall", "true") - else: - add_fallback_remote = False - - if add_fallback_remote and not make_utils.git_remote_exist(args.git_command, fallback_remote): - print_stage("Adding Git LFS fallback remote") - print("Used to fetch files from projects.blender.org if missing.") - - url = "https://projects.blender.org/blender/blender.git" - push_url = "no_push" - make_utils.git_add_remote(args.git_command, fallback_remote, url, push_url) - - if __name__ == "__main__": args = parse_arguments() - blender_skip_msg = "" libraries_skip_msg = "" submodules_skip_msg = "" @@ -632,6 +636,8 @@ if __name__ == "__main__": if not args.no_libraries: libraries_skip_msg += initialize_precompiled_libraries(args) + if args.use_tests: + libraries_skip_msg += initialize_tests_data_files(args) libraries_skip_msg += submodules_lib_update(args, branch) # Report any skipped repositories at the end, so it's not as easy to miss. @@ -640,10 +646,6 @@ if __name__ == "__main__": print_stage("Update finished with the following messages") print(skip_msg.strip()) - if args.use_tests: - print() - print('NOTE: --use-tests is a deprecated command line argument, kept for compatibility purposes.') - # For failed submodule update we throw an error, since not having correct # submodules can make Blender throw errors. # For Blender itself we don't and consider "make update" to be a command diff --git a/build_files/utils/make_utils.py b/build_files/utils/make_utils.py index 79a3856a0fd..14f621e830e 100644 --- a/build_files/utils/make_utils.py +++ b/build_files/utils/make_utils.py @@ -116,20 +116,6 @@ def git_is_remote_repository(git_command: str, repo: str) -> bool: return exit_code == 0 -def git_get_remotes(git_command: str) -> Sequence[str]: - """Get a list of git remotes""" - # Additional check if the remote exists, for safety in case the output of this command - # changes in the future. - remotes = check_output([git_command, "remote"]).split() - return [remote for remote in remotes if git_remote_exist(git_command, remote)] - - -def git_add_remote(git_command: str, name: str, url: str, push_url: str) -> None: - """Add a git remote""" - call((git_command, "remote", "add", name, url), silent=True) - call((git_command, "remote", "set-url", "--push", name, push_url), silent=True) - - def git_branch(git_command: str) -> str: """Get current branch name.""" diff --git a/doc/python_api/static/favicon.png b/doc/python_api/static/favicon.png index b5c5955303b..aaafdb87ed1 100644 Binary files a/doc/python_api/static/favicon.png and b/doc/python_api/static/favicon.png differ diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt index 98b02db250b..d5f8ea237d8 100644 --- a/extern/audaspace/CMakeLists.txt +++ b/extern/audaspace/CMakeLists.txt @@ -14,7 +14,7 @@ # limitations under the License. ################################################################################ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.5) include(CMakeDependentOption) if(POLICY CMP0054) diff --git a/extern/hipew/CMakeLists.txt b/extern/hipew/CMakeLists.txt index e0e88b8139f..ee216b78beb 100644 --- a/extern/hipew/CMakeLists.txt +++ b/extern/hipew/CMakeLists.txt @@ -14,8 +14,6 @@ set(INC_SYS set(SRC src/hipew.c include/hipew.h - include/hipew5.h - include/hipew6.h ) set(LIB @@ -35,9 +33,3 @@ if(HIPRT_INCLUDE_DIR) endif() blender_add_lib(extern_hipew "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") - -find_package(HIP 5.5.0) - -if(HIP_VERSION_MAJOR EQUAL 5) - target_compile_definitions(extern_hipew PUBLIC WITH_HIP_SDK_5) -endif() diff --git a/extern/hipew/include/hipew.h b/extern/hipew/include/hipew.h index add621dcbfc..52bc26f8bbd 100644 --- a/extern/hipew/include/hipew.h +++ b/extern/hipew/include/hipew.h @@ -116,6 +116,13 @@ typedef struct HIPuuid_st { char bytes[16]; } HIPuuid; +typedef enum hipMemcpyKind { + hipMemcpyHostToHost = 0, + hipMemcpyHostToDevice = 1, + hipMemcpyDeviceToHost = 2, + hipMemcpyDeviceToDevice = 3, + hipMemcpyDefault = 4 +} hipMemcpyKind; typedef enum hipChannelFormatKind { hipChannelFormatKindSigned = 0, @@ -198,6 +205,18 @@ typedef enum hipMemoryType { hipMemoryType get_hip_memory_type(hipMemoryType mem_type, int runtime_version); +/** + * Pointer attributes + */ +typedef struct hipPointerAttribute_t { + enum hipMemoryType memoryType; + int device; + void* devicePointer; + void* hostPointer; + int isManaged; + unsigned allocationFlags; /* flags specified when memory was allocated*/ + /* peers? */ +} hipPointerAttribute_t; typedef struct ihipIpcEventHandle_t { char reserved[HIP_IPC_HANDLE_SIZE]; @@ -295,6 +314,128 @@ typedef enum HIPoccupancy_flags_enum { HIP_OCCUPANCY_DISABLE_CACHING_OVERRIDE = 0x1, } HIPoccupancy_flags; +typedef enum hipDeviceAttribute_t { + hipDeviceAttributeCudaCompatibleBegin = 0, + hipDeviceAttributeEccEnabled = hipDeviceAttributeCudaCompatibleBegin, ///< Whether ECC support is enabled. + hipDeviceAttributeAccessPolicyMaxWindowSize, ///< Cuda only. The maximum size of the window policy in bytes. + hipDeviceAttributeAsyncEngineCount, ///< Cuda only. Asynchronous engines number. + hipDeviceAttributeCanMapHostMemory, ///< Whether host memory can be mapped into device address space + hipDeviceAttributeCanUseHostPointerForRegisteredMem,///< Cuda only. Device can access host registered memory + ///< at the same virtual address as the CPU + hipDeviceAttributeClockRate, ///< Peak clock frequency in kilohertz. + hipDeviceAttributeComputeMode, ///< Compute mode that device is currently in. + hipDeviceAttributeComputePreemptionSupported, ///< Cuda only. Device supports Compute Preemption. + hipDeviceAttributeConcurrentKernels, ///< Device can possibly execute multiple kernels concurrently. + hipDeviceAttributeConcurrentManagedAccess, ///< Device can coherently access managed memory concurrently with the CPU + hipDeviceAttributeCooperativeLaunch, ///< Support cooperative launch + hipDeviceAttributeCooperativeMultiDeviceLaunch, ///< Support cooperative launch on multiple devices + hipDeviceAttributeDeviceOverlap, ///< Cuda only. Device can concurrently copy memory and execute a kernel. + ///< Deprecated. Use instead asyncEngineCount. + hipDeviceAttributeDirectManagedMemAccessFromHost, ///< Host can directly access managed memory on + ///< the device without migration + hipDeviceAttributeGlobalL1CacheSupported, ///< Cuda only. Device supports caching globals in L1 + hipDeviceAttributeHostNativeAtomicSupported, ///< Cuda only. Link between the device and the host supports native atomic operations + hipDeviceAttributeIntegrated, ///< Device is integrated GPU + hipDeviceAttributeIsMultiGpuBoard, ///< Multiple GPU devices. + hipDeviceAttributeKernelExecTimeout, ///< Run time limit for kernels executed on the device + hipDeviceAttributeL2CacheSize, ///< Size of L2 cache in bytes. 0 if the device doesn't have L2 cache. + hipDeviceAttributeLocalL1CacheSupported, ///< caching locals in L1 is supported + hipDeviceAttributeLuid, ///< Cuda only. 8-byte locally unique identifier in 8 bytes. Undefined on TCC and non-Windows platforms + hipDeviceAttributeLuidDeviceNodeMask, ///< Cuda only. Luid device node mask. Undefined on TCC and non-Windows platforms + hipDeviceAttributeComputeCapabilityMajor, ///< Major compute capability version number. + hipDeviceAttributeManagedMemory, ///< Device supports allocating managed memory on this system + hipDeviceAttributeMaxBlocksPerMultiProcessor, ///< Cuda only. Max block size per multiprocessor + hipDeviceAttributeMaxBlockDimX, ///< Max block size in width. + hipDeviceAttributeMaxBlockDimY, ///< Max block size in height. + hipDeviceAttributeMaxBlockDimZ, ///< Max block size in depth. + hipDeviceAttributeMaxGridDimX, ///< Max grid size in width. + hipDeviceAttributeMaxGridDimY, ///< Max grid size in height. + hipDeviceAttributeMaxGridDimZ, ///< Max grid size in depth. + hipDeviceAttributeMaxSurface1D, ///< Maximum size of 1D surface. + hipDeviceAttributeMaxSurface1DLayered, ///< Cuda only. Maximum dimensions of 1D layered surface. + hipDeviceAttributeMaxSurface2D, ///< Maximum dimension (width, height) of 2D surface. + hipDeviceAttributeMaxSurface2DLayered, ///< Cuda only. Maximum dimensions of 2D layered surface. + hipDeviceAttributeMaxSurface3D, ///< Maximum dimension (width, height, depth) of 3D surface. + hipDeviceAttributeMaxSurfaceCubemap, ///< Cuda only. Maximum dimensions of Cubemap surface. + hipDeviceAttributeMaxSurfaceCubemapLayered, ///< Cuda only. Maximum dimension of Cubemap layered surface. + hipDeviceAttributeMaxTexture1DWidth, ///< Maximum size of 1D texture. + hipDeviceAttributeMaxTexture1DLayered, ///< Cuda only. Maximum dimensions of 1D layered texture. + hipDeviceAttributeMaxTexture1DLinear, ///< Maximum number of elements allocatable in a 1D linear texture. + ///< Use cudaDeviceGetTexture1DLinearMaxWidth() instead on Cuda. + hipDeviceAttributeMaxTexture1DMipmap, ///< Cuda only. Maximum size of 1D mipmapped texture. + hipDeviceAttributeMaxTexture2DWidth, ///< Maximum dimension width of 2D texture. + hipDeviceAttributeMaxTexture2DHeight, ///< Maximum dimension hight of 2D texture. + hipDeviceAttributeMaxTexture2DGather, ///< Cuda only. Maximum dimensions of 2D texture if gather operations performed. + hipDeviceAttributeMaxTexture2DLayered, ///< Cuda only. Maximum dimensions of 2D layered texture. + hipDeviceAttributeMaxTexture2DLinear, ///< Cuda only. Maximum dimensions (width, height, pitch) of 2D textures bound to pitched memory. + hipDeviceAttributeMaxTexture2DMipmap, ///< Cuda only. Maximum dimensions of 2D mipmapped texture. + hipDeviceAttributeMaxTexture3DWidth, ///< Maximum dimension width of 3D texture. + hipDeviceAttributeMaxTexture3DHeight, ///< Maximum dimension height of 3D texture. + hipDeviceAttributeMaxTexture3DDepth, ///< Maximum dimension depth of 3D texture. + hipDeviceAttributeMaxTexture3DAlt, ///< Cuda only. Maximum dimensions of alternate 3D texture. + hipDeviceAttributeMaxTextureCubemap, ///< Cuda only. Maximum dimensions of Cubemap texture + hipDeviceAttributeMaxTextureCubemapLayered, ///< Cuda only. Maximum dimensions of Cubemap layered texture. + hipDeviceAttributeMaxThreadsDim, ///< Maximum dimension of a block + hipDeviceAttributeMaxThreadsPerBlock, ///< Maximum number of threads per block. + hipDeviceAttributeMaxThreadsPerMultiProcessor, ///< Maximum resident threads per multiprocessor. + hipDeviceAttributeMaxPitch, ///< Maximum pitch in bytes allowed by memory copies + hipDeviceAttributeMemoryBusWidth, ///< Global memory bus width in bits. + hipDeviceAttributeMemoryClockRate, ///< Peak memory clock frequency in kilohertz. + hipDeviceAttributeComputeCapabilityMinor, ///< Minor compute capability version number. + hipDeviceAttributeMultiGpuBoardGroupID, ///< Cuda only. Unique ID of device group on the same multi-GPU board + hipDeviceAttributeMultiprocessorCount, ///< Number of multiprocessors on the device. + hipDeviceAttributeName, ///< Device name. + hipDeviceAttributePageableMemoryAccess, ///< Device supports coherently accessing pageable memory + ///< without calling hipHostRegister on it + hipDeviceAttributePageableMemoryAccessUsesHostPageTables, ///< Device accesses pageable memory via the host's page tables + hipDeviceAttributePciBusId, ///< PCI Bus ID. + hipDeviceAttributePciDeviceId, ///< PCI Device ID. + hipDeviceAttributePciDomainID, ///< PCI Domain ID. + hipDeviceAttributePersistingL2CacheMaxSize, ///< Cuda11 only. Maximum l2 persisting lines capacity in bytes + hipDeviceAttributeMaxRegistersPerBlock, ///< 32-bit registers available to a thread block. This number is shared + ///< by all thread blocks simultaneously resident on a multiprocessor. + hipDeviceAttributeMaxRegistersPerMultiprocessor, ///< 32-bit registers available per block. + hipDeviceAttributeReservedSharedMemPerBlock, ///< Cuda11 only. Shared memory reserved by CUDA driver per block. + hipDeviceAttributeMaxSharedMemoryPerBlock, ///< Maximum shared memory available per block in bytes. + hipDeviceAttributeSharedMemPerBlockOptin, ///< Cuda only. Maximum shared memory per block usable by special opt in. + hipDeviceAttributeSharedMemPerMultiprocessor, ///< Cuda only. Shared memory available per multiprocessor. + hipDeviceAttributeSingleToDoublePrecisionPerfRatio, ///< Cuda only. Performance ratio of single precision to double precision. + hipDeviceAttributeStreamPrioritiesSupported, ///< Cuda only. Whether to support stream priorities. + hipDeviceAttributeSurfaceAlignment, ///< Cuda only. Alignment requirement for surfaces + hipDeviceAttributeTccDriver, ///< Cuda only. Whether device is a Tesla device using TCC driver + hipDeviceAttributeTextureAlignment, ///< Alignment requirement for textures + hipDeviceAttributeTexturePitchAlignment, ///< Pitch alignment requirement for 2D texture references bound to pitched memory; + hipDeviceAttributeTotalConstantMemory, ///< Constant memory size in bytes. + hipDeviceAttributeTotalGlobalMem, ///< Global memory available on devicice. + hipDeviceAttributeUnifiedAddressing, ///< Cuda only. An unified address space shared with the host. + hipDeviceAttributeUuid, ///< Cuda only. Unique ID in 16 byte. + hipDeviceAttributeWarpSize, ///< Warp size in threads. + hipDeviceAttributeCudaCompatibleEnd = 9999, + hipDeviceAttributeAmdSpecificBegin = 10000, + hipDeviceAttributeClockInstructionRate = hipDeviceAttributeAmdSpecificBegin, ///< Frequency in khz of the timer used by the device-side "clock*" + hipDeviceAttributeArch, ///< Device architecture + hipDeviceAttributeMaxSharedMemoryPerMultiprocessor, ///< Maximum Shared Memory PerMultiprocessor. + hipDeviceAttributeGcnArch, ///< Device gcn architecture + hipDeviceAttributeGcnArchName, ///< Device gcnArch name in 256 bytes + hipDeviceAttributeHdpMemFlushCntl, ///< Address of the HDP_MEM_COHERENCY_FLUSH_CNTL register + hipDeviceAttributeHdpRegFlushCntl, ///< Address of the HDP_REG_COHERENCY_FLUSH_CNTL register + hipDeviceAttributeCooperativeMultiDeviceUnmatchedFunc, ///< Supports cooperative launch on multiple + ///< devices with unmatched functions + hipDeviceAttributeCooperativeMultiDeviceUnmatchedGridDim, ///< Supports cooperative launch on multiple + ///< devices with unmatched grid dimensions + hipDeviceAttributeCooperativeMultiDeviceUnmatchedBlockDim, ///< Supports cooperative launch on multiple + ///< devices with unmatched block dimensions + hipDeviceAttributeCooperativeMultiDeviceUnmatchedSharedMem, ///< Supports cooperative launch on multiple + ///< devices with unmatched shared memories + hipDeviceAttributeIsLargeBar, ///< Whether it is LargeBar + hipDeviceAttributeAsicRevision, ///< Revision of the GPU in this device + hipDeviceAttributeCanUseStreamWaitValue, ///< '1' if Device supports hipStreamWaitValue32() and + ///< hipStreamWaitValue64() , '0' otherwise. + hipDeviceAttributeAmdSpecificEnd = 19999, + hipDeviceAttributeVendorSpecificBegin = 20000, + hipDeviceAttribute + // Extended attributes for vendors +} hipDeviceAttribute_t; typedef struct HIPdevprop_st { int maxThreadsPerBlock; @@ -340,6 +481,84 @@ typedef struct { unsigned hasDynamicParallelism : 1; ///< Dynamic parallelism. } hipDeviceArch_t; +typedef struct hipDeviceProp_t { + char name[256]; ///< Device name. + size_t totalGlobalMem; ///< Size of global memory region (in bytes). + size_t sharedMemPerBlock; ///< Size of shared memory region (in bytes). + int regsPerBlock; ///< Registers per block. + int warpSize; ///< Warp size. + int maxThreadsPerBlock; ///< Max work items per work group or workgroup max size. + int maxThreadsDim[3]; ///< Max number of threads in each dimension (XYZ) of a block. + int maxGridSize[3]; ///< Max grid dimensions (XYZ). + int clockRate; ///< Max clock frequency of the multiProcessors in khz. + int memoryClockRate; ///< Max global memory clock frequency in khz. + int memoryBusWidth; ///< Global memory bus width in bits. + size_t totalConstMem; ///< Size of shared memory region (in bytes). + int major; ///< Major compute capability. On HCC, this is an approximation and features may + ///< differ from CUDA CC. See the arch feature flags for portable ways to query + ///< feature caps. + int minor; ///< Minor compute capability. On HCC, this is an approximation and features may + ///< differ from CUDA CC. See the arch feature flags for portable ways to query + ///< feature caps. + int multiProcessorCount; ///< Number of multi-processors (compute units). + int l2CacheSize; ///< L2 cache size. + int maxThreadsPerMultiProcessor; ///< Maximum resident threads per multi-processor. + int computeMode; ///< Compute mode. + int clockInstructionRate; ///< Frequency in khz of the timer used by the device-side "clock*" + ///< instructions. New for HIP. + hipDeviceArch_t arch; ///< Architectural feature flags. New for HIP. + int concurrentKernels; ///< Device can possibly execute multiple kernels concurrently. + int pciDomainID; ///< PCI Domain ID + int pciBusID; ///< PCI Bus ID. + int pciDeviceID; ///< PCI Device ID. + size_t maxSharedMemoryPerMultiProcessor; ///< Maximum Shared Memory Per Multiprocessor. + int isMultiGpuBoard; ///< 1 if device is on a multi-GPU board, 0 if not. + int canMapHostMemory; ///< Check whether HIP can map host memory + int gcnArch; ///< DEPRECATED: use gcnArchName instead + char gcnArchName[256]; ///< AMD GCN Arch Name. + int integrated; ///< APU vs dGPU + int cooperativeLaunch; ///< HIP device supports cooperative launch + int cooperativeMultiDeviceLaunch; ///< HIP device supports cooperative launch on multiple devices + int maxTexture1DLinear; ///< Maximum size for 1D textures bound to linear memory + int maxTexture1D; ///< Maximum number of elements in 1D images + int maxTexture2D[2]; ///< Maximum dimensions (width, height) of 2D images, in image elements + int maxTexture3D[3]; ///< Maximum dimensions (width, height, depth) of 3D images, in image elements + unsigned int* hdpMemFlushCntl; ///< Addres of HDP_MEM_COHERENCY_FLUSH_CNTL register + unsigned int* hdpRegFlushCntl; ///< Addres of HDP_REG_COHERENCY_FLUSH_CNTL register + size_t memPitch; /// &args); + void construct(const std::string &scriptname, const vector &args); void cleanup(); void renameObjects(); void runPreInit(PyObject *name_space); @@ -566,9 +566,7 @@ PyObject *WrapperRegistry::createPyObject(const string &classname, } // prepare typeinfo and register python module -void WrapperRegistry::construct(const bool python_lifecycle, - const string &scriptname, - const vector &args) +void WrapperRegistry::construct(const string &scriptname, const vector &args) { mScriptName = scriptname; this->args = args; @@ -577,15 +575,8 @@ void WrapperRegistry::construct(const bool python_lifecycle, registerMeta(); registerDummyTypes(); - // Don't extend the init-tab when Python is already initialized. - // Since Python 3.12 this isn't supported and will crash. - // - // When `python_lifecycle` is false (when manta-flow is embedded), it's the responsibility - // of the application embedding this code to include #PyInit_manta_main in the init-tab. - if (python_lifecycle) { - // work around for certain gcc versions, cast to char* - PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_manta_main); - } + // work around for certain gcc versions, cast to char* + PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_manta_main); } inline PyObject *castPy(PyTypeObject *p) @@ -720,7 +711,7 @@ void setup(const bool python_lifecycle, const std::vector &args, PyObject *name_space) { - WrapperRegistry::instance().construct(python_lifecycle, filename, args); + WrapperRegistry::instance().construct(filename, args); if (python_lifecycle) { Py_Initialize(); } diff --git a/extern/mantaflow/preprocessed/fileio/iovdb.cpp b/extern/mantaflow/preprocessed/fileio/iovdb.cpp index 755de56ccc8..1846ef7ecbb 100644 --- a/extern/mantaflow/preprocessed/fileio/iovdb.cpp +++ b/extern/mantaflow/preprocessed/fileio/iovdb.cpp @@ -54,28 +54,14 @@ template void importVDB(typename GridType::Ptr from, Gr using ValueT = typename GridType::ValueType; // Check if current grid is to be read as a sparse grid, active voxels (only) will be copied - if (to->saveSparse()) { to->clear(); // Ensure that destination grid is empty before writing for (typename GridType::ValueOnCIter iter = from->cbeginValueOn(); iter.test(); ++iter) { ValueT vdbValue = *iter; + openvdb::Coord coord = iter.getCoord(); T toMantaValue; convertFrom(vdbValue, &toMantaValue); - // #91174 #124064 - Check if iteration is Voxel or Tile - if (iter.isVoxelValue()) { - openvdb::Coord coord = iter.getCoord(); - to->set(coord.x(), coord.y(), coord.z(), toMantaValue); - } - else { - openvdb::CoordBBox bbox; - iter.getBoundingBox(bbox); - // If grid has 8x8x8 block with the same value, it is stored as Tile with single value. - // We need to iterate over the bounding box and copy such value to all voxels in 8x8x8 node. - for (openvdb::CoordBBox::Iterator ijk(bbox); ijk; ++ijk) { - openvdb::Coord coord = *ijk; - to->set(coord.x(), coord.y(), coord.z(), toMantaValue); - } - } + to->set(coord.x(), coord.y(), coord.z(), toMantaValue); } } // When importing all grid cells, using a grid accessor is usually faster than a value iterator diff --git a/extern/quadriflow/src/optimizer.cpp b/extern/quadriflow/src/optimizer.cpp index 5e14f329805..1c59ad0f70c 100644 --- a/extern/quadriflow/src/optimizer.cpp +++ b/extern/quadriflow/src/optimizer.cpp @@ -1296,9 +1296,7 @@ void Optimizer::optimize_integer_constraints(Hierarchy& mRes, std::map solver = std::make_unique(); } #endif - /* This used to be arc_ids.size() which is wrong, the loop below adds - * exactly arcs.size() edges. */ - solver->resize(initial.size() + 2, arcs.size()); + solver->resize(initial.size() + 2, arc_ids.size()); std::set ids; for (int i = 0; i < arcs.size(); ++i) { diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 808f4fe19d7..db00f353e1d 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -1111,12 +1111,10 @@ void BlenderSync::sync_mesh(BL::Depsgraph b_depsgraph, BObjectInfo &b_ob_info, M if (view_layer.use_surfaces) { /* Adaptive subdivision setup. Not for baking since that requires * exact mapping to the Blender mesh. */ - Mesh::SubdivisionType subdivision_type = (b_ob_info.real_object != b_bake_target) ? - object_subdivision_type(b_ob_info.real_object, - preview, - experimental) : - Mesh::SUBDIVISION_NONE; - new_mesh.set_subdivision_type(subdivision_type); + if (!scene->bake_manager->get_baking()) { + new_mesh.set_subdivision_type( + object_subdivision_type(b_ob_info.real_object, preview, experimental)); + } /* For some reason, meshes do not need this... */ bool need_undeformed = new_mesh.need_attribute(scene, ATTR_STD_GENERATED); diff --git a/intern/cycles/blender/object.cpp b/intern/cycles/blender/object.cpp index bc7b5edfdd3..54d88477bc8 100644 --- a/intern/cycles/blender/object.cpp +++ b/intern/cycles/blender/object.cpp @@ -175,7 +175,7 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, if (is_instance) { persistent_id_array = b_instance.persistent_id(); persistent_id = persistent_id_array.data; - if (!motion && !b_ob_info.is_real_object_data()) { + if (!b_ob_info.is_real_object_data()) { /* Remember which object data the geometry is coming from, so that we can sync it when the * object has changed. */ instance_geometries_by_object[b_ob_info.real_object.ptr.data].insert(b_ob_info.object_data); @@ -316,8 +316,6 @@ Object *BlenderSync::sync_object(BL::Depsgraph &b_depsgraph, bool is_caustics_receiver = get_boolean(cobject, "is_caustics_receiver"); object->set_is_caustics_receiver(is_caustics_receiver); - object->set_is_bake_target(b_ob_info.real_object == b_bake_target); - /* sync the asset name for Cryptomatte */ BL::Object parent = b_ob.parent(); ustring parent_name; @@ -563,12 +561,7 @@ void BlenderSync::sync_objects(BL::Depsgraph &b_depsgraph, else { geometry_motion_synced.clear(); } - - if (!motion) { - /* Object to geometry instance mapping is built for the reference time, as other - * times just look up the corresponding geometry. */ - instance_geometries_by_object.clear(); - } + instance_geometries_by_object.clear(); /* initialize culling */ BlenderObjectCulling culling(scene, b_scene); diff --git a/intern/cycles/blender/pointcloud.cpp b/intern/cycles/blender/pointcloud.cpp index 58d9b87898d..7a53e49325d 100644 --- a/intern/cycles/blender/pointcloud.cpp +++ b/intern/cycles/blender/pointcloud.cpp @@ -209,8 +209,6 @@ void BlenderSync::sync_pointcloud(PointCloud *pointcloud, BObjectInfo &b_ob_info need_motion, motion_scale); - pointcloud->clear_non_sockets(); - /* Update original sockets. */ for (const SocketType &socket : new_pointcloud.type->inputs) { /* Those sockets are updated in sync_object, so do not modify them. */ diff --git a/intern/cycles/blender/session.cpp b/intern/cycles/blender/session.cpp index 57ea30f3f07..4a705c9aea1 100644 --- a/intern/cycles/blender/session.cpp +++ b/intern/cycles/blender/session.cpp @@ -686,7 +686,7 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, b_engine, b_userpref, b_scene, background); /* Initialize bake manager, before we load the baking kernels. */ - scene->bake_manager->set_baking(scene, true); + scene->bake_manager->set(scene, b_object.name()); session->set_display_driver(nullptr); session->set_output_driver(make_unique(b_engine)); @@ -694,7 +694,6 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, /* Sync scene. */ BL::Object b_camera_override(b_engine.camera_override()); - sync->set_bake_target(b_object); sync->sync_camera(b_render, b_camera_override, width, height, ""); sync->sync_data(b_render, b_depsgraph, @@ -728,8 +727,8 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_, * other way, in that case Blender will report a warning afterwards. */ Object *bake_object = nullptr; if (!session->progress.get_cancel()) { - for (Object *ob : scene->objects) { - if (ob->get_is_bake_target()) { + foreach (Object *ob, scene->objects) { + if (ob->name == b_object.name()) { bake_object = ob; break; } diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index cbd77cade6f..8d8ac7e67ac 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -842,13 +842,11 @@ static ShaderNode *add_node(Scene *scene, image->set_animated(is_image_animated(b_image_source, b_image_user)); image->set_alpha_type(get_image_alpha_type(b_image)); - if (b_image_source == BL::Image::source_TILED) { - array tiles; - for (BL::UDIMTile &b_tile : b_image.tiles) { - tiles.push_back_slow(b_tile.number()); - } - image->set_tiles(tiles); + array tiles; + for (BL::UDIMTile &b_tile : b_image.tiles) { + tiles.push_back_slow(b_tile.number()); } + image->set_tiles(tiles); /* builtin images will use callback-based reading because * they could only be loaded correct from blender side diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index 86615daafa2..6ee7e45c931 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -2,7 +2,6 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include "RNA_types.hh" #include "scene/background.h" #include "scene/camera.h" #include "scene/curves.h" @@ -48,7 +47,6 @@ BlenderSync::BlenderSync(BL::RenderEngine &b_engine, : b_engine(b_engine), b_data(b_data), b_scene(b_scene), - b_bake_target(PointerRNA_NULL), shader_map(scene), object_map(scene), procedural_map(scene), @@ -89,11 +87,6 @@ void BlenderSync::tag_update() has_updates_ = true; } -void BlenderSync::set_bake_target(BL::Object &b_object) -{ - b_bake_target = b_object; -} - /* Sync */ void BlenderSync::sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d) @@ -585,7 +578,7 @@ void BlenderSync::sync_view_layer(BL::ViewLayer &b_view_layer) /* Filter. */ view_layer.use_background_shader = b_view_layer.use_sky(); /* Always enable surfaces for baking, otherwise there is nothing to bake to. */ - view_layer.use_surfaces = b_view_layer.use_solid() || b_bake_target; + view_layer.use_surfaces = b_view_layer.use_solid() || scene->bake_manager->get_baking(); view_layer.use_hair = b_view_layer.use_strand(); view_layer.use_volumes = b_view_layer.use_volumes(); view_layer.use_motion_blur = b_view_layer.use_motion_blur() && @@ -814,7 +807,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph) /* Baking re-uses the depsgraph multiple times, clearing crashes * reading un-evaluated mesh data which isn't aligned with the * geometry we're baking, see #71012. */ - !b_bake_target && + !scene->bake_manager->get_baking() && /* Persistent data must main caches for performance and correctness. */ !is_persistent_data; diff --git a/intern/cycles/blender/sync.h b/intern/cycles/blender/sync.h index 6c9d50f6644..e42622dd74b 100644 --- a/intern/cycles/blender/sync.h +++ b/intern/cycles/blender/sync.h @@ -57,8 +57,6 @@ class BlenderSync { void tag_update(); - void set_bake_target(BL::Object &b_object); - /* sync */ void sync_recalc(BL::Depsgraph &b_depsgraph, BL::SpaceView3D &b_v3d); void sync_data(BL::RenderSettings &b_render, @@ -225,7 +223,6 @@ class BlenderSync { BL::RenderEngine b_engine; BL::BlendData b_data; BL::Scene b_scene; - BL::Object b_bake_target; enum ShaderFlags { SHADER_WITH_LAYER_ATTRS }; diff --git a/intern/cycles/blender/volume.cpp b/intern/cycles/blender/volume.cpp index 477a9779580..7d0455efa72 100644 --- a/intern/cycles/blender/volume.cpp +++ b/intern/cycles/blender/volume.cpp @@ -198,8 +198,6 @@ static void sync_smoke_volume( ATTR_STD_VOLUME_VELOCITY, ATTR_STD_NONE}; - int frame_interval[2] = {b_domain.cache_frame_start(), b_domain.cache_frame_end()}; - for (int i = 0; attributes[i] != ATTR_STD_NONE; i++) { AttributeStandard std = attributes[i]; if (!volume->need_attribute(scene, std)) { @@ -210,11 +208,6 @@ static void sync_smoke_volume( Attribute *attr = volume->attributes.add(std); - if (frame < frame_interval[0] || frame > frame_interval[1]) { - attr->data_voxel().clear(); - continue; - } - ImageLoader *loader = new BlenderSmokeLoader(b_ob_info.real_object, std); ImageParams params; params.frame = frame; diff --git a/intern/cycles/bvh/split.cpp b/intern/cycles/bvh/split.cpp index 71ba3eb7d05..013a7373351 100644 --- a/intern/cycles/bvh/split.cpp +++ b/intern/cycles/bvh/split.cpp @@ -41,6 +41,8 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder, const BVHReference *ref_ptr = &references_->at(range.start()); float min_sah = FLT_MAX; + storage_->right_bounds.resize(range.size()); + for (int dim = 0; dim < 3; dim++) { /* Sort references. */ bvh_reference_sort(range.start(), @@ -50,11 +52,6 @@ BVHObjectSplit::BVHObjectSplit(BVHBuild *builder, unaligned_heuristic_, aligned_space_); - // Resize must be called after every bvh_reference_sort, as sorting may use a task pool for - // large ranges. This may cause another BVHObjectSplit to use and resize the storage on the - // same thread. - storage_->right_bounds.resize(range.size()); - /* sweep right to left and determine bounds. */ BoundBox right_bounds = BoundBox::empty; for (int i = range.size() - 1; i > 0; i--) { @@ -444,11 +441,11 @@ void BVHSpatialSplit::split_point_primitive(const PointCloud *pointcloud, } point = get_unaligned_point(point); - if (point[dim] - radius <= pos) { + if (point[dim] <= pos) { left_bounds.grow(point, radius); } - if (point[dim] + radius >= pos) { + if (point[dim] >= pos) { right_bounds.grow(point, radius); } } diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp index 92bb7ace29d..4e00c4a5a6c 100644 --- a/intern/cycles/device/device.cpp +++ b/intern/cycles/device/device.cpp @@ -804,17 +804,4 @@ void GPUDevice::generic_copy_to(device_memory &mem) /* DeviceInfo */ -bool DeviceInfo::contains_device_type(const DeviceType type) const -{ - if (this->type == type) { - return true; - } - for (const DeviceInfo &info : multi_devices) { - if (info.contains_device_type(type)) { - return true; - } - } - return false; -} - CCL_NAMESPACE_END diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 1e457c435e6..9aee1928d7e 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -114,7 +114,6 @@ class DeviceInfo { has_gpu_queue = false; use_hardware_raytracing = false; use_metalrt_by_default = false; - kernel_optimization_level = KERNEL_OPTIMIZATION_LEVEL_FULL; denoisers = DENOISER_NONE; } @@ -130,8 +129,6 @@ class DeviceInfo { { return !(*this == info); } - - bool contains_device_type(const DeviceType type) const; }; /* Device */ diff --git a/intern/cycles/device/metal/bvh.mm b/intern/cycles/device/metal/bvh.mm index 9eb688515ed..c4ca2707646 100644 --- a/intern/cycles/device/metal/bvh.mm +++ b/intern/cycles/device/metal/bvh.mm @@ -109,22 +109,6 @@ struct BVHMetalBuildThrottler { } } g_bvh_build_throttler; -/* macOS 15.2 and 15.3 has a bug in the dynamic BVH refitting which leads to missing geometry - * during render. The issue is fixed in the macOS 15.4, until then disable refitting even for - * the viewport. - * Note that dynamic BVH is still used on the scene level to speed up updates of instances and - * such. #132782. */ -static bool support_refit_blas() -{ - if (@available(macos 15.4, *)) { - return true; - } - if (@available(macos 15.2, *)) { - return false; - } - return true; -} - BVHMetal::BVHMetal(const BVHParams ¶ms_, const vector &geometry_, const vector &objects_, @@ -178,7 +162,7 @@ bool BVHMetal::build_BLAS_mesh(Progress &progress, "Building mesh BLAS | %7d tris | %s", (int)mesh->num_triangles(), geom->name.c_str()); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); const array &verts = mesh->get_verts(); const array &tris = mesh->get_triangles(); @@ -399,7 +383,7 @@ bool BVHMetal::build_BLAS_hair(Progress &progress, "Building hair BLAS | %7d curves | %s", (int)hair->num_curves(), geom->name.c_str()); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); size_t num_motion_steps = 1; Attribute *motion_keys = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -743,7 +727,7 @@ bool BVHMetal::build_BLAS_pointcloud(Progress &progress, const float3 *points = pointcloud->get_points().data(); const float *radius = pointcloud->get_radius().data(); - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); size_t num_motion_steps = 1; Attribute *motion_keys = pointcloud->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); @@ -1063,7 +1047,7 @@ bool BVHMetal::build_TLAS(Progress &progress, BVH_status("Building TLAS | %7d instances", (int)num_instances); /*------------------------------------------------*/ - const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC) || !support_refit_blas(); + const bool use_fast_trace_bvh = (params.bvh_type == BVH_TYPE_STATIC); NSMutableArray *all_blas = [NSMutableArray array]; unordered_map instance_mapping; @@ -1340,10 +1324,6 @@ bool BVHMetal::build(Progress &progress, } } - if (!support_refit_blas()) { - refit = false; - } - @autoreleasepool { if (!params.top_level) { return build_BLAS(progress, mtl_device, queue, refit); diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index a1b4580934f..461613de4be 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -392,7 +392,7 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M bool MetalKernelPipeline::should_use_binary_archive() const { /* Issues with binary archives in older macOS versions. */ - if (@available(macOS 15.4, *)) { + if (@available(macOS 13.0, *)) { if (auto str = getenv("CYCLES_METAL_DISABLE_BINARY_ARCHIVES")) { if (atoi(str) != 0) { /* Don't archive if we have opted out by env var. */ diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index f7f11a487c4..5c5919c6b09 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -530,21 +530,18 @@ void OneapiDevice::const_copy_to(const char *name, void *host, size_t size) << string_human_readable_number(size) << " bytes. (" << string_human_readable_size(size) << ")"; - if (strcmp(name, "data") == 0) { - assert(size <= sizeof(KernelData)); - KernelData *const data = static_cast(host); - - /* We need this value when allocating local memory for integrator_sort_bucket_pass - * and integrator_sort_write_pass kernels. */ - scene_max_shaders_ = data->max_shaders; - # ifdef WITH_EMBREE_GPU - if (embree_scene != nullptr) { - /* Update scene handle(since it is different for each device on multi devices) */ - data->device_bvh = embree_scene; - } -# endif + if (embree_scene != nullptr && strcmp(name, "data") == 0) { + assert(size <= sizeof(KernelData)); + + /* Update scene handle(since it is different for each device on multi devices) */ + KernelData *const data = (KernelData *)host; + data->device_bvh = embree_scene; + + /* We need this number later for proper local memory allocation. */ + scene_max_shaders_ = data->max_shaders; } +# endif ConstMemMap::iterator i = const_mem_map_.find(name); device_vector *data; diff --git a/intern/cycles/kernel/closure/bsdf_principled_hair_huang.h b/intern/cycles/kernel/closure/bsdf_principled_hair_huang.h index 73f2cd32ef0..72334fdc1e8 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_hair_huang.h +++ b/intern/cycles/kernel/closure/bsdf_principled_hair_huang.h @@ -869,14 +869,6 @@ ccl_device Spectrum bsdf_hair_huang_eval(KernelGlobals kg, bsdf->extra->gamma_m_min = gamma_m_min; bsdf->extra->gamma_m_max = gamma_m_max; - /* FIXME(weizhen): There is a problem of `fast_sinf(-1.57085085f)` returning 0 instead of - * expected -1, causing the range to be incorrect. As that seems an uncommon case, it feels safer - * to cover this case first, and look into solving the problem in `fast_sinf()` later. */ - kernel_assert(bsdf->extra->gamma_m_min < bsdf->extra->gamma_m_max); - if (!(bsdf->extra->gamma_m_min < bsdf->extra->gamma_m_max)) { - return zero_spectrum(); - } - const float projected_area = cos_theta(local_I) * dh; return (bsdf_hair_huang_eval_r(kg, sc, local_I, local_O) + diff --git a/intern/cycles/kernel/geom/motion_curve.h b/intern/cycles/kernel/geom/motion_curve.h index 09cd2f56aa4..62d676b96ca 100644 --- a/intern/cycles/kernel/geom/motion_curve.h +++ b/intern/cycles/kernel/geom/motion_curve.h @@ -48,7 +48,7 @@ ccl_device_inline void motion_curve_keys_linear( KernelGlobals kg, int object, float time, int k0, int k1, float4 keys[2]) { /* get motion info */ - const int numsteps = kernel_data_fetch(objects, object).num_geom_steps; + const int numsteps = kernel_data_fetch(objects, object).numsteps; const int numverts = kernel_data_fetch(objects, object).numverts; /* figure out which steps we need to fetch and their interpolation factor */ @@ -108,7 +108,7 @@ ccl_device_inline void motion_curve_keys( KernelGlobals kg, int object, float time, int k0, int k1, int k2, int k3, float4 keys[4]) { /* get motion info */ - const int numsteps = kernel_data_fetch(objects, object).num_geom_steps; + const int numsteps = kernel_data_fetch(objects, object).numsteps; const int numverts = kernel_data_fetch(objects, object).numverts; /* figure out which steps we need to fetch and their interpolation factor */ diff --git a/intern/cycles/kernel/geom/motion_point.h b/intern/cycles/kernel/geom/motion_point.h index 7880753f05b..d6bfa527723 100644 --- a/intern/cycles/kernel/geom/motion_point.h +++ b/intern/cycles/kernel/geom/motion_point.h @@ -37,7 +37,7 @@ motion_point_for_step(KernelGlobals kg, int offset, int numverts, int numsteps, ccl_device_inline float4 motion_point(KernelGlobals kg, int object, int prim, float time) { /* get motion info */ - const int numsteps = kernel_data_fetch(objects, object).num_geom_steps; + const int numsteps = kernel_data_fetch(objects, object).numsteps; const int numverts = kernel_data_fetch(objects, object).numverts; /* figure out which steps we need to fetch and their interpolation factor */ diff --git a/intern/cycles/kernel/geom/motion_triangle.h b/intern/cycles/kernel/geom/motion_triangle.h index 4286fc77215..13df5a36825 100644 --- a/intern/cycles/kernel/geom/motion_triangle.h +++ b/intern/cycles/kernel/geom/motion_triangle.h @@ -87,7 +87,7 @@ ccl_device_inline void motion_triangle_compute_info(KernelGlobals kg, ccl_private float *t) { /* Get object motion info. */ - *numsteps = kernel_data_fetch(objects, object).num_geom_steps; + *numsteps = kernel_data_fetch(objects, object).numsteps; /* Figure out which steps we need to fetch and their interpolation factor. */ int maxstep = *numsteps * 2; diff --git a/intern/cycles/kernel/geom/object.h b/intern/cycles/kernel/geom/object.h index fd5a1ff735c..015d5e6e1c3 100644 --- a/intern/cycles/kernel/geom/object.h +++ b/intern/cycles/kernel/geom/object.h @@ -67,8 +67,8 @@ ccl_device_inline Transform object_fetch_motion_pass_transform(KernelGlobals kg, ccl_device_inline Transform object_fetch_transform_motion(KernelGlobals kg, int object, float time) { const uint motion_offset = kernel_data_fetch(objects, object).motion_offset; - const ccl_global DecomposedTransform *motion = &kernel_data_fetch(object_motion, motion_offset); - const uint num_steps = kernel_data_fetch(objects, object).num_tfm_steps; + ccl_global const DecomposedTransform *motion = &kernel_data_fetch(object_motion, motion_offset); + const uint num_steps = kernel_data_fetch(objects, object).numsteps * 2 + 1; Transform tfm; transform_motion_array_interpolate(&tfm, motion, num_steps, time); diff --git a/intern/cycles/kernel/light/background.h b/intern/cycles/kernel/light/background.h index 62253d97714..8f19ed1173d 100644 --- a/intern/cycles/kernel/light/background.h +++ b/intern/cycles/kernel/light/background.h @@ -447,15 +447,10 @@ ccl_device_forceinline bool background_light_tree_parameters(const float3 centro { if (in_volume_segment) { if (t == FLT_MAX) { - /* In world volumes, distant lights can contribute to the lighting of the volume with - * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this - * case to give the distant light some weight, but one that isn't too high for a typical - * world volume use case. */ - theta_d = 1.0f; - } - else { - theta_d = t; + /* In world volume, distant light has no contribution. */ + return false; } + theta_d = t; } /* Cover the whole sphere */ diff --git a/intern/cycles/kernel/light/distant.h b/intern/cycles/kernel/light/distant.h index e25e84af96d..ca1222efde7 100644 --- a/intern/cycles/kernel/light/distant.h +++ b/intern/cycles/kernel/light/distant.h @@ -140,15 +140,10 @@ ccl_device_forceinline bool distant_light_tree_parameters(const float3 centroid, { if (in_volume_segment) { if (t == FLT_MAX) { - /* In world volumes, distant lights can contribute to the lighting of the volume with - * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this - * case to give the distant light some weight, but one that isn't too high for a typical - * world volume use case. */ - theta_d = 1.0f; - } - else { - theta_d = t; + /* In world volume, distant light has no contribution. */ + return false; } + theta_d = t; } /* Treating it as a disk light 1 unit away */ diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index e47b8e42b0f..540cea7d121 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -218,7 +218,7 @@ ccl_device void light_tree_importance(const float3 N_or_D, float cos_max_outgoing_angle; const float cos_theta_plus_theta_u = cos_theta * cos_theta_u - sin_theta * sin_theta_u; if (bcone.theta_e - bcone.theta_o < 0 || cos_theta < 0 || cos_theta_u < 0 || - cos_theta_plus_theta_u < fast_cosf(bcone.theta_e - bcone.theta_o)) + cos_theta_plus_theta_u < cosf(bcone.theta_e - bcone.theta_o)) { min_importance = 0.0f; } @@ -313,15 +313,10 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, cos_theta_u = fast_cosf(bcone.theta_o + bcone.theta_e); distance = 1.0f; /* For distant lights, the integral in Eq. (4) gives the ray length. */ + theta_d = t; if (t == FLT_MAX) { - /* In world volumes, distant lights can contribute to the lighting of the volume with - * specific configurations of procedurally generated volumes. Use a ray length of 1.0 in this - * case to give the distant light some weight, but one that isn't too high for a typical - * world volume use case. */ - theta_d = 1.0f; - } - else { - theta_d = t; + /* In world volume, distant light has no contribution. */ + return; } } else { diff --git a/intern/cycles/kernel/osl/shaders/node_image_texture.osl b/intern/cycles/kernel/osl/shaders/node_image_texture.osl index 10e4f692d31..bfe4ac74e7d 100644 --- a/intern/cycles/kernel/osl/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/osl/shaders/node_image_texture.osl @@ -58,7 +58,7 @@ color image_texture_lookup(string filename, /* Flip the y coordinate, but preserve UDIM tiles. */ float flip_v; if (is_tiled) { - float v_i = floor(v); + float v_i = (int)v; flip_v = v_i + (1.0 - (v - v_i)); } else { diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index b578808e297..56dad1b0548 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1526,8 +1526,7 @@ typedef struct KernelObject { float dupli_uv[2]; int numkeys; - int num_geom_steps; - int num_tfm_steps; + int numsteps; int numverts; uint patch_map_offset; @@ -1550,8 +1549,6 @@ typedef struct KernelObject { /* Volume velocity scale. */ float velocity_scale; - int pad[3]; - /* TODO: separate array to avoid memory overhead when not used. */ uint64_t light_set_membership; uint receiver_light_set; diff --git a/intern/cycles/scene/bake.cpp b/intern/cycles/scene/bake.cpp index dfe5a749a5a..ddb720a53a9 100644 --- a/intern/cycles/scene/bake.cpp +++ b/intern/cycles/scene/bake.cpp @@ -14,18 +14,22 @@ CCL_NAMESPACE_BEGIN -bool BakeManager::get_baking() const +BakeManager::BakeManager() { - return use_baking_; + need_update_ = true; + use_camera_ = false; } -void BakeManager::set_baking(Scene *scene, const bool use) -{ - if (use_baking_ == use) { - return; - } +BakeManager::~BakeManager() {} - use_baking_ = use; +bool BakeManager::get_baking() const +{ + return !object_name.empty(); +} + +void BakeManager::set(Scene *scene, const std::string &object_name_) +{ + object_name = object_name_; /* create device and update scene */ scene->film->tag_modified(); @@ -66,8 +70,8 @@ void BakeManager::device_update(Device * /*device*/, kbake->use_camera = use_camera_; - if (use_baking_) { - const scoped_callback_timer timer([scene](double time) { + if (!object_name.empty()) { + scoped_callback_timer timer([scene](double time) { if (scene->update_stats) { scene->update_stats->bake.times.add_entry({"device_update", time}); } @@ -76,9 +80,9 @@ void BakeManager::device_update(Device * /*device*/, kbake->use = true; int object_index = 0; - for (Object *object : scene->objects) { + foreach (Object *object, scene->objects) { const Geometry *geom = object->get_geometry(); - if (object->get_is_bake_target() && geom->geometry_type == Geometry::MESH) { + if (object->name == object_name && geom->geometry_type == Geometry::MESH) { kbake->object_index = object_index; kbake->tri_offset = geom->prim_offset; break; diff --git a/intern/cycles/scene/bake.h b/intern/cycles/scene/bake.h index 0c0e0be4cd7..67061040998 100644 --- a/intern/cycles/scene/bake.h +++ b/intern/cycles/scene/bake.h @@ -15,10 +15,10 @@ CCL_NAMESPACE_BEGIN class BakeManager { public: - BakeManager() = default; - ~BakeManager() = default; + BakeManager(); + ~BakeManager(); - void set_baking(Scene *scene, const bool use); + void set(Scene *scene, const std::string &object_name); bool get_baking() const; void set_use_camera(bool use_camera); diff --git a/intern/cycles/scene/geometry.cpp b/intern/cycles/scene/geometry.cpp index 1eb71fcc8c8..fed6556b0ed 100644 --- a/intern/cycles/scene/geometry.cpp +++ b/intern/cycles/scene/geometry.cpp @@ -645,7 +645,7 @@ void GeometryManager::device_update_displacement_images(Device *device, } ImageSlotTextureNode *image_node = static_cast(node); - for (int i = 0; i < image_node->handle.num_svm_slots(); i++) { + for (int i = 0; i < image_node->handle.num_tiles(); i++) { const int slot = image_node->handle.svm_slot(i); if (slot != -1) { bump_images.insert(slot); @@ -941,28 +941,12 @@ void GeometryManager::device_update(Device *device, }); TaskPool pool; - /* Work around Embree/oneAPI bug #129596 with BVH updates. */ - const bool use_multithreaded_build = first_bvh_build || - !device->info.contains_device_type(DEVICE_ONEAPI); - first_bvh_build = false; - size_t i = 0; foreach (Geometry *geom, scene->geometry) { if (geom->is_modified() || geom->need_update_bvh_for_offset) { need_update_scene_bvh = true; - if (use_multithreaded_build) { - pool.push(function_bind(&Geometry::compute_bvh, - geom, - device, - dscene, - &scene->params, - &progress, - i, - num_bvh)); - } - else { - geom->compute_bvh(device, dscene, &scene->params, &progress, i, num_bvh); - } + pool.push(function_bind( + &Geometry::compute_bvh, geom, device, dscene, &scene->params, &progress, i, num_bvh)); if (geom->need_build_bvh(bvh_layout)) { i++; } diff --git a/intern/cycles/scene/geometry.h b/intern/cycles/scene/geometry.h index 78bc70a09a8..32ef6d9fde1 100644 --- a/intern/cycles/scene/geometry.h +++ b/intern/cycles/scene/geometry.h @@ -228,7 +228,6 @@ class GeometryManager { /* Update Flags */ bool need_flags_update; - bool first_bvh_build = true; /* Constructor/Destructor */ GeometryManager(); diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp index 2e714fe272c..1f4d129950d 100644 --- a/intern/cycles/scene/image.cpp +++ b/intern/cycles/scene/image.cpp @@ -70,10 +70,10 @@ const char *name_from_type(ImageDataType type) ImageHandle::ImageHandle() : manager(NULL) {} ImageHandle::ImageHandle(const ImageHandle &other) - : slots(other.slots), is_tiled(other.is_tiled), manager(other.manager) + : tile_slots(other.tile_slots), manager(other.manager) { /* Increase image user count. */ - for (const size_t slot : slots) { + foreach (const size_t slot, tile_slots) { manager->add_image_user(slot); } } @@ -82,10 +82,9 @@ ImageHandle &ImageHandle::operator=(const ImageHandle &other) { clear(); manager = other.manager; - is_tiled = other.is_tiled; - slots = other.slots; + tile_slots = other.tile_slots; - for (const size_t slot : slots) { + foreach (const size_t slot, tile_slots) { manager->add_image_user(slot); } @@ -99,72 +98,67 @@ ImageHandle::~ImageHandle() void ImageHandle::clear() { - for (const size_t slot : slots) { + foreach (const size_t slot, tile_slots) { manager->remove_image_user(slot); } - slots.clear(); - manager = nullptr; + tile_slots.clear(); + manager = NULL; } bool ImageHandle::empty() const { - return slots.empty(); + return tile_slots.empty(); } int ImageHandle::num_tiles() const { - return (is_tiled) ? slots.size() : 0; -} - -int ImageHandle::num_svm_slots() const -{ - return slots.size(); + return tile_slots.size(); } ImageMetaData ImageHandle::metadata() { - if (slots.empty()) { + if (tile_slots.empty()) { return ImageMetaData(); } - ImageManager::Image *img = manager->get_image_slot(slots.front()); + ImageManager::Image *img = manager->images[tile_slots.front()]; manager->load_image_metadata(img); return img->metadata; } -int ImageHandle::svm_slot(const int slot_index) const +int ImageHandle::svm_slot(const int tile_index) const { - if (slot_index >= slots.size()) { + if (tile_index >= tile_slots.size()) { return -1; } if (manager->osl_texture_system) { - ImageManager::Image *img = manager->get_image_slot(slots[slot_index]); + ImageManager::Image *img = manager->images[tile_slots[tile_index]]; if (!img->loader->osl_filepath().empty()) { return -1; } } - return slots[slot_index]; + return tile_slots[tile_index]; } vector ImageHandle::get_svm_slots() const { - const size_t num_nodes = divide_up(slots.size(), 2); + const size_t num_nodes = divide_up(tile_slots.size(), 2); vector svm_slots; svm_slots.reserve(num_nodes); for (size_t i = 0; i < num_nodes; i++) { int4 node; - size_t slot = slots[2 * i]; - node.x = manager->get_image_slot(slot)->loader->get_tile_number(); + size_t slot = tile_slots[2 * i]; + node.x = manager->images[slot]->loader->get_tile_number(); node.y = slot; - if ((2 * i + 1) < slots.size()) { - slot = slots[2 * i + 1]; - node.z = manager->get_image_slot(slot)->loader->get_tile_number(); + if ((2 * i + 1) < tile_slots.size()) { + slot = tile_slots[2 * i + 1]; + node.z = manager->images[slot]->loader->get_tile_number(); node.w = slot; } else { @@ -178,23 +172,23 @@ vector ImageHandle::get_svm_slots() const return svm_slots; } -device_texture *ImageHandle::image_memory() const +device_texture *ImageHandle::image_memory(const int tile_index) const { - if (slots.empty()) { - return nullptr; + if (tile_index >= tile_slots.size()) { + return NULL; } - ImageManager::Image *img = manager->get_image_slot(slots[0]); - return img ? img->mem : nullptr; + ImageManager::Image *img = manager->images[tile_slots[tile_index]]; + return img ? img->mem : NULL; } -VDBImageLoader *ImageHandle::vdb_loader() const +VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const { - if (slots.empty()) { - return nullptr; + if (tile_index >= tile_slots.size()) { + return NULL; } - ImageManager::Image *img = manager->get_image_slot(slots[0]); + ImageManager::Image *img = manager->images[tile_slots[tile_index]]; if (img == NULL) { return NULL; @@ -220,7 +214,7 @@ ImageManager *ImageHandle::get_manager() const bool ImageHandle::operator==(const ImageHandle &other) const { - return manager == other.manager && is_tiled == other.is_tiled && slots == other.slots; + return manager == other.manager && tile_slots == other.tile_slots; } /* Image MetaData */ @@ -385,7 +379,7 @@ ImageHandle ImageManager::add_image(const string &filename, const ImageParams &p const size_t slot = add_image_slot(new OIIOImageLoader(filename), params, false); ImageHandle handle; - handle.slots.push_back(slot); + handle.tile_slots.push_back(slot); handle.manager = this; return handle; } @@ -396,13 +390,6 @@ ImageHandle ImageManager::add_image(const string &filename, { ImageHandle handle; handle.manager = this; - handle.is_tiled = !tiles.empty(); - - if (!handle.is_tiled) { - const size_t slot = add_image_slot(new OIIOImageLoader(filename), params, false); - handle.slots.push_back(slot); - return handle; - } foreach (int tile, tiles) { string tile_filename = filename; @@ -410,14 +397,14 @@ ImageHandle ImageManager::add_image(const string &filename, /* Since we don't have information about the exact tile format used in this code location, * just attempt all replacement patterns that Blender supports. */ if (tile != 0) { - string_replace(tile_filename, "", string_printf("%04d", tile)); + string_replace(tile_filename, "", string_printf("%04d", (int)tile)); int u = ((tile - 1001) % 10); int v = ((tile - 1001) / 10); string_replace(tile_filename, "", string_printf("u%d_v%d", u + 1, v + 1)); } const size_t slot = add_image_slot(new OIIOImageLoader(tile_filename), params, false); - handle.slots.push_back(slot); + handle.tile_slots.push_back(slot); } return handle; @@ -430,7 +417,7 @@ ImageHandle ImageManager::add_image(ImageLoader *loader, const size_t slot = add_image_slot(loader, params, builtin); ImageHandle handle; - handle.slots.push_back(slot); + handle.tile_slots.push_back(slot); handle.manager = this; return handle; } @@ -439,11 +426,9 @@ ImageHandle ImageManager::add_image(const vector &loaders, const ImageParams ¶ms) { ImageHandle handle; - handle.is_tiled = true; - for (ImageLoader *loader : loaders) { const size_t slot = add_image_slot(loader, params, true); - handle.slots.push_back(slot); + handle.tile_slots.push_back(slot); } handle.manager = this; @@ -523,13 +508,6 @@ void ImageManager::remove_image_user(size_t slot) } } -ImageManager::Image *ImageManager::get_image_slot(const size_t slot) -{ - /* Need mutex lock, images vector might get resized by another thread. */ - const thread_scoped_lock device_lock(images_mutex); - return images[slot]; -} - static bool image_associate_alpha(ImageManager::Image *img) { /* For typical RGBA images we let OIIO convert to associated alpha, diff --git a/intern/cycles/scene/image.h b/intern/cycles/scene/image.h index 015c63516d8..ee919aaa769 100644 --- a/intern/cycles/scene/image.h +++ b/intern/cycles/scene/image.h @@ -146,20 +146,18 @@ class ImageHandle { bool empty() const; int num_tiles() const; - int num_svm_slots() const; ImageMetaData metadata(); - int svm_slot(const int slot_index = 0) const; + int svm_slot(const int tile_index = 0) const; vector get_svm_slots() const; - device_texture *image_memory() const; + device_texture *image_memory(const int tile_index = 0) const; - VDBImageLoader *vdb_loader() const; + VDBImageLoader *vdb_loader(const int tile_index = 0) const; ImageManager *get_manager() const; protected: - vector slots; - bool is_tiled = false; + vector tile_slots; ImageManager *manager; friend class ImageManager; @@ -229,7 +227,6 @@ class ImageManager { size_t add_image_slot(ImageLoader *loader, const ImageParams ¶ms, const bool builtin); void add_image_user(size_t slot); void remove_image_user(size_t slot); - Image *get_image_slot(const size_t slot); void load_image_metadata(Image *img); diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index ea9878ab862..ac5266f47c2 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -95,8 +95,6 @@ NODE_DEFINE(Object) SOCKET_BOOLEAN(is_caustics_caster, "Cast Shadow Caustics", false); SOCKET_BOOLEAN(is_caustics_receiver, "Receive Shadow Caustics", false); - SOCKET_BOOLEAN(is_bake_target, "Bake Target", false); - SOCKET_NODE(particle_system, "Particle System", ParticleSystem::get_node_type()); SOCKET_INT(particle_index, "Particle Index", 0); @@ -576,8 +574,8 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.dupli_generated[2] = ob->dupli_generated[2]; kobject.dupli_uv[0] = ob->dupli_uv[0]; kobject.dupli_uv[1] = ob->dupli_uv[1]; - kobject.num_geom_steps = (geom->get_motion_steps() - 1) / 2; - kobject.num_tfm_steps = ob->motion.size(); + int totalsteps = geom->get_motion_steps(); + kobject.numsteps = (totalsteps - 1) / 2; kobject.numverts = (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::VOLUME) ? static_cast(geom)->get_verts().size() : @@ -1051,11 +1049,9 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P Mesh *mesh = static_cast(geom); apply = apply && mesh->get_subdivision_type() == Mesh::SUBDIVISION_NONE; } - else if ((geom->geometry_type == Geometry::HAIR) || - (geom->geometry_type == Geometry::POINTCLOUD)) - { - /* Can't apply non-uniform scale to curves and points, this can't be - * represented by control points and radius alone. */ + 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; apply = apply && transform_uniform_scale(object->tfm, scale); } diff --git a/intern/cycles/scene/object.h b/intern/cycles/scene/object.h index d96350082a1..9021da1a015 100644 --- a/intern/cycles/scene/object.h +++ b/intern/cycles/scene/object.h @@ -60,8 +60,6 @@ class Object : public Node { NODE_SOCKET_API(bool, is_caustics_caster) NODE_SOCKET_API(bool, is_caustics_receiver) - NODE_SOCKET_API(bool, is_bake_target) - NODE_SOCKET_API(float3, dupli_generated) NODE_SOCKET_API(float2, dupli_uv) diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 63e44866c32..01aac1508ad 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -45,7 +45,7 @@ int OSLShaderManager::ss_shared_users = 0; thread_mutex OSLShaderManager::ss_shared_mutex; thread_mutex OSLShaderManager::ss_mutex; -std::atomic OSLCompiler::texture_shared_unique_id = 0; +int OSLCompiler::texture_shared_unique_id = 0; /* Shader Manager */ diff --git a/intern/cycles/scene/osl.h b/intern/cycles/scene/osl.h index 63497b3fdc8..3cb2c23556e 100644 --- a/intern/cycles/scene/osl.h +++ b/intern/cycles/scene/osl.h @@ -5,8 +5,6 @@ #ifndef __OSL_H__ #define __OSL_H__ -#include - #include "util/array.h" #include "util/set.h" #include "util/string.h" @@ -180,7 +178,7 @@ class OSLCompiler { ShaderType current_type; Shader *current_shader; - static std::atomic texture_shared_unique_id; + static int texture_shared_unique_id; }; CCL_NAMESPACE_END diff --git a/intern/cycles/scene/pointcloud.cpp b/intern/cycles/scene/pointcloud.cpp index ee362539a25..142d4368b7b 100644 --- a/intern/cycles/scene/pointcloud.cpp +++ b/intern/cycles/scene/pointcloud.cpp @@ -115,11 +115,6 @@ void PointCloud::reserve(int numpoints) attributes.resize(true); } -void PointCloud::clear_non_sockets() -{ - Geometry::clear(true); -} - void PointCloud::clear(const bool preserve_shaders) { Geometry::clear(preserve_shaders); diff --git a/intern/cycles/scene/pointcloud.h b/intern/cycles/scene/pointcloud.h index 97ca3f6c352..c4a8d7f0e96 100644 --- a/intern/cycles/scene/pointcloud.h +++ b/intern/cycles/scene/pointcloud.h @@ -51,7 +51,6 @@ class PointCloud : public Geometry { ~PointCloud(); /* Geometry */ - void clear_non_sockets(); void clear(const bool preserver_shaders = false) override; void resize(int numpoints); diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index c7266c22cc6..d4f298cd8ac 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -263,6 +263,7 @@ ImageTextureNode::ImageTextureNode() : ImageSlotTextureNode(get_node_type()) { colorspace = u_colorspace_raw; animated = false; + tiles.push_back_slow(1001); } ShaderNode *ImageTextureNode::clone(ShaderGraph *graph) const @@ -288,10 +289,8 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) /* Box projection computes its own UVs that always lie in the * 1001 tile, so there's no point in loading any others. */ if (projection == NODE_IMAGE_PROJ_BOX) { - if (tiles.size()) { - tiles.clear(); - tiles.push_back_slow(1001); - } + tiles.clear(); + tiles.push_back_slow(1001); return; } @@ -302,8 +301,8 @@ void ImageTextureNode::cull_tiles(Scene *scene, ShaderGraph *graph) return; } - /* Only check UVs for tile culling when using tiles. */ - if (tiles.size() == 0) { + /* Only check UVs for tile culling if there are multiple tiles. */ + if (tiles.size() < 2) { return; } @@ -398,7 +397,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) if (projection != NODE_IMAGE_PROJ_BOX) { /* If there only is one image (a very common case), we encode it as a negative value. */ int num_nodes; - if (handle.num_tiles() == 0) { + if (handle.num_tiles() == 1) { num_nodes = -handle.svm_slot(); } else { @@ -431,7 +430,7 @@ void ImageTextureNode::compile(SVMCompiler &compiler) } } else { - assert(handle.num_svm_slots() == 1); + assert(handle.num_tiles() == 1); compiler.add_node(NODE_TEX_IMAGE_BOX, handle.svm_slot(), compiler.encode_uchar4(vector_offset, @@ -473,7 +472,7 @@ void ImageTextureNode::compile(OSLCompiler &compiler) alpha_type == IMAGE_ALPHA_IGNORE); const bool is_tiled = (filename.find("") != string::npos || filename.find("") != string::npos) || - handle.num_tiles() > 0; + handle.num_tiles() > 1; compiler.parameter(this, "projection"); compiler.parameter(this, "projection_blend"); diff --git a/intern/cycles/scene/volume.cpp b/intern/cycles/scene/volume.cpp index b22aab81def..8d2d4710608 100644 --- a/intern/cycles/scene/volume.cpp +++ b/intern/cycles/scene/volume.cpp @@ -97,9 +97,8 @@ static int add_vertex(int3 v, int3 res, unordered_map &used_verts) { - const size_t vert_key = v.x + v.y * size_t(res.x + 1) + - v.z * size_t(res.x + 1) * size_t(res.y + 1); - const unordered_map::iterator it = used_verts.find(vert_key); + size_t vert_key = v.x + v.y * (res.x + 1) + v.z * (res.x + 1) * (res.y + 1); + unordered_map::iterator it = used_verts.find(vert_key); if (it != used_verts.end()) { return it->second; @@ -688,10 +687,6 @@ void GeometryManager::create_volume_mesh(const Scene *scene, Volume *volume, Pro ImageHandle &handle = attr.data_voxel(); - if (handle.empty()) { - continue; - } - /* Try building from OpenVDB grid directly. */ VDBImageLoader *vdb_loader = handle.vdb_loader(); openvdb::GridBase::ConstPtr grid; diff --git a/intern/cycles/util/profiling.cpp b/intern/cycles/util/profiling.cpp index f6b48e12cbc..54be0fcd1d1 100644 --- a/intern/cycles/util/profiling.cpp +++ b/intern/cycles/util/profiling.cpp @@ -6,7 +6,6 @@ #include "util/algorithm.h" #include "util/foreach.h" #include "util/set.h" -#include CCL_NAMESPACE_BEGIN diff --git a/intern/ghost/intern/GHOST_DropTargetWin32.cc b/intern/ghost/intern/GHOST_DropTargetWin32.cc index 3b701ec8311..1c56c3b79b8 100644 --- a/intern/ghost/intern/GHOST_DropTargetWin32.cc +++ b/intern/ghost/intern/GHOST_DropTargetWin32.cc @@ -161,22 +161,21 @@ DWORD GHOST_DropTargetWin32::allowedDropEffect(DWORD dw_allowed) GHOST_TDragnDropTypes GHOST_DropTargetWin32::getGhostType(IDataObject *p_data_object) { - /* File-names. Prefer looking for the CF_HDROP data format first as certain file-manager - * applications send CF_TEXT as well. See issue #135672. */ - FORMATETC fmtetc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; - if (p_data_object->QueryGetData(&fmtetc) == S_OK) { - return GHOST_kDragnDropTypeFilenames; - } - /* Text * NOTE: Unicode text is available as CF_TEXT too, the system can do the * conversion, but we do the conversion our self with #WC_NO_BEST_FIT_CHARS. */ - fmtetc.cfFormat = CF_TEXT; + FORMATETC fmtetc = {CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; if (p_data_object->QueryGetData(&fmtetc) == S_OK) { return GHOST_kDragnDropTypeString; } + /* Files-names. */ + fmtetc.cfFormat = CF_HDROP; + if (p_data_object->QueryGetData(&fmtetc) == S_OK) { + return GHOST_kDragnDropTypeFilenames; + } + return GHOST_kDragnDropTypeUnknown; } diff --git a/intern/ghost/intern/GHOST_SystemWayland.cc b/intern/ghost/intern/GHOST_SystemWayland.cc index 1d4c82a3233..b21ec74d3f8 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cc +++ b/intern/ghost/intern/GHOST_SystemWayland.cc @@ -5320,20 +5320,7 @@ static bool xkb_compose_state_feed_and_get_utf8( const int utf8_buf_compose_len = xkb_compose_state_get_utf8( compose_state, utf8_buf_compose, sizeof(utf8_buf_compose)); if (utf8_buf_compose_len > 0) { - if (utf8_buf_compose_len > sizeof(GHOST_TEventKeyData::utf8_buf)) { - /* TODO(@ideasman42): keyboard events in GHOST only support a single character. - * - * - In the case XKB compose enters multiple code-points only the first will be used. - * - * - Besides supporting multiple characters per key input, - * one possible solution would be to generate an IME event. - * - * - In practice I'm not sure how common these are. - * So far no bugs have been reported about this. - */ - CLOG_WARN(LOG, "key (compose_size=%d) exceeds the maximum size", utf8_buf_compose_len); - } - memcpy(r_utf8_buf, utf8_buf_compose, sizeof(GHOST_TEventKeyData::utf8_buf)); + memcpy(r_utf8_buf, utf8_buf_compose, utf8_buf_compose_len); handled = true; } break; diff --git a/source/blender/animrig/ANIM_keyframing.hh b/source/blender/animrig/ANIM_keyframing.hh index 95d91aaeeba..6b029fdbff0 100644 --- a/source/blender/animrig/ANIM_keyframing.hh +++ b/source/blender/animrig/ANIM_keyframing.hh @@ -239,7 +239,7 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id); * * \param rna_paths: Only inserts keys on those RNA paths. */ -void autokeyframe_object(bContext *C, const Scene *scene, Object *ob, Span rna_paths); +void autokeyframe_object(bContext *C, Scene *scene, Object *ob, Span rna_paths); /** * Auto-keyframing feature - for objects * diff --git a/source/blender/animrig/intern/keyframing_auto.cc b/source/blender/animrig/intern/keyframing_auto.cc index 89e5507be43..310a56266be 100644 --- a/source/blender/animrig/intern/keyframing_auto.cc +++ b/source/blender/animrig/intern/keyframing_auto.cc @@ -30,7 +30,7 @@ namespace blender::animrig { -static eInsertKeyFlags get_autokey_flags(const Scene *scene) +static eInsertKeyFlags get_autokey_flags(Scene *scene) { eInsertKeyFlags flag = INSERTKEY_NOFLAGS; @@ -104,7 +104,7 @@ bool autokeyframe_cfra_can_key(const Scene *scene, ID *id) return true; } -void autokeyframe_object(bContext *C, const Scene *scene, Object *ob, Span rna_paths) +void autokeyframe_object(bContext *C, Scene *scene, Object *ob, Span rna_paths) { BLI_assert(ob != nullptr); BLI_assert(scene != nullptr); diff --git a/source/blender/asset_system/tests/asset_catalog_test.cc b/source/blender/asset_system/tests/asset_catalog_test.cc index cdd1c434ed7..b606b211480 100644 --- a/source/blender/asset_system/tests/asset_catalog_test.cc +++ b/source/blender/asset_system/tests/asset_catalog_test.cc @@ -21,7 +21,7 @@ namespace blender::asset_system::tests { -/* UUIDs from tests/files/asset_library/blender_assets.cats.txt */ +/* UUIDs from tests/data/asset_library/blender_assets.cats.txt */ const bUUID UUID_ID_WITHOUT_PATH("e34dd2c5-5d2e-4668-9794-1db5de2a4f71"); const bUUID UUID_POSES_ELLIE("df60e1f6-2259-475b-93d9-69a1b4a8db78"); const bUUID UUID_POSES_ELLIE_WHITESPACE("b06132f6-5687-4751-a6dd-392740eb3c46"); @@ -33,7 +33,7 @@ const bUUID UUID_POSES_RUZENA_FACE("82162c1f-06cc-4d91-a9bf-4f72c104e348"); const bUUID UUID_WITHOUT_SIMPLENAME("d7916a31-6ca9-4909-955f-182ca2b81fa3"); const bUUID UUID_ANOTHER_RUZENA("00000000-d9fa-4b91-b704-e6af1f1339ef"); -/* UUIDs from tests/files/asset_library/modified_assets.cats.txt */ +/* UUIDs from tests/data/asset_library/modified_assets.cats.txt */ const bUUID UUID_AGENT_47("c5744ba5-43f5-4f73-8e52-010ad4a61b34"); /* Subclass that adds accessors such that protected fields can be used in tests. */ diff --git a/source/blender/blenkernel/intern/action.cc b/source/blender/blenkernel/intern/action.cc index e268c737eec..6c2e7ceba60 100644 --- a/source/blender/blenkernel/intern/action.cc +++ b/source/blender/blenkernel/intern/action.cc @@ -384,7 +384,6 @@ static void write_slots(BlendWriter *writer, Span slots) BLO_write_struct_at_address(writer, ActionSlot, slot, &shallow_copy); } } -#endif /* WITH_ANIM_BAKLAVA */ /** * Create a listbase from a Span of channel groups. @@ -577,6 +576,7 @@ static void action_blend_write(BlendWriter *writer, ID *id, const void *id_addre } #ifdef WITH_ANIM_BAKLAVA + static void read_channelbag(BlendDataReader *reader, animrig::ChannelBag &channelbag) { BLO_read_pointer_array( diff --git a/source/blender/blenkernel/intern/anim_path.cc b/source/blender/blenkernel/intern/anim_path.cc index 223a70830dd..46361f9ae17 100644 --- a/source/blender/blenkernel/intern/anim_path.cc +++ b/source/blender/blenkernel/intern/anim_path.cc @@ -184,16 +184,7 @@ static bool binary_search_anim_path(const float *accum_len_arr, int cur_idx = 0, cur_base = 0; int cur_step = seg_size - 1; - /* Special case, for a single segment accessing the `right_len` - * would be an invalid index, see: #132976. */ - if (UNLIKELY(seg_size == 1)) { - *r_idx = 0; - *r_frac = goal_len / accum_len_arr[0]; - return true; - } - while (true) { - BLI_assert(cur_idx + 1 < seg_size); cur_idx = cur_base + cur_step / 2; left_len = accum_len_arr[cur_idx]; right_len = accum_len_arr[cur_idx + 1]; diff --git a/source/blender/blenkernel/intern/appdir.cc b/source/blender/blenkernel/intern/appdir.cc index 99956bfb7b0..7422110a393 100644 --- a/source/blender/blenkernel/intern/appdir.cc +++ b/source/blender/blenkernel/intern/appdir.cc @@ -75,11 +75,6 @@ static struct { char temp_dirname_base[FILE_MAX]; /** Volatile temporary directory (owned by Blender, removed on exit). */ char temp_dirname_session[FILE_MAX]; - /** - * True when this is a sub-directory owned & created by Blender, - * false when a session directory couldn't be created - in this case don't delete it. - */ - bool temp_dirname_session_can_be_deleted; } g_app{}; /** \} */ @@ -1143,19 +1138,16 @@ void BKE_appdir_app_templates(ListBase *templates) * \param tempdir_maxncpy: The size of the \a tempdir buffer. * \param userdir: Directory specified in user preferences (may be nullptr). * note that by default this is an empty string, only use when non-empty. - * - * \return true if `userdir` is used. */ -static bool where_is_temp(char *tempdir, const size_t tempdir_maxncpy, const char *userdir) +static void where_is_temp(char *tempdir, const size_t tempdir_maxncpy, const char *userdir) { if (userdir && BLI_temp_directory_path_copy_if_valid(tempdir, tempdir_maxncpy, userdir)) { - return true; + return; } BLI_temp_directory_path_get(tempdir, tempdir_maxncpy); - return false; } -static bool tempdir_session_create(char *tempdir_session, +static void tempdir_session_create(char *tempdir_session, const size_t tempdir_session_maxncpy, const char *tempdir) { @@ -1184,12 +1176,15 @@ static bool tempdir_session_create(char *tempdir_session, if (BLI_is_dir(tempdir_session)) { BLI_path_slash_ensure(tempdir_session, tempdir_session_maxncpy); /* Success. */ - return true; + return; } } - CLOG_WARN(&LOG, "Could not generate a temp file name for '%s'", tempdir_session); - return false; + CLOG_WARN(&LOG, + "Could not generate a temp file name for '%s', falling back to '%s'", + tempdir_session, + tempdir); + BLI_strncpy(tempdir_session, tempdir, tempdir_session_maxncpy); } void BKE_tempdir_init(const char *userdir) @@ -1199,44 +1194,13 @@ void BKE_tempdir_init(const char *userdir) * Sets #g_app.temp_dirname_session to a #mkdtemp * generated sub-dir of #g_app.temp_dirname_base. */ + where_is_temp(g_app.temp_dirname_base, sizeof(g_app.temp_dirname_base), userdir); + /* Clear existing temp dir, if needed. */ BKE_tempdir_session_purge(); - - /* Perform two passes, the first pass for the user preference path, - * then a second pass if the the preferences failed to create the *session* sub-directory. - * - * This avoid problems if the preferences points to a path without write access, - * `C:\` or `/` for example. */ - g_app.temp_dirname_session_can_be_deleted = false; - for (int pass = 0; pass < 2; pass += 1) { - const bool from_userdir = where_is_temp( - g_app.temp_dirname_base, sizeof(g_app.temp_dirname_base), pass == 0 ? userdir : nullptr); - - /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ - if (tempdir_session_create(g_app.temp_dirname_session, - sizeof(g_app.temp_dirname_session), - g_app.temp_dirname_base)) - { - /* Created the session sub-directory. */ - g_app.temp_dirname_session_can_be_deleted = true; - break; - } - - /* Only perform the second pass if the `userdir` was used - * and failed to created the sub-directory. */ - if (from_userdir == false) { - break; - } - } - - if (UNLIKELY(g_app.temp_dirname_session_can_be_deleted == false)) { - /* This should practically never happen as either the preferences or the systems - * default temporary directory should be usable, if not, use the base directory and warn. */ - STRNCPY(g_app.temp_dirname_session, g_app.temp_dirname_base); - CLOG_WARN(&LOG, - "Could not generate a temp session subdirectory, falling back to '%s'", - g_app.temp_dirname_base); - } + /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ + tempdir_session_create( + g_app.temp_dirname_session, sizeof(g_app.temp_dirname_session), g_app.temp_dirname_base); } const char *BKE_tempdir_session() @@ -1251,11 +1215,6 @@ const char *BKE_tempdir_base() void BKE_tempdir_session_purge() { - if (g_app.temp_dirname_session_can_be_deleted == false) { - /* It's possible this path references an arbitrary location - * in that case *never* recursively remove, see: #139585. */ - return; - } if (g_app.temp_dirname_session[0] && BLI_is_dir(g_app.temp_dirname_session)) { BLI_delete(g_app.temp_dirname_session, true, true); } diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index ef418b5ba36..bcd71ea1cec 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -644,11 +644,10 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph, static bool do_curve_implicit_mesh_conversion(const Curve *curve, ModifierData *first_modifier, const Scene *scene, - const ModifierMode required_mode, - const bool editmode) + const ModifierMode required_mode) { /* Skip implicit filling and conversion to mesh when using "fast text editing". */ - if ((curve->flag & CU_FAST) && editmode) { + if (curve->flag & CU_FAST) { return false; } @@ -711,9 +710,7 @@ static blender::bke::GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph, pretessellatePoint->next; blender::bke::GeometrySet geometry_set; - if (ob->type == OB_SURF || - do_curve_implicit_mesh_conversion(cu, md, scene, required_mode, editmode)) - { + if (ob->type == OB_SURF || do_curve_implicit_mesh_conversion(cu, md, scene, required_mode)) { Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); geometry_set.replace_mesh(mesh); } diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 248f68184e3..333e8621628 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -3981,7 +3981,7 @@ static void fluid_modifier_processDomain(FluidModifierData *fmd, has_config = manta_read_config(fds->fluid, fmd, data_frame); } - if (with_smoke || with_liquid) { + if (with_smoke) { /* Read config and realloc fluid object if needed. */ if (has_config && manta_needs_realloc(fds->fluid, fmd)) { BKE_fluid_reallocate_fluid(fds, fds->res, 1); diff --git a/source/blender/blenkernel/intern/image.cc b/source/blender/blenkernel/intern/image.cc index 571796db597..d0b9f73475c 100644 --- a/source/blender/blenkernel/intern/image.cc +++ b/source/blender/blenkernel/intern/image.cc @@ -1712,7 +1712,6 @@ struct StampDataCustomField { struct StampData { char file[512]; - char filename[512]; char note[512]; char date[512]; char marker[512]; @@ -1750,12 +1749,8 @@ static void stampdata( if (scene->r.stamp & R_STAMP_FILENAME) { const char *blendfile_path = BKE_main_blendfile_path_from_global(); SNPRINTF(stamp_data->file, - do_prefix ? "Path %s" : "%s", - (blendfile_path[0] != '\0') ? blendfile_path : ""); - - const char* filename = BLI_path_basename(blendfile_path); - SNPRINTF(stamp_data->filename, - do_prefix ? "File %s" : "%s", (filename[0] != '\0') ? filename : ""); + do_prefix ? "File %s" : "%s", + (blendfile_path[0] != '\0') ? blendfile_path : ""); } else { stamp_data->file[0] = '\0'; @@ -2096,28 +2091,6 @@ void BKE_image_stamp_buf(Scene *scene, /* Top left corner */ y -= h; - /* also a little of space to the background. */ - buf_rectfill_area(rect, - rectf, - width, - height, - scene->r.bg_stamp, - display, - x - BUFF_MARGIN_X, - y - BUFF_MARGIN_Y, - w + BUFF_MARGIN_X, - y + h + BUFF_MARGIN_Y); - - /* and draw the text. */ - BLF_position(mono, x, y + y_ofs, 0.0); - BLF_draw_buffer(mono, stamp_data.filename, sizeof(stamp_data.filename)); - - /* the extra pixel for background. */ - y -= BUFF_MARGIN_Y * 2; - - /* Draw file *path* here, under the basename */ - y -= h; - /* also a little of space to the background. */ buf_rectfill_area(rect, rectf, @@ -2231,29 +2204,6 @@ void BKE_image_stamp_buf(Scene *scene, } /* Top left corner, below: File, Date, Memory, Render-time, Host-name. */ - if (TEXT_SIZE_CHECK(stamp_data.frame, w, h)) { - y -= h; - - /* and space for background. */ - buf_rectfill_area(rect, - rectf, - width, - height, - scene->r.bg_stamp, - display, - 0, - y - BUFF_MARGIN_Y, - w + BUFF_MARGIN_X, - y + h + BUFF_MARGIN_Y); - - BLF_position(mono, x, y + y_ofs, 0.0); - BLF_draw_buffer(mono, stamp_data.frame, sizeof(stamp_data.frame)); - - /* the extra pixel for background. */ - y -= BUFF_MARGIN_Y * 2; - } - - /* Top left corner, below File, Date, Memory, Rendertime, Hostname */ BLF_enable(mono, BLF_WORD_WRAP); if (TEXT_SIZE_CHECK_WORD_WRAP(stamp_data.note, w, h)) { y -= h; diff --git a/source/blender/blenkernel/intern/image_save.cc b/source/blender/blenkernel/intern/image_save.cc index f84365d32bd..149053af8c1 100644 --- a/source/blender/blenkernel/intern/image_save.cc +++ b/source/blender/blenkernel/intern/image_save.cc @@ -148,17 +148,6 @@ bool BKE_image_save_options_init(ImageSaveOptions *opts, * by the image saving code itself. */ BKE_image_user_file_path_ex(bmain, iuser, ima, opts->filepath, false, false); - /* For movies, replace extension and add the frame number to avoid writing over the movie file - * itself and provide a good default file path. */ - if (ima->source == IMA_SRC_MOVIE) { - char filepath_no_ext[FILE_MAX]; - STRNCPY(filepath_no_ext, opts->filepath); - BLI_path_extension_strip(filepath_no_ext); - SNPRINTF(opts->filepath, "%s_%.*d", filepath_no_ext, 4, ibuf->fileframe); - BKE_image_path_ext_from_imformat_ensure( - opts->filepath, sizeof(opts->filepath), &opts->im_format); - } - /* sanitize all settings */ /* unlikely but just in case */ @@ -397,7 +386,6 @@ static bool image_save_single(ReportList *reports, if (rr == nullptr) { if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) { BKE_report(reports, RPT_ERROR, "Did not write, no Multilayer Image"); - BKE_image_release_renderresult(opts->scene, ima, rr); BKE_image_release_ibuf(ima, ibuf, lock); return ok; } @@ -410,8 +398,8 @@ static bool image_save_single(ReportList *reports, R"(Did not write, the image doesn't have a "%s" and "%s" views)", STEREO_LEFT_NAME, STEREO_RIGHT_NAME); - BKE_image_release_renderresult(opts->scene, ima, rr); BKE_image_release_ibuf(ima, ibuf, lock); + BKE_image_release_renderresult(opts->scene, ima, rr); return ok; } @@ -424,8 +412,8 @@ static bool image_save_single(ReportList *reports, R"(Did not write, the image doesn't have a "%s" and "%s" views)", STEREO_LEFT_NAME, STEREO_RIGHT_NAME); - BKE_image_release_renderresult(opts->scene, ima, rr); BKE_image_release_ibuf(ima, ibuf, lock); + BKE_image_release_renderresult(opts->scene, ima, rr); return ok; } } @@ -437,7 +425,6 @@ static bool image_save_single(ReportList *reports, /* save render result */ ok = BKE_image_render_write_exr( reports, rr, opts->filepath, imf, save_as_render, nullptr, layer); - BKE_image_release_renderresult(opts->scene, ima, rr); image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } @@ -452,7 +439,6 @@ static bool image_save_single(ReportList *reports, ok = BKE_imbuf_write_as(colormanaged_ibuf, opts->filepath, imf, save_copy); imbuf_save_post(ibuf, colormanaged_ibuf); } - BKE_image_release_renderresult(opts->scene, ima, rr); image_save_post(reports, ima, ibuf, @@ -520,8 +506,6 @@ static bool image_save_single(ReportList *reports, ok &= ok_view; } - BKE_image_release_renderresult(opts->scene, ima, rr); - if (is_exr_rr) { BKE_image_release_ibuf(ima, ibuf, lock); } @@ -531,7 +515,6 @@ static bool image_save_single(ReportList *reports, if (imf->imtype == R_IMF_IMTYPE_MULTILAYER) { ok = BKE_image_render_write_exr( reports, rr, opts->filepath, imf, save_as_render, nullptr, layer); - BKE_image_release_renderresult(opts->scene, ima, rr); image_save_post(reports, ima, ibuf, ok, opts, true, opts->filepath, r_colorspace_changed); BKE_image_release_ibuf(ima, ibuf, lock); } @@ -604,13 +587,11 @@ static bool image_save_single(ReportList *reports, for (int i = 0; i < 2; i++) { IMB_freeImBuf(ibuf_stereo[i]); } - - BKE_image_release_renderresult(opts->scene, ima, rr); } } - else { + + if (rr) { BKE_image_release_renderresult(opts->scene, ima, rr); - BKE_image_release_ibuf(ima, ibuf, lock); } return ok; diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index ad2729e6896..5a709c5e999 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -4338,7 +4338,6 @@ void BKE_lib_override_library_validate(Main *bmain, ID *id, ReportList *reports) * properly 'liboverride embedded' IDs, like root node-trees, or shape-keys. */ if (!override_library_is_valid(*liboverride_id, *liboverride, reports)) { BKE_lib_override_library_make_local(nullptr, liboverride_id); - return; } } diff --git a/source/blender/blenkernel/intern/lib_query.cc b/source/blender/blenkernel/intern/lib_query.cc index 0f165f1dbf6..1a1bcce97de 100644 --- a/source/blender/blenkernel/intern/lib_query.cc +++ b/source/blender/blenkernel/intern/lib_query.cc @@ -842,12 +842,7 @@ static bool lib_query_unused_ids_tag_recurse(ID *id, UnusedIDsData &data) id_relations->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED; } - /* If that ID is part of a dependency loop, but it does have a valid user (which is not part of - * that loop), then that dependency loop does not form (or is not part of) an unused archipelago. - * - * In other words, this current `id` is used, and is therefore a valid user of the 'calling ID' - * from previous recursion level.. */ - return is_part_of_dependency_loop && !has_valid_from_users; + return is_part_of_dependency_loop; } static void lib_query_unused_ids_tag(UnusedIDsData &data) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 2cb3191bd45..ebb26a71346 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -445,15 +445,11 @@ static void node_foreach_path(ID *id, BPathForeachPathData *bpath_data) for (bNode *node : ntree->all_nodes()) { if (node->type == SH_NODE_SCRIPT) { NodeShaderScript *nss = static_cast(node->storage); - if (nss->mode == NODE_SCRIPT_EXTERNAL && nss->filepath[0]) { - BKE_bpath_foreach_path_fixed_process(bpath_data, nss->filepath, sizeof(nss->filepath)); - } + BKE_bpath_foreach_path_fixed_process(bpath_data, nss->filepath, sizeof(nss->filepath)); } else if (node->type == SH_NODE_TEX_IES) { NodeShaderTexIES *ies = static_cast(node->storage); - if (ies->mode == NODE_IES_EXTERNAL && ies->filepath[0]) { - BKE_bpath_foreach_path_fixed_process(bpath_data, ies->filepath, sizeof(ies->filepath)); - } + BKE_bpath_foreach_path_fixed_process(bpath_data, ies->filepath, sizeof(ies->filepath)); } } break; diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 8996d161d5e..7886df2cb5b 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -42,7 +42,6 @@ #include "BKE_callbacks.hh" #include "BLI_blenlib.h" -#include "BLI_build_config.h" #include "BLI_math_rotation.h" #include "BLI_string.h" #include "BLI_string_utils.hh" @@ -716,10 +715,6 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data, do_undo_restore, scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old)); - /* WARNING: Handling this object pointer is fairly intricated, to support both 'regular' - * foreach_id processing (in which case both sets of data, current and old, are the same), and - * the restore-after-undo cases. It does not have a helper, because so far it is the only case - * of having to deal with non-'paint' data in a sub-toolsett struct. */ Object *gravity_object = toolsett->sculpt ? toolsett->sculpt->gravity_object : nullptr; Object *gravity_object_old = toolsett_old->sculpt->gravity_object; BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_IDSUPER_P(data, @@ -732,11 +727,7 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data, if (toolsett->sculpt) { toolsett->sculpt->gravity_object = gravity_object; } - /* Do not re-assign `gravity_object_old` object if both current and old data are the same - * (foreach_id case), that would nullify assignement above, making remapping cases fail. */ - if (toolsett_old != toolsett) { - toolsett_old->sculpt->gravity_object = gravity_object_old; - } + toolsett_old->sculpt->gravity_object = gravity_object_old; } if (toolsett_old->gp_paint) { paint = toolsett->gp_paint ? &toolsett->gp_paint->paint : nullptr; @@ -956,22 +947,6 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data) } } -static void scene_foreach_cache(ID *id, - IDTypeForeachCacheFunctionCallback function_callback, - void *user_data) -{ - Scene *scene = (Scene *)id; - IDCacheKey key{}; - key.id_session_uid = id->session_uid; - key.identifier = offsetof(Scene, eevee.light_cache_data); - - function_callback(id, - &key, - (void **)&scene->eevee.light_cache_data, - IDTYPE_CACHE_CB_FLAGS_PERSISTENT, - user_data); -} - static bool seq_foreach_path_callback(Sequence *seq, void *user_data) { if (SEQ_HAS_PATH(seq)) { @@ -1027,13 +1002,22 @@ static void scene_foreach_cache(ID *id, Scene *scene = (Scene *)id; if (scene->ed != nullptr) { IDCacheKey key; + // IDCacheKey key{}; key.id_session_uid = id->session_uid; /* Preserve VSE thumbnail cache across global undo steps. */ key.identifier = offsetof(Editing, runtime.thumbnail_cache); + key.identifier = offsetof(Scene, eevee.light_cache_data); function_callback(id, &key, (void **)&scene->ed->runtime.thumbnail_cache, 0, user_data); + + function_callback(id, + &key, + (void **)&scene->eevee.light_cache_data, + IDTYPE_CACHE_CB_FLAGS_PERSISTENT, + user_data); } } + static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_address) { Scene *sce = (Scene *)id; diff --git a/source/blender/blenkernel/intern/text.cc b/source/blender/blenkernel/intern/text.cc index 4916459aeb6..3bbe74d0655 100644 --- a/source/blender/blenkernel/intern/text.cc +++ b/source/blender/blenkernel/intern/text.cc @@ -155,7 +155,7 @@ static void text_foreach_path(ID *id, BPathForeachPathData *bpath_data) { Text *text = (Text *)id; - if (text->filepath != nullptr && text->filepath[0] != '\0') { + if (text->filepath != nullptr) { BKE_bpath_foreach_path_allocated_process(bpath_data, &text->filepath); } } diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index f599005af9d..785cf4d8703 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -691,7 +691,7 @@ struct MatView : NonCopyable, NonMovable { friend std::ostream &operator<<(std::ostream &stream, const MatView &mat) { - return stream << mat.mat; + return stream << mat->mat; } }; diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 80a2245307e..bc680c5c151 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -201,7 +201,6 @@ set(SRC BLI_bounds.hh BLI_bounds_types.hh BLI_boxpack_2d.h - BLI_build_config.h BLI_buffer.h BLI_build_config.h BLI_cache_mutex.hh @@ -525,7 +524,6 @@ if(WITH_GTESTS) tests/BLI_bit_ref_test.cc tests/BLI_bit_span_test.cc tests/BLI_bit_vector_test.cc - tests/BLI_build_config_test.cc tests/BLI_bitmap_test.cc tests/BLI_bounds_test.cc tests/BLI_build_config_test.cc diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c index 1747deada3d..05a73ca53d8 100644 --- a/source/blender/blenlib/intern/task_iterator.c +++ b/source/blender/blenlib/intern/task_iterator.c @@ -84,7 +84,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, } if (use_userdata_chunk) { - if (settings->func_free != NULL && userdata_chunk != NULL) { + if (settings->func_free != NULL) { /* `func_free` should only free data that was created during execution of `func`. */ settings->func_free(userdata, userdata_chunk); } @@ -138,7 +138,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, settings->func_reduce( userdata, userdata_chunk, mempool_iterator_data[i].tls.userdata_chunk); } - if (settings->func_free && mempool_iterator_data[i].tls.userdata_chunk != NULL) { + if (settings->func_free) { settings->func_free(userdata, mempool_iterator_data[i].tls.userdata_chunk); } } diff --git a/source/blender/blenlib/intern/task_range.cc b/source/blender/blenlib/intern/task_range.cc index 10e555eebf1..be6a9deecd3 100644 --- a/source/blender/blenlib/intern/task_range.cc +++ b/source/blender/blenlib/intern/task_range.cc @@ -62,7 +62,7 @@ struct RangeTask { ~RangeTask() { - if (settings->func_free != nullptr && userdata_chunk != nullptr) { + if (settings->func_free != nullptr) { settings->func_free(userdata, userdata_chunk); } MEM_SAFE_FREE(userdata_chunk); @@ -131,7 +131,7 @@ void BLI_task_parallel_range(const int start, for (int i = start; i < stop; i++) { func(userdata, i, &tls); } - if (settings->func_free != nullptr && settings->userdata_chunk != nullptr) { + if (settings->func_free != nullptr) { settings->func_free(userdata, settings->userdata_chunk); } } diff --git a/source/blender/blenloader/tests/blendfile_load_test.cc b/source/blender/blenloader/tests/blendfile_load_test.cc index 68fb6da1e24..26a485cc181 100644 --- a/source/blender/blenloader/tests/blendfile_load_test.cc +++ b/source/blender/blenloader/tests/blendfile_load_test.cc @@ -9,7 +9,7 @@ class BlendfileLoadingTest : public BlendfileLoadingBaseTest {}; TEST_F(BlendfileLoadingTest, CanaryTest) { - /* Load the smallest blend file we have in the tests/files directory. */ + /* Load the smallest blend file we have in the tests/data directory. */ if (!blendfile_load("modifier_stack" SEP_STR "array_test.blend")) { return; } diff --git a/source/blender/bmesh/tools/bmesh_path_uv.cc b/source/blender/bmesh/tools/bmesh_path_uv.cc index 0557b8c29df..b0551727ef8 100644 --- a/source/blender/bmesh/tools/bmesh_path_uv.cc +++ b/source/blender/bmesh/tools/bmesh_path_uv.cc @@ -247,9 +247,6 @@ static void edgetag_add_adjacent_uv(HeapSimple *heap, BMEdge *e_b; BMIter eiter; BM_ITER_ELEM (e_b, &eiter, l_a_verts[i]->v, BM_EDGES_OF_VERT) { - if (e_b->l == nullptr) { - continue; - } BMLoop *l_first, *l_b; l_first = l_b = e_b->l; do { diff --git a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc index f4c73388c5b..91b1933f1ac 100644 --- a/source/blender/compositor/intern/COM_NodeOperationBuilder.cc +++ b/source/blender/compositor/intern/COM_NodeOperationBuilder.cc @@ -431,15 +431,7 @@ void NodeOperationBuilder::determine_canvases() const rcti &to_canvas = link.to()->get_operation().get_canvas(); bool needs_conversion; - if (link.from()->get_operation().get_flags().is_constant_operation) { - /* COM_convert_canvas() below can introduce non-constant transform operations - * to the input. This breaks the blur node (see BlurBaseOperation::init_data()), - * where it is assumed that if the input operation is constant, - * then it will remain constant after computing cavases as well. - * So we avoid converting cavases explicitly for such cases. */ - needs_conversion = false; - } - else if (link.to()->get_resize_mode() == ResizeMode::Align) { + if (link.to()->get_resize_mode() == ResizeMode::Align) { needs_conversion = from_canvas.xmin != to_canvas.xmin || from_canvas.ymin != to_canvas.ymin; } diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc index 9bfad36e11e..c5327d90e31 100644 --- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc +++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc @@ -2,7 +2,6 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_string.h" #include #include "DNA_node_types.h" @@ -68,23 +67,6 @@ bool Evaluator::validate_node_tree() return false; } - for (const bNodeTree *node_tree : derived_node_tree_->used_btrees()) { - for (const bNode *node : node_tree->all_nodes()) { - /* The poll method of those two nodes perform raw pointer comparisons of node trees, so they - * can wrongly fail since the compositor localizes the node tree, changing its pointer value - * than the one in the main database. So handle those two nodes. */ - if (STR_ELEM(node->idname, "CompositorNodeRLayers", "CompositorNodeCryptomatteV2")) { - continue; - } - - const char *disabled_hint = nullptr; - if (!node->typeinfo->poll(node->typeinfo, node_tree, &disabled_hint)) { - context_.set_info_message("Compositor node tree has unsupported nodes."); - return false; - } - } - } - return true; } diff --git a/source/blender/compositor/realtime_compositor/intern/scheduler.cc b/source/blender/compositor/realtime_compositor/intern/scheduler.cc index f80ba31e4b9..d9bce6a5e90 100644 --- a/source/blender/compositor/realtime_compositor/intern/scheduler.cc +++ b/source/blender/compositor/realtime_compositor/intern/scheduler.cc @@ -20,33 +20,11 @@ namespace blender::realtime_compositor { using namespace nodes::derived_node_tree_types; -/* Returns true if any of the node group nodes that make up this tree context are muted. */ -static bool is_tree_context_muted(const DTreeContext &tree_context) -{ - /* Root contexts are never muted. */ - if (tree_context.is_root()) { - return false; - } - - /* The node group that represents this context is muted. */ - if (tree_context.parent_node()->is_muted()) { - return true; - } - - /* Recursively check parent contexts up until the root context. */ - return is_tree_context_muted(*tree_context.parent_context()); -} - /* Add the viewer node which is marked as NODE_DO_OUTPUT in the given context to the given stack. * If no viewer nodes were found, composite nodes can be added as a fallback * viewer node. */ static bool add_viewer_nodes_in_context(const DTreeContext *context, Stack &node_stack) { - /* Do not add viewers that are inside muted contexts. */ - if (is_tree_context_muted(*context)) { - return false; - } - for (const bNode *node : context->btree().nodes_by_type("CompositorNodeViewer")) { if (node->flag & NODE_DO_OUTPUT && !(node->flag & NODE_MUTED)) { node_stack.push(DNode(context, node)); @@ -71,31 +49,6 @@ static bool add_viewer_nodes_in_context(const DTreeContext *context, Stack &node_stack) -{ - for (const bNode *node : tree_context.btree().nodes_by_type("CompositorNodeOutputFile")) { - if (node->flag & NODE_MUTED) { - continue; - } - - node_stack.push(DNode(&tree_context, node)); - } - - for (const bNode *node : tree_context.btree().group_nodes()) { - if (node->flag & NODE_MUTED) { - continue; - } - - const bNodeTree *group_tree = reinterpret_cast(node->id); - if (!group_tree) { - continue; - } - - add_file_output_nodes(*tree_context.child_context(*node), node_stack); - } -} - /* Add the output nodes whose result should be computed to the given stack. This includes File * Output, Composite, and Viewer nodes. Viewer nodes are a special case, as only the nodes that * satisfies the requirements in the add_viewer_nodes_in_context function are added. First, the @@ -110,7 +63,11 @@ static void add_output_nodes(const Context &context, /* Only add File Output nodes if the context supports them. */ if (context.use_file_output()) { - add_file_output_nodes(root_context, node_stack); + for (const bNode *node : root_context.btree().nodes_by_type("CompositorNodeOutputFile")) { + if (!(node->flag & NODE_MUTED)) { + node_stack.push(DNode(&root_context, node)); + } + } } /* Only add the Composite output node if the context supports composite outputs. The active diff --git a/source/blender/draw/engines/eevee_next/eevee_instance.cc b/source/blender/draw/engines/eevee_next/eevee_instance.cc index a43e105dbdc..48044714460 100644 --- a/source/blender/draw/engines/eevee_next/eevee_instance.cc +++ b/source/blender/draw/engines/eevee_next/eevee_instance.cc @@ -405,10 +405,6 @@ void Instance::render_sample() /* Motion blur may need to do re-sync after a certain number of sample. */ if (!is_viewport() && sampling.do_render_sync()) { render_sync(); - if (!info.empty()) { - printf("%s", info.c_str()); - info = ""; - } } DebugScope debug_scope(debug_scope_render_sample, "EEVEE.render_sample"); diff --git a/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc b/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc index 5ee32149319..4185b6436ac 100644 --- a/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc +++ b/source/blender/draw/engines/eevee_next/eevee_lightprobe_planar.cc @@ -20,8 +20,8 @@ void PlanarProbe::set_view(const draw::View &view, int layer_id) this->world_to_object_transposed = float3x4(transpose(world_to_plane)); this->normal = normalize(plane_to_world.z_axis()); - float3 view_vec = view.is_persp() ? view.location() - plane_to_world.location() : view.forward(); - bool view_is_below_plane = dot(view_vec, plane_to_world.z_axis()) < 0.0; + bool view_is_below_plane = dot(view.location() - plane_to_world.location(), + plane_to_world.z_axis()) < 0.0; if (view_is_below_plane) { this->normal = -this->normal; } diff --git a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc index 5875f21aa30..45086691d9c 100644 --- a/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc +++ b/source/blender/draw/engines/eevee_next/eevee_motion_blur.cc @@ -243,8 +243,19 @@ void MotionBlurModule::render(View &view, GPUTexture **input_tx, GPUTexture **ou tile_indirection_buf_.clear_to_zero(); + const bool do_motion_vectors_swizzle = inst_.render_buffers.vector_tx_format() == GPU_RG16F; + if (do_motion_vectors_swizzle) { + /* Change texture swizzling to avoid complexity in gather pass shader. */ + GPU_texture_swizzle_set(inst_.render_buffers.vector_tx, "rgrg"); + } + inst_.manager->submit(motion_blur_ps_, view); + if (do_motion_vectors_swizzle) { + /* Reset swizzle since this texture might be reused in other places. */ + GPU_texture_swizzle_set(inst_.render_buffers.vector_tx, "rgba"); + } + tiles_tx_.release(); DRW_stats_group_end(); diff --git a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc index 2e8aa1b4c64..e7a594107d0 100644 --- a/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc +++ b/source/blender/draw/engines/eevee_next/eevee_renderbuffers.cc @@ -82,12 +82,6 @@ void RenderBuffers::acquire(int2 extent) /* TODO(fclem): Make vector pass allocation optional if no TAA or motion blur is needed. */ vector_tx.acquire(extent, vector_tx_format(), usage_attachment_read_write); - const bool do_motion_vectors_swizzle = vector_tx_format() == GPU_RG16F; - if (do_motion_vectors_swizzle) { - /* Change texture swizzling to avoid complexity in shaders. */ - GPU_texture_swizzle_set(vector_tx, "rgrg"); - } - int color_len = data.color_len + data.aovs.color_len; int value_len = data.value_len + data.aovs.value_len; @@ -123,25 +117,18 @@ void RenderBuffers::release() // depth_tx.release(); combined_tx.release(); - const bool do_motion_vectors_swizzle = vector_tx_format() == GPU_RG16F; - if (do_motion_vectors_swizzle) { - /* Reset swizzle since this texture might be reused in other places. */ - GPU_texture_swizzle_set(vector_tx, "rgba"); - } vector_tx.release(); - cryptomatte_tx.release(); } eGPUTextureFormat RenderBuffers::vector_tx_format() { const eViewLayerEEVEEPassType enabled_passes = inst_.film.enabled_passes_get(); - bool do_full_vector_render_pass = ((enabled_passes & EEVEE_RENDER_PASS_VECTOR) || - inst_.motion_blur.postfx_enabled()) && - !inst_.is_viewport(); + bool do_vector_render_pass = (enabled_passes & EEVEE_RENDER_PASS_VECTOR) || + (inst_.motion_blur.postfx_enabled() && !inst_.is_viewport()); - /* Only RG16F (motion.prev) for the viewport. */ - return do_full_vector_render_pass ? GPU_RGBA16F : GPU_RG16F; + /* Only RG16F when only doing only reprojection or motion blur. */ + return do_vector_render_pass ? GPU_RGBA16F : GPU_RG16F; } } // namespace blender::eevee diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc index 46cde8c3673..e1b743bdb17 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc @@ -165,14 +165,8 @@ bool VelocityModule::step_object_sync(Object *ob, vel.obj.ofs[STEP_PREVIOUS]) = ob->object_to_world(); } if (vel.obj.ofs[STEP_NEXT] == -1) { - if (inst_.is_viewport()) { - /* Just set it to 0. motion.next is not meant to be valid in the viewport. */ - vel.obj.ofs[STEP_NEXT] = 0; - } - else { - vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++; - object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world(); - } + vel.obj.ofs[STEP_NEXT] = object_steps_usage[STEP_NEXT]++; + object_steps[STEP_NEXT]->get_or_resize(vel.obj.ofs[STEP_NEXT]) = ob->object_to_world(); } } @@ -219,11 +213,11 @@ bool VelocityModule::step_object_sync(Object *ob, if (step_ == STEP_CURRENT && has_motion == true && has_deform == false) { const float4x4 &obmat_curr = (*object_steps[STEP_CURRENT])[vel.obj.ofs[STEP_CURRENT]]; const float4x4 &obmat_prev = (*object_steps[STEP_PREVIOUS])[vel.obj.ofs[STEP_PREVIOUS]]; + const float4x4 &obmat_next = (*object_steps[STEP_NEXT])[vel.obj.ofs[STEP_NEXT]]; if (inst_.is_viewport()) { has_motion = (obmat_curr != obmat_prev); } else { - const float4x4 &obmat_next = (*object_steps[STEP_NEXT])[vel.obj.ofs[STEP_NEXT]]; has_motion = (obmat_curr != obmat_prev || obmat_curr != obmat_next); } } @@ -316,7 +310,6 @@ void VelocityModule::step_swap() std::swap(geometry_steps[step_a], geometry_steps[step_b]); std::swap(camera_steps[step_a], camera_steps[step_b]); std::swap(step_time[step_a], step_time[step_b]); - std::swap(object_steps_usage[step_a], object_steps_usage[step_b]); for (VelocityObjectData &vel : velocity_map.values()) { vel.obj.ofs[step_a] = vel.obj.ofs[step_b]; @@ -347,9 +340,6 @@ void VelocityModule::begin_sync() step_ = STEP_CURRENT; step_camera_sync(); object_steps_usage[step_] = 0; - - /* STEP_NEXT is not used for viewport. (See #131134) */ - BLI_assert(!inst_.is_viewport() || object_steps_usage[STEP_NEXT] == 0); } void VelocityModule::end_sync() diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl index 8ea910c45b7..32fac575ad9 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_velocity_lib.glsl @@ -122,7 +122,6 @@ void velocity_local_pos_get(vec3 lP, int vert_id, out vec3 lP_prev, out vec3 lP_ /** * Given a triple of position, compute the previous and next motion vectors. * Returns a tuple of world space motion deltas. - * WARNING: The returned motion_next is invalid when rendering the viewport. */ void velocity_vertex( vec3 lP_prev, vec3 lP, vec3 lP_next, out vec3 motion_prev, out vec3 motion_next) diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh index 5baa0003832..ae8937e301d 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_velocity_info.hh @@ -13,8 +13,7 @@ * \{ */ /* Pass world space deltas to the fragment shader. - * This is to make sure that the resulting motion vectors are valid even with displacement. - * WARNING: The next value is invalid when rendering the viewport. */ + * This is to make sure that the resulting motion vectors are valid even with displacement. */ GPU_SHADER_INTERFACE_INFO(eevee_velocity_surface_iface, "motion") .smooth(Type::VEC3, "prev") .smooth(Type::VEC3, "next"); diff --git a/source/blender/draw/engines/gpencil/gpencil_render.cc b/source/blender/draw/engines/gpencil/gpencil_render.cc index 5bff94c14d9..1d59557c47d 100644 --- a/source/blender/draw/engines/gpencil/gpencil_render.cc +++ b/source/blender/draw/engines/gpencil/gpencil_render.cc @@ -30,6 +30,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, GPENCIL_FramebufferList *fbl = vedata->fbl; GPENCIL_TextureList *txl = vedata->txl; + Scene *scene = DEG_get_evaluated_scene(depsgraph); const float *viewport_size = DRW_viewport_size_get(); const int size[2] = {int(viewport_size[0]), int(viewport_size[1])}; @@ -83,8 +84,7 @@ void GPENCIL_render_init(GPENCIL_Data *vedata, } } - const bool do_region = !(rect->xmin == 0 && rect->ymin == 0 && rect->xmax == size[0] && - rect->ymax == size[1]); + const bool do_region = (scene->r.mode & R_BORDER) != 0; const bool do_clear_z = !pix_z || do_region; const bool do_clear_col = !pix_col || do_region; diff --git a/source/blender/draw/engines/image/image_buffer_cache.hh b/source/blender/draw/engines/image/image_buffer_cache.hh index 4cb5873efe0..2e4b10cf1a5 100644 --- a/source/blender/draw/engines/image/image_buffer_cache.hh +++ b/source/blender/draw/engines/image/image_buffer_cache.hh @@ -74,10 +74,8 @@ struct FloatBufferCache { if (image_buffer->float_buffer.data != nullptr) { BLI_assert_msg( IMB_colormanagement_space_name_is_scene_linear( - IMB_colormanagement_get_float_colorspace(image_buffer)) || - IMB_colormanagement_space_name_is_data( - IMB_colormanagement_get_float_colorspace(image_buffer)), - "Expected float buffer to be scene_linear or data - if there are code paths where this " + IMB_colormanagement_get_float_colorspace(image_buffer)), + "Expected float buffer to be scene_linear - if there are code paths where this " "isn't the case we should convert those and add to the FloatBufferCache as well."); return image_buffer; } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl index 039cd828c74..954e6b114e1 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_antialiasing_frag.glsl @@ -89,7 +89,7 @@ void neighbor_blend( void main() { ivec2 center_texel = ivec2(gl_FragCoord.xy); - float line_kernel = sizeLine * 0.5 - 0.5; + float line_kernel = sizePixel * 0.5 - 0.5; fragColor = texelFetch(colorTex, center_texel, 0); diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index 36f6c5dc050..71e34c0a052 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -2063,7 +2063,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache, const int next_offset = (i == mesh_eval->faces_num - 1) ? number_of_quads : subdiv_face_offset[i + 1]; const int quad_count = next_offset - subdiv_face_offset[i]; - const uint mat_index = uint(material_indices[i]) < mat_len ? uint(material_indices[i]) : 0; + const int mat_index = material_indices[i]; mat_start[mat_index] += quad_count; } @@ -2082,7 +2082,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache &cache, MEM_mallocN(sizeof(int) * mesh_eval->faces_num, "per_face_mat_offset")); for (int i = 0; i < mesh_eval->faces_num; i++) { - const uint mat_index = uint(material_indices[i]) < mat_len ? uint(material_indices[i]) : 0; + const int mat_index = material_indices[i]; const int single_material_index = subdiv_face_offset[i]; const int material_offset = mat_end[mat_index]; const int next_offset = (i == mesh_eval->faces_num - 1) ? number_of_quads : diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index e9b66d6f2d7..9c1f4dd2710 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -730,7 +730,6 @@ static void drw_call_obinfos_init(DRWObjectInfos *ob_infos, const Object *ob) else { ob_infos->ob_flag += (ob == DST.draw_ctx.obact) ? (1 << 4) : 0; } - ob_infos->ob_flag += (ob->base_flag & BASE_HOLDOUT) ? (1 << 5) : 0; /* Negative scaling. */ ob_infos->ob_flag *= (ob->transflag & OB_NEG_SCALE) ? -1.0f : 1.0f; /* Object Color. */ diff --git a/source/blender/draw/intern/draw_sculpt.cc b/source/blender/draw/intern/draw_sculpt.cc index ca3b37defa3..b38f7ffa147 100644 --- a/source/blender/draw/intern/draw_sculpt.cc +++ b/source/blender/draw/intern/draw_sculpt.cc @@ -14,8 +14,6 @@ #include "BKE_mesh_types.hh" #include "BKE_paint.hh" -#include "bmesh_class.hh" - #include "DRW_pbvh.hh" namespace blender::draw { @@ -132,28 +130,6 @@ static Vector sculpt_batches_get_ex(const Object *ob, return result_batches; } -static const CustomData *get_cdata(const BMesh &bm, const bke::AttrDomain domain) -{ - switch (domain) { - case bke::AttrDomain::Point: - return &bm.vdata; - case bke::AttrDomain::Corner: - return &bm.ldata; - case bke::AttrDomain::Face: - return &bm.pdata; - default: - return nullptr; - } -} - -static bool bmesh_attribute_exists(const BMesh &bm, - const bke::AttributeMetaData &meta_data, - const StringRef name) -{ - const CustomData *cdata = get_cdata(bm, meta_data.domain); - return cdata && CustomData_get_offset_named(cdata, meta_data.data_type, name) != -1; -} - Vector sculpt_batches_get(const Object *ob, SculptBatchFeature features) { Vector attrs; @@ -169,30 +145,19 @@ Vector sculpt_batches_get(const Object *ob, SculptBatchFeature feat const Mesh *mesh = BKE_object_get_original_mesh(ob); const bke::AttributeAccessor attributes = mesh->attributes(); - const SculptSession &ss = *ob->sculpt; - /* If Dyntopo is enabled, the source of truth for an attribute existing or not is the BMesh, not - * the Mesh. */ if (features & SCULPT_BATCH_VERTEX_COLOR) { if (const char *name = mesh->active_color_attribute) { if (const std::optional meta_data = attributes.lookup_meta_data( name)) { - if (ss.bm) { - if (bmesh_attribute_exists(*ss.bm, *meta_data, name)) { - attrs.append(pbvh::GenericRequest{name, meta_data->data_type, meta_data->domain}); - } - } - else { - attrs.append(pbvh::GenericRequest{name, meta_data->data_type, meta_data->domain}); - } + attrs.append(pbvh::GenericRequest{name, meta_data->data_type, meta_data->domain}); } } } if (features & SCULPT_BATCH_UV) { - const CustomData *corner_data = ss.bm ? &ss.bm->ldata : &mesh->corner_data; - if (const char *name = CustomData_get_active_layer_name(corner_data, CD_PROP_FLOAT2)) { + if (const char *name = CustomData_get_active_layer_name(&mesh->corner_data, CD_PROP_FLOAT2)) { attrs.append(pbvh::GenericRequest{name, CD_PROP_FLOAT2, bke::AttrDomain::Corner}); } } diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index 07f846b551d..61ddfd281f9 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -293,7 +293,6 @@ float get_homogenous_z_offset(float vs_z, float hs_w, float vs_offset) #define DRW_BASE_FROM_DUPLI (1 << 2) #define DRW_BASE_FROM_SET (1 << 3) #define DRW_BASE_ACTIVE (1 << 4) -#define DRW_BASE_HOLDOUT (1 << 5) /* Wire Color Types, matching eV3DShadingColorType. */ #define V3D_SHADING_SINGLE_COLOR 2 diff --git a/source/blender/editors/animation/anim_motion_paths.cc b/source/blender/editors/animation/anim_motion_paths.cc index 9e95eb819d3..9cf562fa109 100644 --- a/source/blender/editors/animation/anim_motion_paths.cc +++ b/source/blender/editors/animation/anim_motion_paths.cc @@ -460,8 +460,8 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph, mpt->keylist = ED_keylist_create(); ListBase *fcurve_list = nullptr; - if (adt && adt->action) { - /* Get pointer to animviz settings for each target. */ + if (adt) { + /* get pointer to animviz settings for each target */ bAnimVizSettings *avs = animviz_target_settings_get(mpt); /* it is assumed that keyframes for bones are all grouped in a single group diff --git a/source/blender/editors/armature/armature_add.cc b/source/blender/editors/armature/armature_add.cc index 58425cd046e..d7f78dec58f 100644 --- a/source/blender/editors/armature/armature_add.cc +++ b/source/blender/editors/armature/armature_add.cc @@ -653,14 +653,6 @@ static void updateDuplicateLocRotConstraintSettings(Object *ob, min_vec[0] = max_vec[0] * -1; max_vec[0] = min_x_copy * -1; - - /* Also flip the enabled axis checkboxes accordingly. */ - const bool use_max_x = (limit->flag & LIMIT_XMAX); - const bool use_min_x = (limit->flag & LIMIT_XMIN); - limit->flag |= use_max_x ? LIMIT_XMIN : 0; - limit->flag &= (use_max_x && !use_min_x) ? ~LIMIT_XMAX : limit->flag; - limit->flag |= use_min_x ? LIMIT_XMAX : 0; - limit->flag &= (use_min_x && !use_max_x) ? ~LIMIT_XMIN : limit->flag; } /* convert back to the settings space */ diff --git a/source/blender/editors/armature/bone_collections.cc b/source/blender/editors/armature/bone_collections.cc index 638653125bc..9de64ba8456 100644 --- a/source/blender/editors/armature/bone_collections.cc +++ b/source/blender/editors/armature/bone_collections.cc @@ -268,7 +268,7 @@ static void bone_collection_assign_editbones(bContext *C, ED_armature_edit_sync_selection(arm->edbo); LISTBASE_FOREACH (EditBone *, ebone, arm->edbo) { - if (!EBONE_EDITABLE(ebone) || !EBONE_VISIBLE(arm, ebone)) { + if (!EBONE_EDITABLE(ebone)) { continue; } *made_any_changes |= assign_func(bcoll, ebone); diff --git a/source/blender/editors/armature/pose_slide.cc b/source/blender/editors/armature/pose_slide.cc index efc32545a45..83c00335dea 100644 --- a/source/blender/editors/armature/pose_slide.cc +++ b/source/blender/editors/armature/pose_slide.cc @@ -259,10 +259,6 @@ static int pose_slide_init(bContext *C, wmOperator *op, ePoseSlide_Modes mode) pso->num.idx_max = 0; /* One axis. */ pso->num.unit_type[0] = B_UNIT_NONE; /* Percentages don't have any units. */ - /* Save current bone visibility. */ - View3D *v3d = static_cast(pso->area->spacedata.first); - pso->overlay_flag = v3d->overlay.flag; - /* Return status is whether we've got all the data we were requested to get. */ return 1; } @@ -1066,6 +1062,10 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, const wmEvent * /* Add a modal handler for this operator. */ WM_event_add_modal_handler(C, op); + /* Save current bone visibility. */ + View3D *v3d = static_cast(pso->area->spacedata.first); + pso->overlay_flag = v3d->overlay.flag; + return OPERATOR_RUNNING_MODAL; } diff --git a/source/blender/editors/geometry/node_group_operator.cc b/source/blender/editors/geometry/node_group_operator.cc index 98b80280c15..0d24dd4ae91 100644 --- a/source/blender/editors/geometry/node_group_operator.cc +++ b/source/blender/editors/geometry/node_group_operator.cc @@ -406,9 +406,7 @@ static void replace_inputs_evaluated_data_blocks( { IDP_foreach_property(&properties, IDP_TYPE_FILTER_ID, [&](IDProperty *property) { if (ID *id = IDP_Id(property)) { - if (ID_TYPE_USE_COPY_ON_EVAL(GS(id->name))) { - property->data.pointer = const_cast(depsgraphs.get_evaluated_id(*id)); - } + property->data.pointer = const_cast(depsgraphs.get_evaluated_id(*id)); } }); } @@ -891,44 +889,44 @@ void GEOMETRY_OT_execute_node_group(wmOperatorType *ot) "cursor_position", 3, nullptr, - -FLT_MAX, + FLT_MIN, FLT_MAX, "3D Cursor Position", "", - -FLT_MAX, + FLT_MIN, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_float_array(ot->srna, "cursor_rotation", 4, nullptr, - -FLT_MAX, + FLT_MIN, FLT_MAX, "3D Cursor Rotation", "", - -FLT_MAX, + FLT_MIN, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_float_array(ot->srna, "viewport_projection_matrix", 16, nullptr, - -FLT_MAX, + FLT_MIN, FLT_MAX, "Viewport Projection Transform", "", - -FLT_MAX, + FLT_MIN, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_float_array(ot->srna, "viewport_view_matrix", 16, nullptr, - -FLT_MAX, + FLT_MIN, FLT_MAX, "Viewport View Transform", "", - -FLT_MAX, + FLT_MIN, FLT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN); prop = RNA_def_boolean( diff --git a/source/blender/editors/include/ED_mesh.hh b/source/blender/editors/include/ED_mesh.hh index 4f519850f5e..ccc99c4243e 100644 --- a/source/blender/editors/include/ED_mesh.hh +++ b/source/blender/editors/include/ED_mesh.hh @@ -571,11 +571,6 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px, */ bool ED_mesh_pick_face_vert( bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index); -/** - * Used for paint face loop selection which needs to get closest edge even though in face select - * mode. Changes the select_buffer context to edge selection for this. - */ -bool ED_mesh_pick_edge(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index); MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve); MDeformVert *ED_mesh_active_dvert_get_ob(Object *ob, int *r_index); diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index be62ca1b19b..d5e00d1688c 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -11089,7 +11089,7 @@ static int ui_handle_menu_event(bContext *C, /* Menu search if space-bar or #MenuTypeFlag::SearchOnKeyPress. */ MenuType *mt = WM_menutype_find(menu->menu_idname, true); - if ((mt && bool(mt->flag & MenuTypeFlag::SearchOnKeyPress) && !bool(U.experimental.disable_search_on_keypress)) || + if ((mt && bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) || event->type == EVT_SPACEKEY) { if ((level != 0) && (but == nullptr || !menu->menu_idname[0])) { diff --git a/source/blender/editors/interface/templates/interface_template_search_menu.cc b/source/blender/editors/interface/templates/interface_template_search_menu.cc index 3292a18a507..3b6788c46d1 100644 --- a/source/blender/editors/interface/templates/interface_template_search_menu.cc +++ b/source/blender/editors/interface/templates/interface_template_search_menu.cc @@ -783,35 +783,18 @@ static MenuSearch_Data *menu_items_from_ui_create(bContext *C, uiLayoutSetOperatorContext(sub_layout, WM_OP_INVOKE_REGION_WIN); - /* If this is a panel, check it's poll function succeeds before drawing. - * otherwise draw(..) may be called in an unsupported context and crash, see: #130744. - * - * NOTE(@ideasman42): it would be good if the buttons #UI_BUT_DISABLED flag - * could be used as a more general way to know if poll succeeded, - * at this point it's not set - this could be further investigated. */ - bool poll_success = true; - if (PanelType *pt = UI_but_paneltype_get(but)) { - if (pt->poll && (pt->poll(C, pt) == false)) { - poll_success = false; - } - } - - if (poll_success) { - but->menu_create_func(C, sub_layout, but->poin); - } + but->menu_create_func(C, sub_layout, but->poin); UI_block_end(C, sub_block); - if (poll_success) { - MenuSearch_Parent *menu_parent = (MenuSearch_Parent *)BLI_memarena_calloc( - memarena, sizeof(*menu_parent)); - menu_parent->drawstr = strdup_memarena(memarena, but->drawstr.c_str()); - menu_parent->parent = current_menu.self_as_parent; + MenuSearch_Parent *menu_parent = (MenuSearch_Parent *)BLI_memarena_calloc( + memarena, sizeof(*menu_parent)); + menu_parent->drawstr = strdup_memarena(memarena, but->drawstr.c_str()); + menu_parent->parent = current_menu.self_as_parent; - LISTBASE_FOREACH (uiBut *, sub_but, &sub_block->buttons) { - menu_items_from_ui_create_item_from_button( - data, memarena, mt, sub_but, wm_context, menu_parent); - } + LISTBASE_FOREACH (uiBut *, sub_but, &sub_block->buttons) { + menu_items_from_ui_create_item_from_button( + data, memarena, mt, sub_but, wm_context, menu_parent); } if (region) { diff --git a/source/blender/editors/interface/templates/interface_templates.cc b/source/blender/editors/interface/templates/interface_templates.cc index 2fda5a782e1..b2ec5a4a219 100644 --- a/source/blender/editors/interface/templates/interface_templates.cc +++ b/source/blender/editors/interface/templates/interface_templates.cc @@ -3078,22 +3078,10 @@ static void draw_export_properties(bContext *C, uiLayoutSetPropDecorate(col, false); PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); - if (prop) { - std::string placeholder = "//" + filename; - uiItemFullR(col, - op->ptr, - prop, - RNA_NO_INDEX, - 0, - UI_ITEM_NONE, - nullptr, - ICON_NONE, - placeholder.c_str()); - } - else { - std::string label = std::string(IFACE_(" not found in: ")) + op->idname; - uiItemL(col, label.c_str(), ICON_ERROR); - } + std::string placeholder = "//" + filename; + uiItemFullR( + col, op->ptr, prop, RNA_NO_INDEX, 0, UI_ITEM_NONE, nullptr, ICON_NONE, placeholder.c_str()); + template_operator_property_buts_draw_single( C, op, layout, UI_BUT_LABEL_ALIGN_NONE, UI_TEMPLATE_OP_PROPS_HIDE_PRESETS); } diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 9bfe27c20eb..0ebeec01d34 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -356,6 +356,36 @@ void paintface_select_linked(bContext *C, Object *ob, const int mval[2], const b paintface_flush_flags(C, ob, true, false); } +static int find_closest_edge_in_poly(ARegion *region, + blender::Span edges, + blender::Span face_edges, + blender::Span vert_positions, + const int mval[2]) +{ + using namespace blender; + int closest_edge_index; + + const float2 mval_f = {float(mval[0]), float(mval[1])}; + float min_distance = FLT_MAX; + for (const int i : face_edges) { + float2 screen_coordinate; + const int2 edge = edges[i]; + const float3 edge_vert_average = math::midpoint(vert_positions[edge[0]], + vert_positions[edge[1]]); + eV3DProjStatus status = ED_view3d_project_float_object( + region, edge_vert_average, screen_coordinate, V3D_PROJ_TEST_CLIP_DEFAULT); + if (status != V3D_PROJ_RET_OK) { + continue; + } + const float distance = math::distance_squared(mval_f, screen_coordinate); + if (distance < min_distance) { + min_distance = distance; + closest_edge_index = i; + } + } + return closest_edge_index; +} + static int get_opposing_edge_index(const blender::IndexRange face, const blender::Span corner_edges, const int current_edge_index) @@ -437,12 +467,8 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo return; } - uint closest_edge_index = uint(-1); - if (!ED_mesh_pick_edge(C, ob, mval, ED_MESH_PICK_DEFAULT_VERT_DIST, &closest_edge_index)) { - return; - } - - if (closest_edge_index == -1) { + uint poly_pick_index = uint(-1); + if (!ED_mesh_pick_face(C, ob, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &poly_pick_index)) { return; } @@ -452,7 +478,13 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo Mesh *mesh = BKE_mesh_from_object(ob); const Span corner_edges = mesh->corner_edges(); + const Span verts = mesh->vert_positions(); const OffsetIndices faces = mesh->faces(); + const Span edges = mesh->edges(); + + const IndexRange face = faces[poly_pick_index]; + const int closest_edge_index = find_closest_edge_in_poly( + region, edges, corner_edges.slice(face), verts, mval); Array edge_to_face_offsets; Array edge_to_face_indices; @@ -466,12 +498,6 @@ void paintface_select_loop(bContext *C, Object *ob, const int mval[2], const boo ".hide_poly", bke::AttrDomain::Face, false); const Span faces_to_closest_edge = edge_to_face_map[closest_edge_index]; - - /* Picked edge may not be linked to a face (loose edge). */ - if (faces_to_closest_edge.is_empty()) { - return; - } - const bool traced_full_loop = follow_face_loop(faces_to_closest_edge[0], closest_edge_index, faces, diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index aa0bd920e37..f36a1d8beb2 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -32,7 +32,6 @@ #include "BKE_deform.hh" #include "BKE_editmesh.hh" #include "BKE_key.hh" -#include "BKE_layer.hh" #include "BKE_lib_id.hh" #include "BKE_material.h" #include "BKE_mesh.hh" @@ -1298,49 +1297,6 @@ bool ED_mesh_pick_face_vert( return false; } -bool ED_mesh_pick_edge(bContext *C, Object *ob, const int mval[2], uint dist_px, uint *r_index) -{ - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - Mesh *mesh = static_cast(ob->data); - - BLI_assert(mesh && GS(mesh->id.name) == ID_ME); - - if (!mesh || mesh->edges_num == 0) { - return false; - } - - ViewContext vc = ED_view3d_viewcontext_init(C, depsgraph); - ED_view3d_select_id_validate(&vc); - Base *base = BKE_view_layer_base_find(vc.view_layer, vc.obact); - DRW_select_buffer_context_create(vc.depsgraph, {base}, SCE_SELECT_EDGE); - - uint edge_idx_best = ORIGINDEX_NONE; - - if (dist_px) { - /* Sample rect to increase chances of selecting, so that when clicking - * on an edge in the back-buffer, we can still select a face. */ - edge_idx_best = DRW_select_buffer_find_nearest_to_point( - vc.depsgraph, vc.region, vc.v3d, mval, 1, mesh->edges_num + 1, &dist_px); - } - else { - /* sample only on the exact position */ - edge_idx_best = DRW_select_buffer_sample_point(vc.depsgraph, vc.region, vc.v3d, mval); - } - - if (edge_idx_best == 0 || edge_idx_best > uint(mesh->edges_num)) { - return false; - } - - edge_idx_best--; - - if ((edge_idx_best != ORIGINDEX_NONE)) { - *r_index = edge_idx_best; - return true; - } - - return false; -} - /** * Vertex selection in object mode, * currently only weight paint uses this. diff --git a/source/blender/editors/object/object_bake_api.cc b/source/blender/editors/object/object_bake_api.cc index ec550c2fc2b..23a76b50a24 100644 --- a/source/blender/editors/object/object_bake_api.cc +++ b/source/blender/editors/object/object_bake_api.cc @@ -1625,7 +1625,7 @@ static int bake(const BakeAPIRender *bkr, for (i = 0; i < tot_highpoly; i++) { ok = RE_bake_engine(re, depsgraph, - highpoly[i].ob_eval, + highpoly[i].ob, i, pixel_array_high, &targets, diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 3cd08d55fe6..6f6a5a39173 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -2010,7 +2010,8 @@ void vgroup_mirror(Object *ob, int *r_totmirr, int *r_totfail) { - /* TODO: vgroup locking. */ + /* TODO: vgroup locking. + * TODO: face masking. */ const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1; int totmirr = 0, totfail = 0; @@ -2099,8 +2100,8 @@ void vgroup_mirror(Object *ob, } else { /* object mode / weight paint */ - const bool use_sel = (mesh->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != - 0; + const bool use_vert_sel = (mesh->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; + if (mesh->deform_verts().is_empty()) { goto cleanup; } @@ -2117,8 +2118,8 @@ void vgroup_mirror(Object *ob, if ((vidx_mirr = mesh_get_x_mirror_vert(ob, nullptr, vidx, use_topology)) != -1) { if (vidx != vidx_mirr) { if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) { - const bool sel = use_sel ? select_vert[vidx] : true; - const bool sel_mirr = use_sel ? select_vert[vidx_mirr] : true; + const bool sel = use_vert_sel ? select_vert[vidx] : true; + const bool sel_mirr = use_vert_sel ? select_vert[vidx_mirr] : true; if (sel || sel_mirr) { dvert_mirror_op(&dverts[vidx], diff --git a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc index 06fd45f5f95..17c8f1134d9 100644 --- a/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc +++ b/source/blender/editors/sculpt_paint/paint_image_ops_paint.cc @@ -334,7 +334,7 @@ static std::unique_ptr texture_paint_init(bContext *C, } static void paint_stroke_update_step(bContext *C, - wmOperator *op, + wmOperator * /*op*/, PaintStroke *stroke, PointerRNA *itemptr) { @@ -357,7 +357,7 @@ static void paint_stroke_update_step(bContext *C, RNA_float_get_array(itemptr, "mouse", mouse); pressure = RNA_float_get(itemptr, "pressure"); - eraser = RNA_boolean_get(op->ptr, "pen_flip"); + eraser = RNA_boolean_get(itemptr, "pen_flip"); size = RNA_float_get(itemptr, "size"); /* stroking with fill tool only acts on stroke end */ diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index d5cf8f612b7..d3355f286a0 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -570,8 +570,6 @@ static void invert_mask_grids(Main &bmain, MultiresModifierData &mmd = *BKE_sculpt_multires_active(&scene, &object); BKE_sculpt_mask_layers_ensure(&depsgraph, &bmain, &object, &mmd); - Vector nodes = bke::pbvh::search_gather(*object.sculpt->pbvh, {}); - SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg; undo::push_nodes(depsgraph, object, node_mask, undo::Type::Mask); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.cc b/source/blender/editors/sculpt_paint/paint_stroke.cc index 6ab709ded13..ce198be5695 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.cc +++ b/source/blender/editors/sculpt_paint/paint_stroke.cc @@ -627,6 +627,7 @@ static void paint_brush_stroke_add_step( RNA_float_set_array(&itemptr, "mouse", mouse_out); /* Original mouse coordinates. */ RNA_float_set_array(&itemptr, "mouse_event", mval); + RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip); RNA_float_set(&itemptr, "pressure", pressure); RNA_float_set(&itemptr, "x_tilt", stroke->x_tilt); RNA_float_set(&itemptr, "y_tilt", stroke->y_tilt); @@ -1524,8 +1525,6 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS /* one time stroke initialization */ if (!stroke->stroke_started) { - RNA_boolean_set(op->ptr, "pen_flip", stroke->pen_flip); - stroke->last_pressure = sample_average.pressure; copy_v2_v2(stroke->last_mouse_position, sample_average.mouse); if (paint_stroke_use_scene_spacing(*br, mode)) { diff --git a/source/blender/editors/sculpt_paint/paint_utils.cc b/source/blender/editors/sculpt_paint/paint_utils.cc index 7bdecdb5982..92e5c41ffcc 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.cc +++ b/source/blender/editors/sculpt_paint/paint_utils.cc @@ -205,12 +205,6 @@ void paint_stroke_operator_properties(wmOperatorType *ot) "Stroke Mode", "Action taken when a paint stroke is made"); RNA_def_property_flag(prop, PropertyFlag(PROP_SKIP_SAVE)); - - /* TODO: Pen flip logic should likely be combined into the stroke mode logic instead of being - * an entirely separate concept. */ - prop = RNA_def_boolean( - ot->srna, "pen_flip", false, "Pen Flip", "Whether a tablet's eraser mode is being used"); - RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } /* 3D Paint */ diff --git a/source/blender/editors/sculpt_paint/paint_weight.cc b/source/blender/editors/sculpt_paint/paint_weight.cc index 0a0e1e8d521..2c62ebdd192 100644 --- a/source/blender/editors/sculpt_paint/paint_weight.cc +++ b/source/blender/editors/sculpt_paint/paint_weight.cc @@ -1786,7 +1786,7 @@ static void wpaint_do_symmetrical_brush_actions( } static void wpaint_stroke_update_step(bContext *C, - wmOperator *op, + wmOperator * /*op*/, PaintStroke *stroke, PointerRNA *itemptr) { @@ -1840,7 +1840,7 @@ static void wpaint_stroke_update_step(bContext *C, wpi.vgroup_validmap = wpd->vgroup_validmap; wpi.vgroup_locked = wpd->vgroup_locked; wpi.vgroup_unlocked = wpd->vgroup_unlocked; - wpi.do_flip = RNA_boolean_get(op->ptr, "pen_flip") || ss.cache->invert; + wpi.do_flip = RNA_boolean_get(itemptr, "pen_flip") || ss.cache->invert; wpi.do_multipaint = wpd->do_multipaint; wpi.do_auto_normalize = ((ts.auto_normalize != 0) && (wpi.vgroup_validmap != nullptr) && (wpi.do_multipaint || wpi.vgroup_validmap[wpi.active.index])); diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 941bae21f41..7f8c024f2bc 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2059,23 +2059,6 @@ void calc_area_normal_and_center(const Depsgraph &depsgraph, /** \name Generic Brush Utilities * \{ */ -/** - * Calculates the sign of the direction of the brush stroke, typically indicates whether the stroke - * will deform a surface inwards or outwards along the brush normal. - */ -static float brush_flip(const Brush &brush, const blender::ed::sculpt_paint::StrokeCache &cache) -{ - if (brush.flag & BRUSH_INVERT_TO_SCRAPE_FILL) { - return 1.0f; - } - - const float dir = (brush.flag & BRUSH_DIR_IN) ? -1.0f : 1.0f; - const float pen_flip = cache.pen_flip ? -1.0f : 1.0f; - const float invert = cache.invert ? -1.0f : 1.0f; - - return dir * pen_flip * invert; -} - /** * Return modified brush strength. Includes the direction of the brush, positive * values pull vertices, negative values push. Uses tablet pressure and a @@ -2093,12 +2076,18 @@ static float brush_strength(const Sculpt &sd, /* Primary strength input; square it to make lower values more sensitive. */ const float root_alpha = BKE_brush_alpha_get(scene, &brush); const float alpha = root_alpha * root_alpha; + const float dir = (brush.flag & BRUSH_DIR_IN) ? -1.0f : 1.0f; const float pressure = BKE_brush_use_alpha_pressure(&brush) ? cache.pressure : 1.0f; + const float pen_flip = cache.pen_flip ? -1.0f : 1.0f; + const float invert = cache.invert ? -1.0f : 1.0f; float overlap = ups.overlap_factor; /* Spacing is integer percentage of radius, divide by 50 to get * normalized diameter. */ - const float flip = brush_flip(brush, cache); + float flip = dir * invert * pen_flip; + if (brush.flag & BRUSH_INVERT_TO_SCRAPE_FILL) { + flip = 1.0f; + } /* Pressure final value after being tweaked depending on the brush. */ float final_pressure; @@ -3878,7 +3867,6 @@ static void sculpt_update_cache_invariants( copy_v3_v3(cache->initial_normal, ss.cursor_normal); mode = RNA_enum_get(op->ptr, "mode"); - cache->pen_flip = RNA_boolean_get(op->ptr, "pen_flip"); cache->invert = mode == BRUSH_STROKE_INVERT; cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH; cache->normal_weight = brush->normal_weight; @@ -3911,8 +3899,6 @@ static void sculpt_update_cache_invariants( copy_v2_v2(cache->mouse_event, cache->initial_mouse); copy_v2_v2(ups->tex_mouse, cache->initial_mouse); - cache->initial_direction_flipped = brush_flip(*brush, *cache) < 0.0f; - /* Truly temporary data that isn't stored in properties. */ cache->vc = vc; cache->brush = brush; @@ -4259,6 +4245,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt &sd, Object &ob, Po RNA_float_get_array(ptr, "location", cache.location); } + cache.pen_flip = RNA_boolean_get(ptr, "pen_flip"); RNA_float_get_array(ptr, "mouse", cache.mouse); RNA_float_get_array(ptr, "mouse_event", cache.mouse_event); diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.cc b/source/blender/editors/sculpt_paint/sculpt_detail.cc index 1e8f38e4a25..7ba698cf398 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.cc +++ b/source/blender/editors/sculpt_paint/sculpt_detail.cc @@ -515,7 +515,6 @@ static void dyntopo_detail_size_parallel_lines_draw(uint pos3d, normalize_v3(spacing_disp); float line_disp[3]; - zero_v3(line_disp); rotate_v2_v2fl(line_disp, spacing_disp, DEG2RAD(angle)); mul_v3_fl(spacing_disp, total_len / tot_lines_fl); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index c347d765dc8..00574b244a5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -164,15 +164,6 @@ struct StrokeCache { } mirror_modifier_clip; float2 initial_mouse; - /** - * Some brushes change behavior drastically depending on the directional value (i.e. the smooth - * and enhance details functionality being bound to the Smooth brush). - * - * Storing the initial direction allows discerning the behavior without checking the sign of the - * brush direction at every step, which would have ambiguity at 0. - */ - bool initial_direction_flipped; - /* Variants */ float radius; float radius_squared; diff --git a/source/blender/editors/space_image/image_buttons.cc b/source/blender/editors/space_image/image_buttons.cc index 68dbd728ee3..d893170bf63 100644 --- a/source/blender/editors/space_image/image_buttons.cc +++ b/source/blender/editors/space_image/image_buttons.cc @@ -159,7 +159,6 @@ static void ui_imageuser_layer_menu(bContext * /*C*/, uiLayout *layout, void *rn /* May have been freed since drawing. */ RenderResult *rr = BKE_image_acquire_renderresult(scene, image); if (UNLIKELY(rr == nullptr)) { - BKE_image_release_renderresult(scene, image, rr); return; } @@ -232,7 +231,6 @@ static void ui_imageuser_pass_menu(bContext * /*C*/, uiLayout *layout, void *rnd /* may have been freed since drawing */ rr = BKE_image_acquire_renderresult(scene, image); if (UNLIKELY(rr == nullptr)) { - BKE_image_release_renderresult(scene, image, rr); return; } @@ -305,7 +303,6 @@ static void ui_imageuser_view_menu_rr(bContext * /*C*/, uiLayout *layout, void * /* may have been freed since drawing */ rr = BKE_image_acquire_renderresult(scene, image); if (UNLIKELY(rr == nullptr)) { - BKE_image_release_renderresult(scene, image, rr); return; } @@ -413,7 +410,6 @@ static bool ui_imageuser_layer_menu_step(bContext *C, int direction, void *rnd_p rr = BKE_image_acquire_renderresult(scene, image); if (UNLIKELY(rr == nullptr)) { - BKE_image_release_renderresult(scene, image, rr); return false; } diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index bbe27e93347..79a900f53f8 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -465,7 +465,6 @@ struct UndoImageBuf { UndoImageBuf *post; char ibuf_filepath[IMB_FILEPATH_SIZE]; - int ibuf_fileframe; UndoImageTile **tiles; @@ -497,7 +496,6 @@ static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf) MEM_callocN(sizeof(*ubuf->tiles) * ubuf->tiles_len, __func__)); STRNCPY(ubuf->ibuf_filepath, ibuf->filepath); - ubuf->ibuf_fileframe = ibuf->fileframe; ubuf->image_state.source = image->source; ubuf->image_state.use_float = ibuf->float_buffer.data != nullptr; @@ -667,11 +665,10 @@ static void uhandle_free_list(ListBase *undo_handles) static UndoImageBuf *uhandle_lookup_ubuf(UndoImageHandle *uh, const Image * /*image*/, - const char *ibuf_filepath, - const int ibuf_fileframe) + const char *ibuf_filepath) { LISTBASE_FOREACH (UndoImageBuf *, ubuf, &uh->buffers) { - if (STREQ(ubuf->ibuf_filepath, ibuf_filepath) && ubuf->ibuf_fileframe == ibuf_fileframe) { + if (STREQ(ubuf->ibuf_filepath, ibuf_filepath)) { return ubuf; } } @@ -680,7 +677,7 @@ static UndoImageBuf *uhandle_lookup_ubuf(UndoImageHandle *uh, static UndoImageBuf *uhandle_add_ubuf(UndoImageHandle *uh, Image *image, ImBuf *ibuf) { - BLI_assert(uhandle_lookup_ubuf(uh, image, ibuf->filepath, ibuf->fileframe) == nullptr); + BLI_assert(uhandle_lookup_ubuf(uh, image, ibuf->filepath) == nullptr); UndoImageBuf *ubuf = ubuf_from_image_no_tiles(image, ibuf); BLI_addtail(&uh->buffers, ubuf); @@ -691,7 +688,7 @@ static UndoImageBuf *uhandle_add_ubuf(UndoImageHandle *uh, Image *image, ImBuf * static UndoImageBuf *uhandle_ensure_ubuf(UndoImageHandle *uh, Image *image, ImBuf *ibuf) { - UndoImageBuf *ubuf = uhandle_lookup_ubuf(uh, image, ibuf->filepath, ibuf->fileframe); + UndoImageBuf *ubuf = uhandle_lookup_ubuf(uh, image, ibuf->filepath); if (ubuf == nullptr) { ubuf = uhandle_add_ubuf(uh, image, ibuf); } @@ -774,8 +771,7 @@ static UndoImageBuf *ubuf_lookup_from_reference(ImageUndoStep *us_prev, /* Use name lookup because the pointer is cleared for previous steps. */ UndoImageHandle *uh_prev = uhandle_lookup_by_name(&us_prev->handles, image, tile_number); if (uh_prev != nullptr) { - UndoImageBuf *ubuf_reference = uhandle_lookup_ubuf( - uh_prev, image, ubuf->ibuf_filepath, ubuf->ibuf_fileframe); + UndoImageBuf *ubuf_reference = uhandle_lookup_ubuf(uh_prev, image, ubuf->ibuf_filepath); if (ubuf_reference) { ubuf_reference = ubuf_reference->post; if ((ubuf_reference->image_dims[0] == ubuf->image_dims[0]) && diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc index 6b4d95f43a8..ced9bcdeca3 100644 --- a/source/blender/editors/space_node/clipboard.cc +++ b/source/blender/editors/space_node/clipboard.cc @@ -373,32 +373,21 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) for (NodeClipboardItem &item : clipboard.nodes) { const bNode &node = *item.node; const char *disabled_hint = nullptr; - - /* Some poll functions (e.g. for the nodegroup node, see #node_group_poll_instance) do require - * fully valid node data, including the potential ID pointers. So first create the new copy of - * the clipboard node, make it as valid as possible, then call its #poll_instance function, and - * discard the new copy if it fails. - * - * See also #141415. - */ - - /* Do not access referenced ID pointers here, as they are still the old ones, which may be - * invalid. */ - bNode *new_node = bke::node_copy_with_mapping( - &tree, node, LIB_ID_CREATE_NO_USER_REFCOUNT, true, socket_map); - /* Update the newly copied node's ID references. */ - clipboard.paste_update_node_id_references(*new_node); - /* Reset socket shape in case a node is copied to a different tree type. */ - LISTBASE_FOREACH (bNodeSocket *, socket, &new_node->inputs) { - socket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; - } - LISTBASE_FOREACH (bNodeSocket *, socket, &new_node->outputs) { - socket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; - } - - if (!new_node->typeinfo->poll_instance || - new_node->typeinfo->poll_instance(new_node, &tree, &disabled_hint)) + if (node.typeinfo->poll_instance && node.typeinfo->poll_instance(&node, &tree, &disabled_hint)) { + /* Do not access referenced ID pointers here, as they are still the old ones, which may be + * invalid. */ + bNode *new_node = bke::node_copy_with_mapping( + &tree, node, LIB_ID_CREATE_NO_USER_REFCOUNT, true, socket_map); + /* Update the newly copied node's ID references. */ + clipboard.paste_update_node_id_references(*new_node); + /* Reset socket shape in case a node is copied to a different tree type. */ + LISTBASE_FOREACH (bNodeSocket *, socket, &new_node->inputs) { + socket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; + } + LISTBASE_FOREACH (bNodeSocket *, socket, &new_node->outputs) { + socket->display_shape = SOCK_DISPLAY_SHAPE_CIRCLE; + } node_map.add_new(&node, new_node); } else { @@ -417,7 +406,6 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) node.name, tree.id.name + 2); } - bke::node_free_node(&tree, new_node); } } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 86a5e4bb675..75f6ab1d796 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -1636,12 +1636,7 @@ static void create_inspection_string_for_geometry_socket(fmt::memory_buffer &buf return; } - Vector supported_types = socket_decl->supported_types(); - if (!U.experimental.use_grease_pencil_version3) { - supported_types.remove_if([&](const bke::GeometryComponent::Type type) { - return type == bke::GeometryComponent::Type::GreasePencil; - }); - } + Span supported_types = socket_decl->supported_types(); if (supported_types.is_empty()) { fmt::format_to(fmt::appender(buf), TIP_("Supported: All Types")); return; @@ -3429,7 +3424,7 @@ static void node_draw_basis(const bContext &C, float iconofs = rct.xmax - 0.35f * U.widget_unit; /* Group edit. This icon should be the first for the node groups. */ - if (node.is_group()) { + if (node.type == NODE_GROUP) { iconofs -= iconbutw; UI_block_emboss_set(&block, UI_EMBOSS_NONE); uiBut *but = uiDefIconBut(&block, @@ -3560,7 +3555,7 @@ static void node_draw_basis(const bContext &C, showname, int(rct.xmin + NODE_MARGIN_X + 0.4f), int(rct.ymax - NODE_DY), - short(iconofs - rct.xmin - NODE_MARGIN_X), + short(iconofs - rct.xmin - (18.0f * UI_SCALE_FAC)), short(NODE_DY), nullptr, 0, diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 27ca4412f70..3b51e01a45e 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -2558,6 +2558,19 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ } } + /* No visible sockets, unhide first of highest priority. */ + for (int priority = maxpriority; priority >= 0; priority--) { + LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { + if (sock->flag & SOCK_UNAVAIL) { + continue; + } + if (priority == get_main_socket_priority(sock)) { + sock->flag &= ~SOCK_HIDDEN; + return sock; + } + } + } + return nullptr; } diff --git a/source/blender/editors/space_view3d/view3d_navigate_view_roll.cc b/source/blender/editors/space_view3d/view3d_navigate_view_roll.cc index e69718800b9..3230166fd6a 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_view_roll.cc +++ b/source/blender/editors/space_view3d/view3d_navigate_view_roll.cc @@ -236,26 +236,8 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event) viewroll_exec(C, op); } else { - /* The equivalent functionality for orbiting the view: VIEW3D_OT_orbit & VIEW3D_OT_rotate are - * separate operators with different poll functions [which are only permissive for non-locked - * views]. This operator however mixes modal-interaction & instant-stepping into the same - * operator and its current poll function permissively finds the non-locked region in quad - * view. For instant-stepping into the operator via keyboard shortcuts, forwarding to the - * non-locked view (when in a locked view) makes sense, but modal-interaction with the locked - * view forwarding to a different view doesn't (hence the check). */ - { - ARegion *region = CTX_wm_region(C); - if (region->regiontype == RGN_TYPE_WINDOW) { - const RegionView3D *rv3d = static_cast(region->regiondata); - if (rv3d->viewlock & RV3D_LOCK_ROTATION) { - return OPERATOR_PASS_THROUGH; - } - } - } - /* makes op->customdata */ vod = viewops_data_create(C, event, &ViewOpsType_roll, false); - const float start_position[2] = {float(BLI_rcti_cent_x(&vod->region->winrct)), float(BLI_rcti_cent_y(&vod->region->winrct))}; vod->init.dial = BLI_dial_init(start_position, FLT_EPSILON); diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index a1d61476161..0a710f9b616 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -2749,9 +2749,6 @@ static bool ed_object_select_pick(bContext *C, /* Special case, even when there are no hits, pose logic may de-select all bones. */ ((gpu->hits == 0) && has_pose_old)) { - /* Regarding the `basact` null checks. - * While it's unlikely there are GPU hits *without* `basact` being found, - * it's possible looking up the selection index fails, see: #143161. */ if (basact && (gpu->has_bones && (basact->object->type == OB_CAMERA))) { MovieClip *clip = BKE_object_movieclip_get(scene, basact->object, false); @@ -2773,8 +2770,7 @@ static bool ed_object_select_pick(bContext *C, } } } - else if ((basact || oldbasact) && - ED_armature_pose_select_pick_with_buffer(scene, + else if (ED_armature_pose_select_pick_with_buffer(scene, view_layer, v3d, basact ? basact : (Base *)oldbasact, diff --git a/source/blender/editors/space_view3d/view3d_utils.cc b/source/blender/editors/space_view3d/view3d_utils.cc index 6de3710085e..3c2e9ca1d7b 100644 --- a/source/blender/editors/space_view3d/view3d_utils.cc +++ b/source/blender/editors/space_view3d/view3d_utils.cc @@ -19,8 +19,6 @@ #include "DNA_scene_types.h" #include "DNA_world_types.h" -#include "RNA_path.hh" - #include "MEM_guardedalloc.h" #include "BLI_array_utils.h" @@ -30,7 +28,6 @@ #include "BLI_math_rotation.h" #include "BLI_math_vector.h" #include "BLI_utildefines.h" -#include "BLI_vector.hh" #include "BKE_camera.h" #include "BKE_context.hh" @@ -677,45 +674,30 @@ bool ED_view3d_camera_lock_sync(const Depsgraph *depsgraph, View3D *v3d, RegionV bool ED_view3d_camera_autokey( const Scene *scene, ID *id_key, bContext *C, const bool do_rotate, const bool do_translate) { - BLI_assert(GS(id_key->name) == ID_OB); - using namespace blender; + using namespace blender::animrig; + if (autokeyframe_cfra_can_key(scene, id_key)) { + const float cfra = float(scene->r.cfra); + blender::Vector sources; + /* add data-source override for the camera object */ + ANIM_relative_keyingset_add_source(sources, id_key); - /* While `autokeyframe_object` does already call `autokeyframe_cfra_can_key` we need this here - * because at the time of writing this it returns void. Once the keying result is returned, like - * implemented for `blender::animrig::insert_keyframes`, this `if` can be removed. */ - if (!animrig::autokeyframe_cfra_can_key(scene, id_key)) { - return false; - } - - Object *camera_object = reinterpret_cast(id_key); - - Vector rna_paths; - - if (do_rotate) { - switch (camera_object->rotmode) { - case ROT_MODE_QUAT: - rna_paths.append({"rotation_quaternion"}); - break; - - case ROT_MODE_AXISANGLE: - rna_paths.append({"rotation_axis_angle"}); - break; - - case ROT_MODE_EUL: - rna_paths.append({"rotation_euler"}); - break; - - default: - break; + /* insert keyframes + * 1) on the first frame + * 2) on each subsequent frame + * TODO: need to check in future that frame changed before doing this + */ + if (do_rotate) { + KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_ROTATION_ID); + ANIM_apply_keyingset(C, &sources, ks, ModifyKeyMode::INSERT, cfra); + } + if (do_translate) { + KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID); + ANIM_apply_keyingset(C, &sources, ks, ModifyKeyMode::INSERT, cfra); } - } - if (do_translate) { - rna_paths.append({"location"}); - } - animrig::autokeyframe_object(C, scene, camera_object, rna_paths); - WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, nullptr); - return true; + return true; + } + return false; } bool ED_view3d_camera_lock_autokey( diff --git a/source/blender/editors/transform/transform_convert_armature.cc b/source/blender/editors/transform/transform_convert_armature.cc index b1938568615..c0c136ebcb8 100644 --- a/source/blender/editors/transform/transform_convert_armature.cc +++ b/source/blender/editors/transform/transform_convert_armature.cc @@ -1060,7 +1060,7 @@ static void recalcData_edit_armature(TransInfo *t) if (ebo_parent) { /* If this bone has a parent tip that has been moved. */ - if (EBONE_VISIBLE(arm, ebo_parent) && (ebo_parent->flag & BONE_TIPSEL)) { + if (ebo_parent->flag & BONE_TIPSEL) { copy_v3_v3(ebo->head, ebo_parent->tail); if (t->mode == TFM_BONE_ENVELOPE) { ebo->rad_head = ebo_parent->rad_tail; diff --git a/source/blender/editors/transform/transform_convert_mesh.cc b/source/blender/editors/transform/transform_convert_mesh.cc index d405f0f7e0a..17b5bd542b3 100644 --- a/source/blender/editors/transform/transform_convert_mesh.cc +++ b/source/blender/editors/transform/transform_convert_mesh.cc @@ -1108,22 +1108,14 @@ void transform_convert_mesh_connectivity_distance(BMesh *bm, } if (bmesh_test_dist_add(v2, v1, nullptr, dists, index, mtx)) { - /* Add adjacent edges to the queue if: - * - Adjacent edge is loose - * - Edge itself is loose - * - Edge has vertex that was originally selected - * In all these cases a direct distance along the edge is accurate and - * required to make sure we visit all edges. Other edges are handled by - * propagation across edges below. */ - const bool need_direct_distance = BM_elem_flag_test(e, tag_loose) || - BM_elem_flag_test(v1, BM_ELEM_SELECT) || - BM_elem_flag_test(v2, BM_ELEM_SELECT); + /* Add adjacent loose edges to the queue, or all edges if this is a loose edge. + * Other edges are handled by propagation across edges below. */ BMEdge *e_other; BMIter eiter; BM_ITER_ELEM (e_other, &eiter, v2, BM_EDGES_OF_VERT) { if (e_other != e && BM_elem_flag_test(e_other, tag_queued) == 0 && !BM_elem_flag_test(e_other, BM_ELEM_HIDDEN) && - (need_direct_distance || BM_elem_flag_test(e_other, tag_loose))) + (BM_elem_flag_test(e, tag_loose) || BM_elem_flag_test(e_other, tag_loose))) { BM_elem_flag_enable(e_other, tag_queued); BLI_LINKSTACK_PUSH(queue_next, e_other); diff --git a/source/blender/editors/transform/transform_data.hh b/source/blender/editors/transform/transform_data.hh index c9d0afcfa10..bd5f96a4b84 100644 --- a/source/blender/editors/transform/transform_data.hh +++ b/source/blender/editors/transform/transform_data.hh @@ -138,9 +138,6 @@ struct TransData { TransDataCurveHandleFlags *hdata; /** If set, copy of Object or #bPoseChannel protection. */ short protectflag; - /** Local rotation accumulator for Trackball (is initialized) */ - short rotmtx_init; - float rotmtx[3][3]; }; #define TRANSDATA_THREAD_LIMIT 1024 diff --git a/source/blender/editors/transform/transform_mode_trackball.cc b/source/blender/editors/transform/transform_mode_trackball.cc index 3f7aa03a916..7550b2e5e38 100644 --- a/source/blender/editors/transform/transform_mode_trackball.cc +++ b/source/blender/editors/transform/transform_mode_trackball.cc @@ -53,18 +53,7 @@ static void transdata_elem_trackball(const TransInfo *t, float mat_buf[3][3]; const float(*mat)[3] = mat_final; if (t->flag & T_PROP_EDIT) { - if (UNLIKELY(!td->rotmtx_init)) { - unit_m3(td->rotmtx); - td->rotmtx_init = true; - } axis_angle_normalized_to_mat3(mat_buf, axis, td->factor * angle); - - /* Apply "continuous" trackball rotation. */ - if (U.uiflag & USER_ACCUMULATE_TRACKBALL) { - mul_m3_m3_post(mat_buf, td->rotmtx); - copy_m3_m3(td->rotmtx, mat_buf); - } - mat = mat_buf; } ElementRotation(t, tc, td, mat, t->around); @@ -107,16 +96,8 @@ static void applyTrackballValue(TransInfo *t, const float axis[3], const float a float mat_final[3][3]; int i; - /* Hack: Use otherwise-unused matrix storage for this */ - float (*mat_temp)[3] = t->orient[0].matrix; - axis_angle_normalized_to_mat3(mat_final, axis, angle); - if (U.uiflag & USER_ACCUMULATE_TRACKBALL) { - mul_m3_m3_post(mat_final, mat_temp); - copy_m3_m3(mat_temp, mat_final); - } - FOREACH_TRANS_DATA_CONTAINER (t, tc) { if (tc->data_len < TRANSDATA_THREAD_LIMIT) { TransData *td = tc->data; @@ -148,17 +129,8 @@ static void applyTrackball(TransInfo *t) size_t ofs = 0; float phi[2]; - /* Store previous mouse coordinates as (z,w) in the xyzw vector */ - float* phi_prev = t->values + 2; - copy_v2_v2(phi, t->values); - /* Get mouse delta only since phi_prev */ - if (U.uiflag & USER_ACCUMULATE_TRACKBALL) { - sub_v2_v2(phi, phi_prev); - copy_v2_v2(phi_prev, t->values); - } - transform_snap_increment(t, phi); applyNumInput(&t->num, phi); @@ -221,9 +193,6 @@ static void initTrackball(TransInfo *t, wmOperator * /*op*/) initMouseInputMode(t, &t->mouse, INPUT_TRACKBALL); - /* Initialize re-used matrix storage to I */ - unit_m3(t->orient[0].matrix); - t->idx_max = 1; t->num.idx_max = 1; t->snap[0] = DEG2RAD(5.0); diff --git a/source/blender/gpu/metal/mtl_memory.mm b/source/blender/gpu/metal/mtl_memory.mm index ec1f6dd8403..591d401bbd9 100644 --- a/source/blender/gpu/metal/mtl_memory.mm +++ b/source/blender/gpu/metal/mtl_memory.mm @@ -564,7 +564,6 @@ MTLSafeFreeList::MTLSafeFreeList() in_free_queue_ = false; current_list_index_ = 0; next_ = nullptr; - referenced_by_workload_ = false; } void MTLSafeFreeList::insert_buffer(gpu::MTLBuffer *buffer) diff --git a/source/blender/imbuf/IMB_imbuf_types.hh b/source/blender/imbuf/IMB_imbuf_types.hh index fa94dc9c379..629bf94fb1e 100644 --- a/source/blender/imbuf/IMB_imbuf_types.hh +++ b/source/blender/imbuf/IMB_imbuf_types.hh @@ -249,8 +249,6 @@ struct ImBuf { ImbFormatOptions foptions; /** The absolute file path associated with this image. */ char filepath[IMB_FILEPATH_SIZE]; - /* For movie files, the frame number loaded from the file. */ - int fileframe; /* memory cache limiter */ /** reference counter for multiple users */ diff --git a/source/blender/imbuf/intern/anim_movie.cc b/source/blender/imbuf/intern/anim_movie.cc index 36c8b77e1a0..a911eb4dac5 100644 --- a/source/blender/imbuf/intern/anim_movie.cc +++ b/source/blender/imbuf/intern/anim_movie.cc @@ -1291,8 +1291,7 @@ ImBuf *IMB_anim_absolute(ImBufAnim *anim, #endif if (ibuf) { - STRNCPY(ibuf->filepath, anim->filepath); - ibuf->fileframe = anim->cur_position + 1; + SNPRINTF(ibuf->filepath, "%s.%04d", anim->filepath, anim->cur_position + 1); } return ibuf; } diff --git a/source/blender/imbuf/intern/jpeg.cc b/source/blender/imbuf/intern/jpeg.cc index 8028e1ba304..4a2a3780917 100644 --- a/source/blender/imbuf/intern/jpeg.cc +++ b/source/blender/imbuf/intern/jpeg.cc @@ -587,7 +587,7 @@ static void write_jpeg(jpeg_compress_struct *cinfo, ImBuf *ibuf) * name and property value, followed by the nullptr-terminator * which isn't needed by JPEG but #BLI_snprintf_rlen requires it. */ const int text_length_required = 7 + 2 + strlen(prop->name) + strlen(IDP_String(prop)) + 1; - if (text_length_required > static_text_size) { + if (text_length_required <= static_text_size) { text = static_cast(MEM_mallocN(text_length_required, "jpeg metadata field")); text_size = text_length_required; } diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index bd36603c008..404996de613 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -967,7 +967,7 @@ static void read_edge_creases(Mesh *mesh, continue; } - creases[*index] = std::clamp((*sharpnesses)[s], 0.0f, 1.0f); + creases[*index] = unit_float_to_uchar_clamp((*sharpnesses)[s]); } } diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp index 99db17965a8..88bcb832a1c 100644 --- a/source/blender/io/collada/collada_utils.cpp +++ b/source/blender/io/collada/collada_utils.cpp @@ -287,14 +287,14 @@ Mesh *bc_get_mesh_copy(BlenderContext &blender_context, Mesh *mesh = BKE_mesh_copy_for_eval(*tmpmesh); - /* Ensure data exists if currently in edit mode. */ - BKE_mesh_wrapper_ensure_mdata(mesh); - if (triangulate) { bc_triangulate_mesh(mesh); } BKE_mesh_tessface_ensure(mesh); + /* Ensure data exists if currently in edit mode. */ + BKE_mesh_wrapper_ensure_mdata(mesh); + return mesh; } diff --git a/source/blender/io/usd/hydra/image.cc b/source/blender/io/usd/hydra/image.cc index e2fb198ff6b..c2f8433e8b1 100644 --- a/source/blender/io/usd/hydra/image.cc +++ b/source/blender/io/usd/hydra/image.cc @@ -31,16 +31,15 @@ static std::string cache_image_file( std::string file_path; ImageSaveOptions opts; if (BKE_image_save_options_init(&opts, bmain, scene, image, iuser, false, false)) { - const char *file_ext[BKE_IMAGE_PATH_EXT_MAX]; - file_ext[0] = BLI_path_extension_or_end(image->id.name); + char file_name[32]; + const char *r_ext = BLI_path_extension_or_end(image->id.name); if (!pxr::HioImageRegistry::GetInstance().IsSupportedImageFile(image->id.name)) { BKE_image_path_ext_from_imformat(&scene->r.im_format, &r_ext); BKE_image_format_free(&opts.im_format); BKE_image_format_copy(&opts.im_format, &scene->r.im_format); } - char file_name[FILE_MAX]; - SNPRINTF(file_name, "img_%p%s", image, file_ext[0]); + SNPRINTF(file_name, "img_%p%s", image, r_ext); file_path = blender::io::usd::get_image_cache_file(file_name); if (check_exist && BLI_exists(file_path.c_str())) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index f7cb714fdcf..32a1e71dafe 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1782,11 +1782,6 @@ enum { MOD_WVG_PROXIMITY_INVERT_VGROUP_MASK = (1 << 3), MOD_WVG_PROXIMITY_INVERT_FALLOFF = (1 << 4), MOD_WVG_PROXIMITY_WEIGHTS_NORMALIZE = (1 << 5), - /* Having an "all flags" name for geometry modes because these bits are accessed with RNA via a - different property and this makes it easier to do bit setting/testing. See - `rna_VertexWeightProximityModifier_proximity_geometry_set` in rna_modifier.cc */ - MOD_WVG_PROXIMITY_GEOM_ALL = (MOD_WVG_PROXIMITY_GEOM_VERTS | MOD_WVG_PROXIMITY_GEOM_EDGES | - MOD_WVG_PROXIMITY_GEOM_FACES), }; /* Defines common to all WeightVG modifiers. */ diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index a29d01bf9a9..55bee39e860 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -389,7 +389,7 @@ typedef struct wmWindow { /** * Input Method Editor data - complex character input (especially for Asian character input) - * Only used when `WITH_INPUT_IME` is defined, runtime-only data. + * Currently WIN32 and APPLE, runtime-only data. */ const struct wmIMEData *ime_data; char ime_data_is_composing; diff --git a/source/blender/makesdna/intern/dna_genfile.cc b/source/blender/makesdna/intern/dna_genfile.cc index 38f23ed65fc..ccd02361f6b 100644 --- a/source/blender/makesdna/intern/dna_genfile.cc +++ b/source/blender/makesdna/intern/dna_genfile.cc @@ -21,13 +21,13 @@ #include "MEM_guardedalloc.h" /* for MEM_freeN MEM_mallocN MEM_callocN */ #include "BLI_endian_switch.h" -#include "BLI_ghash.h" #include "BLI_math_matrix_types.hh" #include "BLI_memarena.h" -#include "BLI_set.hh" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" + #include "DNA_genfile.h" #include "DNA_sdna_types.h" /* for SDNA ;-) */ @@ -327,16 +327,10 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error /* Clear pointers in case of error. */ sdna->members = nullptr; sdna->types = nullptr; - sdna->types_size = nullptr; - sdna->types_alignment = nullptr; sdna->structs = nullptr; #ifdef WITH_DNA_GHASH sdna->types_to_structs_map = nullptr; #endif - - sdna->names = nullptr; - sdna->names_array_len = nullptr; - sdna->mem_arena = nullptr; /* Lazy initialize. */ @@ -365,7 +359,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error sdna->members = static_cast( MEM_callocN(sizeof(void *) * sdna->members_num, "sdnanames")); } - if (!sdna->names) { + else { *r_error_message = "NAME error in SDNA file"; return false; } @@ -405,7 +399,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error sdna->types = static_cast( MEM_callocN(sizeof(void *) * sdna->types_num, "sdnatypes")); } - if (!sdna->types) { + else { *r_error_message = "TYPE error in SDNA file"; return false; } @@ -436,7 +430,7 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error sp += sdna->types_num; } - if (!sdna->types_size) { + else { *r_error_message = "TLEN error in SDNA file"; return false; } @@ -459,13 +453,11 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error sdna->structs = static_cast( MEM_callocN(sizeof(SDNA_Struct *) * sdna->structs_num, "sdnastrcs")); } - if (!sdna->structs) { + else { *r_error_message = "STRC error in SDNA file"; return false; } - /* Safety check, to ensure that there is no multiple usages of a same struct index. */ - blender::Set struct_indices; sp = (short *)data; for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) { SDNA_Struct *struct_info = (SDNA_Struct *)sp; diff --git a/source/blender/makesrna/intern/rna_ID.cc b/source/blender/makesrna/intern/rna_ID.cc index a7e4965cc9d..91aad03db17 100644 --- a/source/blender/makesrna/intern/rna_ID.cc +++ b/source/blender/makesrna/intern/rna_ID.cc @@ -2668,10 +2668,12 @@ static void rna_def_library_weak_reference(BlenderRNA *brna) prop = RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, nullptr, "library_filepath"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file"); prop = RNA_def_property(srna, "id_name", PROP_STRING, PROP_FILEPATH); RNA_def_property_string_sdna(prop, nullptr, "library_id_name"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( prop, "ID name", diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index 849c23d9121..1fa3488ccb1 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -1689,7 +1689,7 @@ static void property_enum_translate(PropertyRNA *prop, const int *totitem, bool *r_free) { - if (!(RNA_property_flag(prop) & PROP_ENUM_NO_TRANSLATE)) { + if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) { int i; /* NOTE: Only do those tests once, and then use BLT_pgettext. */ @@ -1725,11 +1725,9 @@ static void property_enum_translate(PropertyRNA *prop, *r_free = true; } - const char *translation_context = RNA_property_translation_context(prop); - for (i = 0; nitem[i].identifier; i++) { if (nitem[i].name && do_iface) { - nitem[i].name = BLT_pgettext(translation_context, nitem[i].name); + nitem[i].name = BLT_pgettext(prop->translation_context, nitem[i].name); } if (nitem[i].description && do_tooltip) { nitem[i].description = BLT_pgettext(nullptr, nitem[i].description); @@ -1777,7 +1775,7 @@ void RNA_property_enum_items_gettexted_all(bContext *C, } if (eprop->item_fn != nullptr) { - const bool no_context = (eprop->property.flag & PROP_ENUM_NO_CONTEXT) || + const bool no_context = (prop->flag & PROP_ENUM_NO_CONTEXT) || ((ptr->type->flag & STRUCT_NO_CONTEXT_WITHOUT_OWNER_ID) && (ptr->owner_id == nullptr)); if (C != nullptr || no_context) { @@ -1999,7 +1997,7 @@ bool RNA_property_enum_name_gettexted( if (result) { if (!(prop->flag & PROP_ENUM_NO_TRANSLATE)) { - *r_name = BLT_translate_do_iface(RNA_property_translation_context(prop), *r_name); + *r_name = BLT_translate_do_iface(prop->translation_context, *r_name); } } @@ -2039,8 +2037,8 @@ bool RNA_property_enum_item_from_value_gettexted( { const bool result = RNA_property_enum_item_from_value(C, ptr, prop, value, r_item); - if (result && !(RNA_property_flag(prop) & PROP_ENUM_NO_TRANSLATE)) { - r_item->name = BLT_translate_do_iface(RNA_property_translation_context(prop), r_item->name); + if (result && !(prop->flag & PROP_ENUM_NO_TRANSLATE)) { + r_item->name = BLT_translate_do_iface(prop->translation_context, r_item->name); r_item->description = BLT_translate_do_tooltip(nullptr, r_item->description); } @@ -2068,7 +2066,7 @@ int RNA_property_enum_bitflag_identifiers( const char *RNA_property_ui_name(const PropertyRNA *prop) { - return CTX_IFACE_(RNA_property_translation_context(prop), rna_ensure_property_name(prop)); + return CTX_IFACE_(prop->translation_context, rna_ensure_property_name(prop)); } const char *RNA_property_ui_name_raw(const PropertyRNA *prop) diff --git a/source/blender/makesrna/intern/rna_access_compare_override.cc b/source/blender/makesrna/intern/rna_access_compare_override.cc index 5ff2461cf60..667bd8e874c 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.cc +++ b/source/blender/makesrna/intern/rna_access_compare_override.cc @@ -1427,14 +1427,6 @@ static bool override_apply_property_check_skip(Main *bmain, { UNUSED_VARS_NDEBUG(bmain, id_ptr_src); - // HACK: Specifically prevent overriding actions when Resync Enforce is used - if ((rnaapply_ctx.flag & RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS) != 0) { - StructRNA* rna_type = RNA_property_pointer_type(&rnaapply_ctx.ptr_dst, rnaapply_ctx.prop_dst); - if (RNA_struct_is_ID(rna_type) && RNA_type_to_ID_code(rna_type) == ID_AC) { - return false; - } - } - if ((rnaapply_ctx.flag & RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS) == 0) { return false; } diff --git a/source/blender/makesrna/intern/rna_fcurve.cc b/source/blender/makesrna/intern/rna_fcurve.cc index a53427301dc..e1fea4b1b4b 100644 --- a/source/blender/makesrna/intern/rna_fcurve.cc +++ b/source/blender/makesrna/intern/rna_fcurve.cc @@ -1078,7 +1078,7 @@ static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value) } static BezTriple *rna_FKeyframe_points_insert( - ID *id, FCurve *fcu, Main *bmain, float frame, float value, int flag, int keyframe_type) + ID *id, FCurve *fcu, Main *bmain, float frame, float value, int keyframe_type, int flag) { using namespace blender::animrig; KeyframeSettings settings = get_keyframe_settings(false); diff --git a/source/blender/makesrna/intern/rna_modifier.cc b/source/blender/makesrna/intern/rna_modifier.cc index 58eab6c1ee8..fd0cb56735e 100644 --- a/source/blender/makesrna/intern/rna_modifier.cc +++ b/source/blender/makesrna/intern/rna_modifier.cc @@ -2428,17 +2428,6 @@ static void rna_GreasePencilShrinkwrapModifier_face_cull_set(PointerRNA *ptr, in smd->shrink_opts = (smd->shrink_opts & ~MOD_SHRINKWRAP_CULL_TARGET_MASK) | value; } -static void rna_VertexWeightProximityModifier_proximity_geometry_set(PointerRNA *ptr, int value) -{ - WeightVGProximityModifierData *wpmd = reinterpret_cast( - ptr->data); - - /* The geometry mode shares the `proximity_flags` variable with a few other boolean properties, - * setting the mode value this way ensures only relevant bits are changed. */ - wpmd->proximity_flags = (wpmd->proximity_flags & (~MOD_WVG_PROXIMITY_GEOM_ALL)) | - (value & MOD_WVG_PROXIMITY_GEOM_ALL); -} - #else static void rna_def_modifier_panel_open_prop(StructRNA *srna, const char *identifier, const int id) @@ -6220,8 +6209,6 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna) RNA_def_property_enum_items(prop, proximity_geometry_items); RNA_def_property_flag(prop, PROP_ENUM_FLAG); /* important to run before default set */ RNA_def_property_enum_default(prop, MOD_WVG_PROXIMITY_GEOM_FACES); - RNA_def_property_enum_funcs( - prop, nullptr, "rna_VertexWeightProximityModifier_proximity_geometry_set", nullptr); RNA_def_property_ui_text(prop, "Proximity Geometry", "Use the shortest computed distance to target object's geometry " diff --git a/source/blender/makesrna/intern/rna_rna.cc b/source/blender/makesrna/intern/rna_rna.cc index 3856461f77b..ca44328825d 100644 --- a/source/blender/makesrna/intern/rna_rna.cc +++ b/source/blender/makesrna/intern/rna_rna.cc @@ -1570,24 +1570,16 @@ static void rna_property_override_diff_propptr(Main *bmain, if (opop == nullptr) { const char *subitem_refname = rna_itemname_b ? rna_itemname_b->c_str() : nullptr; const char *subitem_locname = rna_itemname_a ? rna_itemname_a->c_str() : nullptr; - opop = BKE_lib_override_library_property_operation_get(op, - LIBOVERRIDE_OP_REPLACE, - subitem_refname, - subitem_locname, - ptrdiff_ctx.rna_itemid_b, - ptrdiff_ctx.rna_itemid_a, - rna_itemindex_b, - rna_itemindex_a, - true, - nullptr, - &created); - /* Do not use BKE_lib_override_library_operations_tag here, we do not want to - * validate as used all of its operations. */ - op->tag &= ~LIBOVERRIDE_PROP_OP_TAG_UNUSED; + opop = BKE_lib_override_library_property_operation_find(op, + subitem_refname, + subitem_locname, + ptrdiff_ctx.rna_itemid_b, + ptrdiff_ctx.rna_itemid_a, + rna_itemindex_b, + rna_itemindex_a, + true, + nullptr); opop->tag &= ~LIBOVERRIDE_PROP_OP_TAG_UNUSED; - if (created) { - ptrdiff_ctx.rnadiff_ctx.report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; - } } BLI_assert(propptr_a->data == propptr_a->owner_id); diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index b4ff17b1376..67348f175ec 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -377,6 +377,19 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, Mesh *mesh) { using namespace blender; + if (mesh->verts_num == 0) { + /* Output just the start cap even if the mesh is empty. */ + Object *start_cap_ob = amd->start_cap; + if (start_cap_ob && start_cap_ob != ctx->object) { + Mesh *start_cap_mesh = BKE_modifier_get_evaluated_mesh_from_evaluated_object(start_cap_ob); + if (start_cap_mesh) { + BKE_mesh_wrapper_ensure_mdata(start_cap_mesh); + return BKE_mesh_copy_for_eval(*start_cap_mesh); + } + } + return mesh; + } + int2 *edge; int i, j, c, count; float length = amd->length; @@ -615,11 +628,9 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } /* adjust edge vertex indices */ - if (chunk_nedges) { - edge = &result_edges[c * chunk_nedges]; - for (i = 0; i < chunk_nedges; i++, edge++) { - (*edge) += c * chunk_nverts; - } + edge = &result_edges[c * chunk_nedges]; + for (i = 0; i < chunk_nedges; i++, edge++) { + (*edge) += c * chunk_nverts; } for (i = 0; i < chunk_nfaces; i++) { diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 912212589cd..79239c92717 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1878,14 +1878,7 @@ static Mesh *modify_mesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh modifyGeometry(md, ctx, geometry_set); - bke::MeshComponent &mesh_component = geometry_set.get_component_for_write(); - if (mesh_component.get() != mesh) { - /* If this is the same as the input mesh, it's not necessary to make a copy of it even if it's - * not owned by the geometry set. That's because we know that the caller manages the ownership - * of the mesh. */ - mesh_component.ensure_owns_direct_data(); - } - Mesh *new_mesh = mesh_component.release(); + Mesh *new_mesh = geometry_set.get_component_for_write().release(); if (new_mesh == nullptr) { return BKE_mesh_new_nomain(0, 0, 0, 0); } diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 18bc824ac86..24c21b66c82 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -5858,13 +5858,13 @@ const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_gr } for (const bNodeTreeInterfaceSocket *interface_bsocket : btree.interface_inputs()) { const bke::bNodeSocketType *typeinfo = interface_bsocket->socket_typeinfo(); - if (!typeinfo || !typeinfo->geometry_nodes_cpp_type) { + if (typeinfo->geometry_nodes_cpp_type == nullptr) { return nullptr; } } for (const bNodeTreeInterfaceSocket *interface_bsocket : btree.interface_outputs()) { const bke::bNodeSocketType *typeinfo = interface_bsocket->socket_typeinfo(); - if (!typeinfo || !typeinfo->geometry_nodes_cpp_type) { + if (typeinfo->geometry_nodes_cpp_type == nullptr) { return nullptr; } } diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.cc b/source/blender/python/bmesh/bmesh_py_ops_call.cc index 624e4d02e98..d5a2e6b02ad 100644 --- a/source/blender/python/bmesh/bmesh_py_ops_call.cc +++ b/source/blender/python/bmesh/bmesh_py_ops_call.cc @@ -548,12 +548,11 @@ static int bpy_slot_from_py(BMesh *bm, break; } case BMO_OP_SLOT_SUBTYPE_MAP_EMPTY: { - if (PySet_GET_SIZE(value) > 0) { - PyObject *it = PyObject_GetIter(value); + if (PySet_Size(value) > 0) { PyObject *arg_key; - while ((arg_key = PyIter_Next(it))) { - /* Borrow from the set. */ - Py_DECREF(arg_key); + Py_ssize_t arg_pos = 0; + Py_ssize_t arg_hash = 0; + while (_PySet_NextEntry(value, &arg_pos, &arg_key, &arg_hash)) { if (bpy_slot_from_py_elem_check((BPy_BMElem *)arg_key, bm, @@ -562,16 +561,11 @@ static int bpy_slot_from_py(BMesh *bm, slot_name, "invalid key in set") == -1) { - /* Error is set in #bpy_slot_from_py_elem_check(). */ - break; + return -1; /* error is set in bpy_slot_from_py_elem_check() */ } BMO_slot_map_empty_insert(bmop, slot, ((BPy_BMElem *)arg_key)->ele); } - Py_DECREF(it); - if (arg_key) { - return -1; - } } break; } diff --git a/source/blender/python/generic/imbuf_py_api.cc b/source/blender/python/generic/imbuf_py_api.cc index 87bce257b8b..3b50d79c753 100644 --- a/source/blender/python/generic/imbuf_py_api.cc +++ b/source/blender/python/generic/imbuf_py_api.cc @@ -495,7 +495,7 @@ static PyObject *M_imbuf_new(PyObject * /*self*/, PyObject *args, PyObject *kw) } /* TODO: make options. */ - const uchar planes = 32; + const uchar planes = 4; const uint flags = IB_rect; ImBuf *ibuf = IMB_allocImBuf(UNPACK2(size), planes, flags); diff --git a/source/blender/python/generic/py_capi_rna.cc b/source/blender/python/generic/py_capi_rna.cc index a41e474f619..11827fa0836 100644 --- a/source/blender/python/generic/py_capi_rna.cc +++ b/source/blender/python/generic/py_capi_rna.cc @@ -75,66 +75,60 @@ BLI_bitmap *pyrna_enum_bitmap_from_set(const EnumPropertyItem *items, int bitmap_size, const char *error_prefix) { - BLI_assert(PySet_Check(value)); + /* Set looping. */ + Py_ssize_t pos = 0; + Py_ssize_t hash = 0; + PyObject *key; + BLI_bitmap *bitmap = BLI_BITMAP_NEW(bitmap_size, __func__); - if (PySet_GET_SIZE(value) > 0) { - /* Set looping. */ - PyObject *it = PyObject_GetIter(value); - PyObject *key; - while ((key = PyIter_Next(it))) { - /* Borrow from the set. */ - Py_DECREF(key); - - const char *param = PyUnicode_AsUTF8(key); - if (param == nullptr) { - PyErr_Format(PyExc_TypeError, - "%.200s expected a string, not %.200s", - error_prefix, - Py_TYPE(key)->tp_name); - break; - } - - int ret; - if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { - break; - } - - int index = ret; - - if (type_convert_sign) { - if (type_size == 2) { - union { - signed short as_signed; - ushort as_unsigned; - } ret_convert; - ret_convert.as_signed = (signed short)ret; - index = int(ret_convert.as_unsigned); - } - else if (type_size == 1) { - union { - signed char as_signed; - uchar as_unsigned; - } ret_convert; - ret_convert.as_signed = (signed char)ret; - index = int(ret_convert.as_unsigned); - } - else { - BLI_assert_unreachable(); - } - } - BLI_assert(index < bitmap_size); - BLI_BITMAP_ENABLE(bitmap, index); + while (_PySet_NextEntry(value, &pos, &key, &hash)) { + const char *param = PyUnicode_AsUTF8(key); + if (param == nullptr) { + PyErr_Format(PyExc_TypeError, + "%.200s expected a string, not %.200s", + error_prefix, + Py_TYPE(key)->tp_name); + goto error; } - Py_DECREF(it); - if (key) { - MEM_freeN(bitmap); - bitmap = nullptr; + int ret; + if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { + goto error; } + + int index = ret; + + if (type_convert_sign) { + if (type_size == 2) { + union { + signed short as_signed; + ushort as_unsigned; + } ret_convert; + ret_convert.as_signed = (signed short)ret; + index = int(ret_convert.as_unsigned); + } + else if (type_size == 1) { + union { + signed char as_signed; + uchar as_unsigned; + } ret_convert; + ret_convert.as_signed = (signed char)ret; + index = int(ret_convert.as_unsigned); + } + else { + BLI_assert_unreachable(); + } + } + BLI_assert(index < bitmap_size); + BLI_BITMAP_ENABLE(bitmap, index); } return bitmap; + +error: + MEM_freeN(bitmap); + return nullptr; } int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items, @@ -142,40 +136,32 @@ int pyrna_enum_bitfield_from_set(const EnumPropertyItem *items, int *r_value, const char *error_prefix) { - BLI_assert(PySet_Check(value)); /* Set of enum items, concatenate all values with OR. */ - int flag = 0; + int ret, flag = 0; + + /* Set looping. */ + Py_ssize_t pos = 0; + Py_ssize_t hash = 0; + PyObject *key; *r_value = 0; - PyObject *key = nullptr; - if (PySet_GET_SIZE(value) > 0) { - /* Set looping. */ - PyObject *it = PyObject_GetIter(value); - while ((key = PyIter_Next(it))) { - /* Borrow from the set. */ - Py_DECREF(key); + while (_PySet_NextEntry(value, &pos, &key, &hash)) { + const char *param = PyUnicode_AsUTF8(key); - const char *param = PyUnicode_AsUTF8(key); - if (param == nullptr) { - PyErr_Format(PyExc_TypeError, - "%.200s expected a string, not %.200s", - error_prefix, - Py_TYPE(key)->tp_name); - break; - } - - int ret; - if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { - break; - } - - flag |= ret; - } - Py_DECREF(it); - if (key) { + if (param == nullptr) { + PyErr_Format(PyExc_TypeError, + "%.200s expected a string, not %.200s", + error_prefix, + Py_TYPE(key)->tp_name); return -1; } + + if (pyrna_enum_value_from_id(items, param, &ret, error_prefix) == -1) { + return -1; + } + + flag |= ret; } *r_value = flag; diff --git a/source/blender/python/generic/py_capi_utils.cc b/source/blender/python/generic/py_capi_utils.cc index c3a7a945a8b..3311064e7c5 100644 --- a/source/blender/python/generic/py_capi_utils.cc +++ b/source/blender/python/generic/py_capi_utils.cc @@ -39,12 +39,6 @@ # include "BLI_math_base.h" /* isfinite() */ #endif -#include "float.h" /* FLT_MAX */ -#if PY_VERSION_HEX < 0x030d0000 /* <3.13 */ -# define PyLong_AsInt _PyLong_AsInt -# define PyUnicode_CompareWithASCIIString _PyUnicode_EqualToASCIIString -#endif - /* -------------------------------------------------------------------- */ /** \name Fast Python to C Array Conversion for Primitive Types * \{ */ @@ -880,12 +874,10 @@ static void pyc_exception_buffer_handle_system_exit() if (!PyErr_ExceptionMatches(PyExc_SystemExit)) { return; } -/* Inspecting, follow Python's logic in #_Py_HandleSystemExit & treat as a regular exception. */ -# if 0 /* FIXME: */ + /* Inspecting, follow Python's logic in #_Py_HandleSystemExit & treat as a regular exception. */ if (_Py_GetConfig()->inspect) { return; } -# endif /* NOTE(@ideasman42): A `SystemExit` exception will exit immediately (unless inspecting). * So print the error and exit now. Without this #PyErr_Display shows the error stack-trace @@ -1432,6 +1424,11 @@ int PyC_FlagSet_ToBitfield(const PyC_FlagSet *items, /* set of enum items, concatenate all values with OR */ int ret, flag = 0; + /* set looping */ + Py_ssize_t pos = 0; + Py_ssize_t hash = 0; + PyObject *key; + if (!PySet_Check(value)) { PyErr_Format(PyExc_TypeError, "%.200s expected a set, not %.200s", @@ -1442,32 +1439,22 @@ int PyC_FlagSet_ToBitfield(const PyC_FlagSet *items, *r_value = 0; - if (PySet_GET_SIZE(value) > 0) { - PyObject *it = PyObject_GetIter(value); - PyObject *key; - while ((key = PyIter_Next(it))) { - /* Borrow from the set. */ - Py_DECREF(key); + while (_PySet_NextEntry(value, &pos, &key, &hash)) { + const char *param = PyUnicode_AsUTF8(key); - const char *param = PyUnicode_AsUTF8(key); - if (param == nullptr) { - PyErr_Format(PyExc_TypeError, - "%.200s set must contain strings, not %.200s", - error_prefix, - Py_TYPE(key)->tp_name); - break; - } - - if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) { - break; - } - - flag |= ret; - } - Py_DECREF(it); - if (key != nullptr) { + if (param == nullptr) { + PyErr_Format(PyExc_TypeError, + "%.200s set must contain strings, not %.200s", + error_prefix, + Py_TYPE(key)->tp_name); return -1; } + + if (PyC_FlagSet_ValueFromID(items, param, &ret, error_prefix) < 0) { + return -1; + } + + flag |= ret; } *r_value = flag; @@ -1569,11 +1556,8 @@ bool PyC_RunString_AsNumber(const char *imports[], ok = false; } else if (!isfinite(val)) { - if (val > 0.0) { - *r_value = FLT_MAX; - } else { - *r_value = -FLT_MAX; - } + *r_value = 0.0; + ok = true; } else { *r_value = val; @@ -1740,7 +1724,7 @@ static ulong pyc_Long_AsUnsignedLong(PyObject *value) int PyC_Long_AsBool(PyObject *value) { - const int test = PyLong_AsInt(value); + const int test = _PyLong_AsInt(value); if (UNLIKELY(test == -1 && PyErr_Occurred())) { return -1; } @@ -1753,7 +1737,7 @@ int PyC_Long_AsBool(PyObject *value) int8_t PyC_Long_AsI8(PyObject *value) { - const int test = PyLong_AsInt(value); + const int test = _PyLong_AsInt(value); if (UNLIKELY(test == -1 && PyErr_Occurred())) { return -1; } @@ -1766,7 +1750,7 @@ int8_t PyC_Long_AsI8(PyObject *value) int16_t PyC_Long_AsI16(PyObject *value) { - const int test = PyLong_AsInt(value); + const int test = _PyLong_AsInt(value); if (UNLIKELY(test == -1 && PyErr_Occurred())) { return -1; } diff --git a/source/blender/python/generic/py_capi_utils.hh b/source/blender/python/generic/py_capi_utils.hh index 29222d35c2c..4a641f78471 100644 --- a/source/blender/python/generic/py_capi_utils.hh +++ b/source/blender/python/generic/py_capi_utils.hh @@ -339,11 +339,7 @@ uint64_t PyC_Long_AsU64(PyObject *value); /* inline so type signatures match as expected */ Py_LOCAL_INLINE(int32_t) PyC_Long_AsI32(PyObject *value) { -#if PY_VERSION_HEX < 0x030d0000 /* <3.13 */ return (int32_t)_PyLong_AsInt(value); -#else - return (int32_t)PyLong_AsInt(value); -#endif } Py_LOCAL_INLINE(int64_t) PyC_Long_AsI64(PyObject *value) { diff --git a/source/blender/python/generic/python_compat.hh b/source/blender/python/generic/python_compat.hh index 6a973b7c80e..f18d0fb59b3 100644 --- a/source/blender/python/generic/python_compat.hh +++ b/source/blender/python/generic/python_compat.hh @@ -10,6 +10,7 @@ #pragma once /* Add `intialized` member for Python 3.12+. */ +#if PY_VERSION_HEX >= 0x030c0000 # define PY_ARG_PARSER_HEAD_COMPAT() 0, #else # define PY_ARG_PARSER_HEAD_COMPAT() diff --git a/source/blender/python/gpu/gpu_py_framebuffer.cc b/source/blender/python/gpu/gpu_py_framebuffer.cc index ae4de5bfd65..77832f2e2ef 100644 --- a/source/blender/python/gpu/gpu_py_framebuffer.cc +++ b/source/blender/python/gpu/gpu_py_framebuffer.cc @@ -286,14 +286,14 @@ static bool pygpu_framebuffer_new_parse_arg(PyObject *o, GPUAttachment *r_attach return false; } - if (c_texture && PyUnicode_CompareWithASCIIString(key, c_texture)) { + if (c_texture && _PyUnicode_EqualToASCIIString(key, c_texture)) { /* Compare only once. */ c_texture = nullptr; if (!bpygpu_ParseTexture(value, &tmp_attach.tex)) { return false; } } - else if (c_layer && PyUnicode_CompareWithASCIIString(key, c_layer)) { + else if (c_layer && _PyUnicode_EqualToASCIIString(key, c_layer)) { /* Compare only once. */ c_layer = nullptr; tmp_attach.layer = PyLong_AsLong(value); @@ -301,7 +301,7 @@ static bool pygpu_framebuffer_new_parse_arg(PyObject *o, GPUAttachment *r_attach return false; } } - else if (c_mip && PyUnicode_CompareWithASCIIString(key, c_mip)) { + else if (c_mip && _PyUnicode_EqualToASCIIString(key, c_mip)) { /* Compare only once. */ c_mip = nullptr; tmp_attach.mip = PyLong_AsLong(value); diff --git a/source/blender/python/intern/bpy.cc b/source/blender/python/intern/bpy.cc index be3c5226378..685874dfc43 100644 --- a/source/blender/python/intern/bpy.cc +++ b/source/blender/python/intern/bpy.cc @@ -609,40 +609,38 @@ PyDoc_STRVAR( " :rtype: dict[str, bool]\n"); static PyObject *bpy_wm_capabilities(PyObject *self) { - PyObject *py_id_capabilities = PyUnicode_FromString("_wm_capabilities_"); - PyObject *result = nullptr; - switch (PyObject_GetOptionalAttr(self, py_id_capabilities, &result)) { - case 1: { - result = PyDict_New(); + static _Py_Identifier PyId_capabilities = {"_wm_capabilities_", -1}; - const eWM_CapabilitiesFlag flag = WM_capabilities_flag(); + PyObject *result = nullptr; + switch (_PyObject_LookupAttrId(self, &PyId_capabilities, &result)) { + case 1: + return result; + case 0: + break; + default: + /* Unlikely, but there may be an error, forward it. */ + return nullptr; + } + + result = PyDict_New(); + + const eWM_CapabilitiesFlag flag = WM_capabilities_flag(); #define SetFlagItem(x) \ PyDict_SetItemString(result, STRINGIFY(x), PyBool_FromLong((WM_CAPABILITY_##x) & flag)); - SetFlagItem(CURSOR_WARP); - SetFlagItem(WINDOW_POSITION); - SetFlagItem(PRIMARY_CLIPBOARD); - SetFlagItem(GPU_FRONT_BUFFER_READ); - SetFlagItem(CLIPBOARD_IMAGES); - SetFlagItem(DESKTOP_SAMPLE); - SetFlagItem(INPUT_IME); - SetFlagItem(TRACKPAD_PHYSICAL_DIRECTION); + SetFlagItem(CURSOR_WARP); + SetFlagItem(WINDOW_POSITION); + SetFlagItem(PRIMARY_CLIPBOARD); + SetFlagItem(GPU_FRONT_BUFFER_READ); + SetFlagItem(CLIPBOARD_IMAGES); + SetFlagItem(DESKTOP_SAMPLE); + SetFlagItem(INPUT_IME); + SetFlagItem(TRACKPAD_PHYSICAL_DIRECTION); #undef SetFlagItem - PyObject_SetAttr(self, py_id_capabilities, result); - break; - } - case 0: - BLI_assert(result != nullptr); - break; - default: - /* Unlikely, but there may be an error, forward it. */ - BLI_assert(result == nullptr); - break; - } - Py_DECREF(py_id_capabilities); + _PyObject_SetAttrId(self, &PyId_capabilities, result); return result; } diff --git a/source/blender/python/intern/bpy_app_translations.cc b/source/blender/python/intern/bpy_app_translations.cc index f33af66aa1c..ee028169d2b 100644 --- a/source/blender/python/intern/bpy_app_translations.cc +++ b/source/blender/python/intern/bpy_app_translations.cc @@ -887,7 +887,7 @@ PyDoc_STRVAR( "\n"); static PyTypeObject BlenderAppTranslationsType = { /*ob_base*/ PyVarObject_HEAD_INIT(nullptr, 0) - /*tp_name*/ "bpy_app_translations", + /*tp_name*/ "bpy.app._translations_type", /*tp_basicsize*/ sizeof(BlenderAppTranslations), /*tp_itemsize*/ 0, /*tp_dealloc*/ nullptr, diff --git a/source/blender/python/intern/bpy_driver.cc b/source/blender/python/intern/bpy_driver.cc index 96c10752782..b32bfbc2a56 100644 --- a/source/blender/python/intern/bpy_driver.cc +++ b/source/blender/python/intern/bpy_driver.cc @@ -43,13 +43,6 @@ # include #endif -#if PY_VERSION_HEX >= 0x030d0000 /* >=3.13 */ -/* WARNING(@ideasman42): Using `Py_BUILD_CORE` is a last resort, - * the alternative would be not to inspect OP-CODES at all. */ -# define Py_BUILD_CORE -# include -#endif - PyObject *bpy_pydriver_Dict = nullptr; #ifdef USE_BYTECODE_WHITELIST @@ -382,35 +375,7 @@ static bool is_opcode_secure(const int opcode) OK_OP(LOAD_CONST) /* Ok because constants are accepted. */ OK_OP(LOAD_NAME) /* Ok, because `PyCodeObject.names` is checked. */ OK_OP(CALL) /* Ok, because we check its "name" before calling. */ -# if PY_VERSION_HEX >= 0x030d0000 - OK_OP(CALL_KW) /* Ok, because it's used for calling functions with keyword arguments. */ - - OK_OP(CALL_FUNCTION_EX); - - /* OK because the names are checked. */ - OK_OP(CALL_ALLOC_AND_ENTER_INIT) - OK_OP(CALL_BOUND_METHOD_EXACT_ARGS) - OK_OP(CALL_BOUND_METHOD_GENERAL) - OK_OP(CALL_BUILTIN_CLASS) - OK_OP(CALL_BUILTIN_FAST) - OK_OP(CALL_BUILTIN_FAST_WITH_KEYWORDS) - OK_OP(CALL_BUILTIN_O) - OK_OP(CALL_ISINSTANCE) - OK_OP(CALL_LEN) - OK_OP(CALL_LIST_APPEND) - OK_OP(CALL_METHOD_DESCRIPTOR_FAST) - OK_OP(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) - OK_OP(CALL_METHOD_DESCRIPTOR_NOARGS) - OK_OP(CALL_METHOD_DESCRIPTOR_O) - OK_OP(CALL_NON_PY_GENERAL) - OK_OP(CALL_PY_EXACT_ARGS) - OK_OP(CALL_PY_GENERAL) - OK_OP(CALL_STR_1) - OK_OP(CALL_TUPLE_1) - OK_OP(CALL_TYPE_1) -# else - OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */ -# endif + OK_OP(KW_NAMES) /* Ok, because it's used for calling functions with keyword arguments. */ # if PY_VERSION_HEX < 0x030c0000 OK_OP(PRECALL) /* Ok, because it's used for calling. */ @@ -618,6 +583,7 @@ float BPY_driver_exec(PathResolvedRNA *anim_rna, /* Maybe this can be removed but for now best keep until were sure. */ driver_orig->flag |= DRIVER_FLAG_RENAMEVAR; driver_orig->flag &= ~DRIVER_FLAG_PYTHON_BLOCKED; + #ifdef USE_BYTECODE_WHITELIST is_recompile = true; #endif diff --git a/source/blender/python/intern/bpy_library_write.cc b/source/blender/python/intern/bpy_library_write.cc index e68cc73a32a..b6308a3c02d 100644 --- a/source/blender/python/intern/bpy_library_write.cc +++ b/source/blender/python/intern/bpy_library_write.cc @@ -149,7 +149,6 @@ static PyObject *bpy_lib_write(BPy_PropertyRNA *self, PyObject *args, PyObject * else { partial_write_ctx.id_add(id, add_options, nullptr); } - Py_DECREF(it); } BLI_assert(partial_write_ctx.is_valid()); diff --git a/source/blender/python/intern/bpy_msgbus.cc b/source/blender/python/intern/bpy_msgbus.cc index c7e38f69a8a..dfab20a2de7 100644 --- a/source/blender/python/intern/bpy_msgbus.cc +++ b/source/blender/python/intern/bpy_msgbus.cc @@ -143,10 +143,6 @@ static void bpy_msgbus_notify(bContext *C, { PyGILState_STATE gilstate; bpy_context_set(C, &gilstate); - const bool is_write_ok = pyrna_write_check(); - if (!is_write_ok) { - pyrna_write_set(true); - } PyObject *user_data = static_cast(msg_val->user_data); BLI_assert(PyTuple_GET_SIZE(user_data) == BPY_MSGBUS_USER_DATA_LEN); @@ -154,6 +150,11 @@ static void bpy_msgbus_notify(bContext *C, PyObject *callback_args = PyTuple_GET_ITEM(user_data, 0); PyObject *callback_notify = PyTuple_GET_ITEM(user_data, 1); + const bool is_write_ok = pyrna_write_check(); + if (!is_write_ok) { + pyrna_write_set(true); + } + PyObject *ret = PyObject_CallObject(callback_notify, callback_args); if (ret == nullptr) { @@ -167,10 +168,11 @@ static void bpy_msgbus_notify(bContext *C, Py_DECREF(ret); } + bpy_context_clear(C, &gilstate); + if (!is_write_ok) { pyrna_write_set(false); } - bpy_context_clear(C, &gilstate); } /* Follow wmMsgSubscribeValueFreeDataFn spec */ diff --git a/source/blender/python/intern/bpy_props.cc b/source/blender/python/intern/bpy_props.cc index d8f9dacc3d1..abb56eea193 100644 --- a/source/blender/python/intern/bpy_props.cc +++ b/source/blender/python/intern/bpy_props.cc @@ -414,33 +414,6 @@ static void bpy_prop_assign_flag_override(PropertyRNA *prop, const int flag_over RNA_def_property_override_flag(prop, PropertyOverrideFlag(flag_override)); } -/* These utility functions de-duplicate boiler plate code used by most property callbacks. - * It's important they're at the beginning & end of the callbacks and both are always called. */ - -struct BPyPropGIL_RNAWritable_State { - PyGILState_STATE gilstate; - bool is_write_ok; -}; - -static BPyPropGIL_RNAWritable_State bpy_prop_gil_rna_writable_begin() -{ - /* It's important to acquire the lock before reading other state information, see: #127767. */ - const PyGILState_STATE gilstate = PyGILState_Ensure(); - const bool is_write_ok = pyrna_write_check(); - return { - /*gilstate*/ gilstate, - /*is_write_ok*/ is_write_ok, - }; -} - -static void bpy_prop_gil_rna_writable_end(const BPyPropGIL_RNAWritable_State &prop_state) -{ - if (!prop_state.is_write_ok) { - pyrna_write_set(false); - } - PyGILState_Release(prop_state.gilstate); -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -594,21 +567,22 @@ static void bpy_prop_array_matrix_swap_row_column_vn(float *values, /* callbacks */ static void bpy_prop_update_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop) { - PyGILState_STATE gilstate; - bpy_context_set(C, &gilstate); - const bool is_write_ok = pyrna_write_check(); - if (!is_write_ok) { - pyrna_write_set(true); - } - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); + PyGILState_STATE gilstate; PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + bpy_context_set(C, &gilstate); + py_func = prop_store->py_data.update_fn; args = PyTuple_New(2); @@ -634,11 +608,11 @@ static void bpy_prop_update_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } + bpy_context_clear(C, &gilstate); + if (!is_write_ok) { pyrna_write_set(false); } - - bpy_context_clear(C, &gilstate); } /** \} */ @@ -649,17 +623,28 @@ static void bpy_prop_update_fn(bContext *C, PointerRNA *ptr, PropertyRNA *prop) static bool bpy_prop_boolean_get_fn(PointerRNA *ptr, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); bool value; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -688,23 +673,40 @@ static bool bpy_prop_boolean_get_fn(PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } return value; } static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -729,19 +731,25 @@ static void bpy_prop_boolean_set_fn(PointerRNA *ptr, PropertyRNA *prop, bool val Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bool *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); bool is_values_set = false; int i, len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; @@ -750,6 +758,16 @@ static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bo BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -783,20 +801,26 @@ static void bpy_prop_boolean_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, bo } } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const bool *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; PyObject *py_values; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); const int len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; array_len_info.len_total = len; @@ -804,6 +828,16 @@ static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, co BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -835,7 +869,13 @@ static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, co Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } /** \} */ @@ -846,18 +886,28 @@ static void bpy_prop_boolean_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, co static int bpy_prop_int_get_fn(PointerRNA *ptr, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); int value; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -883,23 +933,40 @@ static int bpy_prop_int_get_fn(PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } return value; } static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -924,19 +991,25 @@ static void bpy_prop_int_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); bool is_values_set = false; int i, len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; @@ -945,6 +1018,16 @@ static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *v BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -978,20 +1061,26 @@ static void bpy_prop_int_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, int *v } } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const int *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; PyObject *py_values; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); const int len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; array_len_info.len_total = len; @@ -999,6 +1088,16 @@ static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -1031,7 +1130,13 @@ static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } /** \} */ @@ -1042,18 +1147,28 @@ static void bpy_prop_int_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const static float bpy_prop_float_get_fn(PointerRNA *ptr, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); float value; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -1079,23 +1194,40 @@ static float bpy_prop_float_get_fn(PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } return value; } static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -1120,19 +1252,25 @@ static void bpy_prop_float_set_fn(PointerRNA *ptr, PropertyRNA *prop, float valu Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, float *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); bool is_values_set = false; int i, len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; @@ -1141,6 +1279,16 @@ static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, floa BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -1178,20 +1326,26 @@ static void bpy_prop_float_array_get_fn(PointerRNA *ptr, PropertyRNA *prop, floa } } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, const float *values) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; PyObject *py_values; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); const int len = RNA_property_array_length(ptr, prop); BPyPropArrayLength array_len_info{}; array_len_info.len_total = len; @@ -1199,6 +1353,16 @@ static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, cons BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -1231,7 +1395,13 @@ static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, cons Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } /** \} */ @@ -1242,16 +1412,27 @@ static void bpy_prop_float_array_set_fn(PointerRNA *ptr, PropertyRNA *prop, cons static void bpy_prop_string_get_fn(PointerRNA *ptr, PropertyRNA *prop, char *value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -1280,23 +1461,39 @@ static void bpy_prop_string_get_fn(PointerRNA *ptr, PropertyRNA *prop, char *val Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static int bpy_prop_string_length_fn(PointerRNA *ptr, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); int length; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -1325,25 +1522,41 @@ static int bpy_prop_string_length_fn(PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } return length; } static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const char *value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); PyObject *py_value; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -1375,7 +1588,13 @@ static void bpy_prop_string_set_fn(PointerRNA *ptr, PropertyRNA *prop, const cha Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } static bool bpy_prop_string_visit_fn_call( @@ -1432,7 +1651,16 @@ static void bpy_prop_string_visit_for_search_fn( const char *edit_text, blender::FunctionRef visit_fn) { + BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); + PyObject *py_func; + PyObject *args; + PyObject *self; + PyObject *ret; PyGILState_STATE gilstate; + PyObject *py_edit_text; + + BLI_assert(prop_store != nullptr); + if (C) { bpy_context_set((bContext *)C, &gilstate); } @@ -1440,15 +1668,6 @@ static void bpy_prop_string_visit_for_search_fn( gilstate = PyGILState_Ensure(); } - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); - PyObject *py_func; - PyObject *args; - PyObject *self; - PyObject *ret; - PyObject *py_edit_text; - - BLI_assert(prop_store != nullptr); - py_func = prop_store->py_data.string_data.search_fn; args = PyTuple_New(3); @@ -1542,8 +1761,6 @@ static void bpy_prop_string_visit_for_search_fn( static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_self; PyObject *py_candidate; @@ -1551,6 +1768,8 @@ static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, Pro PyObject *args; PyObject *ret; bool result; + const int is_write_ok = pyrna_write_check(); + const PyGILState_STATE gilstate = PyGILState_Ensure(); BLI_assert(self != nullptr); @@ -1558,6 +1777,10 @@ static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, Pro py_candidate = pyrna_struct_as_instance(&candidate); py_func = prop_store->py_data.pointer_data.poll_fn; + if (!is_write_ok) { + pyrna_write_set(true); + } + args = PyTuple_New(2); PyTuple_SET_ITEM(args, 0, py_self); PyTuple_SET_ITEM(args, 1, py_candidate); @@ -1575,7 +1798,10 @@ static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, Pro Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + PyGILState_Release(gilstate); + if (!is_write_ok) { + pyrna_write_set(false); + } return result; } @@ -1588,18 +1814,28 @@ static bool bpy_prop_pointer_poll_fn(PointerRNA *self, PointerRNA candidate, Pro static int bpy_prop_enum_get_fn(PointerRNA *ptr, PropertyRNA *prop) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; - + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); int value; BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.get_fn; args = PyTuple_New(1); @@ -1625,23 +1861,40 @@ static int bpy_prop_enum_get_fn(PointerRNA *ptr, PropertyRNA *prop) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } return value; } static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value) { - const BPyPropGIL_RNAWritable_State bpy_state = bpy_prop_gil_rna_writable_begin(); - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func; PyObject *args; PyObject *self; PyObject *ret; + PyGILState_STATE gilstate; + bool use_gil; + const bool is_write_ok = pyrna_write_check(); BLI_assert(prop_store != nullptr); + if (!is_write_ok) { + pyrna_write_set(true); + } + + use_gil = true; /* !PyC_IsInterpreterActive(); */ + + if (use_gil) { + gilstate = PyGILState_Ensure(); + } + py_func = prop_store->py_data.set_fn; args = PyTuple_New(2); @@ -1666,7 +1919,13 @@ static void bpy_prop_enum_set_fn(PointerRNA *ptr, PropertyRNA *prop, int value) Py_DECREF(ret); } - bpy_prop_gil_rna_writable_end(bpy_state); + if (use_gil) { + PyGILState_Release(gilstate); + } + + if (!is_write_ok) { + pyrna_write_set(false); + } } /* utility function we need for parsing int's in an if statement */ @@ -1896,13 +2155,6 @@ static const EnumPropertyItem *bpy_prop_enum_itemf_fn(bContext *C, bool *r_free) { PyGILState_STATE gilstate; - if (C) { - bpy_context_set(C, &gilstate); - } - else { - gilstate = PyGILState_Ensure(); - } - BPyPropStore *prop_store = static_cast(RNA_property_py_data_get(prop)); PyObject *py_func = prop_store->py_data.enum_data.itemf_fn; PyObject *self = nullptr; @@ -1912,6 +2164,13 @@ static const EnumPropertyItem *bpy_prop_enum_itemf_fn(bContext *C, const EnumPropertyItem *eitems = nullptr; int err = 0; + if (C) { + bpy_context_set(C, &gilstate); + } + else { + gilstate = PyGILState_Ensure(); + } + args = PyTuple_New(2); self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); diff --git a/source/blender/python/intern/bpy_rna.cc b/source/blender/python/intern/bpy_rna.cc index 959065ba829..bc6866ee8f4 100644 --- a/source/blender/python/intern/bpy_rna.cc +++ b/source/blender/python/intern/bpy_rna.cc @@ -366,33 +366,22 @@ static bool rna_id_write_error(PointerRNA *ptr, PyObject *key) #endif /* USE_PEDANTIC_WRITE */ #ifdef USE_PEDANTIC_WRITE - -/* NOTE: Without the GIL, this can cause problems when called from threads, see: #127767. */ - bool pyrna_write_check() { - BLI_assert(PyGILState_Check()); - return !rna_disallow_writes; } void pyrna_write_set(bool val) { - BLI_assert(PyGILState_Check()); - rna_disallow_writes = !val; } #else /* USE_PEDANTIC_WRITE */ bool pyrna_write_check() { - BLI_assert(PyGILState_Check()); - return true; } void pyrna_write_set(bool /*val*/) { - BLI_assert(PyGILState_Check()); - /* pass */ } #endif /* USE_PEDANTIC_WRITE */ @@ -4508,8 +4497,8 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) std::optional path_str; if (newptr.owner_id) { - path_str = RNA_path_from_ID_to_property(&newptr, newprop); idptr = RNA_id_pointer_create(newptr.owner_id); + path_str = RNA_path_from_ID_to_property(&idptr, newprop); base_ptr = &idptr; } else { @@ -8650,7 +8639,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummy_ptr, continue; } - /* TODO(@ideasman42): Use #PyObject_GetOptionalAttr(), also in the macro below. */ + /* TODO(@ideasman42): Use Python3.7x _PyObject_LookupAttr(), also in the macro below. */ identifier = RNA_property_identifier(prop); item = PyObject_GetAttrString(py_class, identifier); @@ -9284,7 +9273,7 @@ static PyObject *pyrna_register_class(PyObject * /*self*/, PyObject *py_class) /* Call classed register method. * Note that zero falls through, no attribute, no error. */ - switch (PyObject_GetOptionalAttr(py_class, bpy_intern_str_register, &py_cls_meth)) { + switch (_PyObject_LookupAttr(py_class, bpy_intern_str_register, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, nullptr); Py_DECREF(py_cls_meth); @@ -9399,7 +9388,7 @@ static PyObject *pyrna_unregister_class(PyObject * /*self*/, PyObject *py_class) /* Call classed unregister method. * Note that zero falls through, no attribute, no error. */ - switch (PyObject_GetOptionalAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) { + switch (_PyObject_LookupAttr(py_class, bpy_intern_str_unregister, &py_cls_meth)) { case 1: { PyObject *ret = PyObject_CallObject(py_cls_meth, nullptr); Py_DECREF(py_cls_meth); diff --git a/source/blender/python/intern/bpy_rna_context.cc b/source/blender/python/intern/bpy_rna_context.cc index 1f96d6bcf10..28ee6d70913 100644 --- a/source/blender/python/intern/bpy_rna_context.cc +++ b/source/blender/python/intern/bpy_rna_context.cc @@ -153,32 +153,38 @@ struct BPyContextTempOverride { static void bpy_rna_context_temp_override__tp_dealloc(BPyContextTempOverride *self) { - PyObject_GC_UnTrack(self); - Py_CLEAR(self->py_state_context_dict); - PyObject_GC_Del(self); + PyObject_DEL(self); } -static int bpy_rna_context_temp_override_traverse(BPyContextTempOverride *self, - visitproc visit, - void *arg) +static PyObject *bpy_rna_context_temp_override_enter(BPyContextTempOverride *self) { - Py_VISIT(self->py_state_context_dict); - return 0; -} + bContext *C = self->context; + Main *bmain = CTX_data_main(C); -static int bpy_rna_context_temp_override_clear(BPyContextTempOverride *self) -{ - Py_CLEAR(self->py_state_context_dict); - return 0; -} + CTX_py_state_push(C, &self->py_state, self->py_state_context_dict); -static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTempOverride *self, - const Main *bmain, - const wmWindow *win, - const bScreen *screen, - const ScrArea *area, - const ARegion *region) -{ + self->ctx_init.win = CTX_wm_window(C); + self->ctx_init.screen = self->ctx_init.win ? WM_window_get_active_screen(self->ctx_init.win) : + CTX_wm_screen(C); + self->ctx_init.area = CTX_wm_area(C); + self->ctx_init.region = CTX_wm_region(C); + + wmWindow *win = self->ctx_temp.win_is_set ? self->ctx_temp.win : self->ctx_init.win; + bScreen *screen = self->ctx_temp.screen_is_set ? self->ctx_temp.screen : self->ctx_init.screen; + ScrArea *area = self->ctx_temp.area_is_set ? self->ctx_temp.area : self->ctx_init.area; + ARegion *region = self->ctx_temp.region_is_set ? self->ctx_temp.region : self->ctx_init.region; + + self->ctx_init.win_is_set = (self->ctx_init.win != win); + self->ctx_init.screen_is_set = (self->ctx_init.screen != screen); + self->ctx_init.area_is_set = (self->ctx_init.area != area); + self->ctx_init.region_is_set = (self->ctx_init.region != region); + + /* When the screen isn't passed but a window is, match the screen to the window, + * it's important to do this after setting `self->ctx_init.screen_is_set` because the screen is + * *not* set, only the window, restoring the window will also restore its screen, see #116297. */ + if ((self->ctx_temp.win_is_set == true) && (self->ctx_temp.screen_is_set == false)) { + screen = win ? WM_window_get_active_screen(win) : nullptr; + } /* NOTE(@ideasman42): Regarding sanity checks. * There are 3 different situations to be accounted for here regarding overriding windowing data. @@ -211,33 +217,33 @@ static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTemp if (self->ctx_temp.region_is_set && (region != nullptr)) { if (screen == nullptr && area == nullptr) { PyErr_SetString(PyExc_TypeError, "Region set with screen & area set to None"); - return false; + return nullptr; } if (!wm_check_region_exists(screen, area, region)) { PyErr_SetString(PyExc_TypeError, "Region not found in area or screen"); - return false; + return nullptr; } } if (self->ctx_temp.area_is_set && (area != nullptr)) { if (win == nullptr && screen == nullptr) { PyErr_SetString(PyExc_TypeError, "Area set with window & screen set to None"); - return false; + return nullptr; } if (!wm_check_area_exists(win, screen, area)) { PyErr_SetString(PyExc_TypeError, "Area not found in screen"); - return false; + return nullptr; } } if (self->ctx_temp.screen_is_set && (screen != nullptr)) { if (win == nullptr) { PyErr_SetString(PyExc_TypeError, "Screen set with null window"); - return false; + return nullptr; } if (!wm_check_screen_exists(bmain, screen)) { PyErr_SetString(PyExc_TypeError, "Screen not found"); - return false; + return nullptr; } /* Skip some checks when the screen is unchanged. */ @@ -248,16 +254,16 @@ static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTemp { PyErr_SetString(PyExc_TypeError, "Overriding context with an active temporary screen isn't supported"); - return false; + return nullptr; } if (!wm_check_screen_switch_supported(screen)) { PyErr_SetString(PyExc_TypeError, "Overriding context with temporary screen isn't supported"); - return false; + return nullptr; } if (BKE_workspace_layout_find_global(bmain, screen, nullptr) == nullptr) { PyErr_SetString(PyExc_TypeError, "Screen has no workspace"); - return false; + return nullptr; } LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { @@ -267,7 +273,7 @@ static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTemp } if (screen == WM_window_get_active_screen(win_iter)) { PyErr_SetString(PyExc_TypeError, "Screen is used by another window"); - return false; + return nullptr; } } } @@ -277,49 +283,10 @@ static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTemp if (self->ctx_temp.win_is_set && (win != nullptr)) { if (!wm_check_window_exists(bmain, win)) { PyErr_SetString(PyExc_TypeError, "Window not found"); - return false; + return nullptr; } } - return true; -} - -static PyObject *bpy_rna_context_temp_override_enter(BPyContextTempOverride *self) -{ - bContext *C = self->context; - Main *bmain = CTX_data_main(C); - - /* It's crucial to call #CTX_py_state_pop if this function fails with an error. */ - CTX_py_state_push(C, &self->py_state, self->py_state_context_dict); - - self->ctx_init.win = CTX_wm_window(C); - self->ctx_init.screen = self->ctx_init.win ? WM_window_get_active_screen(self->ctx_init.win) : - CTX_wm_screen(C); - self->ctx_init.area = CTX_wm_area(C); - self->ctx_init.region = CTX_wm_region(C); - - wmWindow *win = self->ctx_temp.win_is_set ? self->ctx_temp.win : self->ctx_init.win; - bScreen *screen = self->ctx_temp.screen_is_set ? self->ctx_temp.screen : self->ctx_init.screen; - ScrArea *area = self->ctx_temp.area_is_set ? self->ctx_temp.area : self->ctx_init.area; - ARegion *region = self->ctx_temp.region_is_set ? self->ctx_temp.region : self->ctx_init.region; - - self->ctx_init.win_is_set = (self->ctx_init.win != win); - self->ctx_init.screen_is_set = (self->ctx_init.screen != screen); - self->ctx_init.area_is_set = (self->ctx_init.area != area); - self->ctx_init.region_is_set = (self->ctx_init.region != region); - - /* When the screen isn't passed but a window is, match the screen to the window, - * it's important to do this after setting `self->ctx_init.screen_is_set` because the screen is - * *not* set, only the window, restoring the window will also restore its screen, see #116297. */ - if ((self->ctx_temp.win_is_set == true) && (self->ctx_temp.screen_is_set == false)) { - screen = win ? WM_window_get_active_screen(win) : nullptr; - } - - if (!bpy_rna_context_temp_override_enter_ok_or_error(self, bmain, win, screen, area, region)) { - CTX_py_state_pop(C, &self->py_state); - return nullptr; - } - /* Manipulate the context (setup). */ if (self->ctx_temp.screen_is_set) { self->ctx_temp_orig.screen = WM_window_get_active_screen(win); @@ -503,6 +470,7 @@ static PyObject *bpy_rna_context_temp_override_exit(BPyContextTempOverride *self Py_DECREF(context_dict_test); } CTX_py_state_pop(C, &self->py_state); + Py_CLEAR(self->py_state_context_dict); Py_RETURN_NONE; } @@ -542,10 +510,10 @@ static PyTypeObject BPyContextTempOverride_Type = { /*tp_getattro*/ nullptr, /*tp_setattro*/ nullptr, /*tp_as_buffer*/ nullptr, - /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + /*tp_flags*/ Py_TPFLAGS_DEFAULT, /*tp_doc*/ nullptr, - /*tp_traverse*/ (traverseproc)bpy_rna_context_temp_override_traverse, - /*tp_clear*/ (inquiry)bpy_rna_context_temp_override_clear, + /*tp_traverse*/ nullptr, + /*tp_clear*/ nullptr, /*tp_richcompare*/ nullptr, /*tp_weaklistoffset*/ 0, /*tp_iter*/ nullptr, @@ -729,8 +697,7 @@ static PyObject *bpy_context_temp_override(PyObject *self, PyObject *args, PyObj ctx_temp.region_is_set = true; } - BPyContextTempOverride *ret = PyObject_GC_New(BPyContextTempOverride, - &BPyContextTempOverride_Type); + BPyContextTempOverride *ret = PyObject_New(BPyContextTempOverride, &BPyContextTempOverride_Type); ret->context = C; ret->ctx_temp = ctx_temp; memset(&ret->ctx_init, 0, sizeof(ret->ctx_init)); @@ -739,8 +706,6 @@ static PyObject *bpy_context_temp_override(PyObject *self, PyObject *args, PyObj ret->py_state_context_dict = kwds; - PyObject_GC_Track(ret); - return (PyObject *)ret; } diff --git a/source/blender/render/hydra/viewport_engine.cc b/source/blender/render/hydra/viewport_engine.cc index 3f86855ba82..fea85ae9448 100644 --- a/source/blender/render/hydra/viewport_engine.cc +++ b/source/blender/render/hydra/viewport_engine.cc @@ -23,8 +23,6 @@ #include "GPU_matrix.hh" -#include "DEG_depsgraph_query.hh" - #include "RE_engine.h" namespace blender::render::hydra { @@ -46,19 +44,20 @@ ViewSettings::ViewSettings(bContext *context) View3D *view3d = CTX_wm_view3d(context); RegionView3D *region_data = static_cast(CTX_wm_region_data(context)); ARegion *region = CTX_wm_region(context); - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(context); - Scene *scene = DEG_get_evaluated_scene(depsgraph); screen_width = region->winx; screen_height = region->winy; + Scene *scene = CTX_data_scene(context); + /* Getting render border. */ int x1 = 0, y1 = 0; int x2 = screen_width, y2 = screen_height; if (region_data->persp == RV3D_CAMOB) { - Object *camera_obj = scene->camera; - if ((scene->r.mode & R_BORDER) && camera_obj && camera_obj->type == OB_CAMERA) { + if (scene->r.mode & R_BORDER) { + Object *camera_obj = scene->camera; + float camera_points[4][3]; BKE_camera_view_frame(scene, static_cast(camera_obj->data), camera_points); @@ -114,7 +113,7 @@ ViewSettings::ViewSettings(bContext *context) border = pxr::GfVec4i(x1, y1, x2, y2); - camera = gf_camera(depsgraph, + camera = gf_camera(CTX_data_ensure_evaluated_depsgraph(context), view3d, region, pxr::GfVec4f(float(border[0]) / screen_width, diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index c5feeded855..a5f60993637 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -1423,17 +1423,14 @@ static void renderresult_stampinfo(Render *re) RE_SetActiveRenderView(re, rv->name); RE_AcquireResultImage(re, &rres, nr); - if (rres.ibuf != nullptr) { - Object *ob_camera_eval = DEG_get_evaluated_object(re->pipeline_depsgraph, RE_GetCamera(re)); - BKE_image_stamp_buf(re->scene, - ob_camera_eval, - (re->scene->r.stamp & R_STAMP_STRIPMETA) ? rres.stamp_data : nullptr, - rres.ibuf->byte_buffer.data, - rres.ibuf->float_buffer.data, - rres.rectx, - rres.recty); - } - + Object *ob_camera_eval = DEG_get_evaluated_object(re->pipeline_depsgraph, RE_GetCamera(re)); + BKE_image_stamp_buf(re->scene, + ob_camera_eval, + (re->scene->r.stamp & R_STAMP_STRIPMETA) ? rres.stamp_data : nullptr, + rres.ibuf->byte_buffer.data, + rres.ibuf->float_buffer.data, + rres.rectx, + rres.recty); RE_ReleaseResultImage(re); nr++; } diff --git a/source/blender/render/intern/texture_image.cc b/source/blender/render/intern/texture_image.cc index 032bc858f5f..1061d7ca4e3 100644 --- a/source/blender/render/intern/texture_image.cc +++ b/source/blender/render/intern/texture_image.cc @@ -50,7 +50,7 @@ static void boxsample(ImBuf *ibuf, /* x and y have to be checked for image size */ static void ibuf_get_color(float col[4], ImBuf *ibuf, int x, int y) { - const int64_t ofs = int64_t(y) * ibuf->x + x; + int ofs = y * ibuf->x + x; if (ibuf->float_buffer.data) { if (ibuf->channels == 4) { @@ -723,7 +723,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf } if (ibuf->float_buffer.data) { - const float *fp = ibuf->float_buffer.data + (x + int64_t(y) * ibuf->x) * ibuf->channels; + const float *fp = ibuf->float_buffer.data + (x + y * ibuf->x) * ibuf->channels; if (ibuf->channels == 1) { col[0] = col[1] = col[2] = col[3] = *fp; } @@ -735,7 +735,7 @@ static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extf } } else { - const uchar *rect = ibuf->byte_buffer.data + 4 * (x + int64_t(y) * ibuf->x); + const uchar *rect = ibuf->byte_buffer.data + 4 * (x + y * ibuf->x); float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f); col[0] = rect[0] * inv_alpha_fac; col[1] = rect[1] * inv_alpha_fac; diff --git a/source/blender/sequencer/intern/render.cc b/source/blender/sequencer/intern/render.cc index 504874c2dae..d529a55c5ad 100644 --- a/source/blender/sequencer/intern/render.cc +++ b/source/blender/sequencer/intern/render.cc @@ -302,13 +302,7 @@ StripScreenQuad get_strip_screen_quad(const SeqRenderData *context, const Sequen float quad[4][2]; SEQ_image_transform_final_quad_get(scene, seq, quad); - const float scale = context->preview_render_size == SEQ_RENDER_SIZE_SCENE ? - float(scene->r.size) / 100.0f : - SEQ_rendersize_to_scale_factor(context->preview_render_size); - return StripScreenQuad{float2(quad[0]) * scale + offset, - float2(quad[1]) * scale + offset, - float2(quad[2]) * scale + offset, - float2(quad[3]) * scale + offset}; + return StripScreenQuad{quad[0] + offset, quad[1] + offset, quad[2] + offset, quad[3] + offset}; } /* Is quad `a` fully contained (i.e. covered by) quad `b`? For that to happen, diff --git a/source/blender/windowmanager/WM_api.hh b/source/blender/windowmanager/WM_api.hh index 4d2e0793363..c36e2435508 100644 --- a/source/blender/windowmanager/WM_api.hh +++ b/source/blender/windowmanager/WM_api.hh @@ -378,20 +378,9 @@ bool WM_stereo3d_enabled(wmWindow *win, bool skip_stereo3d_check); /* `wm_files.cc`. */ void WM_file_autoexec_init(const char *filepath); -/** - * \param use_scripts_autoexec_check: When true, script auto-execution checks excluded directories. - * Note that this is passed in as an argument because `filepath` may reference a path to recover. - * In this case the that used for exclusion is the recovery path which is only known once - * the file has been loaded. - */ -bool WM_file_read(bContext *C, - const char *filepath, - const bool use_scripts_autoexec_check, - ReportList *reports); +bool WM_file_read(bContext *C, const char *filepath, ReportList *reports); void WM_file_autosave_init(wmWindowManager *wm); -bool WM_file_recover_last_session(bContext *C, - bool use_scripts_autoexec_check, - ReportList *reports); +bool WM_file_recover_last_session(bContext *C, ReportList *reports); void WM_file_tag_modified(); /** diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.cc b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.cc index ec6b9acb414..b92b609c0ae 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.cc +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.cc @@ -536,12 +536,7 @@ static void gizmo_draw_select_3d_loop(const bContext *C, GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } else { - /* WORKAROUND(#132196): `GPU_DEPTH_NONE` leads to issues with Intel GPU drivers on Windows - * where camera gizmos cannot be shifted. `glGetQueryObjectuiv` for `GL_SAMPLES_PASSED` - * seems to return zero in all cases. This might be due to undefined behavior of OpenGL - * when the depth test is disabled and rendering to a depth render target-only framebuffer. - * Using `GPU_DEPTH_ALWAYS` fixes the issue. */ - GPU_depth_test(GPU_DEPTH_ALWAYS); + GPU_depth_test(GPU_DEPTH_NONE); } is_depth_prev = is_depth; } diff --git a/source/blender/windowmanager/intern/wm.cc b/source/blender/windowmanager/intern/wm.cc index 4c93bb9b880..1c1d2ad2dd9 100644 --- a/source/blender/windowmanager/intern/wm.cc +++ b/source/blender/windowmanager/intern/wm.cc @@ -172,7 +172,7 @@ static void window_manager_blend_read_data(BlendDataReader *reader, ID *id) win->eventstate_prev_press_time_ms = 0; win->event_last_handled = nullptr; win->cursor_keymap_status = nullptr; -#ifdef WITH_INPUT_IME +#if defined(WIN32) || defined(__APPLE__) win->ime_data = nullptr; win->ime_data_is_composing = false; #endif diff --git a/source/blender/windowmanager/intern/wm_cursors.cc b/source/blender/windowmanager/intern/wm_cursors.cc index abc575a964d..709549ed61f 100644 --- a/source/blender/windowmanager/intern/wm_cursors.cc +++ b/source/blender/windowmanager/intern/wm_cursors.cc @@ -356,7 +356,7 @@ bool wm_cursor_arrow_move(wmWindow *win, const wmEvent *event) return false; } -void WM_cursor_time(wmWindow *win, const int nr) +void WM_cursor_time(wmWindow *win, int nr) { /* 10 8x8 digits. */ const char number_bitmaps[10][8] = { @@ -378,24 +378,18 @@ void WM_cursor_time(wmWindow *win, const int nr) win->lastcursor = win->cursor; } - /* Negative numbers not supported by #wm_cursor_time_large & #wm_cursor_time_small. - * Make absolute to show *something* although in typical usage this shouldn't be negative. - * NOTE: Use of unsigned here to allow negation when `nr` is `std::numeric_limits::min()` - * which *can't* be negated. */ - uint32_t nr_abs = nr >= 0 ? uint32_t(nr) : -uint32_t(nr); - memset(&mask, 0xFF, sizeof(mask)); /* Print number bottom right justified. */ - for (int idx = 3; nr_abs && idx >= 0; idx--) { - const char *digit = number_bitmaps[nr_abs % 10]; + for (int idx = 3; nr && idx >= 0; idx--) { + const char *digit = number_bitmaps[nr % 10]; int x = idx % 2; int y = idx / 2; for (int i = 0; i < 8; i++) { bitmap[i + y * 8][x] = digit[i]; } - nr_abs /= 10; + nr /= 10; } window_set_custom_cursor(win, mask, bitmap, 7, 7); diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index ed0eeef89e0..41166cfccc9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -1026,11 +1026,8 @@ void WM_reportf(eReportType type, const char *format, ...) va_list args; format = RPT_(format); - va_start(args, format); char *str = BLI_vsprintfN(format, args); - va_end(args); - WM_report(type, str); MEM_freeN(str); } diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index 66cde874d00..2303bfd4583 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -1041,10 +1041,7 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) bf_reports->resynced_lib_overrides_libraries = nullptr; } -bool WM_file_read(bContext *C, - const char *filepath, - const bool use_scripts_autoexec_check, - ReportList *reports) +bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) { /* Assume automated tasks with background, don't write recent file list. */ const bool do_history_file_update = (G.background == false) && @@ -1111,14 +1108,6 @@ bool WM_file_read(bContext *C, G.f = (G.f & ~flags_keep) | (G_f_orig & flags_keep); } - /* Set by the `use_scripts` property on file load. - * If this was not set, then it should be calculated based on the file-path. - * Note that this uses `bmain->filepath` and not `filepath`, necessary when - * recovering the last session, where the file-path can be #BLENDER_QUIT_FILE. */ - if (use_scripts_autoexec_check) { - WM_file_autoexec_init(bmain->filepath); - } - WM_check(C); /* Opens window(s), checks keymaps. */ if (do_history_file_update) { @@ -2452,10 +2441,9 @@ void wm_open_init_load_ui(wmOperator *op, bool use_prefs) } } -bool wm_open_init_use_scripts(wmOperator *op, bool use_prefs) +void wm_open_init_use_scripts(wmOperator *op, bool use_prefs) { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts"); - bool use_scripts_autoexec_check = false; if (!RNA_property_is_set(op->ptr, prop)) { /* Use #G_FLAG_SCRIPT_AUTOEXEC rather than the userpref because this means if * the flag has been disabled from the command line, then opening @@ -2464,9 +2452,7 @@ bool wm_open_init_use_scripts(wmOperator *op, bool use_prefs) ((G.f & G_FLAG_SCRIPT_AUTOEXEC) != 0); RNA_property_boolean_set(op->ptr, prop, value); - use_scripts_autoexec_check = true; } - return use_scripts_autoexec_check; } /** \} */ @@ -3051,16 +3037,18 @@ void WM_OT_read_factory_settings(wmOperatorType *ot) /** * Wrap #WM_file_read, shared by file reading operators. */ -static bool wm_file_read_opwrap(bContext *C, - const char *filepath, - const bool use_scripts_autoexec_check, - ReportList *reports) +static bool wm_file_read_opwrap(bContext *C, const char *filepath, ReportList *reports) { /* XXX: wm in context is not set correctly after #WM_file_read -> crash. */ /* Do it before for now, but is this correct with multiple windows? */ WM_event_add_notifier(C, NC_WINDOW, nullptr); - const bool success = WM_file_read(C, filepath, use_scripts_autoexec_check, reports); + /* Set by the "use_scripts" property on file load. */ + if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) { + WM_file_autoexec_init(filepath); + } + + const bool success = WM_file_read(C, filepath, reports); return success; } @@ -3161,8 +3149,7 @@ static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op) RNA_string_set(op->ptr, "filepath", blendfile_path); wm_open_init_load_ui(op, true); - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); - UNUSED_VARS(use_scripts_autoexec_check); /* The user can set this in the UI. */ + wm_open_init_use_scripts(op, true); op->customdata = nullptr; WM_event_add_fileselect(C, op); @@ -3183,11 +3170,11 @@ static int wm_open_mainfile__open(bContext *C, wmOperator *op) /* Re-use last loaded setting so we can reload a file without changing. */ wm_open_init_load_ui(op, false); - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); + wm_open_init_use_scripts(op, false); SET_FLAG_FROM_TEST(G.fileflags, !RNA_boolean_get(op->ptr, "load_ui"), G_FILE_NO_UI); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); - success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); + success = wm_file_read_opwrap(C, filepath, op->reports); if (success) { if (G.fileflags & G_FILE_NO_UI) { @@ -3389,12 +3376,12 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op) bool success; char filepath[FILE_MAX]; - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); + wm_open_init_use_scripts(op, false); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); STRNCPY(filepath, BKE_main_blendfile_path(bmain)); - success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); + success = wm_file_read_opwrap(C, filepath, op->reports); if (success) { return OPERATOR_FINISHED; @@ -3427,24 +3414,21 @@ void WM_OT_revert_mainfile(wmOperatorType *ot) /** \name Recover Last Session Operator * \{ */ -bool WM_file_recover_last_session(bContext *C, - const bool use_scripts_autoexec_check, - ReportList *reports) +bool WM_file_recover_last_session(bContext *C, ReportList *reports) { char filepath[FILE_MAX]; BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_base(), BLENDER_QUIT_FILE); G.fileflags |= G_FILE_RECOVER_READ; - const bool success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, reports); + const bool success = wm_file_read_opwrap(C, filepath, reports); G.fileflags &= ~G_FILE_RECOVER_READ; return success; } -static int wm_recover_last_session_impl(bContext *C, - wmOperator *op, - const bool use_scripts_autoexec_check) +static int wm_recover_last_session_exec(bContext *C, wmOperator *op) { + wm_open_init_use_scripts(op, true); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); - if (WM_file_recover_last_session(C, use_scripts_autoexec_check, op->reports)) { + if (WM_file_recover_last_session(C, op->reports)) { if (!G.background) { wmOperatorType *ot = op->type; PointerRNA *props_ptr = MEM_new(__func__); @@ -3457,12 +3441,6 @@ static int wm_recover_last_session_impl(bContext *C, return OPERATOR_CANCELLED; } -static int wm_recover_last_session_exec(bContext *C, wmOperator *op) -{ - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); - return wm_recover_last_session_impl(C, op, use_scripts_autoexec_check); -} - static void wm_recover_last_session_after_dialog_callback(bContext *C, void *user_data) { WM_operator_name_call_with_properties( @@ -3473,14 +3451,14 @@ static int wm_recover_last_session_invoke(bContext *C, wmOperator *op, const wmE { /* Keep the current setting instead of using the preferences since a file selector * doesn't give us the option to change the setting. */ - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, false); + wm_open_init_use_scripts(op, false); if (wm_operator_close_file_dialog_if_needed( C, op, wm_recover_last_session_after_dialog_callback)) { return OPERATOR_INTERFACE; } - return wm_recover_last_session_impl(C, op, use_scripts_autoexec_check); + return wm_recover_last_session_exec(C, op); } void WM_OT_recover_last_session(wmOperatorType *ot) @@ -3509,12 +3487,12 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", filepath); BLI_path_canonicalize_native(filepath, sizeof(filepath)); - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); + wm_open_init_use_scripts(op, true); SET_FLAG_FROM_TEST(G.f, RNA_boolean_get(op->ptr, "use_scripts"), G_FLAG_SCRIPT_AUTOEXEC); G.fileflags |= G_FILE_RECOVER_READ; - success = wm_file_read_opwrap(C, filepath, use_scripts_autoexec_check, op->reports); + success = wm_file_read_opwrap(C, filepath, op->reports); G.fileflags &= ~G_FILE_RECOVER_READ; @@ -3537,8 +3515,7 @@ static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEven wm_autosave_location(filepath); RNA_string_set(op->ptr, "filepath", filepath); - const bool use_scripts_autoexec_check = wm_open_init_use_scripts(op, true); - UNUSED_VARS(use_scripts_autoexec_check); /* The user can set this in the UI. */ + wm_open_init_use_scripts(op, true); WM_event_add_fileselect(C, op); return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/windowmanager/intern/wm_gesture.cc b/source/blender/windowmanager/intern/wm_gesture.cc index eb668b35466..fcd60084aa9 100644 --- a/source/blender/windowmanager/intern/wm_gesture.cc +++ b/source/blender/windowmanager/intern/wm_gesture.cc @@ -448,7 +448,7 @@ static void draw_start_vertex_circle(const wmGesture >, const uint shdr_pos) const float dist = len_v2v2(start_pos, current_pos); const float limit = pow2f(blender::wm::gesture::POLYLINE_CLICK_RADIUS * UI_SCALE_FAC); - if (dist < limit && numverts > 3) { + if (dist < limit && numverts > 2) { const float u = smoothstep(0.0f, limit, dist); const float radius = interpf( 1.0f * UI_SCALE_FAC, blender::wm::gesture::POLYLINE_CLICK_RADIUS * UI_SCALE_FAC, u); diff --git a/source/blender/windowmanager/intern/wm_playanim.cc b/source/blender/windowmanager/intern/wm_playanim.cc index d79467a741f..9fd8320df22 100644 --- a/source/blender/windowmanager/intern/wm_playanim.cc +++ b/source/blender/windowmanager/intern/wm_playanim.cc @@ -2019,7 +2019,6 @@ static bool wm_main_playanim_intern(int argc, const char **argv, PlayArgs *args_ #endif /* USE_FRAME_CACHE_LIMIT */ STRNCPY(ibuf->filepath, ps.picture->filepath); - ibuf->fileframe = ps.picture->frame; } while (pupdate_time()) { diff --git a/source/blender/windowmanager/intern/wm_splash_screen.cc b/source/blender/windowmanager/intern/wm_splash_screen.cc index 0c1ddd10cbe..b601b9a61c9 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.cc +++ b/source/blender/windowmanager/intern/wm_splash_screen.cc @@ -154,7 +154,6 @@ static ImBuf *wm_block_splash_image(int width, int *r_height) if (ibuf == nullptr) { const uchar *splash_data = (const uchar *)datatoc_splash_png; size_t splash_data_size = datatoc_splash_png_size; - ibuf = IMB_ibImageFromMemory( splash_data, splash_data_size, IB_rect, nullptr, ""); } diff --git a/source/blender/windowmanager/wm.hh b/source/blender/windowmanager/wm.hh index 53ee7621a6b..42e6f5b5b10 100644 --- a/source/blender/windowmanager/wm.hh +++ b/source/blender/windowmanager/wm.hh @@ -8,8 +8,6 @@ #pragma once -#include "BLI_compiler_attrs.h" - struct wmWindow; #include "gizmo/wm_gizmo_wmapi.hh" @@ -117,7 +115,4 @@ void wm_stereo3d_set_cancel(bContext *C, wmOperator *op); * Initialize operator properties. */ void wm_open_init_load_ui(wmOperator *op, bool use_prefs); -/** - * Return true if the script auto-execution should be cleared based on #WM_file_autoexec_init. - */ -bool wm_open_init_use_scripts(wmOperator *op, bool use_prefs) ATTR_WARN_UNUSED_RESULT; +void wm_open_init_use_scripts(wmOperator *op, bool use_prefs); diff --git a/tests/gtests/testing/testing.h b/tests/gtests/testing/testing.h index b355ec3989c..8142bebec03 100644 --- a/tests/gtests/testing/testing.h +++ b/tests/gtests/testing/testing.h @@ -14,7 +14,7 @@ namespace blender::tests { /* These strings are passed on the CLI with the --test-asset-dir and --test-release-dir arguments. * The arguments are added automatically when invoking tests via `ctest`. */ -const std::string &flags_test_asset_dir(); /* tests/files in the Blender repository. */ +const std::string &flags_test_asset_dir(); /* tests/data in the Blender repository. */ const std::string &flags_test_release_dir(); /* bin/{blender version} in the build directory. */ } // namespace blender::tests diff --git a/tests/gtests/testing/testing_main.cc b/tests/gtests/testing/testing_main.cc index b5b5d846ad7..29530b14c07 100644 --- a/tests/gtests/testing/testing_main.cc +++ b/tests/gtests/testing/testing_main.cc @@ -6,7 +6,7 @@ #include "MEM_guardedalloc.h" -DEFINE_string(test_assets_dir, "", "tests/files directory containing the test assets."); +DEFINE_string(test_assets_dir, "", "tests/data directory containing the test assets."); DEFINE_string(test_release_dir, "", "bin/{blender version} directory of the current build."); namespace blender::tests { @@ -14,7 +14,7 @@ namespace blender::tests { const std::string &flags_test_asset_dir() { if (FLAGS_test_assets_dir.empty()) { - ADD_FAILURE() << "Pass the flag --test-assets-dir and point to the tests/files directory."; + ADD_FAILURE() << "Pass the flag --test-assets-dir and point to the tests/data directory."; } return FLAGS_test_assets_dir; } diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 356ff3455c7..90c315b0b9b 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -8,7 +8,7 @@ # and don't give deterministic results set(USE_EXPERIMENTAL_TESTS FALSE) -set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/tests/files) +set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/tests/data) set(TEST_PYTHON_DIR ${CMAKE_SOURCE_DIR}/tests/python) set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests) @@ -154,11 +154,6 @@ endif() # ------------------------------------------------------------------------------ # PY API TESTS -add_blender_test( - script_pyapi_bpy_app_tempdir - --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_app_tempdir.py -) - add_blender_test( script_pyapi_bpy_path --python ${CMAKE_CURRENT_LIST_DIR}/bl_pyapi_bpy_path.py @@ -758,17 +753,6 @@ if(WITH_CYCLES OR WITH_GPU_RENDER_TESTS) list(APPEND _gpu_render_tests_arguments --fail-silently) endif() - # Eevee - foreach(render_test ${gpu_render_tests}) - add_render_test( - eevee_${render_test} - ${CMAKE_CURRENT_LIST_DIR}/eevee_render_tests.py - -testdir "${TEST_SRC_DIR}/render/${render_test}" - -outdir "${TEST_OUT_DIR}/eevee" - ${_gpu_render_tests_arguments} - ) - endforeach() - # Eevee Next if(WITH_OPENGL_BACKEND) foreach(render_test ${gpu_render_tests}) diff --git a/tests/python/bl_alembic_io_test.py b/tests/python/bl_alembic_io_test.py index b10d3b78e6f..7c2b64e6c25 100644 --- a/tests/python/bl_alembic_io_test.py +++ b/tests/python/bl_alembic_io_test.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later """ -./blender.bin --background --factory-startup --python tests/python/bl_alembic_io_test.py -- --testdir /path/to/tests/files/alembic +./blender.bin --background --factory-startup --python tests/python/bl_alembic_io_test.py -- --testdir /path/to/tests/data/alembic """ import math diff --git a/tests/python/bl_animation_drivers.py b/tests/python/bl_animation_drivers.py index 1c16d629a6b..faf119b6b3c 100644 --- a/tests/python/bl_animation_drivers.py +++ b/tests/python/bl_animation_drivers.py @@ -9,7 +9,7 @@ import sys from rna_prop_ui import rna_idprop_quote_path """ -blender -b --factory-startup --python tests/python/bl_animation_drivers.py -- --testdir /path/to/tests/files/animation +blender -b --factory-startup --python tests/python/bl_animation_drivers.py -- --testdir /path/to/tests/data/animation """ diff --git a/tests/python/bl_animation_fcurves.py b/tests/python/bl_animation_fcurves.py index c87e0bfe825..8a49ad9e54b 100644 --- a/tests/python/bl_animation_fcurves.py +++ b/tests/python/bl_animation_fcurves.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later """ -blender -b --factory-startup --python tests/python/bl_animation_fcurves.py -- --testdir /path/to/tests/files/animation +blender -b --factory-startup --python tests/python/bl_animation_fcurves.py -- --testdir /path/to/tests/data/animation """ import pathlib diff --git a/tests/python/bl_animation_keyframing.py b/tests/python/bl_animation_keyframing.py index 3d0a5ee1ef0..28fc7c2f64e 100644 --- a/tests/python/bl_animation_keyframing.py +++ b/tests/python/bl_animation_keyframing.py @@ -9,7 +9,7 @@ import sys from math import radians """ -blender -b --factory-startup --python tests/python/bl_animation_keyframing.py -- --testdir /path/to/tests/files/animation +blender -b --factory-startup --python tests/python/bl_animation_keyframing.py -- --testdir /path/to/tests/data/animation """ diff --git a/tests/python/bl_blendfile_versioning.py b/tests/python/bl_blendfile_versioning.py index a242088c3a8..cde78f23480 100644 --- a/tests/python/bl_blendfile_versioning.py +++ b/tests/python/bl_blendfile_versioning.py @@ -152,7 +152,7 @@ def argparse_create(): # When --help or no args are given, print this help description = ("Test basic versioning code by opening all blend files " - "in `tests/files` directory.") + "in `tests/data` directory.") parser = argparse.ArgumentParser(description=description) parser.add_argument( "--src-test-dir", diff --git a/tests/python/bl_constraints.py b/tests/python/bl_constraints.py index f6617cb26ba..1136eaad93f 100644 --- a/tests/python/bl_constraints.py +++ b/tests/python/bl_constraints.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later """ -./blender.bin --background --factory-startup --python tests/python/bl_constraints.py -- --testdir /path/to/tests/files/constraints +./blender.bin --background --factory-startup --python tests/python/bl_constraints.py -- --testdir /path/to/tests/data/constraints """ import pathlib diff --git a/tests/python/bl_rigging_symmetrize.py b/tests/python/bl_rigging_symmetrize.py index 46cea562ce9..898dcf684da 100644 --- a/tests/python/bl_rigging_symmetrize.py +++ b/tests/python/bl_rigging_symmetrize.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later """ -blender -b --factory-startup --python tests/python/bl_rigging_symmetrize.py -- --testdir /path/to/tests/files/animation +blender -b --factory-startup --python tests/python/bl_rigging_symmetrize.py -- --testdir /path/to/tests/data/animation """ import pathlib diff --git a/tests/python/collada/animation/test_animation_simple.py b/tests/python/collada/animation/test_animation_simple.py index 3d86bbabfb8..f28a6542c9d 100644 --- a/tests/python/collada/animation/test_animation_simple.py +++ b/tests/python/collada/animation/test_animation_simple.py @@ -5,7 +5,7 @@ """ Call as follows: -python collada_mesh_simple.py --blender PATH_TO_BLENDER_EXE --testdir tests/files/collada/mesh +python collada_mesh_simple.py --blender PATH_TO_BLENDER_EXE --testdir tests/data/collada/mesh """ import sys diff --git a/tests/python/collada/mesh/test_mesh_simple.py b/tests/python/collada/mesh/test_mesh_simple.py index 20806100ee5..bbf723f7819 100644 --- a/tests/python/collada/mesh/test_mesh_simple.py +++ b/tests/python/collada/mesh/test_mesh_simple.py @@ -5,7 +5,7 @@ """ Call as follows: -python collada_mesh_simple.py --blender PATH_TO_BLENDER_EXE --testdir tests/files/collada/mesh +python collada_mesh_simple.py --blender PATH_TO_BLENDER_EXE --testdir tests/data/collada/mesh """ import sys diff --git a/tests/python/curve_to_mesh.py b/tests/python/curve_to_mesh.py index ef047ee0b67..fe0d299e371 100644 --- a/tests/python/curve_to_mesh.py +++ b/tests/python/curve_to_mesh.py @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # To run all tests, use -# BLENDER_VERBOSE=1 ./bin/blender ../tests/files/modeling/curve_to_mesh.blend --python ../blender/tests/python/bl_curve_to_mesh.py -- --run-all-tests +# BLENDER_VERBOSE=1 ./bin/blender ../tests/data/modeling/curve_to_mesh.blend --python ../blender/tests/python/bl_curve_to_mesh.py -- --run-all-tests # (that assumes the test is run from a build directory in the same directory as the source code) import bpy import os diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py index f84553c8da0..227556af40a 100755 --- a/tests/python/modules/render_report.py +++ b/tests/python/modules/render_report.py @@ -240,7 +240,7 @@ class Report: message += """

BLENDER_TEST_UPDATE=1 ctest -R %s

""" % self.engine_name message += """

This then happens for new and failing tests; reference images of """ \ """passing test cases will not be updated. Be sure to commit the new reference """ \ - """images to the tests/files git submodule afterwards.

""" + """images to the tests/data git submodule afterwards.

""" message += """""" else: message = "" diff --git a/tests/python/view_layer/CMakeLists.txt b/tests/python/view_layer/CMakeLists.txt index 8b994e70936..4d5a25890f0 100644 --- a/tests/python/view_layer/CMakeLists.txt +++ b/tests/python/view_layer/CMakeLists.txt @@ -6,7 +6,7 @@ # Use '--write-blend=/tmp/test.blend' to view output -set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/tests/files) +set(TEST_SRC_DIR ${CMAKE_SOURCE_DIR}/tests/data) set(TEST_OUT_DIR ${CMAKE_BINARY_DIR}/tests) # ugh, any better way to do this on testing only? diff --git a/tools/check_source/check_mypy_config.py b/tools/check_source/check_mypy_config.py index b2018c3e1f3..1ad4b384f48 100644 --- a/tools/check_source/check_mypy_config.py +++ b/tools/check_source/check_mypy_config.py @@ -17,7 +17,6 @@ PATHS: Tuple[Tuple[str, Tuple[Any, ...], Dict[str, str]], ...] = ( ("scripts/modules/_bpy_internal/extensions/junction_module.py", (), {}), ("scripts/modules/_bpy_internal/extensions/wheel_manager.py", (), {}), ("scripts/modules/_bpy_internal/freedesktop.py", (), {}), - ("tests/python/bl_pyapi_bpy_app_tempdir.py", (), {}), ("tools/check_blender_release/", (), {}), ("tools/check_docs/", (), {}), ("tools/check_source/", (), {'MYPYPATH': "modules"}), diff --git a/tools/utils_maintenance/autopep8_format_paths.py b/tools/utils_maintenance/autopep8_format_paths.py index bbdf38d4077..0ca9e488e19 100755 --- a/tools/utils_maintenance/autopep8_format_paths.py +++ b/tools/utils_maintenance/autopep8_format_paths.py @@ -84,7 +84,7 @@ def source_files_from_git(paths: List[str], changed_only: bool) -> List[str]: else: cmd = ("git", "ls-tree", "-r", "HEAD", *paths, "--name-only", "-z") files = subprocess.check_output(cmd).split(b'\0') - return [f.decode('utf-8') for f in files] + return [f.decode('ascii') for f in files] def autopep8_parse_version(version: str) -> Tuple[int, int, int]: diff --git a/tools/utils_maintenance/clang_format_paths.py b/tools/utils_maintenance/clang_format_paths.py index 3cdce497cc4..8b65145425b 100755 --- a/tools/utils_maintenance/clang_format_paths.py +++ b/tools/utils_maintenance/clang_format_paths.py @@ -97,7 +97,7 @@ def source_files_from_git(paths: Sequence[str], changed_only: bool) -> List[str] else: cmd = ("git", "ls-tree", "-r", "HEAD", *paths, "--name-only", "-z") files = subprocess.check_output(cmd).split(b'\0') - return [f.decode('utf-8') for f in files] + return [f.decode('ascii') for f in files] def convert_tabs_to_spaces(files: Sequence[str]) -> None: